xref: /linux/net/ipv6/seg6_local.c (revision c411ed854584a71b0e86ac3019b60e4789d88086)
1 /*
2  *  SR-IPv6 implementation
3  *
4  *  Author:
5  *  David Lebrun <david.lebrun@uclouvain.be>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or
9  *        modify it under the terms of the GNU General Public License
10  *        as published by the Free Software Foundation; either version
11  *        2 of the License, or (at your option) any later version.
12  */
13 
14 #include <linux/types.h>
15 #include <linux/skbuff.h>
16 #include <linux/net.h>
17 #include <linux/module.h>
18 #include <net/ip.h>
19 #include <net/lwtunnel.h>
20 #include <net/netevent.h>
21 #include <net/netns/generic.h>
22 #include <net/ip6_fib.h>
23 #include <net/route.h>
24 #include <net/seg6.h>
25 #include <linux/seg6.h>
26 #include <linux/seg6_local.h>
27 #include <net/addrconf.h>
28 #include <net/ip6_route.h>
29 #include <net/dst_cache.h>
30 #ifdef CONFIG_IPV6_SEG6_HMAC
31 #include <net/seg6_hmac.h>
32 #endif
33 #include <linux/etherdevice.h>
34 
35 struct seg6_local_lwt;
36 
37 struct seg6_action_desc {
38 	int action;
39 	unsigned long attrs;
40 	int (*input)(struct sk_buff *skb, struct seg6_local_lwt *slwt);
41 	int static_headroom;
42 };
43 
44 struct seg6_local_lwt {
45 	int action;
46 	struct ipv6_sr_hdr *srh;
47 	int table;
48 	struct in_addr nh4;
49 	struct in6_addr nh6;
50 	int iif;
51 	int oif;
52 
53 	int headroom;
54 	struct seg6_action_desc *desc;
55 };
56 
57 static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt)
58 {
59 	return (struct seg6_local_lwt *)lwt->data;
60 }
61 
62 static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb)
63 {
64 	struct ipv6_sr_hdr *srh;
65 	struct ipv6hdr *hdr;
66 	int len;
67 
68 	hdr = ipv6_hdr(skb);
69 	if (hdr->nexthdr != IPPROTO_ROUTING)
70 		return NULL;
71 
72 	srh = (struct ipv6_sr_hdr *)(hdr + 1);
73 	len = (srh->hdrlen + 1) << 3;
74 
75 	if (!pskb_may_pull(skb, sizeof(*hdr) + len))
76 		return NULL;
77 
78 	if (!seg6_validate_srh(srh, len))
79 		return NULL;
80 
81 	return srh;
82 }
83 
84 static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb)
85 {
86 	struct ipv6_sr_hdr *srh;
87 
88 	srh = get_srh(skb);
89 	if (!srh)
90 		return NULL;
91 
92 	if (srh->segments_left == 0)
93 		return NULL;
94 
95 #ifdef CONFIG_IPV6_SEG6_HMAC
96 	if (!seg6_hmac_validate_skb(skb))
97 		return NULL;
98 #endif
99 
100 	return srh;
101 }
102 
103 static bool decap_and_validate(struct sk_buff *skb, int proto)
104 {
105 	struct ipv6_sr_hdr *srh;
106 	unsigned int off = 0;
107 
108 	srh = get_srh(skb);
109 	if (srh && srh->segments_left > 0)
110 		return false;
111 
112 #ifdef CONFIG_IPV6_SEG6_HMAC
113 	if (srh && !seg6_hmac_validate_skb(skb))
114 		return false;
115 #endif
116 
117 	if (ipv6_find_hdr(skb, &off, proto, NULL, NULL) < 0)
118 		return false;
119 
120 	if (!pskb_pull(skb, off))
121 		return false;
122 
123 	skb_postpull_rcsum(skb, skb_network_header(skb), off);
124 
125 	skb_reset_network_header(skb);
126 	skb_reset_transport_header(skb);
127 	skb->encapsulation = 0;
128 
129 	return true;
130 }
131 
132 static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
133 {
134 	struct in6_addr *addr;
135 
136 	srh->segments_left--;
137 	addr = srh->segments + srh->segments_left;
138 	*daddr = *addr;
139 }
140 
141 static void lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
142 			   u32 tbl_id)
143 {
144 	struct net *net = dev_net(skb->dev);
145 	struct ipv6hdr *hdr = ipv6_hdr(skb);
146 	int flags = RT6_LOOKUP_F_HAS_SADDR;
147 	struct dst_entry *dst = NULL;
148 	struct rt6_info *rt;
149 	struct flowi6 fl6;
150 
151 	fl6.flowi6_iif = skb->dev->ifindex;
152 	fl6.daddr = nhaddr ? *nhaddr : hdr->daddr;
153 	fl6.saddr = hdr->saddr;
154 	fl6.flowlabel = ip6_flowinfo(hdr);
155 	fl6.flowi6_mark = skb->mark;
156 	fl6.flowi6_proto = hdr->nexthdr;
157 
158 	if (nhaddr)
159 		fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH;
160 
161 	if (!tbl_id) {
162 		dst = ip6_route_input_lookup(net, skb->dev, &fl6, flags);
163 	} else {
164 		struct fib6_table *table;
165 
166 		table = fib6_get_table(net, tbl_id);
167 		if (!table)
168 			goto out;
169 
170 		rt = ip6_pol_route(net, table, 0, &fl6, flags);
171 		dst = &rt->dst;
172 	}
173 
174 	if (dst && dst->dev->flags & IFF_LOOPBACK && !dst->error) {
175 		dst_release(dst);
176 		dst = NULL;
177 	}
178 
179 out:
180 	if (!dst) {
181 		rt = net->ipv6.ip6_blk_hole_entry;
182 		dst = &rt->dst;
183 		dst_hold(dst);
184 	}
185 
186 	skb_dst_drop(skb);
187 	skb_dst_set(skb, dst);
188 }
189 
190 /* regular endpoint function */
191 static int input_action_end(struct sk_buff *skb, struct seg6_local_lwt *slwt)
192 {
193 	struct ipv6_sr_hdr *srh;
194 
195 	srh = get_and_validate_srh(skb);
196 	if (!srh)
197 		goto drop;
198 
199 	advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
200 
201 	lookup_nexthop(skb, NULL, 0);
202 
203 	return dst_input(skb);
204 
205 drop:
206 	kfree_skb(skb);
207 	return -EINVAL;
208 }
209 
210 /* regular endpoint, and forward to specified nexthop */
211 static int input_action_end_x(struct sk_buff *skb, struct seg6_local_lwt *slwt)
212 {
213 	struct ipv6_sr_hdr *srh;
214 
215 	srh = get_and_validate_srh(skb);
216 	if (!srh)
217 		goto drop;
218 
219 	advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
220 
221 	lookup_nexthop(skb, &slwt->nh6, 0);
222 
223 	return dst_input(skb);
224 
225 drop:
226 	kfree_skb(skb);
227 	return -EINVAL;
228 }
229 
230 static int input_action_end_t(struct sk_buff *skb, struct seg6_local_lwt *slwt)
231 {
232 	struct ipv6_sr_hdr *srh;
233 
234 	srh = get_and_validate_srh(skb);
235 	if (!srh)
236 		goto drop;
237 
238 	advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
239 
240 	lookup_nexthop(skb, NULL, slwt->table);
241 
242 	return dst_input(skb);
243 
244 drop:
245 	kfree_skb(skb);
246 	return -EINVAL;
247 }
248 
249 /* decapsulate and forward inner L2 frame on specified interface */
250 static int input_action_end_dx2(struct sk_buff *skb,
251 				struct seg6_local_lwt *slwt)
252 {
253 	struct net *net = dev_net(skb->dev);
254 	struct net_device *odev;
255 	struct ethhdr *eth;
256 
257 	if (!decap_and_validate(skb, NEXTHDR_NONE))
258 		goto drop;
259 
260 	if (!pskb_may_pull(skb, ETH_HLEN))
261 		goto drop;
262 
263 	skb_reset_mac_header(skb);
264 	eth = (struct ethhdr *)skb->data;
265 
266 	/* To determine the frame's protocol, we assume it is 802.3. This avoids
267 	 * a call to eth_type_trans(), which is not really relevant for our
268 	 * use case.
269 	 */
270 	if (!eth_proto_is_802_3(eth->h_proto))
271 		goto drop;
272 
273 	odev = dev_get_by_index_rcu(net, slwt->oif);
274 	if (!odev)
275 		goto drop;
276 
277 	/* As we accept Ethernet frames, make sure the egress device is of
278 	 * the correct type.
279 	 */
280 	if (odev->type != ARPHRD_ETHER)
281 		goto drop;
282 
283 	if (!(odev->flags & IFF_UP) || !netif_carrier_ok(odev))
284 		goto drop;
285 
286 	skb_orphan(skb);
287 
288 	if (skb_warn_if_lro(skb))
289 		goto drop;
290 
291 	skb_forward_csum(skb);
292 
293 	if (skb->len - ETH_HLEN > odev->mtu)
294 		goto drop;
295 
296 	skb->dev = odev;
297 	skb->protocol = eth->h_proto;
298 
299 	return dev_queue_xmit(skb);
300 
301 drop:
302 	kfree_skb(skb);
303 	return -EINVAL;
304 }
305 
306 /* decapsulate and forward to specified nexthop */
307 static int input_action_end_dx6(struct sk_buff *skb,
308 				struct seg6_local_lwt *slwt)
309 {
310 	struct in6_addr *nhaddr = NULL;
311 
312 	/* this function accepts IPv6 encapsulated packets, with either
313 	 * an SRH with SL=0, or no SRH.
314 	 */
315 
316 	if (!decap_and_validate(skb, IPPROTO_IPV6))
317 		goto drop;
318 
319 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
320 		goto drop;
321 
322 	/* The inner packet is not associated to any local interface,
323 	 * so we do not call netif_rx().
324 	 *
325 	 * If slwt->nh6 is set to ::, then lookup the nexthop for the
326 	 * inner packet's DA. Otherwise, use the specified nexthop.
327 	 */
328 
329 	if (!ipv6_addr_any(&slwt->nh6))
330 		nhaddr = &slwt->nh6;
331 
332 	lookup_nexthop(skb, nhaddr, 0);
333 
334 	return dst_input(skb);
335 drop:
336 	kfree_skb(skb);
337 	return -EINVAL;
338 }
339 
340 static int input_action_end_dx4(struct sk_buff *skb,
341 				struct seg6_local_lwt *slwt)
342 {
343 	struct iphdr *iph;
344 	__be32 nhaddr;
345 	int err;
346 
347 	if (!decap_and_validate(skb, IPPROTO_IPIP))
348 		goto drop;
349 
350 	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
351 		goto drop;
352 
353 	skb->protocol = htons(ETH_P_IP);
354 
355 	iph = ip_hdr(skb);
356 
357 	nhaddr = slwt->nh4.s_addr ?: iph->daddr;
358 
359 	skb_dst_drop(skb);
360 
361 	err = ip_route_input(skb, nhaddr, iph->saddr, 0, skb->dev);
362 	if (err)
363 		goto drop;
364 
365 	return dst_input(skb);
366 
367 drop:
368 	kfree_skb(skb);
369 	return -EINVAL;
370 }
371 
372 static int input_action_end_dt6(struct sk_buff *skb,
373 				struct seg6_local_lwt *slwt)
374 {
375 	if (!decap_and_validate(skb, IPPROTO_IPV6))
376 		goto drop;
377 
378 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
379 		goto drop;
380 
381 	lookup_nexthop(skb, NULL, slwt->table);
382 
383 	return dst_input(skb);
384 
385 drop:
386 	kfree_skb(skb);
387 	return -EINVAL;
388 }
389 
390 /* push an SRH on top of the current one */
391 static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
392 {
393 	struct ipv6_sr_hdr *srh;
394 	int err = -EINVAL;
395 
396 	srh = get_and_validate_srh(skb);
397 	if (!srh)
398 		goto drop;
399 
400 	err = seg6_do_srh_inline(skb, slwt->srh);
401 	if (err)
402 		goto drop;
403 
404 	ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
405 	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
406 
407 	lookup_nexthop(skb, NULL, 0);
408 
409 	return dst_input(skb);
410 
411 drop:
412 	kfree_skb(skb);
413 	return err;
414 }
415 
416 /* encapsulate within an outer IPv6 header and a specified SRH */
417 static int input_action_end_b6_encap(struct sk_buff *skb,
418 				     struct seg6_local_lwt *slwt)
419 {
420 	struct ipv6_sr_hdr *srh;
421 	int err = -EINVAL;
422 
423 	srh = get_and_validate_srh(skb);
424 	if (!srh)
425 		goto drop;
426 
427 	advance_nextseg(srh, &ipv6_hdr(skb)->daddr);
428 
429 	skb_reset_inner_headers(skb);
430 	skb->encapsulation = 1;
431 
432 	err = seg6_do_srh_encap(skb, slwt->srh, IPPROTO_IPV6);
433 	if (err)
434 		goto drop;
435 
436 	ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
437 	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
438 
439 	lookup_nexthop(skb, NULL, 0);
440 
441 	return dst_input(skb);
442 
443 drop:
444 	kfree_skb(skb);
445 	return err;
446 }
447 
448 static struct seg6_action_desc seg6_action_table[] = {
449 	{
450 		.action		= SEG6_LOCAL_ACTION_END,
451 		.attrs		= 0,
452 		.input		= input_action_end,
453 	},
454 	{
455 		.action		= SEG6_LOCAL_ACTION_END_X,
456 		.attrs		= (1 << SEG6_LOCAL_NH6),
457 		.input		= input_action_end_x,
458 	},
459 	{
460 		.action		= SEG6_LOCAL_ACTION_END_T,
461 		.attrs		= (1 << SEG6_LOCAL_TABLE),
462 		.input		= input_action_end_t,
463 	},
464 	{
465 		.action		= SEG6_LOCAL_ACTION_END_DX2,
466 		.attrs		= (1 << SEG6_LOCAL_OIF),
467 		.input		= input_action_end_dx2,
468 	},
469 	{
470 		.action		= SEG6_LOCAL_ACTION_END_DX6,
471 		.attrs		= (1 << SEG6_LOCAL_NH6),
472 		.input		= input_action_end_dx6,
473 	},
474 	{
475 		.action		= SEG6_LOCAL_ACTION_END_DX4,
476 		.attrs		= (1 << SEG6_LOCAL_NH4),
477 		.input		= input_action_end_dx4,
478 	},
479 	{
480 		.action		= SEG6_LOCAL_ACTION_END_DT6,
481 		.attrs		= (1 << SEG6_LOCAL_TABLE),
482 		.input		= input_action_end_dt6,
483 	},
484 	{
485 		.action		= SEG6_LOCAL_ACTION_END_B6,
486 		.attrs		= (1 << SEG6_LOCAL_SRH),
487 		.input		= input_action_end_b6,
488 	},
489 	{
490 		.action		= SEG6_LOCAL_ACTION_END_B6_ENCAP,
491 		.attrs		= (1 << SEG6_LOCAL_SRH),
492 		.input		= input_action_end_b6_encap,
493 		.static_headroom	= sizeof(struct ipv6hdr),
494 	}
495 };
496 
497 static struct seg6_action_desc *__get_action_desc(int action)
498 {
499 	struct seg6_action_desc *desc;
500 	int i, count;
501 
502 	count = sizeof(seg6_action_table) / sizeof(struct seg6_action_desc);
503 	for (i = 0; i < count; i++) {
504 		desc = &seg6_action_table[i];
505 		if (desc->action == action)
506 			return desc;
507 	}
508 
509 	return NULL;
510 }
511 
512 static int seg6_local_input(struct sk_buff *skb)
513 {
514 	struct dst_entry *orig_dst = skb_dst(skb);
515 	struct seg6_action_desc *desc;
516 	struct seg6_local_lwt *slwt;
517 
518 	if (skb->protocol != htons(ETH_P_IPV6)) {
519 		kfree_skb(skb);
520 		return -EINVAL;
521 	}
522 
523 	slwt = seg6_local_lwtunnel(orig_dst->lwtstate);
524 	desc = slwt->desc;
525 
526 	return desc->input(skb, slwt);
527 }
528 
529 static const struct nla_policy seg6_local_policy[SEG6_LOCAL_MAX + 1] = {
530 	[SEG6_LOCAL_ACTION]	= { .type = NLA_U32 },
531 	[SEG6_LOCAL_SRH]	= { .type = NLA_BINARY },
532 	[SEG6_LOCAL_TABLE]	= { .type = NLA_U32 },
533 	[SEG6_LOCAL_NH4]	= { .type = NLA_BINARY,
534 				    .len = sizeof(struct in_addr) },
535 	[SEG6_LOCAL_NH6]	= { .type = NLA_BINARY,
536 				    .len = sizeof(struct in6_addr) },
537 	[SEG6_LOCAL_IIF]	= { .type = NLA_U32 },
538 	[SEG6_LOCAL_OIF]	= { .type = NLA_U32 },
539 };
540 
541 static int parse_nla_srh(struct nlattr **attrs, struct seg6_local_lwt *slwt)
542 {
543 	struct ipv6_sr_hdr *srh;
544 	int len;
545 
546 	srh = nla_data(attrs[SEG6_LOCAL_SRH]);
547 	len = nla_len(attrs[SEG6_LOCAL_SRH]);
548 
549 	/* SRH must contain at least one segment */
550 	if (len < sizeof(*srh) + sizeof(struct in6_addr))
551 		return -EINVAL;
552 
553 	if (!seg6_validate_srh(srh, len))
554 		return -EINVAL;
555 
556 	slwt->srh = kmalloc(len, GFP_KERNEL);
557 	if (!slwt->srh)
558 		return -ENOMEM;
559 
560 	memcpy(slwt->srh, srh, len);
561 
562 	slwt->headroom += len;
563 
564 	return 0;
565 }
566 
567 static int put_nla_srh(struct sk_buff *skb, struct seg6_local_lwt *slwt)
568 {
569 	struct ipv6_sr_hdr *srh;
570 	struct nlattr *nla;
571 	int len;
572 
573 	srh = slwt->srh;
574 	len = (srh->hdrlen + 1) << 3;
575 
576 	nla = nla_reserve(skb, SEG6_LOCAL_SRH, len);
577 	if (!nla)
578 		return -EMSGSIZE;
579 
580 	memcpy(nla_data(nla), srh, len);
581 
582 	return 0;
583 }
584 
585 static int cmp_nla_srh(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
586 {
587 	int len = (a->srh->hdrlen + 1) << 3;
588 
589 	if (len != ((b->srh->hdrlen + 1) << 3))
590 		return 1;
591 
592 	return memcmp(a->srh, b->srh, len);
593 }
594 
595 static int parse_nla_table(struct nlattr **attrs, struct seg6_local_lwt *slwt)
596 {
597 	slwt->table = nla_get_u32(attrs[SEG6_LOCAL_TABLE]);
598 
599 	return 0;
600 }
601 
602 static int put_nla_table(struct sk_buff *skb, struct seg6_local_lwt *slwt)
603 {
604 	if (nla_put_u32(skb, SEG6_LOCAL_TABLE, slwt->table))
605 		return -EMSGSIZE;
606 
607 	return 0;
608 }
609 
610 static int cmp_nla_table(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
611 {
612 	if (a->table != b->table)
613 		return 1;
614 
615 	return 0;
616 }
617 
618 static int parse_nla_nh4(struct nlattr **attrs, struct seg6_local_lwt *slwt)
619 {
620 	memcpy(&slwt->nh4, nla_data(attrs[SEG6_LOCAL_NH4]),
621 	       sizeof(struct in_addr));
622 
623 	return 0;
624 }
625 
626 static int put_nla_nh4(struct sk_buff *skb, struct seg6_local_lwt *slwt)
627 {
628 	struct nlattr *nla;
629 
630 	nla = nla_reserve(skb, SEG6_LOCAL_NH4, sizeof(struct in_addr));
631 	if (!nla)
632 		return -EMSGSIZE;
633 
634 	memcpy(nla_data(nla), &slwt->nh4, sizeof(struct in_addr));
635 
636 	return 0;
637 }
638 
639 static int cmp_nla_nh4(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
640 {
641 	return memcmp(&a->nh4, &b->nh4, sizeof(struct in_addr));
642 }
643 
644 static int parse_nla_nh6(struct nlattr **attrs, struct seg6_local_lwt *slwt)
645 {
646 	memcpy(&slwt->nh6, nla_data(attrs[SEG6_LOCAL_NH6]),
647 	       sizeof(struct in6_addr));
648 
649 	return 0;
650 }
651 
652 static int put_nla_nh6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
653 {
654 	struct nlattr *nla;
655 
656 	nla = nla_reserve(skb, SEG6_LOCAL_NH6, sizeof(struct in6_addr));
657 	if (!nla)
658 		return -EMSGSIZE;
659 
660 	memcpy(nla_data(nla), &slwt->nh6, sizeof(struct in6_addr));
661 
662 	return 0;
663 }
664 
665 static int cmp_nla_nh6(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
666 {
667 	return memcmp(&a->nh6, &b->nh6, sizeof(struct in6_addr));
668 }
669 
670 static int parse_nla_iif(struct nlattr **attrs, struct seg6_local_lwt *slwt)
671 {
672 	slwt->iif = nla_get_u32(attrs[SEG6_LOCAL_IIF]);
673 
674 	return 0;
675 }
676 
677 static int put_nla_iif(struct sk_buff *skb, struct seg6_local_lwt *slwt)
678 {
679 	if (nla_put_u32(skb, SEG6_LOCAL_IIF, slwt->iif))
680 		return -EMSGSIZE;
681 
682 	return 0;
683 }
684 
685 static int cmp_nla_iif(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
686 {
687 	if (a->iif != b->iif)
688 		return 1;
689 
690 	return 0;
691 }
692 
693 static int parse_nla_oif(struct nlattr **attrs, struct seg6_local_lwt *slwt)
694 {
695 	slwt->oif = nla_get_u32(attrs[SEG6_LOCAL_OIF]);
696 
697 	return 0;
698 }
699 
700 static int put_nla_oif(struct sk_buff *skb, struct seg6_local_lwt *slwt)
701 {
702 	if (nla_put_u32(skb, SEG6_LOCAL_OIF, slwt->oif))
703 		return -EMSGSIZE;
704 
705 	return 0;
706 }
707 
708 static int cmp_nla_oif(struct seg6_local_lwt *a, struct seg6_local_lwt *b)
709 {
710 	if (a->oif != b->oif)
711 		return 1;
712 
713 	return 0;
714 }
715 
716 struct seg6_action_param {
717 	int (*parse)(struct nlattr **attrs, struct seg6_local_lwt *slwt);
718 	int (*put)(struct sk_buff *skb, struct seg6_local_lwt *slwt);
719 	int (*cmp)(struct seg6_local_lwt *a, struct seg6_local_lwt *b);
720 };
721 
722 static struct seg6_action_param seg6_action_params[SEG6_LOCAL_MAX + 1] = {
723 	[SEG6_LOCAL_SRH]	= { .parse = parse_nla_srh,
724 				    .put = put_nla_srh,
725 				    .cmp = cmp_nla_srh },
726 
727 	[SEG6_LOCAL_TABLE]	= { .parse = parse_nla_table,
728 				    .put = put_nla_table,
729 				    .cmp = cmp_nla_table },
730 
731 	[SEG6_LOCAL_NH4]	= { .parse = parse_nla_nh4,
732 				    .put = put_nla_nh4,
733 				    .cmp = cmp_nla_nh4 },
734 
735 	[SEG6_LOCAL_NH6]	= { .parse = parse_nla_nh6,
736 				    .put = put_nla_nh6,
737 				    .cmp = cmp_nla_nh6 },
738 
739 	[SEG6_LOCAL_IIF]	= { .parse = parse_nla_iif,
740 				    .put = put_nla_iif,
741 				    .cmp = cmp_nla_iif },
742 
743 	[SEG6_LOCAL_OIF]	= { .parse = parse_nla_oif,
744 				    .put = put_nla_oif,
745 				    .cmp = cmp_nla_oif },
746 };
747 
748 static int parse_nla_action(struct nlattr **attrs, struct seg6_local_lwt *slwt)
749 {
750 	struct seg6_action_param *param;
751 	struct seg6_action_desc *desc;
752 	int i, err;
753 
754 	desc = __get_action_desc(slwt->action);
755 	if (!desc)
756 		return -EINVAL;
757 
758 	if (!desc->input)
759 		return -EOPNOTSUPP;
760 
761 	slwt->desc = desc;
762 	slwt->headroom += desc->static_headroom;
763 
764 	for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
765 		if (desc->attrs & (1 << i)) {
766 			if (!attrs[i])
767 				return -EINVAL;
768 
769 			param = &seg6_action_params[i];
770 
771 			err = param->parse(attrs, slwt);
772 			if (err < 0)
773 				return err;
774 		}
775 	}
776 
777 	return 0;
778 }
779 
780 static int seg6_local_build_state(struct nlattr *nla, unsigned int family,
781 				  const void *cfg, struct lwtunnel_state **ts,
782 				  struct netlink_ext_ack *extack)
783 {
784 	struct nlattr *tb[SEG6_LOCAL_MAX + 1];
785 	struct lwtunnel_state *newts;
786 	struct seg6_local_lwt *slwt;
787 	int err;
788 
789 	if (family != AF_INET6)
790 		return -EINVAL;
791 
792 	err = nla_parse_nested(tb, SEG6_LOCAL_MAX, nla, seg6_local_policy,
793 			       extack);
794 
795 	if (err < 0)
796 		return err;
797 
798 	if (!tb[SEG6_LOCAL_ACTION])
799 		return -EINVAL;
800 
801 	newts = lwtunnel_state_alloc(sizeof(*slwt));
802 	if (!newts)
803 		return -ENOMEM;
804 
805 	slwt = seg6_local_lwtunnel(newts);
806 	slwt->action = nla_get_u32(tb[SEG6_LOCAL_ACTION]);
807 
808 	err = parse_nla_action(tb, slwt);
809 	if (err < 0)
810 		goto out_free;
811 
812 	newts->type = LWTUNNEL_ENCAP_SEG6_LOCAL;
813 	newts->flags = LWTUNNEL_STATE_INPUT_REDIRECT;
814 	newts->headroom = slwt->headroom;
815 
816 	*ts = newts;
817 
818 	return 0;
819 
820 out_free:
821 	kfree(slwt->srh);
822 	kfree(newts);
823 	return err;
824 }
825 
826 static void seg6_local_destroy_state(struct lwtunnel_state *lwt)
827 {
828 	struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt);
829 
830 	kfree(slwt->srh);
831 }
832 
833 static int seg6_local_fill_encap(struct sk_buff *skb,
834 				 struct lwtunnel_state *lwt)
835 {
836 	struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt);
837 	struct seg6_action_param *param;
838 	int i, err;
839 
840 	if (nla_put_u32(skb, SEG6_LOCAL_ACTION, slwt->action))
841 		return -EMSGSIZE;
842 
843 	for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
844 		if (slwt->desc->attrs & (1 << i)) {
845 			param = &seg6_action_params[i];
846 			err = param->put(skb, slwt);
847 			if (err < 0)
848 				return err;
849 		}
850 	}
851 
852 	return 0;
853 }
854 
855 static int seg6_local_get_encap_size(struct lwtunnel_state *lwt)
856 {
857 	struct seg6_local_lwt *slwt = seg6_local_lwtunnel(lwt);
858 	unsigned long attrs;
859 	int nlsize;
860 
861 	nlsize = nla_total_size(4); /* action */
862 
863 	attrs = slwt->desc->attrs;
864 
865 	if (attrs & (1 << SEG6_LOCAL_SRH))
866 		nlsize += nla_total_size((slwt->srh->hdrlen + 1) << 3);
867 
868 	if (attrs & (1 << SEG6_LOCAL_TABLE))
869 		nlsize += nla_total_size(4);
870 
871 	if (attrs & (1 << SEG6_LOCAL_NH4))
872 		nlsize += nla_total_size(4);
873 
874 	if (attrs & (1 << SEG6_LOCAL_NH6))
875 		nlsize += nla_total_size(16);
876 
877 	if (attrs & (1 << SEG6_LOCAL_IIF))
878 		nlsize += nla_total_size(4);
879 
880 	if (attrs & (1 << SEG6_LOCAL_OIF))
881 		nlsize += nla_total_size(4);
882 
883 	return nlsize;
884 }
885 
886 static int seg6_local_cmp_encap(struct lwtunnel_state *a,
887 				struct lwtunnel_state *b)
888 {
889 	struct seg6_local_lwt *slwt_a, *slwt_b;
890 	struct seg6_action_param *param;
891 	int i;
892 
893 	slwt_a = seg6_local_lwtunnel(a);
894 	slwt_b = seg6_local_lwtunnel(b);
895 
896 	if (slwt_a->action != slwt_b->action)
897 		return 1;
898 
899 	if (slwt_a->desc->attrs != slwt_b->desc->attrs)
900 		return 1;
901 
902 	for (i = 0; i < SEG6_LOCAL_MAX + 1; i++) {
903 		if (slwt_a->desc->attrs & (1 << i)) {
904 			param = &seg6_action_params[i];
905 			if (param->cmp(slwt_a, slwt_b))
906 				return 1;
907 		}
908 	}
909 
910 	return 0;
911 }
912 
913 static const struct lwtunnel_encap_ops seg6_local_ops = {
914 	.build_state	= seg6_local_build_state,
915 	.destroy_state	= seg6_local_destroy_state,
916 	.input		= seg6_local_input,
917 	.fill_encap	= seg6_local_fill_encap,
918 	.get_encap_size	= seg6_local_get_encap_size,
919 	.cmp_encap	= seg6_local_cmp_encap,
920 	.owner		= THIS_MODULE,
921 };
922 
923 int __init seg6_local_init(void)
924 {
925 	return lwtunnel_encap_add_ops(&seg6_local_ops,
926 				      LWTUNNEL_ENCAP_SEG6_LOCAL);
927 }
928 
929 void seg6_local_exit(void)
930 {
931 	lwtunnel_encap_del_ops(&seg6_local_ops, LWTUNNEL_ENCAP_SEG6_LOCAL);
932 }
933