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 err = 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 err = 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()
1389 struct ipv6_sr_hdr *srh = srh_state->srh; in seg6_bpf_has_valid_srh()
1394 if (unlikely(!srh_state->valid)) { in seg6_bpf_has_valid_srh()
1395 if ((srh_state->hdrlen & 7) != 0) in seg6_bpf_has_valid_srh()
1398 srh->hdrlen = (u8)(srh_state->hdrlen >> 3); in seg6_bpf_has_valid_srh()
1399 if (!seg6_validate_srh(srh, (srh->hdrlen + 1) << 3, true)) in seg6_bpf_has_valid_srh()
1402 srh_state->valid = true; in seg6_bpf_has_valid_srh()
1419 return -EINVAL; in input_action_end_bpf()
1421 advance_nextseg(srh, &ipv6_hdr(skb)->daddr); in input_action_end_bpf()
1423 /* preempt_disable is needed to protect the per-CPU buffer srh_state, in input_action_end_bpf()
1427 srh_state->srh = srh; in input_action_end_bpf()
1428 srh_state->hdrlen = srh->hdrlen << 3; in input_action_end_bpf()
1429 srh_state->valid = true; in input_action_end_bpf()
1433 ret = bpf_prog_run_save_cb(slwt->bpf.prog, skb); in input_action_end_bpf()
1443 pr_warn_once("bpf-seg6local: Illegal return value %u\n", ret); in input_action_end_bpf()
1447 if (srh_state->srh && !seg6_bpf_has_valid_srh(skb)) in input_action_end_bpf()
1459 return -EINVAL; in input_action_end_bpf()
1569 if (desc->action == action) in __get_action_desc()
1578 return slwt->parsed_optattrs & SEG6_F_LOCAL_COUNTERS; in seg6_lwtunnel_counters_enabled()
1586 pcounters = this_cpu_ptr(slwt->pcpu_counters); in seg6_local_update_counters()
1587 u64_stats_update_begin(&pcounters->syncp); in seg6_local_update_counters()
1590 u64_stats_inc(&pcounters->packets); in seg6_local_update_counters()
1591 u64_stats_add(&pcounters->bytes, len); in seg6_local_update_counters()
1593 u64_stats_inc(&pcounters->errors); in seg6_local_update_counters()
1596 u64_stats_update_end(&pcounters->syncp); in seg6_local_update_counters()
1605 unsigned int len = skb->len; in seg6_local_input_core()
1608 slwt = seg6_local_lwtunnel(orig_dst->lwtstate); in seg6_local_input_core()
1609 desc = slwt->desc; in seg6_local_input_core()
1611 rc = desc->input(skb, slwt); in seg6_local_input_core()
1623 if (skb->protocol != htons(ETH_P_IPV6)) { in seg6_local_input()
1625 return -EINVAL; in seg6_local_input()
1630 dev_net(skb->dev), NULL, skb, skb->dev, NULL, in seg6_local_input()
1633 return seg6_local_input_core(dev_net(skb->dev), NULL, skb); in seg6_local_input()
1661 return -EINVAL; in parse_nla_srh()
1664 return -EINVAL; in parse_nla_srh()
1666 slwt->srh = kmemdup(srh, len, GFP_KERNEL); in parse_nla_srh()
1667 if (!slwt->srh) in parse_nla_srh()
1668 return -ENOMEM; in parse_nla_srh()
1670 slwt->headroom += len; in parse_nla_srh()
1681 srh = slwt->srh; in put_nla_srh()
1682 len = (srh->hdrlen + 1) << 3; in put_nla_srh()
1686 return -EMSGSIZE; in put_nla_srh()
1695 int len = (a->srh->hdrlen + 1) << 3; in cmp_nla_srh()
1697 if (len != ((b->srh->hdrlen + 1) << 3)) in cmp_nla_srh()
1700 return memcmp(a->srh, b->srh, len); in cmp_nla_srh()
1705 kfree(slwt->srh); in destroy_attr_srh()
1711 slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]); in parse_nla_table()
1718 if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table)) in put_nla_table()
1719 return -EMSGSIZE; in put_nla_table()
1726 if (a->table != b->table) in cmp_nla_table()
1736 return &slwt->dt_info; in seg6_possible_end_dt_info()
1738 return ERR_PTR(-EOPNOTSUPP); in seg6_possible_end_dt_info()
1751 info->vrf_table = nla_get_u32(attrs[SEG6_LOCAL_VRFTABLE]); in parse_nla_vrftable()
1763 if (nla_put_u32(skb, SEG6_LOCAL_VRFTABLE, info->vrf_table)) in put_nla_vrftable()
1764 return -EMSGSIZE; in put_nla_vrftable()
1774 if (info_a->vrf_table != info_b->vrf_table) in cmp_nla_vrftable()
1783 memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]), in parse_nla_nh4()
1795 return -EMSGSIZE; in put_nla_nh4()
1797 memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr)); in put_nla_nh4()
1804 return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr)); in cmp_nla_nh4()
1810 memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]), in parse_nla_nh6()
1822 return -EMSGSIZE; in put_nla_nh6()
1824 memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr)); in put_nla_nh6()
1831 return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr)); in cmp_nla_nh6()
1837 slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]); in parse_nla_iif()
1844 if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif)) in put_nla_iif()
1845 return -EMSGSIZE; in put_nla_iif()
1852 if (a->iif != b->iif) in cmp_nla_iif()
1861 slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]); in parse_nla_oif()
1868 if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif)) in put_nla_oif()
1869 return -EMSGSIZE; in put_nla_oif()
1876 if (a->oif != b->oif) in cmp_nla_oif()
1904 return -EINVAL; in parse_nla_bpf()
1906 slwt->bpf.name = nla_memdup(tb[SEG6_LOCAL_BPF_PROG_NAME], GFP_KERNEL); in parse_nla_bpf()
1907 if (!slwt->bpf.name) in parse_nla_bpf()
1908 return -ENOMEM; in parse_nla_bpf()
1913 kfree(slwt->bpf.name); in parse_nla_bpf()
1917 slwt->bpf.prog = p; in parse_nla_bpf()
1925 if (!slwt->bpf.prog) in put_nla_bpf()
1930 return -EMSGSIZE; in put_nla_bpf()
1932 if (nla_put_u32(skb, SEG6_LOCAL_BPF_PROG, slwt->bpf.prog->aux->id)) in put_nla_bpf()
1933 return -EMSGSIZE; in put_nla_bpf()
1935 if (slwt->bpf.name && in put_nla_bpf()
1936 nla_put_string(skb, SEG6_LOCAL_BPF_PROG_NAME, slwt->bpf.name)) in put_nla_bpf()
1937 return -EMSGSIZE; in put_nla_bpf()
1944 if (!a->bpf.name && !b->bpf.name) in cmp_nla_bpf()
1947 if (!a->bpf.name || !b->bpf.name) in cmp_nla_bpf()
1950 return strcmp(a->bpf.name, b->bpf.name); in cmp_nla_bpf()
1955 kfree(slwt->bpf.name); in destroy_attr_bpf()
1956 if (slwt->bpf.prog) in destroy_attr_bpf()
1957 bpf_prog_put(slwt->bpf.prog); in destroy_attr_bpf()
1986 return -EINVAL; in parse_nla_counters()
1991 return -ENOMEM; in parse_nla_counters()
1993 slwt->pcpu_counters = pcounters; in parse_nla_counters()
2001 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_PACKETS, counters->packets, in seg6_local_fill_nla_counters()
2003 return -EMSGSIZE; in seg6_local_fill_nla_counters()
2005 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_BYTES, counters->bytes, in seg6_local_fill_nla_counters()
2007 return -EMSGSIZE; in seg6_local_fill_nla_counters()
2009 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_ERRORS, counters->errors, in seg6_local_fill_nla_counters()
2011 return -EMSGSIZE; in seg6_local_fill_nla_counters()
2024 return -EMSGSIZE; in put_nla_counters()
2031 pcounters = per_cpu_ptr(slwt->pcpu_counters, i); in put_nla_counters()
2033 start = u64_stats_fetch_begin(&pcounters->syncp); in put_nla_counters()
2035 packets = u64_stats_read(&pcounters->packets); in put_nla_counters()
2036 bytes = u64_stats_read(&pcounters->bytes); in put_nla_counters()
2037 errors = u64_stats_read(&pcounters->errors); in put_nla_counters()
2039 } while (u64_stats_fetch_retry(&pcounters->syncp, start)); in put_nla_counters()
2058 return (!!((unsigned long)a->pcpu_counters)) ^ in cmp_nla_counters()
2059 (!!((unsigned long)b->pcpu_counters)); in cmp_nla_counters()
2064 free_percpu(slwt->pcpu_counters); in destroy_attr_counters()
2074 /* check whether the lengths of the Locator-Block and Locator-Node Function
2075 * are compatible with the dimension of a C-SID container.
2079 /* Locator-Block and Locator-Node Function cannot exceed 128 bits in seg6_chk_next_csid_cfg()
2080 * (i.e. C-SID container lenghts). in seg6_chk_next_csid_cfg()
2083 return -EINVAL; in seg6_chk_next_csid_cfg()
2085 /* Locator-Block length must be greater than zero and evenly divisible in seg6_chk_next_csid_cfg()
2086 * by 8. There must be room for a Locator-Node Function, at least. in seg6_chk_next_csid_cfg()
2089 return -EINVAL; in seg6_chk_next_csid_cfg()
2091 /* Locator-Node Function length must be greater than zero and evenly in seg6_chk_next_csid_cfg()
2092 * divisible by 8. There must be room for the Locator-Block. in seg6_chk_next_csid_cfg()
2095 return -EINVAL; in seg6_chk_next_csid_cfg()
2121 finfo->lcblock_bits = block_len; in seg6_parse_nla_next_csid_cfg()
2122 finfo->lcnode_func_bits = func_len; in seg6_parse_nla_next_csid_cfg()
2130 struct seg6_flavors_info *finfo = &slwt->flv_info; in parse_nla_flavors()
2132 int action = slwt->action; in parse_nla_flavors()
2146 return -EINVAL; in parse_nla_flavors()
2152 return -EOPNOTSUPP; in parse_nla_flavors()
2155 finfo->flv_ops = fops; in parse_nla_flavors()
2158 /* Locator-Block and Locator-Node Function lengths can be in parse_nla_flavors()
2173 if (nla_put_u8(skb, SEG6_LOCAL_FLV_LCBLOCK_BITS, finfo->lcblock_bits)) in seg6_fill_nla_next_csid_cfg()
2174 return -EMSGSIZE; in seg6_fill_nla_next_csid_cfg()
2177 finfo->lcnode_func_bits)) in seg6_fill_nla_next_csid_cfg()
2178 return -EMSGSIZE; in seg6_fill_nla_next_csid_cfg()
2185 struct seg6_flavors_info *finfo = &slwt->flv_info; in put_nla_flavors()
2186 __u32 fops = finfo->flv_ops; in put_nla_flavors()
2192 return -EMSGSIZE; in put_nla_flavors()
2195 rc = -EMSGSIZE; in put_nla_flavors()
2215 if (finfo_a->lcblock_bits != finfo_b->lcblock_bits) in seg6_cmp_nla_next_csid_cfg()
2218 if (finfo_a->lcnode_func_bits != finfo_b->lcnode_func_bits) in seg6_cmp_nla_next_csid_cfg()
2226 struct seg6_flavors_info *finfo_a = &a->flv_info; in cmp_nla_flavors()
2227 struct seg6_flavors_info *finfo_b = &b->flv_info; in cmp_nla_flavors()
2229 if (finfo_a->flv_ops != finfo_b->flv_ops) in cmp_nla_flavors()
2232 if (seg6_next_csid_enabled(finfo_a->flv_ops)) { in cmp_nla_flavors()
2242 struct seg6_flavors_info *finfo = &slwt->flv_info; in encap_size_flavors()
2248 if (seg6_next_csid_enabled(finfo->flv_ops)) in encap_size_flavors()
2338 if (param->destroy) in __destroy_attrs()
2339 param->destroy(slwt); in __destroy_attrs()
2348 unsigned long attrs = slwt->desc->attrs | slwt->parsed_optattrs; in destroy_attrs()
2357 struct seg6_action_desc *desc = slwt->desc; in parse_nla_optional_attrs()
2363 if (!(desc->optattrs & SEG6_F_ATTR(i)) || !attrs[i]) in parse_nla_optional_attrs()
2366 /* once here, the i-th attribute is provided by the in parse_nla_optional_attrs()
2371 err = param->parse(attrs, slwt, extack); in parse_nla_optional_attrs()
2382 slwt->parsed_optattrs = parsed_optattrs; in parse_nla_optional_attrs()
2399 struct seg6_action_desc *desc = slwt->desc; in seg6_local_lwtunnel_build_state()
2402 ops = &desc->slwt_ops; in seg6_local_lwtunnel_build_state()
2403 if (!ops->build_state) in seg6_local_lwtunnel_build_state()
2406 return ops->build_state(slwt, cfg, extack); in seg6_local_lwtunnel_build_state()
2414 struct seg6_action_desc *desc = slwt->desc; in seg6_local_lwtunnel_destroy_state()
2417 ops = &desc->slwt_ops; in seg6_local_lwtunnel_destroy_state()
2418 if (!ops->destroy_state) in seg6_local_lwtunnel_destroy_state()
2421 ops->destroy_state(slwt); in seg6_local_lwtunnel_destroy_state()
2432 desc = __get_action_desc(slwt->action); in parse_nla_action()
2434 return -EINVAL; in parse_nla_action()
2436 if (!desc->input) in parse_nla_action()
2437 return -EOPNOTSUPP; in parse_nla_action()
2439 slwt->desc = desc; in parse_nla_action()
2440 slwt->headroom += desc->static_headroom; in parse_nla_action()
2442 /* Forcing the desc->optattrs *set* and the desc->attrs *set* to be in parse_nla_action()
2454 invalid_attrs = desc->attrs & desc->optattrs; in parse_nla_action()
2458 return -EINVAL; in parse_nla_action()
2463 if (desc->attrs & SEG6_F_ATTR(i)) { in parse_nla_action()
2465 return -EINVAL; in parse_nla_action()
2469 err = param->parse(attrs, slwt, extack); in parse_nla_action()
2483 /* release any resource that may have been acquired during the i-1 in parse_nla_action()
2486 __destroy_attrs(desc->attrs, i, slwt); in parse_nla_action()
2493 struct lwtunnel_state **ts, in seg6_local_build_state() argument
2502 return -EINVAL; in seg6_local_build_state()
2511 return -EINVAL; in seg6_local_build_state()
2515 return -ENOMEM; in seg6_local_build_state()
2518 slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]); in seg6_local_build_state()
2528 newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL; in seg6_local_build_state()
2529 newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT; in seg6_local_build_state()
2530 newts->headroom = slwt->headroom; in seg6_local_build_state()
2532 *ts = newts; in seg6_local_build_state()
2562 if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action)) in seg6_local_fill_encap()
2563 return -EMSGSIZE; in seg6_local_fill_encap()
2565 attrs = slwt->desc->attrs | slwt->parsed_optattrs; in seg6_local_fill_encap()
2570 err = param->put(skb, slwt); in seg6_local_fill_encap()
2587 attrs = slwt->desc->attrs | slwt->parsed_optattrs; in seg6_local_get_encap_size()
2590 nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3); in seg6_local_get_encap_size()
2641 if (slwt_a->action != slwt_b->action) in seg6_local_cmp_encap()
2644 attrs_a = slwt_a->desc->attrs | slwt_a->parsed_optattrs; in seg6_local_cmp_encap()
2645 attrs_b = slwt_b->desc->attrs | slwt_b->parsed_optattrs; in seg6_local_cmp_encap()
2653 if (param->cmp(slwt_a, slwt_b)) in seg6_local_cmp_encap()
2687 /* If the default NEXT-C-SID Locator-Block/Node Function lengths (in in seg6_local_init()