Lines Matching +full:x +full:- +full:ts +full:- +full:routes
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * SR-IPv6 implementation
76 /* default length values (expressed in bits) for both Locator-Block and
77 * Locator-Node Function.
82 * Locator-Block and Locator-Node Function must be byte-aligned (we can
97 * used directly to check whether the lengths (in bits) of Locator-Block and
98 * Locator-Node Function are valid according to (i), (ii), (iii).
130 /* Locator-Block length, expressed in bits */
132 /* Locator-Node Function length, expressed in bits*/
137 DT_INVALID_MODE = -EINVAL,
169 * values after the per-CPU counter evaluation has been performed.
213 return (struct seg6_local_lwt *)lwt->data; in seg6_local_lwtunnel()
238 if (srh && srh->segments_left > 0) in decap_and_validate()
266 srh->segments_left--; in advance_nextseg()
267 addr = srh->segments + srh->segments_left; in advance_nextseg()
275 struct net *net = dev_net(skb->dev); in seg6_lookup_any_nexthop()
284 fl6.flowi6_iif = skb->dev->ifindex; in seg6_lookup_any_nexthop()
285 fl6.daddr = nhaddr ? *nhaddr : hdr->daddr; in seg6_lookup_any_nexthop()
286 fl6.saddr = hdr->saddr; in seg6_lookup_any_nexthop()
288 fl6.flowi6_mark = skb->mark; in seg6_lookup_any_nexthop()
289 fl6.flowi6_proto = hdr->nexthdr; in seg6_lookup_any_nexthop()
295 dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags); in seg6_lookup_any_nexthop()
304 dst = &rt->dst; in seg6_lookup_any_nexthop()
313 if (dst && (dst->dev->flags & dev_flags) && !dst->error) { in seg6_lookup_any_nexthop()
320 rt = net->ipv6.ip6_blk_hole_entry; in seg6_lookup_any_nexthop()
321 dst = &rt->dst; in seg6_lookup_any_nexthop()
327 return dst->error; in seg6_lookup_any_nexthop()
338 return finfo->lcblock_bits >> 3; in seg6_flv_lcblock_octects()
343 return finfo->lcnode_func_bits >> 3; in seg6_flv_lcnode_func_octects()
354 arg_octects = 16 - blk_octects - fnc_octects; in seg6_next_csid_is_arg_zero()
356 if (addr->s6_addr[blk_octects + fnc_octects + i] != 0x00) in seg6_next_csid_is_arg_zero()
371 memmove(&addr->s6_addr[blk_octects], in seg6_next_csid_advance_arg()
372 &addr->s6_addr[blk_octects + fnc_octects], in seg6_next_csid_advance_arg()
373 16 - blk_octects - fnc_octects); in seg6_next_csid_advance_arg()
375 memset(&addr->s6_addr[16 - fnc_octects], 0x00, fnc_octects); in seg6_next_csid_advance_arg()
395 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in input_action_end_core()
401 return -EINVAL; in input_action_end_core()
406 const struct seg6_flavors_info *finfo = &slwt->flv_info; in end_next_csid_core()
407 struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; in end_next_csid_core()
421 seg6_lookup_nexthop(skb, &slwt->nh6, 0); in input_action_end_x_finish()
435 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in input_action_end_x_core()
441 return -EINVAL; in input_action_end_x_core()
447 const struct seg6_flavors_info *finfo = &slwt->flv_info; in end_x_next_csid_core()
448 struct in6_addr *daddr = &ipv6_hdr(skb)->daddr; in end_x_next_csid_core()
464 /* Processing of SRv6 End, End.X, and End.T behaviors can be extended through
480 return -EOPNOTSUPP; in seg6_flv_supp_ops_by_action()
500 #define SEG6_LOCAL_PKTINFO_MAX (__SEG6_LOCAL_PKTINFO_MAX - 1)
509 sgl = srh->segments_left; in seg6_get_srh_pktinfo()
525 #define SEG6_LOCAL_FLV_ACT_MAX (__SEG6_LOCAL_FLV_ACT_MAX - 1)
537 * +----------------+----------------+
539 * +----------------+----------------+
540 * ph-1 ... p1 p0 fk-1 ... f1 f0
544 * - 'afm' (adjusted flavor mask) is the mask containing a combination of the
546 * argument of the macro whose value is righ-shifted by 1 bit. By doing so,
549 * - 'pf' encodes the packet info (pktinfo) regarding the presence/absence of
600 * - info extracted from the packet (i.e. pktinfo data) regarding the
603 * - the mask of flavors configured for the specific SRv6 End* behavior.
624 /* skb->data must be aligned with skb->network_header */
630 int thoff = -1; in seg6_pop_srh()
638 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); in seg6_pop_srh()
646 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); in seg6_pop_srh()
647 srh_nexthdr = srh->nexthdr; in seg6_pop_srh()
661 thoff = nhlen - srhlen; in seg6_pop_srh()
688 if (iph->nexthdr == NEXTHDR_ROUTING) { in seg6_pop_srh()
689 iph->nexthdr = srh_nexthdr; in seg6_pop_srh()
698 __u8 nexthdr = iph->nexthdr; in seg6_pop_srh()
709 if (hp->nexthdr == NEXTHDR_ROUTING) { in seg6_pop_srh()
710 hp->nexthdr = srh_nexthdr; in seg6_pop_srh()
725 nexthdr = hp->nexthdr; in seg6_pop_srh()
729 iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); in seg6_pop_srh()
741 const struct seg6_flavors_info *finfo = &slwt->flv_info; in end_flv8986_core()
749 srhoff = srh ? ((unsigned char *)srh - skb->data) : 0; in end_flv8986_core()
755 flvmask = finfo->flv_ops; in end_flv8986_core()
768 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in end_flv8986_core()
771 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in end_flv8986_core()
789 return -EINVAL; in end_flv8986_core()
795 const struct seg6_flavors_info *finfo = &slwt->flv_info; in input_action_end()
796 __u32 fops = finfo->flv_ops; in input_action_end()
801 /* check for the presence of NEXT-C-SID since it applies first */ in input_action_end()
816 const struct seg6_flavors_info *finfo = &slwt->flv_info; in input_action_end_x()
817 __u32 fops = finfo->flv_ops; in input_action_end_x()
819 /* check for the presence of NEXT-C-SID since it applies first */ in input_action_end_x()
834 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in input_action_end_t()
836 seg6_lookup_nexthop(skb, NULL, slwt->table); in input_action_end_t()
842 return -EINVAL; in input_action_end_t()
849 struct net *net = dev_net(skb->dev); in input_action_end_dx2()
860 eth = (struct ethhdr *)skb->data; in input_action_end_dx2()
866 if (!eth_proto_is_802_3(eth->h_proto)) in input_action_end_dx2()
869 odev = dev_get_by_index_rcu(net, slwt->oif); in input_action_end_dx2()
876 if (odev->type != ARPHRD_ETHER) in input_action_end_dx2()
879 if (!(odev->flags & IFF_UP) || !netif_carrier_ok(odev)) in input_action_end_dx2()
889 if (skb->len - ETH_HLEN > odev->mtu) in input_action_end_dx2()
892 skb->dev = odev; in input_action_end_dx2()
893 skb->protocol = eth->h_proto; in input_action_end_dx2()
899 return -EINVAL; in input_action_end_dx2()
909 slwt = seg6_local_lwtunnel(orig_dst->lwtstate); in input_action_end_dx6_finish()
914 * If slwt->nh6 is set to ::, then lookup the nexthop for the in input_action_end_dx6_finish()
917 if (!ipv6_addr_any(&slwt->nh6)) in input_action_end_dx6_finish()
918 nhaddr = &slwt->nh6; in input_action_end_dx6_finish()
944 dev_net(skb->dev), NULL, skb, skb->dev, in input_action_end_dx6()
947 return input_action_end_dx6_finish(dev_net(skb->dev), NULL, skb); in input_action_end_dx6()
950 return -EINVAL; in input_action_end_dx6()
962 slwt = seg6_local_lwtunnel(orig_dst->lwtstate); in input_action_end_dx4_finish()
966 nhaddr = slwt->nh4.s_addr ?: iph->daddr; in input_action_end_dx4_finish()
970 reason = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev); in input_action_end_dx4_finish()
973 return -EINVAL; in input_action_end_dx4_finish()
988 skb->protocol = htons(ETH_P_IP); in input_action_end_dx4()
994 dev_net(skb->dev), NULL, skb, skb->dev, in input_action_end_dx4()
997 return input_action_end_dx4_finish(dev_net(skb->dev), NULL, skb); in input_action_end_dx4()
1000 return -EINVAL; in input_action_end_dx4()
1006 const struct nl_info *nli = &fib6_cfg->fc_nlinfo; in fib6_config_get_net()
1008 return nli->nl_net; in fib6_config_get_net()
1014 struct seg6_end_dt_info *info = &slwt->dt_info; in __seg6_end_dt_vrf_build()
1022 info->vrf_table); in __seg6_end_dt_vrf_build()
1024 if (vrf_ifindex == -EPERM) { in __seg6_end_dt_vrf_build()
1027 } else if (vrf_ifindex == -ENODEV) { in __seg6_end_dt_vrf_build()
1038 info->net = net; in __seg6_end_dt_vrf_build()
1039 info->vrf_ifindex = vrf_ifindex; in __seg6_end_dt_vrf_build()
1041 info->family = family; in __seg6_end_dt_vrf_build()
1042 info->mode = DT_VRF_MODE; in __seg6_end_dt_vrf_build()
1048 * routes the IPv4/IPv6 packet by looking at the configured routing table.
1071 * - the sk_buff* when the VRF rcv handler has processed the packet correctly;
1072 * - NULL when the skb is consumed by the VRF rcv handler;
1073 * - a pointer which encodes a negative error number in case of error.
1083 if (unlikely(!dev->l3mdev_ops->l3mdev_l3_rcv)) in end_dt_vrf_rcv()
1092 skb = dev->l3mdev_ops->l3mdev_l3_rcv(dev, skb, family); in end_dt_vrf_rcv()
1100 if (unlikely(skb->dev != dev || skb->skb_iif != dev->ifindex)) in end_dt_vrf_rcv()
1107 return ERR_PTR(-EINVAL); in end_dt_vrf_rcv()
1113 int vrf_ifindex = info->vrf_ifindex; in end_dt_get_vrf_rcu()
1114 struct net *net = info->net; in end_dt_get_vrf_rcu()
1119 if (unlikely(!net_eq(dev_net(skb->dev), net))) in end_dt_get_vrf_rcu()
1131 struct seg6_end_dt_info *info = &slwt->dt_info; in end_dt_vrf_core()
1155 if (unlikely(info->family != AF_UNSPEC && info->family != family)) { in end_dt_vrf_core()
1160 skb->protocol = protocol; in end_dt_vrf_core()
1171 return ERR_PTR(-EINVAL); in end_dt_vrf_core()
1196 reason = ip_route_input(skb, iph->daddr, iph->saddr, 0, skb->dev); in input_action_end_dt4()
1204 return -EINVAL; in input_action_end_dt4()
1216 unsigned long parsed_optattrs = slwt->parsed_optattrs; in seg6_end_dt6_parse_mode()
1231 struct seg6_end_dt_info *info = &slwt->dt_info; in seg6_end_dt6_get_mode()
1233 return info->mode; in seg6_end_dt6_get_mode()
1240 struct seg6_end_dt_info *info = &slwt->dt_info; in seg6_end_dt6_build()
1244 info->mode = DT_LEGACY_MODE; in seg6_end_dt6_build()
1250 return -EINVAL; in seg6_end_dt6_build()
1288 seg6_lookup_any_nexthop(skb, NULL, slwt->table, true); in input_action_end_dt6()
1294 return -EINVAL; in input_action_end_dt6()
1310 nexthdr = ipv6_find_hdr(skb, &off, -1, NULL, NULL); in input_action_end_dt46()
1323 return -EINVAL; in input_action_end_dt46()
1331 int err = -EINVAL; in input_action_end_b6()
1337 err = seg6_do_srh_inline(skb, slwt->srh); in input_action_end_b6()
1357 int err = -EINVAL; in input_action_end_b6_encap()
1363 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in input_action_end_b6_encap()
1366 skb->encapsulation = 1; in input_action_end_b6_encap()
1368 err = seg6_do_srh_encap(skb, slwt->srh, IPPROTO_IPV6); in input_action_end_b6_encap()
1391 struct ipv6_sr_hdr *srh = srh_state->srh; in seg6_bpf_has_valid_srh()
1393 lockdep_assert_held(&srh_state->bh_lock); in seg6_bpf_has_valid_srh()
1397 if (unlikely(!srh_state->valid)) { in seg6_bpf_has_valid_srh()
1398 if ((srh_state->hdrlen & 7) != 0) in seg6_bpf_has_valid_srh()
1401 srh->hdrlen = (u8)(srh_state->hdrlen >> 3); in seg6_bpf_has_valid_srh()
1402 if (!seg6_validate_srh(srh, (srh->hdrlen + 1) << 3, true)) in seg6_bpf_has_valid_srh()
1405 srh_state->valid = true; in seg6_bpf_has_valid_srh()
1421 return -EINVAL; in input_action_end_bpf()
1423 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in input_action_end_bpf()
1425 /* The access to the per-CPU buffer srh_state is protected by running in input_action_end_bpf()
1433 srh_state->srh = srh; in input_action_end_bpf()
1434 srh_state->hdrlen = srh->hdrlen << 3; in input_action_end_bpf()
1435 srh_state->valid = true; in input_action_end_bpf()
1439 ret = bpf_prog_run_save_cb(slwt->bpf.prog, skb); in input_action_end_bpf()
1449 pr_warn_once("bpf-seg6local: Illegal return value %u\n", ret); in input_action_end_bpf()
1453 if (srh_state->srh && !seg6_bpf_has_valid_srh(skb)) in input_action_end_bpf()
1465 return -EINVAL; in input_action_end_bpf()
1575 if (desc->action == action) in __get_action_desc()
1584 return slwt->parsed_optattrs & SEG6_F_LOCAL_COUNTERS; in seg6_lwtunnel_counters_enabled()
1592 pcounters = this_cpu_ptr(slwt->pcpu_counters); in seg6_local_update_counters()
1593 u64_stats_update_begin(&pcounters->syncp); in seg6_local_update_counters()
1596 u64_stats_inc(&pcounters->packets); in seg6_local_update_counters()
1597 u64_stats_add(&pcounters->bytes, len); in seg6_local_update_counters()
1599 u64_stats_inc(&pcounters->errors); in seg6_local_update_counters()
1602 u64_stats_update_end(&pcounters->syncp); in seg6_local_update_counters()
1611 unsigned int len = skb->len; in seg6_local_input_core()
1614 slwt = seg6_local_lwtunnel(orig_dst->lwtstate); in seg6_local_input_core()
1615 desc = slwt->desc; in seg6_local_input_core()
1617 rc = desc->input(skb, slwt); in seg6_local_input_core()
1629 if (skb->protocol != htons(ETH_P_IPV6)) { in seg6_local_input()
1631 return -EINVAL; in seg6_local_input()
1636 dev_net(skb->dev), NULL, skb, skb->dev, NULL, in seg6_local_input()
1639 return seg6_local_input_core(dev_net(skb->dev), NULL, skb); in seg6_local_input()
1669 return -EINVAL; in parse_nla_srh()
1672 return -EINVAL; in parse_nla_srh()
1674 slwt->srh = kmemdup(srh, len, GFP_KERNEL); in parse_nla_srh()
1675 if (!slwt->srh) in parse_nla_srh()
1676 return -ENOMEM; in parse_nla_srh()
1678 slwt->headroom += len; in parse_nla_srh()
1689 srh = slwt->srh; in put_nla_srh()
1690 len = (srh->hdrlen + 1) << 3; in put_nla_srh()
1694 return -EMSGSIZE; in put_nla_srh()
1703 int len = (a->srh->hdrlen + 1) << 3; in cmp_nla_srh()
1705 if (len != ((b->srh->hdrlen + 1) << 3)) in cmp_nla_srh()
1708 return memcmp(a->srh, b->srh, len); in cmp_nla_srh()
1713 kfree(slwt->srh); in destroy_attr_srh()
1719 slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]); in parse_nla_table()
1726 if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table)) in put_nla_table()
1727 return -EMSGSIZE; in put_nla_table()
1734 if (a->table != b->table) in cmp_nla_table()
1744 return &slwt->dt_info; in seg6_possible_end_dt_info()
1746 return ERR_PTR(-EOPNOTSUPP); in seg6_possible_end_dt_info()
1759 info->vrf_table = nla_get_u32(attrs[SEG6_LOCAL_VRFTABLE]); in parse_nla_vrftable()
1771 if (nla_put_u32(skb, SEG6_LOCAL_VRFTABLE, info->vrf_table)) in put_nla_vrftable()
1772 return -EMSGSIZE; in put_nla_vrftable()
1782 if (info_a->vrf_table != info_b->vrf_table) in cmp_nla_vrftable()
1791 memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]), in parse_nla_nh4()
1803 return -EMSGSIZE; in put_nla_nh4()
1805 memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr)); in put_nla_nh4()
1812 return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr)); in cmp_nla_nh4()
1818 memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]), in parse_nla_nh6()
1830 return -EMSGSIZE; in put_nla_nh6()
1832 memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr)); in put_nla_nh6()
1839 return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr)); in cmp_nla_nh6()
1845 slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]); in parse_nla_iif()
1852 if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif)) in put_nla_iif()
1853 return -EMSGSIZE; in put_nla_iif()
1860 if (a->iif != b->iif) in cmp_nla_iif()
1869 slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]); in parse_nla_oif()
1876 if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif)) in put_nla_oif()
1877 return -EMSGSIZE; in put_nla_oif()
1884 if (a->oif != b->oif) in cmp_nla_oif()
1912 return -EINVAL; in parse_nla_bpf()
1914 slwt->bpf.name = nla_memdup(tb[SEG6_LOCAL_BPF_PROG_NAME], GFP_KERNEL); in parse_nla_bpf()
1915 if (!slwt->bpf.name) in parse_nla_bpf()
1916 return -ENOMEM; in parse_nla_bpf()
1921 kfree(slwt->bpf.name); in parse_nla_bpf()
1925 slwt->bpf.prog = p; in parse_nla_bpf()
1933 if (!slwt->bpf.prog) in put_nla_bpf()
1938 return -EMSGSIZE; in put_nla_bpf()
1940 if (nla_put_u32(skb, SEG6_LOCAL_BPF_PROG, slwt->bpf.prog->aux->id)) in put_nla_bpf()
1941 return -EMSGSIZE; in put_nla_bpf()
1943 if (slwt->bpf.name && in put_nla_bpf()
1944 nla_put_string(skb, SEG6_LOCAL_BPF_PROG_NAME, slwt->bpf.name)) in put_nla_bpf()
1945 return -EMSGSIZE; in put_nla_bpf()
1952 if (!a->bpf.name && !b->bpf.name) in cmp_nla_bpf()
1955 if (!a->bpf.name || !b->bpf.name) in cmp_nla_bpf()
1958 return strcmp(a->bpf.name, b->bpf.name); in cmp_nla_bpf()
1963 kfree(slwt->bpf.name); in destroy_attr_bpf()
1964 if (slwt->bpf.prog) in destroy_attr_bpf()
1965 bpf_prog_put(slwt->bpf.prog); in destroy_attr_bpf()
1994 return -EINVAL; in parse_nla_counters()
1999 return -ENOMEM; in parse_nla_counters()
2001 slwt->pcpu_counters = pcounters; in parse_nla_counters()
2009 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_PACKETS, counters->packets, in seg6_local_fill_nla_counters()
2011 return -EMSGSIZE; in seg6_local_fill_nla_counters()
2013 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_BYTES, counters->bytes, in seg6_local_fill_nla_counters()
2015 return -EMSGSIZE; in seg6_local_fill_nla_counters()
2017 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_ERRORS, counters->errors, in seg6_local_fill_nla_counters()
2019 return -EMSGSIZE; in seg6_local_fill_nla_counters()
2032 return -EMSGSIZE; in put_nla_counters()
2039 pcounters = per_cpu_ptr(slwt->pcpu_counters, i); in put_nla_counters()
2041 start = u64_stats_fetch_begin(&pcounters->syncp); in put_nla_counters()
2043 packets = u64_stats_read(&pcounters->packets); in put_nla_counters()
2044 bytes = u64_stats_read(&pcounters->bytes); in put_nla_counters()
2045 errors = u64_stats_read(&pcounters->errors); in put_nla_counters()
2047 } while (u64_stats_fetch_retry(&pcounters->syncp, start)); in put_nla_counters()
2066 return (!!((unsigned long)a->pcpu_counters)) ^ in cmp_nla_counters()
2067 (!!((unsigned long)b->pcpu_counters)); in cmp_nla_counters()
2072 free_percpu(slwt->pcpu_counters); in destroy_attr_counters()
2082 /* check whether the lengths of the Locator-Block and Locator-Node Function
2083 * are compatible with the dimension of a C-SID container.
2087 /* Locator-Block and Locator-Node Function cannot exceed 128 bits in seg6_chk_next_csid_cfg()
2088 * (i.e. C-SID container lenghts). in seg6_chk_next_csid_cfg()
2091 return -EINVAL; in seg6_chk_next_csid_cfg()
2093 /* Locator-Block length must be greater than zero and evenly divisible in seg6_chk_next_csid_cfg()
2094 * by 8. There must be room for a Locator-Node Function, at least. in seg6_chk_next_csid_cfg()
2097 return -EINVAL; in seg6_chk_next_csid_cfg()
2099 /* Locator-Node Function length must be greater than zero and evenly in seg6_chk_next_csid_cfg()
2100 * divisible by 8. There must be room for the Locator-Block. in seg6_chk_next_csid_cfg()
2103 return -EINVAL; in seg6_chk_next_csid_cfg()
2129 finfo->lcblock_bits = block_len; in seg6_parse_nla_next_csid_cfg()
2130 finfo->lcnode_func_bits = func_len; in seg6_parse_nla_next_csid_cfg()
2138 struct seg6_flavors_info *finfo = &slwt->flv_info; in parse_nla_flavors()
2140 int action = slwt->action; in parse_nla_flavors()
2154 return -EINVAL; in parse_nla_flavors()
2160 return -EOPNOTSUPP; in parse_nla_flavors()
2163 finfo->flv_ops = fops; in parse_nla_flavors()
2166 /* Locator-Block and Locator-Node Function lengths can be in parse_nla_flavors()
2181 if (nla_put_u8(skb, SEG6_LOCAL_FLV_LCBLOCK_BITS, finfo->lcblock_bits)) in seg6_fill_nla_next_csid_cfg()
2182 return -EMSGSIZE; in seg6_fill_nla_next_csid_cfg()
2185 finfo->lcnode_func_bits)) in seg6_fill_nla_next_csid_cfg()
2186 return -EMSGSIZE; in seg6_fill_nla_next_csid_cfg()
2193 struct seg6_flavors_info *finfo = &slwt->flv_info; in put_nla_flavors()
2194 __u32 fops = finfo->flv_ops; in put_nla_flavors()
2200 return -EMSGSIZE; in put_nla_flavors()
2203 rc = -EMSGSIZE; in put_nla_flavors()
2223 if (finfo_a->lcblock_bits != finfo_b->lcblock_bits) in seg6_cmp_nla_next_csid_cfg()
2226 if (finfo_a->lcnode_func_bits != finfo_b->lcnode_func_bits) in seg6_cmp_nla_next_csid_cfg()
2234 struct seg6_flavors_info *finfo_a = &a->flv_info; in cmp_nla_flavors()
2235 struct seg6_flavors_info *finfo_b = &b->flv_info; in cmp_nla_flavors()
2237 if (finfo_a->flv_ops != finfo_b->flv_ops) in cmp_nla_flavors()
2240 if (seg6_next_csid_enabled(finfo_a->flv_ops)) { in cmp_nla_flavors()
2250 struct seg6_flavors_info *finfo = &slwt->flv_info; in encap_size_flavors()
2256 if (seg6_next_csid_enabled(finfo->flv_ops)) in encap_size_flavors()
2346 if (param->destroy) in __destroy_attrs()
2347 param->destroy(slwt); in __destroy_attrs()
2356 unsigned long attrs = slwt->desc->attrs | slwt->parsed_optattrs; in destroy_attrs()
2365 struct seg6_action_desc *desc = slwt->desc; in parse_nla_optional_attrs()
2371 if (!(desc->optattrs & SEG6_F_ATTR(i)) || !attrs[i]) in parse_nla_optional_attrs()
2374 /* once here, the i-th attribute is provided by the in parse_nla_optional_attrs()
2379 err = param->parse(attrs, slwt, extack); in parse_nla_optional_attrs()
2390 slwt->parsed_optattrs = parsed_optattrs; in parse_nla_optional_attrs()
2407 struct seg6_action_desc *desc = slwt->desc; in seg6_local_lwtunnel_build_state()
2410 ops = &desc->slwt_ops; in seg6_local_lwtunnel_build_state()
2411 if (!ops->build_state) in seg6_local_lwtunnel_build_state()
2414 return ops->build_state(slwt, cfg, extack); in seg6_local_lwtunnel_build_state()
2422 struct seg6_action_desc *desc = slwt->desc; in seg6_local_lwtunnel_destroy_state()
2425 ops = &desc->slwt_ops; in seg6_local_lwtunnel_destroy_state()
2426 if (!ops->destroy_state) in seg6_local_lwtunnel_destroy_state()
2429 ops->destroy_state(slwt); in seg6_local_lwtunnel_destroy_state()
2440 desc = __get_action_desc(slwt->action); in parse_nla_action()
2442 return -EINVAL; in parse_nla_action()
2444 if (!desc->input) in parse_nla_action()
2445 return -EOPNOTSUPP; in parse_nla_action()
2447 slwt->desc = desc; in parse_nla_action()
2448 slwt->headroom += desc->static_headroom; in parse_nla_action()
2450 /* Forcing the desc->optattrs *set* and the desc->attrs *set* to be in parse_nla_action()
2462 invalid_attrs = desc->attrs & desc->optattrs; in parse_nla_action()
2466 return -EINVAL; in parse_nla_action()
2471 if (desc->attrs & SEG6_F_ATTR(i)) { in parse_nla_action()
2473 return -EINVAL; in parse_nla_action()
2477 err = param->parse(attrs, slwt, extack); in parse_nla_action()
2491 /* release any resource that may have been acquired during the i-1 in parse_nla_action()
2494 __destroy_attrs(desc->attrs, i, slwt); in parse_nla_action()
2501 struct lwtunnel_state **ts, in seg6_local_build_state() argument
2510 return -EINVAL; in seg6_local_build_state()
2519 return -EINVAL; in seg6_local_build_state()
2523 return -ENOMEM; in seg6_local_build_state()
2526 slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]); in seg6_local_build_state()
2536 newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL; in seg6_local_build_state()
2537 newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT; in seg6_local_build_state()
2538 newts->headroom = slwt->headroom; in seg6_local_build_state()
2540 *ts = newts; in seg6_local_build_state()
2570 if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action)) in seg6_local_fill_encap()
2571 return -EMSGSIZE; in seg6_local_fill_encap()
2573 attrs = slwt->desc->attrs | slwt->parsed_optattrs; in seg6_local_fill_encap()
2578 err = param->put(skb, slwt); in seg6_local_fill_encap()
2595 attrs = slwt->desc->attrs | slwt->parsed_optattrs; in seg6_local_get_encap_size()
2598 nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3); in seg6_local_get_encap_size()
2649 if (slwt_a->action != slwt_b->action) in seg6_local_cmp_encap()
2652 attrs_a = slwt_a->desc->attrs | slwt_a->parsed_optattrs; in seg6_local_cmp_encap()
2653 attrs_b = slwt_b->desc->attrs | slwt_b->parsed_optattrs; in seg6_local_cmp_encap()
2661 if (param->cmp(slwt_a, slwt_b)) in seg6_local_cmp_encap()
2695 /* If the default NEXT-C-SID Locator-Block/Node Function lengths (in in seg6_local_init()