1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * SR-IPv6 implementation
4 *
5 * Authors:
6 * David Lebrun <david.lebrun@uclouvain.be>
7 * eBPF support: Mathieu Xhonneux <m.xhonneux@gmail.com>
8 */
9
10 #include <linux/types.h>
11 #include <linux/skbuff.h>
12 #include <linux/net.h>
13 #include <linux/module.h>
14 #include <net/ip.h>
15 #include <net/lwtunnel.h>
16 #include <net/netevent.h>
17 #include <net/netns/generic.h>
18 #include <net/ip6_fib.h>
19 #include <net/route.h>
20 #include <net/seg6.h>
21 #include <linux/seg6.h>
22 #include <linux/seg6_local.h>
23 #include <net/addrconf.h>
24 #include <net/ip6_route.h>
25 #include <net/dst_cache.h>
26 #include <net/ip_tunnels.h>
27 #ifdef CONFIG_IPV6_SEG6_HMAC
28 #include <net/seg6_hmac.h>
29 #endif
30 #include <net/seg6_local.h>
31 #include <linux/etherdevice.h>
32 #include <linux/bpf.h>
33
34 #define SEG6_F_ATTR(i) BIT(i)
35
36 struct seg6_local_lwt;
37
38 /* callbacks used for customizing the creation and destruction of a behavior */
39 struct seg6_local_lwtunnel_ops {
40 int (*build_state)(struct seg6_local_lwt *slwt, const void *cfg,
41 struct netlink_ext_ack *extack);
42 void (*destroy_state)(struct seg6_local_lwt *slwt);
43 };
44
45 struct seg6_action_desc {
46 int action;
47 unsigned long attrs;
48
49 /* The optattrs field is used for specifying all the optional
50 * attributes supported by a specific behavior.
51 * It means that if one of these attributes is not provided in the
52 * netlink message during the behavior creation, no errors will be
53 * returned to the userspace.
54 *
55 * Each attribute can be only of two types (mutually exclusive):
56 * 1) required or 2) optional.
57 * Every user MUST obey to this rule! If you set an attribute as
58 * required the same attribute CANNOT be set as optional and vice
59 * versa.
60 */
61 unsigned long optattrs;
62
63 int (*input)(struct sk_buff *skb, struct seg6_local_lwt *slwt);
64 int static_headroom;
65
66 struct seg6_local_lwtunnel_ops slwt_ops;
67 };
68
69 struct bpf_lwt_prog {
70 struct bpf_prog *prog;
71 char *name;
72 };
73
74 enum seg6_end_dt_mode {
75 DT_INVALID_MODE = -EINVAL,
76 DT_LEGACY_MODE = 0,
77 DT_VRF_MODE = 1,
78 };
79
80 struct seg6_end_dt_info {
81 enum seg6_end_dt_mode mode;
82
83 struct net *net;
84 /* VRF device associated to the routing table used by the SRv6
85 * End.DT4/DT6 behavior for routing IPv4/IPv6 packets.
86 */
87 int vrf_ifindex;
88 int vrf_table;
89
90 /* tunneled packet proto and family (IPv4 or IPv6) */
91 __be16 proto;
92 u16 family;
93 int hdrlen;
94 };
95
96 struct pcpu_seg6_local_counters {
97 u64_stats_t packets;
98 u64_stats_t bytes;
99 u64_stats_t errors;
100
101 struct u64_stats_sync syncp;
102 };
103
104 /* This struct groups all the SRv6 Behavior counters supported so far.
105 *
106 * put_nla_counters() makes use of this data structure to collect all counter
107 * values after the per-CPU counter evaluation has been performed.
108 * Finally, each counter value (in seg6_local_counters) is stored in the
109 * corresponding netlink attribute and sent to user space.
110 *
111 * NB: we don't want to expose this structure to user space!
112 */
113 struct seg6_local_counters {
114 __u64 packets;
115 __u64 bytes;
116 __u64 errors;
117 };
118
119 #define seg6_local_alloc_pcpu_counters(__gfp) \
120 __netdev_alloc_pcpu_stats(struct pcpu_seg6_local_counters, \
121 ((__gfp) | __GFP_ZERO))
122
123 #define SEG6_F_LOCAL_COUNTERS SEG6_F_ATTR(SEG6_LOCAL_COUNTERS)
124
125 struct seg6_local_lwt {
126 int action;
127 struct ipv6_sr_hdr *srh;
128 int table;
129 struct in_addr nh4;
130 struct in6_addr nh6;
131 int iif;
132 int oif;
133 struct bpf_lwt_prog bpf;
134 #ifdef CONFIG_NET_L3_MASTER_DEV
135 struct seg6_end_dt_info dt_info;
136 #endif
137 struct pcpu_seg6_local_counters __percpu *pcpu_counters;
138
139 int headroom;
140 struct seg6_action_desc *desc;
141 /* unlike the required attrs, we have to track the optional attributes
142 * that have been effectively parsed.
143 */
144 unsigned long parsed_optattrs;
145 };
146
seg6_local_lwtunnel(struct lwtunnel_state * lwt)147 static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt)
148 {
149 return (struct seg6_local_lwt *)lwt->data;
150 }
151
get_srh(struct sk_buff * skb,int flags)152 static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb, int flags)
153 {
154 struct ipv6_sr_hdr *srh;
155 int len, srhoff = 0;
156
157 if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, &flags) < 0)
158 return NULL;
159
160 if (!pskb_may_pull(skb, srhoff + sizeof(*srh)))
161 return NULL;
162
163 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
164
165 len = (srh->hdrlen + 1) << 3;
166
167 if (!pskb_may_pull(skb, srhoff + len))
168 return NULL;
169
170 /* note that pskb_may_pull may change pointers in header;
171 * for this reason it is necessary to reload them when needed.
172 */
173 srh = (struct ipv6_sr_hdr *)(skb->data + srhoff);
174
175 if (!seg6_validate_srh(srh, len, true))
176 return NULL;
177
178 return srh;
179 }
180
get_and_validate_srh(struct sk_buff * skb)181 static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb)
182 {
183 struct ipv6_sr_hdr *srh;
184
185 srh = get_srh(skb, IP6_FH_F_SKIP_RH);
186 if (!srh)
187 return NULL;
188
189 #ifdef CONFIG_IPV6_SEG6_HMAC
190 if (!seg6_hmac_validate_skb(skb))
191 return NULL;
192 #endif
193
194 return srh;
195 }
196
decap_and_validate(struct sk_buff * skb,int proto)197 static bool decap_and_validate(struct sk_buff *skb, int proto)
198 {
199 struct ipv6_sr_hdr *srh;
200 unsigned int off = 0;
201
202 srh = get_srh(skb, 0);
203 if (srh && srh->segments_left > 0)
204 return false;
205
206 #ifdef CONFIG_IPV6_SEG6_HMAC
207 if (srh && !seg6_hmac_validate_skb(skb))
208 return false;
209 #endif
210
211 if (ipv6_find_hdr(skb, &off, proto, NULL, NULL) < 0)
212 return false;
213
214 if (!pskb_pull(skb, off))
215 return false;
216
217 skb_postpull_rcsum(skb, skb_network_header(skb), off);
218
219 skb_reset_network_header(skb);
220 skb_reset_transport_header(skb);
221 if (iptunnel_pull_offloads(skb))
222 return false;
223
224 return true;
225 }
226
advance_nextseg(struct ipv6_sr_hdr * srh,struct in6_addr * daddr)227 static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
228 {
229 struct in6_addr *addr;
230
231 srh->segments_left--;
232 addr = srh->segments + srh->segments_left;
233 *daddr = *addr;
234 }
235
236 static int
seg6_lookup_any_nexthop(struct sk_buff * skb,struct in6_addr * nhaddr,u32 tbl_id,bool local_delivery)237 seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
238 u32 tbl_id, bool local_delivery)
239 {
240 struct net *net = dev_net(skb->dev);
241 struct ipv6hdr *hdr = ipv6_hdr(skb);
242 int flags = RT6_LOOKUP_F_HAS_SADDR;
243 struct dst_entry *dst = NULL;
244 struct rt6_info *rt;
245 struct flowi6 fl6;
246 int dev_flags = 0;
247
248 fl6.flowi6_iif = skb->dev->ifindex;
249 fl6.daddr = nhaddr ? *nhaddr : hdr->daddr;
250 fl6.saddr = hdr->saddr;
251 fl6.flowlabel = ip6_flowinfo(hdr);
252 fl6.flowi6_mark = skb->mark;
253 fl6.flowi6_proto = hdr->nexthdr;
254
255 if (nhaddr)
256 fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH;
257
258 if (!tbl_id) {
259 dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags);
260 } else {
261 struct fib6_table *table;
262
263 table = fib6_get_table(net, tbl_id);
264 if (!table)
265 goto out;
266
267 rt = ip6_pol_route(net, table, 0, &fl6, skb, flags);
268 dst = &rt->dst;
269 }
270
271 /* we want to discard traffic destined for local packet processing,
272 * if @local_delivery is set to false.
273 */
274 if (!local_delivery)
275 dev_flags |= IFF_LOOPBACK;
276
277 if (dst && (dst->dev->flags & dev_flags) && !dst->error) {
278 dst_release(dst);
279 dst = NULL;
280 }
281
282 out:
283 if (!dst) {
284 rt = net->ipv6.ip6_blk_hole_entry;
285 dst = &rt->dst;
286 dst_hold(dst);
287 }
288
289 skb_dst_drop(skb);
290 skb_dst_set(skb, dst);
291 return dst->error;
292 }
293
seg6_lookup_nexthop(struct sk_buff * skb,struct in6_addr * nhaddr,u32 tbl_id)294 int seg6_lookup_nexthop(struct sk_buff *skb,
295 struct in6_addr *nhaddr, u32 tbl_id)
296 {
297 return seg6_lookup_any_nexthop(skb, nhaddr, tbl_id, false);
298 }
299
300 /* regular endpoint function */
input_action_end(struct sk_buff * skb,struct seg6_local_lwt * slwt)301 static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt)
302 {
303 struct ipv6_sr_hdr *srh;
304
305 srh = get_and_validate_srh(skb);
306 if (!srh)
307 goto drop;
308
309 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
310
311 seg6_lookup_nexthop(skb, NULL, 0);
312
313 return dst_input(skb);
314
315 drop:
316 kfree_skb(skb);
317 return -EINVAL;
318 }
319
320 /* regular endpoint, and forward to specified nexthop */
input_action_end_x(struct sk_buff * skb,struct seg6_local_lwt * slwt)321 static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt)
322 {
323 struct ipv6_sr_hdr *srh;
324
325 srh = get_and_validate_srh(skb);
326 if (!srh)
327 goto drop;
328
329 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
330
331 seg6_lookup_nexthop(skb, &slwt->nh6, 0);
332
333 return dst_input(skb);
334
335 drop:
336 kfree_skb(skb);
337 return -EINVAL;
338 }
339
input_action_end_t(struct sk_buff * skb,struct seg6_local_lwt * slwt)340 static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt)
341 {
342 struct ipv6_sr_hdr *srh;
343
344 srh = get_and_validate_srh(skb);
345 if (!srh)
346 goto drop;
347
348 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
349
350 seg6_lookup_nexthop(skb, NULL, slwt->table);
351
352 return dst_input(skb);
353
354 drop:
355 kfree_skb(skb);
356 return -EINVAL;
357 }
358
359 /* decapsulate and forward inner L2 frame on specified interface */
input_action_end_dx2(struct sk_buff * skb,struct seg6_local_lwt * slwt)360 static int input_action_end_dx2(struct sk_buff *skb,
361 struct seg6_local_lwt *slwt)
362 {
363 struct net *net = dev_net(skb->dev);
364 struct net_device *odev;
365 struct ethhdr *eth;
366
367 if (!decap_and_validate(skb, IPPROTO_ETHERNET))
368 goto drop;
369
370 if (!pskb_may_pull(skb, ETH_HLEN))
371 goto drop;
372
373 skb_reset_mac_header(skb);
374 eth = (struct ethhdr *)skb->data;
375
376 /* To determine the frame's protocol, we assume it is 802.3. This avoids
377 * a call to eth_type_trans(), which is not really relevant for our
378 * use case.
379 */
380 if (!eth_proto_is_802_3(eth->h_proto))
381 goto drop;
382
383 odev = dev_get_by_index_rcu(net, slwt->oif);
384 if (!odev)
385 goto drop;
386
387 /* As we accept Ethernet frames, make sure the egress device is of
388 * the correct type.
389 */
390 if (odev->type != ARPHRD_ETHER)
391 goto drop;
392
393 if (!(odev->flags & IFF_UP) || !netif_carrier_ok(odev))
394 goto drop;
395
396 skb_orphan(skb);
397
398 if (skb_warn_if_lro(skb))
399 goto drop;
400
401 skb_forward_csum(skb);
402
403 if (skb->len - ETH_HLEN > odev->mtu)
404 goto drop;
405
406 skb->dev = odev;
407 skb->protocol = eth->h_proto;
408
409 return dev_queue_xmit(skb);
410
411 drop:
412 kfree_skb(skb);
413 return -EINVAL;
414 }
415
416 /* decapsulate and forward to specified nexthop */
input_action_end_dx6(struct sk_buff * skb,struct seg6_local_lwt * slwt)417 static int input_action_end_dx6(struct sk_buff *skb,
418 struct seg6_local_lwt *slwt)
419 {
420 struct in6_addr *nhaddr = NULL;
421
422 /* this function accepts IPv6 encapsulated packets, with either
423 * an SRH with SL=0, or no SRH.
424 */
425
426 if (!decap_and_validate(skb, IPPROTO_IPV6))
427 goto drop;
428
429 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
430 goto drop;
431
432 /* The inner packet is not associated to any local interface,
433 * so we do not call netif_rx().
434 *
435 * If slwt->nh6 is set to ::, then lookup the nexthop for the
436 * inner packet's DA. Otherwise, use the specified nexthop.
437 */
438
439 if (!ipv6_addr_any(&slwt->nh6))
440 nhaddr = &slwt->nh6;
441
442 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
443
444 seg6_lookup_nexthop(skb, nhaddr, 0);
445
446 return dst_input(skb);
447 drop:
448 kfree_skb(skb);
449 return -EINVAL;
450 }
451
input_action_end_dx4(struct sk_buff * skb,struct seg6_local_lwt * slwt)452 static int input_action_end_dx4(struct sk_buff *skb,
453 struct seg6_local_lwt *slwt)
454 {
455 struct iphdr *iph;
456 __be32 nhaddr;
457 int err;
458
459 if (!decap_and_validate(skb, IPPROTO_IPIP))
460 goto drop;
461
462 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
463 goto drop;
464
465 skb->protocol = htons(ETH_P_IP);
466
467 iph = ip_hdr(skb);
468
469 nhaddr = slwt->nh4.s_addr ?: iph->daddr;
470
471 skb_dst_drop(skb);
472
473 skb_set_transport_header(skb, sizeof(struct iphdr));
474
475 err = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev);
476 if (err)
477 goto drop;
478
479 return dst_input(skb);
480
481 drop:
482 kfree_skb(skb);
483 return -EINVAL;
484 }
485
486 #ifdef CONFIG_NET_L3_MASTER_DEV
fib6_config_get_net(const struct fib6_config * fib6_cfg)487 static struct net *fib6_config_get_net(const struct fib6_config *fib6_cfg)
488 {
489 const struct nl_info *nli = &fib6_cfg->fc_nlinfo;
490
491 return nli->nl_net;
492 }
493
__seg6_end_dt_vrf_build(struct seg6_local_lwt * slwt,const void * cfg,u16 family,struct netlink_ext_ack * extack)494 static int __seg6_end_dt_vrf_build(struct seg6_local_lwt *slwt, const void *cfg,
495 u16 family, struct netlink_ext_ack *extack)
496 {
497 struct seg6_end_dt_info *info = &slwt->dt_info;
498 int vrf_ifindex;
499 struct net *net;
500
501 net = fib6_config_get_net(cfg);
502
503 /* note that vrf_table was already set by parse_nla_vrftable() */
504 vrf_ifindex = l3mdev_ifindex_lookup_by_table_id(L3MDEV_TYPE_VRF, net,
505 info->vrf_table);
506 if (vrf_ifindex < 0) {
507 if (vrf_ifindex == -EPERM) {
508 NL_SET_ERR_MSG(extack,
509 "Strict mode for VRF is disabled");
510 } else if (vrf_ifindex == -ENODEV) {
511 NL_SET_ERR_MSG(extack,
512 "Table has no associated VRF device");
513 } else {
514 pr_debug("seg6local: SRv6 End.DT* creation error=%d\n",
515 vrf_ifindex);
516 }
517
518 return vrf_ifindex;
519 }
520
521 info->net = net;
522 info->vrf_ifindex = vrf_ifindex;
523
524 switch (family) {
525 case AF_INET:
526 info->proto = htons(ETH_P_IP);
527 info->hdrlen = sizeof(struct iphdr);
528 break;
529 case AF_INET6:
530 info->proto = htons(ETH_P_IPV6);
531 info->hdrlen = sizeof(struct ipv6hdr);
532 break;
533 default:
534 return -EINVAL;
535 }
536
537 info->family = family;
538 info->mode = DT_VRF_MODE;
539
540 return 0;
541 }
542
543 /* The SRv6 End.DT4/DT6 behavior extracts the inner (IPv4/IPv6) packet and
544 * routes the IPv4/IPv6 packet by looking at the configured routing table.
545 *
546 * In the SRv6 End.DT4/DT6 use case, we can receive traffic (IPv6+Segment
547 * Routing Header packets) from several interfaces and the outer IPv6
548 * destination address (DA) is used for retrieving the specific instance of the
549 * End.DT4/DT6 behavior that should process the packets.
550 *
551 * However, the inner IPv4/IPv6 packet is not really bound to any receiving
552 * interface and thus the End.DT4/DT6 sets the VRF (associated with the
553 * corresponding routing table) as the *receiving* interface.
554 * In other words, the End.DT4/DT6 processes a packet as if it has been received
555 * directly by the VRF (and not by one of its slave devices, if any).
556 * In this way, the VRF interface is used for routing the IPv4/IPv6 packet in
557 * according to the routing table configured by the End.DT4/DT6 instance.
558 *
559 * This design allows you to get some interesting features like:
560 * 1) the statistics on rx packets;
561 * 2) the possibility to install a packet sniffer on the receiving interface
562 * (the VRF one) for looking at the incoming packets;
563 * 3) the possibility to leverage the netfilter prerouting hook for the inner
564 * IPv4 packet.
565 *
566 * This function returns:
567 * - the sk_buff* when the VRF rcv handler has processed the packet correctly;
568 * - NULL when the skb is consumed by the VRF rcv handler;
569 * - a pointer which encodes a negative error number in case of error.
570 * Note that in this case, the function takes care of freeing the skb.
571 */
end_dt_vrf_rcv(struct sk_buff * skb,u16 family,struct net_device * dev)572 static struct sk_buff *end_dt_vrf_rcv(struct sk_buff *skb, u16 family,
573 struct net_device *dev)
574 {
575 /* based on l3mdev_ip_rcv; we are only interested in the master */
576 if (unlikely(!netif_is_l3_master(dev) && !netif_has_l3_rx_handler(dev)))
577 goto drop;
578
579 if (unlikely(!dev->l3mdev_ops->l3mdev_l3_rcv))
580 goto drop;
581
582 /* the decap packet IPv4/IPv6 does not come with any mac header info.
583 * We must unset the mac header to allow the VRF device to rebuild it,
584 * just in case there is a sniffer attached on the device.
585 */
586 skb_unset_mac_header(skb);
587
588 skb = dev->l3mdev_ops->l3mdev_l3_rcv(dev, skb, family);
589 if (!skb)
590 /* the skb buffer was consumed by the handler */
591 return NULL;
592
593 /* when a packet is received by a VRF or by one of its slaves, the
594 * master device reference is set into the skb.
595 */
596 if (unlikely(skb->dev != dev || skb->skb_iif != dev->ifindex))
597 goto drop;
598
599 return skb;
600
601 drop:
602 kfree_skb(skb);
603 return ERR_PTR(-EINVAL);
604 }
605
end_dt_get_vrf_rcu(struct sk_buff * skb,struct seg6_end_dt_info * info)606 static struct net_device *end_dt_get_vrf_rcu(struct sk_buff *skb,
607 struct seg6_end_dt_info *info)
608 {
609 int vrf_ifindex = info->vrf_ifindex;
610 struct net *net = info->net;
611
612 if (unlikely(vrf_ifindex < 0))
613 goto error;
614
615 if (unlikely(!net_eq(dev_net(skb->dev), net)))
616 goto error;
617
618 return dev_get_by_index_rcu(net, vrf_ifindex);
619
620 error:
621 return NULL;
622 }
623
end_dt_vrf_core(struct sk_buff * skb,struct seg6_local_lwt * slwt)624 static struct sk_buff *end_dt_vrf_core(struct sk_buff *skb,
625 struct seg6_local_lwt *slwt)
626 {
627 struct seg6_end_dt_info *info = &slwt->dt_info;
628 struct net_device *vrf;
629
630 vrf = end_dt_get_vrf_rcu(skb, info);
631 if (unlikely(!vrf))
632 goto drop;
633
634 skb->protocol = info->proto;
635
636 skb_dst_drop(skb);
637
638 skb_set_transport_header(skb, info->hdrlen);
639
640 return end_dt_vrf_rcv(skb, info->family, vrf);
641
642 drop:
643 kfree_skb(skb);
644 return ERR_PTR(-EINVAL);
645 }
646
input_action_end_dt4(struct sk_buff * skb,struct seg6_local_lwt * slwt)647 static int input_action_end_dt4(struct sk_buff *skb,
648 struct seg6_local_lwt *slwt)
649 {
650 struct iphdr *iph;
651 int err;
652
653 if (!decap_and_validate(skb, IPPROTO_IPIP))
654 goto drop;
655
656 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
657 goto drop;
658
659 skb = end_dt_vrf_core(skb, slwt);
660 if (!skb)
661 /* packet has been processed and consumed by the VRF */
662 return 0;
663
664 if (IS_ERR(skb))
665 return PTR_ERR(skb);
666
667 iph = ip_hdr(skb);
668
669 err = ip_route_input(skb, iph->daddr, iph->saddr, 0, skb->dev);
670 if (unlikely(err))
671 goto drop;
672
673 return dst_input(skb);
674
675 drop:
676 kfree_skb(skb);
677 return -EINVAL;
678 }
679
seg6_end_dt4_build(struct seg6_local_lwt * slwt,const void * cfg,struct netlink_ext_ack * extack)680 static int seg6_end_dt4_build(struct seg6_local_lwt *slwt, const void *cfg,
681 struct netlink_ext_ack *extack)
682 {
683 return __seg6_end_dt_vrf_build(slwt, cfg, AF_INET, extack);
684 }
685
686 static enum
seg6_end_dt6_parse_mode(struct seg6_local_lwt * slwt)687 seg6_end_dt_mode seg6_end_dt6_parse_mode(struct seg6_local_lwt *slwt)
688 {
689 unsigned long parsed_optattrs = slwt->parsed_optattrs;
690 bool legacy, vrfmode;
691
692 legacy = !!(parsed_optattrs & SEG6_F_ATTR(SEG6_LOCAL_TABLE));
693 vrfmode = !!(parsed_optattrs & SEG6_F_ATTR(SEG6_LOCAL_VRFTABLE));
694
695 if (!(legacy ^ vrfmode))
696 /* both are absent or present: invalid DT6 mode */
697 return DT_INVALID_MODE;
698
699 return legacy ? DT_LEGACY_MODE : DT_VRF_MODE;
700 }
701
seg6_end_dt6_get_mode(struct seg6_local_lwt * slwt)702 static enum seg6_end_dt_mode seg6_end_dt6_get_mode(struct seg6_local_lwt *slwt)
703 {
704 struct seg6_end_dt_info *info = &slwt->dt_info;
705
706 return info->mode;
707 }
708
seg6_end_dt6_build(struct seg6_local_lwt * slwt,const void * cfg,struct netlink_ext_ack * extack)709 static int seg6_end_dt6_build(struct seg6_local_lwt *slwt, const void *cfg,
710 struct netlink_ext_ack *extack)
711 {
712 enum seg6_end_dt_mode mode = seg6_end_dt6_parse_mode(slwt);
713 struct seg6_end_dt_info *info = &slwt->dt_info;
714
715 switch (mode) {
716 case DT_LEGACY_MODE:
717 info->mode = DT_LEGACY_MODE;
718 return 0;
719 case DT_VRF_MODE:
720 return __seg6_end_dt_vrf_build(slwt, cfg, AF_INET6, extack);
721 default:
722 NL_SET_ERR_MSG(extack, "table or vrftable must be specified");
723 return -EINVAL;
724 }
725 }
726 #endif
727
input_action_end_dt6(struct sk_buff * skb,struct seg6_local_lwt * slwt)728 static int input_action_end_dt6(struct sk_buff *skb,
729 struct seg6_local_lwt *slwt)
730 {
731 if (!decap_and_validate(skb, IPPROTO_IPV6))
732 goto drop;
733
734 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
735 goto drop;
736
737 #ifdef CONFIG_NET_L3_MASTER_DEV
738 if (seg6_end_dt6_get_mode(slwt) == DT_LEGACY_MODE)
739 goto legacy_mode;
740
741 /* DT6_VRF_MODE */
742 skb = end_dt_vrf_core(skb, slwt);
743 if (!skb)
744 /* packet has been processed and consumed by the VRF */
745 return 0;
746
747 if (IS_ERR(skb))
748 return PTR_ERR(skb);
749
750 /* note: this time we do not need to specify the table because the VRF
751 * takes care of selecting the correct table.
752 */
753 seg6_lookup_any_nexthop(skb, NULL, 0, true);
754
755 return dst_input(skb);
756
757 legacy_mode:
758 #endif
759 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
760
761 seg6_lookup_any_nexthop(skb, NULL, slwt->table, true);
762
763 return dst_input(skb);
764
765 drop:
766 kfree_skb(skb);
767 return -EINVAL;
768 }
769
770 /* push an SRH on top of the current one */
input_action_end_b6(struct sk_buff * skb,struct seg6_local_lwt * slwt)771 static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
772 {
773 struct ipv6_sr_hdr *srh;
774 int err = -EINVAL;
775
776 srh = get_and_validate_srh(skb);
777 if (!srh)
778 goto drop;
779
780 err = seg6_do_srh_inline(skb, slwt->srh);
781 if (err)
782 goto drop;
783
784 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
785 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
786
787 seg6_lookup_nexthop(skb, NULL, 0);
788
789 return dst_input(skb);
790
791 drop:
792 kfree_skb(skb);
793 return err;
794 }
795
796 /* encapsulate within an outer IPv6 header and a specified SRH */
input_action_end_b6_encap(struct sk_buff * skb,struct seg6_local_lwt * slwt)797 static int input_action_end_b6_encap(struct sk_buff *skb,
798 struct seg6_local_lwt *slwt)
799 {
800 struct ipv6_sr_hdr *srh;
801 int err = -EINVAL;
802
803 srh = get_and_validate_srh(skb);
804 if (!srh)
805 goto drop;
806
807 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
808
809 skb_reset_inner_headers(skb);
810 skb->encapsulation = 1;
811
812 err = seg6_do_srh_encap(skb, slwt->srh, IPPROTO_IPV6);
813 if (err)
814 goto drop;
815
816 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
817 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
818
819 seg6_lookup_nexthop(skb, NULL, 0);
820
821 return dst_input(skb);
822
823 drop:
824 kfree_skb(skb);
825 return err;
826 }
827
828 DEFINE_PER_CPU(struct seg6_bpf_srh_state, seg6_bpf_srh_states);
829
seg6_bpf_has_valid_srh(struct sk_buff * skb)830 bool seg6_bpf_has_valid_srh(struct sk_buff *skb)
831 {
832 struct seg6_bpf_srh_state *srh_state =
833 this_cpu_ptr(&seg6_bpf_srh_states);
834 struct ipv6_sr_hdr *srh = srh_state->srh;
835
836 if (unlikely(srh == NULL))
837 return false;
838
839 if (unlikely(!srh_state->valid)) {
840 if ((srh_state->hdrlen & 7) != 0)
841 return false;
842
843 srh->hdrlen = (u8)(srh_state->hdrlen >> 3);
844 if (!seg6_validate_srh(srh, (srh->hdrlen + 1) << 3, true))
845 return false;
846
847 srh_state->valid = true;
848 }
849
850 return true;
851 }
852
input_action_end_bpf(struct sk_buff * skb,struct seg6_local_lwt * slwt)853 static int input_action_end_bpf(struct sk_buff *skb,
854 struct seg6_local_lwt *slwt)
855 {
856 struct seg6_bpf_srh_state *srh_state =
857 this_cpu_ptr(&seg6_bpf_srh_states);
858 struct ipv6_sr_hdr *srh;
859 int ret;
860
861 srh = get_and_validate_srh(skb);
862 if (!srh) {
863 kfree_skb(skb);
864 return -EINVAL;
865 }
866 advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
867
868 /* preempt_disable is needed to protect the per-CPU buffer srh_state,
869 * which is also accessed by the bpf_lwt_seg6_* helpers
870 */
871 preempt_disable();
872 srh_state->srh = srh;
873 srh_state->hdrlen = srh->hdrlen << 3;
874 srh_state->valid = true;
875
876 rcu_read_lock();
877 bpf_compute_data_pointers(skb);
878 ret = bpf_prog_run_save_cb(slwt->bpf.prog, skb);
879 rcu_read_unlock();
880
881 switch (ret) {
882 case BPF_OK:
883 case BPF_REDIRECT:
884 break;
885 case BPF_DROP:
886 goto drop;
887 default:
888 pr_warn_once("bpf-seg6local: Illegal return value %u\n", ret);
889 goto drop;
890 }
891
892 if (srh_state->srh && !seg6_bpf_has_valid_srh(skb))
893 goto drop;
894
895 preempt_enable();
896 if (ret != BPF_REDIRECT)
897 seg6_lookup_nexthop(skb, NULL, 0);
898
899 return dst_input(skb);
900
901 drop:
902 preempt_enable();
903 kfree_skb(skb);
904 return -EINVAL;
905 }
906
907 static struct seg6_action_desc seg6_action_table[] = {
908 {
909 .action = SEG6_LOCAL_ACTION_END,
910 .attrs = 0,
911 .optattrs = SEG6_F_LOCAL_COUNTERS,
912 .input = input_action_end,
913 },
914 {
915 .action = SEG6_LOCAL_ACTION_END_X,
916 .attrs = SEG6_F_ATTR(SEG6_LOCAL_NH6),
917 .optattrs = SEG6_F_LOCAL_COUNTERS,
918 .input = input_action_end_x,
919 },
920 {
921 .action = SEG6_LOCAL_ACTION_END_T,
922 .attrs = SEG6_F_ATTR(SEG6_LOCAL_TABLE),
923 .optattrs = SEG6_F_LOCAL_COUNTERS,
924 .input = input_action_end_t,
925 },
926 {
927 .action = SEG6_LOCAL_ACTION_END_DX2,
928 .attrs = SEG6_F_ATTR(SEG6_LOCAL_OIF),
929 .optattrs = SEG6_F_LOCAL_COUNTERS,
930 .input = input_action_end_dx2,
931 },
932 {
933 .action = SEG6_LOCAL_ACTION_END_DX6,
934 .attrs = SEG6_F_ATTR(SEG6_LOCAL_NH6),
935 .optattrs = SEG6_F_LOCAL_COUNTERS,
936 .input = input_action_end_dx6,
937 },
938 {
939 .action = SEG6_LOCAL_ACTION_END_DX4,
940 .attrs = SEG6_F_ATTR(SEG6_LOCAL_NH4),
941 .optattrs = SEG6_F_LOCAL_COUNTERS,
942 .input = input_action_end_dx4,
943 },
944 {
945 .action = SEG6_LOCAL_ACTION_END_DT4,
946 .attrs = SEG6_F_ATTR(SEG6_LOCAL_VRFTABLE),
947 .optattrs = SEG6_F_LOCAL_COUNTERS,
948 #ifdef CONFIG_NET_L3_MASTER_DEV
949 .input = input_action_end_dt4,
950 .slwt_ops = {
951 .build_state = seg6_end_dt4_build,
952 },
953 #endif
954 },
955 {
956 .action = SEG6_LOCAL_ACTION_END_DT6,
957 #ifdef CONFIG_NET_L3_MASTER_DEV
958 .attrs = 0,
959 .optattrs = SEG6_F_LOCAL_COUNTERS |
960 SEG6_F_ATTR(SEG6_LOCAL_TABLE) |
961 SEG6_F_ATTR(SEG6_LOCAL_VRFTABLE),
962 .slwt_ops = {
963 .build_state = seg6_end_dt6_build,
964 },
965 #else
966 .attrs = SEG6_F_ATTR(SEG6_LOCAL_TABLE),
967 .optattrs = SEG6_F_LOCAL_COUNTERS,
968 #endif
969 .input = input_action_end_dt6,
970 },
971 {
972 .action = SEG6_LOCAL_ACTION_END_B6,
973 .attrs = SEG6_F_ATTR(SEG6_LOCAL_SRH),
974 .optattrs = SEG6_F_LOCAL_COUNTERS,
975 .input = input_action_end_b6,
976 },
977 {
978 .action = SEG6_LOCAL_ACTION_END_B6_ENCAP,
979 .attrs = SEG6_F_ATTR(SEG6_LOCAL_SRH),
980 .optattrs = SEG6_F_LOCAL_COUNTERS,
981 .input = input_action_end_b6_encap,
982 .static_headroom = sizeof(struct ipv6hdr),
983 },
984 {
985 .action = SEG6_LOCAL_ACTION_END_BPF,
986 .attrs = SEG6_F_ATTR(SEG6_LOCAL_BPF),
987 .optattrs = SEG6_F_LOCAL_COUNTERS,
988 .input = input_action_end_bpf,
989 },
990
991 };
992
__get_action_desc(int action)993 static struct seg6_action_desc *__get_action_desc(int action)
994 {
995 struct seg6_action_desc *desc;
996 int i, count;
997
998 count = ARRAY_SIZE(seg6_action_table);
999 for (i = 0; i < count; i++) {
1000 desc = &seg6_action_table[i];
1001 if (desc->action == action)
1002 return desc;
1003 }
1004
1005 return NULL;
1006 }
1007
seg6_lwtunnel_counters_enabled(struct seg6_local_lwt * slwt)1008 static bool seg6_lwtunnel_counters_enabled(struct seg6_local_lwt *slwt)
1009 {
1010 return slwt->parsed_optattrs & SEG6_F_LOCAL_COUNTERS;
1011 }
1012
seg6_local_update_counters(struct seg6_local_lwt * slwt,unsigned int len,int err)1013 static void seg6_local_update_counters(struct seg6_local_lwt *slwt,
1014 unsigned int len, int err)
1015 {
1016 struct pcpu_seg6_local_counters *pcounters;
1017
1018 pcounters = this_cpu_ptr(slwt->pcpu_counters);
1019 u64_stats_update_begin(&pcounters->syncp);
1020
1021 if (likely(!err)) {
1022 u64_stats_inc(&pcounters->packets);
1023 u64_stats_add(&pcounters->bytes, len);
1024 } else {
1025 u64_stats_inc(&pcounters->errors);
1026 }
1027
1028 u64_stats_update_end(&pcounters->syncp);
1029 }
1030
seg6_local_input(struct sk_buff * skb)1031 static int seg6_local_input(struct sk_buff *skb)
1032 {
1033 struct dst_entry *orig_dst = skb_dst(skb);
1034 struct seg6_action_desc *desc;
1035 struct seg6_local_lwt *slwt;
1036 unsigned int len = skb->len;
1037 int rc;
1038
1039 if (skb->protocol != htons(ETH_P_IPV6)) {
1040 kfree_skb(skb);
1041 return -EINVAL;
1042 }
1043
1044 slwt = seg6_local_lwtunnel(orig_dst->lwtstate);
1045 desc = slwt->desc;
1046
1047 rc = desc->input(skb, slwt);
1048
1049 if (!seg6_lwtunnel_counters_enabled(slwt))
1050 return rc;
1051
1052 seg6_local_update_counters(slwt, len, rc);
1053
1054 return rc;
1055 }
1056
1057 static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = {
1058 [SEG6_LOCAL_ACTION] = { .type = NLA_U32 },
1059 [SEG6_LOCAL_SRH] = { .type = NLA_BINARY },
1060 [SEG6_LOCAL_TABLE] = { .type = NLA_U32 },
1061 [SEG6_LOCAL_VRFTABLE] = { .type = NLA_U32 },
1062 [SEG6_LOCAL_NH4] = { .type = NLA_BINARY,
1063 .len = sizeof(struct in_addr) },
1064 [SEG6_LOCAL_NH6] = { .type = NLA_BINARY,
1065 .len = sizeof(struct in6_addr) },
1066 [SEG6_LOCAL_IIF] = { .type = NLA_U32 },
1067 [SEG6_LOCAL_OIF] = { .type = NLA_U32 },
1068 [SEG6_LOCAL_BPF] = { .type = NLA_NESTED },
1069 [SEG6_LOCAL_COUNTERS] = { .type = NLA_NESTED },
1070 };
1071
parse_nla_srh(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1072 static int parse_nla_srh(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1073 {
1074 struct ipv6_sr_hdr *srh;
1075 int len;
1076
1077 srh = nla_data(attrs[SEG6_LOCAL_SRH]);
1078 len = nla_len(attrs[SEG6_LOCAL_SRH]);
1079
1080 /* SRH must contain at least one segment */
1081 if (len < sizeof(*srh) + sizeof(struct in6_addr))
1082 return -EINVAL;
1083
1084 if (!seg6_validate_srh(srh, len, false))
1085 return -EINVAL;
1086
1087 slwt->srh = kmemdup(srh, len, GFP_KERNEL);
1088 if (!slwt->srh)
1089 return -ENOMEM;
1090
1091 slwt->headroom += len;
1092
1093 return 0;
1094 }
1095
put_nla_srh(struct sk_buff * skb,struct seg6_local_lwt * slwt)1096 static int put_nla_srh(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1097 {
1098 struct ipv6_sr_hdr *srh;
1099 struct nlattr *nla;
1100 int len;
1101
1102 srh = slwt->srh;
1103 len = (srh->hdrlen + 1) << 3;
1104
1105 nla = nla_reserve(skb, SEG6_LOCAL_SRH, len);
1106 if (!nla)
1107 return -EMSGSIZE;
1108
1109 memcpy(nla_data(nla), srh, len);
1110
1111 return 0;
1112 }
1113
cmp_nla_srh(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1114 static int cmp_nla_srh(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1115 {
1116 int len = (a->srh->hdrlen + 1) << 3;
1117
1118 if (len != ((b->srh->hdrlen + 1) << 3))
1119 return 1;
1120
1121 return memcmp(a->srh, b->srh, len);
1122 }
1123
destroy_attr_srh(struct seg6_local_lwt * slwt)1124 static void destroy_attr_srh(struct seg6_local_lwt *slwt)
1125 {
1126 kfree(slwt->srh);
1127 }
1128
parse_nla_table(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1129 static int parse_nla_table(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1130 {
1131 slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]);
1132
1133 return 0;
1134 }
1135
put_nla_table(struct sk_buff * skb,struct seg6_local_lwt * slwt)1136 static int put_nla_table(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1137 {
1138 if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table))
1139 return -EMSGSIZE;
1140
1141 return 0;
1142 }
1143
cmp_nla_table(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1144 static int cmp_nla_table(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1145 {
1146 if (a->table != b->table)
1147 return 1;
1148
1149 return 0;
1150 }
1151
1152 static struct
seg6_possible_end_dt_info(struct seg6_local_lwt * slwt)1153 seg6_end_dt_info *seg6_possible_end_dt_info(struct seg6_local_lwt *slwt)
1154 {
1155 #ifdef CONFIG_NET_L3_MASTER_DEV
1156 return &slwt->dt_info;
1157 #else
1158 return ERR_PTR(-EOPNOTSUPP);
1159 #endif
1160 }
1161
parse_nla_vrftable(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1162 static int parse_nla_vrftable(struct nlattr **attrs,
1163 struct seg6_local_lwt *slwt)
1164 {
1165 struct seg6_end_dt_info *info = seg6_possible_end_dt_info(slwt);
1166
1167 if (IS_ERR(info))
1168 return PTR_ERR(info);
1169
1170 info->vrf_table = nla_get_u32(attrs[SEG6_LOCAL_VRFTABLE]);
1171
1172 return 0;
1173 }
1174
put_nla_vrftable(struct sk_buff * skb,struct seg6_local_lwt * slwt)1175 static int put_nla_vrftable(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1176 {
1177 struct seg6_end_dt_info *info = seg6_possible_end_dt_info(slwt);
1178
1179 if (IS_ERR(info))
1180 return PTR_ERR(info);
1181
1182 if (nla_put_u32(skb, SEG6_LOCAL_VRFTABLE, info->vrf_table))
1183 return -EMSGSIZE;
1184
1185 return 0;
1186 }
1187
cmp_nla_vrftable(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1188 static int cmp_nla_vrftable(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1189 {
1190 struct seg6_end_dt_info *info_a = seg6_possible_end_dt_info(a);
1191 struct seg6_end_dt_info *info_b = seg6_possible_end_dt_info(b);
1192
1193 if (info_a->vrf_table != info_b->vrf_table)
1194 return 1;
1195
1196 return 0;
1197 }
1198
parse_nla_nh4(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1199 static int parse_nla_nh4(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1200 {
1201 memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]),
1202 sizeof(struct in_addr));
1203
1204 return 0;
1205 }
1206
put_nla_nh4(struct sk_buff * skb,struct seg6_local_lwt * slwt)1207 static int put_nla_nh4(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1208 {
1209 struct nlattr *nla;
1210
1211 nla = nla_reserve(skb, SEG6_LOCAL_NH4, sizeof(struct in_addr));
1212 if (!nla)
1213 return -EMSGSIZE;
1214
1215 memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr));
1216
1217 return 0;
1218 }
1219
cmp_nla_nh4(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1220 static int cmp_nla_nh4(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1221 {
1222 return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr));
1223 }
1224
parse_nla_nh6(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1225 static int parse_nla_nh6(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1226 {
1227 memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]),
1228 sizeof(struct in6_addr));
1229
1230 return 0;
1231 }
1232
put_nla_nh6(struct sk_buff * skb,struct seg6_local_lwt * slwt)1233 static int put_nla_nh6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1234 {
1235 struct nlattr *nla;
1236
1237 nla = nla_reserve(skb, SEG6_LOCAL_NH6, sizeof(struct in6_addr));
1238 if (!nla)
1239 return -EMSGSIZE;
1240
1241 memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr));
1242
1243 return 0;
1244 }
1245
cmp_nla_nh6(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1246 static int cmp_nla_nh6(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1247 {
1248 return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr));
1249 }
1250
parse_nla_iif(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1251 static int parse_nla_iif(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1252 {
1253 slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]);
1254
1255 return 0;
1256 }
1257
put_nla_iif(struct sk_buff * skb,struct seg6_local_lwt * slwt)1258 static int put_nla_iif(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1259 {
1260 if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif))
1261 return -EMSGSIZE;
1262
1263 return 0;
1264 }
1265
cmp_nla_iif(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1266 static int cmp_nla_iif(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1267 {
1268 if (a->iif != b->iif)
1269 return 1;
1270
1271 return 0;
1272 }
1273
parse_nla_oif(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1274 static int parse_nla_oif(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1275 {
1276 slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]);
1277
1278 return 0;
1279 }
1280
put_nla_oif(struct sk_buff * skb,struct seg6_local_lwt * slwt)1281 static int put_nla_oif(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1282 {
1283 if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif))
1284 return -EMSGSIZE;
1285
1286 return 0;
1287 }
1288
cmp_nla_oif(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1289 static int cmp_nla_oif(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1290 {
1291 if (a->oif != b->oif)
1292 return 1;
1293
1294 return 0;
1295 }
1296
1297 #define MAX_PROG_NAME 256
1298 static const struct nla_policy bpf_prog_policy[SEG6_LOCAL_BPF_PROG_MAX + 1] = {
1299 [SEG6_LOCAL_BPF_PROG] = { .type = NLA_U32, },
1300 [SEG6_LOCAL_BPF_PROG_NAME] = { .type = NLA_NUL_STRING,
1301 .len = MAX_PROG_NAME },
1302 };
1303
parse_nla_bpf(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1304 static int parse_nla_bpf(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1305 {
1306 struct nlattr *tb[SEG6_LOCAL_BPF_PROG_MAX + 1];
1307 struct bpf_prog *p;
1308 int ret;
1309 u32 fd;
1310
1311 ret = nla_parse_nested_deprecated(tb, SEG6_LOCAL_BPF_PROG_MAX,
1312 attrs[SEG6_LOCAL_BPF],
1313 bpf_prog_policy, NULL);
1314 if (ret < 0)
1315 return ret;
1316
1317 if (!tb[SEG6_LOCAL_BPF_PROG] || !tb[SEG6_LOCAL_BPF_PROG_NAME])
1318 return -EINVAL;
1319
1320 slwt->bpf.name = nla_memdup(tb[SEG6_LOCAL_BPF_PROG_NAME], GFP_KERNEL);
1321 if (!slwt->bpf.name)
1322 return -ENOMEM;
1323
1324 fd = nla_get_u32(tb[SEG6_LOCAL_BPF_PROG]);
1325 p = bpf_prog_get_type(fd, BPF_PROG_TYPE_LWT_SEG6LOCAL);
1326 if (IS_ERR(p)) {
1327 kfree(slwt->bpf.name);
1328 return PTR_ERR(p);
1329 }
1330
1331 slwt->bpf.prog = p;
1332 return 0;
1333 }
1334
put_nla_bpf(struct sk_buff * skb,struct seg6_local_lwt * slwt)1335 static int put_nla_bpf(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1336 {
1337 struct nlattr *nest;
1338
1339 if (!slwt->bpf.prog)
1340 return 0;
1341
1342 nest = nla_nest_start_noflag(skb, SEG6_LOCAL_BPF);
1343 if (!nest)
1344 return -EMSGSIZE;
1345
1346 if (nla_put_u32(skb, SEG6_LOCAL_BPF_PROG, slwt->bpf.prog->aux->id))
1347 return -EMSGSIZE;
1348
1349 if (slwt->bpf.name &&
1350 nla_put_string(skb, SEG6_LOCAL_BPF_PROG_NAME, slwt->bpf.name))
1351 return -EMSGSIZE;
1352
1353 return nla_nest_end(skb, nest);
1354 }
1355
cmp_nla_bpf(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1356 static int cmp_nla_bpf(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1357 {
1358 if (!a->bpf.name && !b->bpf.name)
1359 return 0;
1360
1361 if (!a->bpf.name || !b->bpf.name)
1362 return 1;
1363
1364 return strcmp(a->bpf.name, b->bpf.name);
1365 }
1366
destroy_attr_bpf(struct seg6_local_lwt * slwt)1367 static void destroy_attr_bpf(struct seg6_local_lwt *slwt)
1368 {
1369 kfree(slwt->bpf.name);
1370 if (slwt->bpf.prog)
1371 bpf_prog_put(slwt->bpf.prog);
1372 }
1373
1374 static const struct
1375 nla_policy seg6_local_counters_policy[SEG6_LOCAL_CNT_MAX + 1] = {
1376 [SEG6_LOCAL_CNT_PACKETS] = { .type = NLA_U64 },
1377 [SEG6_LOCAL_CNT_BYTES] = { .type = NLA_U64 },
1378 [SEG6_LOCAL_CNT_ERRORS] = { .type = NLA_U64 },
1379 };
1380
parse_nla_counters(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1381 static int parse_nla_counters(struct nlattr **attrs,
1382 struct seg6_local_lwt *slwt)
1383 {
1384 struct pcpu_seg6_local_counters __percpu *pcounters;
1385 struct nlattr *tb[SEG6_LOCAL_CNT_MAX + 1];
1386 int ret;
1387
1388 ret = nla_parse_nested_deprecated(tb, SEG6_LOCAL_CNT_MAX,
1389 attrs[SEG6_LOCAL_COUNTERS],
1390 seg6_local_counters_policy, NULL);
1391 if (ret < 0)
1392 return ret;
1393
1394 /* basic support for SRv6 Behavior counters requires at least:
1395 * packets, bytes and errors.
1396 */
1397 if (!tb[SEG6_LOCAL_CNT_PACKETS] || !tb[SEG6_LOCAL_CNT_BYTES] ||
1398 !tb[SEG6_LOCAL_CNT_ERRORS])
1399 return -EINVAL;
1400
1401 /* counters are always zero initialized */
1402 pcounters = seg6_local_alloc_pcpu_counters(GFP_KERNEL);
1403 if (!pcounters)
1404 return -ENOMEM;
1405
1406 slwt->pcpu_counters = pcounters;
1407
1408 return 0;
1409 }
1410
seg6_local_fill_nla_counters(struct sk_buff * skb,struct seg6_local_counters * counters)1411 static int seg6_local_fill_nla_counters(struct sk_buff *skb,
1412 struct seg6_local_counters *counters)
1413 {
1414 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_PACKETS, counters->packets,
1415 SEG6_LOCAL_CNT_PAD))
1416 return -EMSGSIZE;
1417
1418 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_BYTES, counters->bytes,
1419 SEG6_LOCAL_CNT_PAD))
1420 return -EMSGSIZE;
1421
1422 if (nla_put_u64_64bit(skb, SEG6_LOCAL_CNT_ERRORS, counters->errors,
1423 SEG6_LOCAL_CNT_PAD))
1424 return -EMSGSIZE;
1425
1426 return 0;
1427 }
1428
put_nla_counters(struct sk_buff * skb,struct seg6_local_lwt * slwt)1429 static int put_nla_counters(struct sk_buff *skb, struct seg6_local_lwt *slwt)
1430 {
1431 struct seg6_local_counters counters = { 0, 0, 0 };
1432 struct nlattr *nest;
1433 int rc, i;
1434
1435 nest = nla_nest_start(skb, SEG6_LOCAL_COUNTERS);
1436 if (!nest)
1437 return -EMSGSIZE;
1438
1439 for_each_possible_cpu(i) {
1440 struct pcpu_seg6_local_counters *pcounters;
1441 u64 packets, bytes, errors;
1442 unsigned int start;
1443
1444 pcounters = per_cpu_ptr(slwt->pcpu_counters, i);
1445 do {
1446 start = u64_stats_fetch_begin_irq(&pcounters->syncp);
1447
1448 packets = u64_stats_read(&pcounters->packets);
1449 bytes = u64_stats_read(&pcounters->bytes);
1450 errors = u64_stats_read(&pcounters->errors);
1451
1452 } while (u64_stats_fetch_retry_irq(&pcounters->syncp, start));
1453
1454 counters.packets += packets;
1455 counters.bytes += bytes;
1456 counters.errors += errors;
1457 }
1458
1459 rc = seg6_local_fill_nla_counters(skb, &counters);
1460 if (rc < 0) {
1461 nla_nest_cancel(skb, nest);
1462 return rc;
1463 }
1464
1465 return nla_nest_end(skb, nest);
1466 }
1467
cmp_nla_counters(struct seg6_local_lwt * a,struct seg6_local_lwt * b)1468 static int cmp_nla_counters(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
1469 {
1470 /* a and b are equal if both have pcpu_counters set or not */
1471 return (!!((unsigned long)a->pcpu_counters)) ^
1472 (!!((unsigned long)b->pcpu_counters));
1473 }
1474
destroy_attr_counters(struct seg6_local_lwt * slwt)1475 static void destroy_attr_counters(struct seg6_local_lwt *slwt)
1476 {
1477 free_percpu(slwt->pcpu_counters);
1478 }
1479
1480 struct seg6_action_param {
1481 int (*parse)(struct nlattr **attrs, struct seg6_local_lwt *slwt);
1482 int (*put)(struct sk_buff *skb, struct seg6_local_lwt *slwt);
1483 int (*cmp)(struct seg6_local_lwt *a, struct seg6_local_lwt *b);
1484
1485 /* optional destroy() callback useful for releasing resources which
1486 * have been previously acquired in the corresponding parse()
1487 * function.
1488 */
1489 void (*destroy)(struct seg6_local_lwt *slwt);
1490 };
1491
1492 static struct seg6_action_param seg6_action_params[SEG6_LOCAL_MAX + 1] = {
1493 [SEG6_LOCAL_SRH] = { .parse = parse_nla_srh,
1494 .put = put_nla_srh,
1495 .cmp = cmp_nla_srh,
1496 .destroy = destroy_attr_srh },
1497
1498 [SEG6_LOCAL_TABLE] = { .parse = parse_nla_table,
1499 .put = put_nla_table,
1500 .cmp = cmp_nla_table },
1501
1502 [SEG6_LOCAL_NH4] = { .parse = parse_nla_nh4,
1503 .put = put_nla_nh4,
1504 .cmp = cmp_nla_nh4 },
1505
1506 [SEG6_LOCAL_NH6] = { .parse = parse_nla_nh6,
1507 .put = put_nla_nh6,
1508 .cmp = cmp_nla_nh6 },
1509
1510 [SEG6_LOCAL_IIF] = { .parse = parse_nla_iif,
1511 .put = put_nla_iif,
1512 .cmp = cmp_nla_iif },
1513
1514 [SEG6_LOCAL_OIF] = { .parse = parse_nla_oif,
1515 .put = put_nla_oif,
1516 .cmp = cmp_nla_oif },
1517
1518 [SEG6_LOCAL_BPF] = { .parse = parse_nla_bpf,
1519 .put = put_nla_bpf,
1520 .cmp = cmp_nla_bpf,
1521 .destroy = destroy_attr_bpf },
1522
1523 [SEG6_LOCAL_VRFTABLE] = { .parse = parse_nla_vrftable,
1524 .put = put_nla_vrftable,
1525 .cmp = cmp_nla_vrftable },
1526
1527 [SEG6_LOCAL_COUNTERS] = { .parse = parse_nla_counters,
1528 .put = put_nla_counters,
1529 .cmp = cmp_nla_counters,
1530 .destroy = destroy_attr_counters },
1531 };
1532
1533 /* call the destroy() callback (if available) for each set attribute in
1534 * @parsed_attrs, starting from the first attribute up to the @max_parsed
1535 * (excluded) attribute.
1536 */
__destroy_attrs(unsigned long parsed_attrs,int max_parsed,struct seg6_local_lwt * slwt)1537 static void __destroy_attrs(unsigned long parsed_attrs, int max_parsed,
1538 struct seg6_local_lwt *slwt)
1539 {
1540 struct seg6_action_param *param;
1541 int i;
1542
1543 /* Every required seg6local attribute is identified by an ID which is
1544 * encoded as a flag (i.e: 1 << ID) in the 'attrs' bitmask;
1545 *
1546 * We scan the 'parsed_attrs' bitmask, starting from the first attribute
1547 * up to the @max_parsed (excluded) attribute.
1548 * For each set attribute, we retrieve the corresponding destroy()
1549 * callback. If the callback is not available, then we skip to the next
1550 * attribute; otherwise, we call the destroy() callback.
1551 */
1552 for (i = 0; i < max_parsed; ++i) {
1553 if (!(parsed_attrs & SEG6_F_ATTR(i)))
1554 continue;
1555
1556 param = &seg6_action_params[i];
1557
1558 if (param->destroy)
1559 param->destroy(slwt);
1560 }
1561 }
1562
1563 /* release all the resources that may have been acquired during parsing
1564 * operations.
1565 */
destroy_attrs(struct seg6_local_lwt * slwt)1566 static void destroy_attrs(struct seg6_local_lwt *slwt)
1567 {
1568 unsigned long attrs = slwt->desc->attrs | slwt->parsed_optattrs;
1569
1570 __destroy_attrs(attrs, SEG6_LOCAL_MAX + 1, slwt);
1571 }
1572
parse_nla_optional_attrs(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1573 static int parse_nla_optional_attrs(struct nlattr **attrs,
1574 struct seg6_local_lwt *slwt)
1575 {
1576 struct seg6_action_desc *desc = slwt->desc;
1577 unsigned long parsed_optattrs = 0;
1578 struct seg6_action_param *param;
1579 int err, i;
1580
1581 for (i = 0; i < SEG6_LOCAL_MAX + 1; ++i) {
1582 if (!(desc->optattrs & SEG6_F_ATTR(i)) || !attrs[i])
1583 continue;
1584
1585 /* once here, the i-th attribute is provided by the
1586 * userspace AND it is identified optional as well.
1587 */
1588 param = &seg6_action_params[i];
1589
1590 err = param->parse(attrs, slwt);
1591 if (err < 0)
1592 goto parse_optattrs_err;
1593
1594 /* current attribute has been correctly parsed */
1595 parsed_optattrs |= SEG6_F_ATTR(i);
1596 }
1597
1598 /* store in the tunnel state all the optional attributed successfully
1599 * parsed.
1600 */
1601 slwt->parsed_optattrs = parsed_optattrs;
1602
1603 return 0;
1604
1605 parse_optattrs_err:
1606 __destroy_attrs(parsed_optattrs, i, slwt);
1607
1608 return err;
1609 }
1610
1611 /* call the custom constructor of the behavior during its initialization phase
1612 * and after that all its attributes have been parsed successfully.
1613 */
1614 static int
seg6_local_lwtunnel_build_state(struct seg6_local_lwt * slwt,const void * cfg,struct netlink_ext_ack * extack)1615 seg6_local_lwtunnel_build_state(struct seg6_local_lwt *slwt, const void *cfg,
1616 struct netlink_ext_ack *extack)
1617 {
1618 struct seg6_action_desc *desc = slwt->desc;
1619 struct seg6_local_lwtunnel_ops *ops;
1620
1621 ops = &desc->slwt_ops;
1622 if (!ops->build_state)
1623 return 0;
1624
1625 return ops->build_state(slwt, cfg, extack);
1626 }
1627
1628 /* call the custom destructor of the behavior which is invoked before the
1629 * tunnel is going to be destroyed.
1630 */
seg6_local_lwtunnel_destroy_state(struct seg6_local_lwt * slwt)1631 static void seg6_local_lwtunnel_destroy_state(struct seg6_local_lwt *slwt)
1632 {
1633 struct seg6_action_desc *desc = slwt->desc;
1634 struct seg6_local_lwtunnel_ops *ops;
1635
1636 ops = &desc->slwt_ops;
1637 if (!ops->destroy_state)
1638 return;
1639
1640 ops->destroy_state(slwt);
1641 }
1642
parse_nla_action(struct nlattr ** attrs,struct seg6_local_lwt * slwt)1643 static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt)
1644 {
1645 struct seg6_action_param *param;
1646 struct seg6_action_desc *desc;
1647 unsigned long invalid_attrs;
1648 int i, err;
1649
1650 desc = __get_action_desc(slwt->action);
1651 if (!desc)
1652 return -EINVAL;
1653
1654 if (!desc->input)
1655 return -EOPNOTSUPP;
1656
1657 slwt->desc = desc;
1658 slwt->headroom += desc->static_headroom;
1659
1660 /* Forcing the desc->optattrs *set* and the desc->attrs *set* to be
1661 * disjoined, this allow us to release acquired resources by optional
1662 * attributes and by required attributes independently from each other
1663 * without any interference.
1664 * In other terms, we are sure that we do not release some the acquired
1665 * resources twice.
1666 *
1667 * Note that if an attribute is configured both as required and as
1668 * optional, it means that the user has messed something up in the
1669 * seg6_action_table. Therefore, this check is required for SRv6
1670 * behaviors to work properly.
1671 */
1672 invalid_attrs = desc->attrs & desc->optattrs;
1673 if (invalid_attrs) {
1674 WARN_ONCE(1,
1675 "An attribute cannot be both required AND optional");
1676 return -EINVAL;
1677 }
1678
1679 /* parse the required attributes */
1680 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
1681 if (desc->attrs & SEG6_F_ATTR(i)) {
1682 if (!attrs[i])
1683 return -EINVAL;
1684
1685 param = &seg6_action_params[i];
1686
1687 err = param->parse(attrs, slwt);
1688 if (err < 0)
1689 goto parse_attrs_err;
1690 }
1691 }
1692
1693 /* parse the optional attributes, if any */
1694 err = parse_nla_optional_attrs(attrs, slwt);
1695 if (err < 0)
1696 goto parse_attrs_err;
1697
1698 return 0;
1699
1700 parse_attrs_err:
1701 /* release any resource that may have been acquired during the i-1
1702 * parse() operations.
1703 */
1704 __destroy_attrs(desc->attrs, i, slwt);
1705
1706 return err;
1707 }
1708
seg6_local_build_state(struct net * net,struct nlattr * nla,unsigned int family,const void * cfg,struct lwtunnel_state ** ts,struct netlink_ext_ack * extack)1709 static int seg6_local_build_state(struct net *net, struct nlattr *nla,
1710 unsigned int family, const void *cfg,
1711 struct lwtunnel_state **ts,
1712 struct netlink_ext_ack *extack)
1713 {
1714 struct nlattr *tb[SEG6_LOCAL_MAX + 1];
1715 struct lwtunnel_state *newts;
1716 struct seg6_local_lwt *slwt;
1717 int err;
1718
1719 if (family != AF_INET6)
1720 return -EINVAL;
1721
1722 err = nla_parse_nested_deprecated(tb, SEG6_LOCAL_MAX, nla,
1723 seg6_local_policy, extack);
1724
1725 if (err < 0)
1726 return err;
1727
1728 if (!tb[SEG6_LOCAL_ACTION])
1729 return -EINVAL;
1730
1731 newts = lwtunnel_state_alloc(sizeof(*slwt));
1732 if (!newts)
1733 return -ENOMEM;
1734
1735 slwt = seg6_local_lwtunnel(newts);
1736 slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]);
1737
1738 err = parse_nla_action(tb, slwt);
1739 if (err < 0)
1740 goto out_free;
1741
1742 err = seg6_local_lwtunnel_build_state(slwt, cfg, extack);
1743 if (err < 0)
1744 goto out_destroy_attrs;
1745
1746 newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL;
1747 newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT;
1748 newts->headroom = slwt->headroom;
1749
1750 *ts = newts;
1751
1752 return 0;
1753
1754 out_destroy_attrs:
1755 destroy_attrs(slwt);
1756 out_free:
1757 kfree(newts);
1758 return err;
1759 }
1760
seg6_local_destroy_state(struct lwtunnel_state * lwt)1761 static void seg6_local_destroy_state(struct lwtunnel_state *lwt)
1762 {
1763 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt);
1764
1765 seg6_local_lwtunnel_destroy_state(slwt);
1766
1767 destroy_attrs(slwt);
1768
1769 return;
1770 }
1771
seg6_local_fill_encap(struct sk_buff * skb,struct lwtunnel_state * lwt)1772 static int seg6_local_fill_encap(struct sk_buff *skb,
1773 struct lwtunnel_state *lwt)
1774 {
1775 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt);
1776 struct seg6_action_param *param;
1777 unsigned long attrs;
1778 int i, err;
1779
1780 if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action))
1781 return -EMSGSIZE;
1782
1783 attrs = slwt->desc->attrs | slwt->parsed_optattrs;
1784
1785 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
1786 if (attrs & SEG6_F_ATTR(i)) {
1787 param = &seg6_action_params[i];
1788 err = param->put(skb, slwt);
1789 if (err < 0)
1790 return err;
1791 }
1792 }
1793
1794 return 0;
1795 }
1796
seg6_local_get_encap_size(struct lwtunnel_state * lwt)1797 static int seg6_local_get_encap_size(struct lwtunnel_state *lwt)
1798 {
1799 struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt);
1800 unsigned long attrs;
1801 int nlsize;
1802
1803 nlsize = nla_total_size(4); /* action */
1804
1805 attrs = slwt->desc->attrs | slwt->parsed_optattrs;
1806
1807 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_SRH))
1808 nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3);
1809
1810 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_TABLE))
1811 nlsize += nla_total_size(4);
1812
1813 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_NH4))
1814 nlsize += nla_total_size(4);
1815
1816 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_NH6))
1817 nlsize += nla_total_size(16);
1818
1819 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_IIF))
1820 nlsize += nla_total_size(4);
1821
1822 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_OIF))
1823 nlsize += nla_total_size(4);
1824
1825 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_BPF))
1826 nlsize += nla_total_size(sizeof(struct nlattr)) +
1827 nla_total_size(MAX_PROG_NAME) +
1828 nla_total_size(4);
1829
1830 if (attrs & SEG6_F_ATTR(SEG6_LOCAL_VRFTABLE))
1831 nlsize += nla_total_size(4);
1832
1833 if (attrs & SEG6_F_LOCAL_COUNTERS)
1834 nlsize += nla_total_size(0) + /* nest SEG6_LOCAL_COUNTERS */
1835 /* SEG6_LOCAL_CNT_PACKETS */
1836 nla_total_size_64bit(sizeof(__u64)) +
1837 /* SEG6_LOCAL_CNT_BYTES */
1838 nla_total_size_64bit(sizeof(__u64)) +
1839 /* SEG6_LOCAL_CNT_ERRORS */
1840 nla_total_size_64bit(sizeof(__u64));
1841
1842 return nlsize;
1843 }
1844
seg6_local_cmp_encap(struct lwtunnel_state * a,struct lwtunnel_state * b)1845 static int seg6_local_cmp_encap(struct lwtunnel_state *a,
1846 struct lwtunnel_state *b)
1847 {
1848 struct seg6_local_lwt *slwt_a, *slwt_b;
1849 struct seg6_action_param *param;
1850 unsigned long attrs_a, attrs_b;
1851 int i;
1852
1853 slwt_a = seg6_local_lwtunnel(a);
1854 slwt_b = seg6_local_lwtunnel(b);
1855
1856 if (slwt_a->action != slwt_b->action)
1857 return 1;
1858
1859 attrs_a = slwt_a->desc->attrs | slwt_a->parsed_optattrs;
1860 attrs_b = slwt_b->desc->attrs | slwt_b->parsed_optattrs;
1861
1862 if (attrs_a != attrs_b)
1863 return 1;
1864
1865 for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
1866 if (attrs_a & SEG6_F_ATTR(i)) {
1867 param = &seg6_action_params[i];
1868 if (param->cmp(slwt_a, slwt_b))
1869 return 1;
1870 }
1871 }
1872
1873 return 0;
1874 }
1875
1876 static const struct lwtunnel_encap_ops seg6_local_ops = {
1877 .build_state = seg6_local_build_state,
1878 .destroy_state = seg6_local_destroy_state,
1879 .input = seg6_local_input,
1880 .fill_encap = seg6_local_fill_encap,
1881 .get_encap_size = seg6_local_get_encap_size,
1882 .cmp_encap = seg6_local_cmp_encap,
1883 .owner = THIS_MODULE,
1884 };
1885
seg6_local_init(void)1886 int __init seg6_local_init(void)
1887 {
1888 /* If the max total number of defined attributes is reached, then your
1889 * kernel build stops here.
1890 *
1891 * This check is required to avoid arithmetic overflows when processing
1892 * behavior attributes and the maximum number of defined attributes
1893 * exceeds the allowed value.
1894 */
1895 BUILD_BUG_ON(SEG6_LOCAL_MAX + 1 > BITS_PER_TYPE(unsigned long));
1896
1897 return lwtunnel_encap_add_ops(&seg6_local_ops,
1898 LWTUNNEL_ENCAP_SEG6_LOCAL);
1899 }
1900
seg6_local_exit(void)1901 void seg6_local_exit(void)
1902 {
1903 lwtunnel_encap_del_ops(&seg6_local_ops, LWTUNNEL_ENCAP_SEG6_LOCAL);
1904 }
1905