xref: /linux/net/ipv6/seg6_iptunnel.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  SR-IPv6 implementation
4  *
5  *  Author:
6  *  David Lebrun <david.lebrun@uclouvain.be>
7  */
8 
9 #include <linux/types.h>
10 #include <linux/skbuff.h>
11 #include <linux/net.h>
12 #include <linux/module.h>
13 #include <net/ip.h>
14 #include <net/ip_tunnels.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_iptunnel.h>
23 #include <net/addrconf.h>
24 #include <net/ip6_route.h>
25 #include <net/dst_cache.h>
26 #ifdef CONFIG_IPV6_SEG6_HMAC
27 #include <net/seg6_hmac.h>
28 #endif
29 #include <linux/netfilter.h>
30 
seg6_lwt_headroom(struct seg6_iptunnel_encap * tuninfo)31 static size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo)
32 {
33 	int head = 0;
34 
35 	switch (tuninfo->mode) {
36 	case SEG6_IPTUN_MODE_INLINE:
37 		break;
38 	case SEG6_IPTUN_MODE_ENCAP:
39 	case SEG6_IPTUN_MODE_ENCAP_RED:
40 		head = sizeof(struct ipv6hdr);
41 		break;
42 	case SEG6_IPTUN_MODE_L2ENCAP:
43 	case SEG6_IPTUN_MODE_L2ENCAP_RED:
44 		return 0;
45 	}
46 
47 	return ((tuninfo->srh->hdrlen + 1) << 3) + head;
48 }
49 
50 struct seg6_lwt {
51 	struct dst_cache cache_input;
52 	struct dst_cache cache_output;
53 	struct in6_addr tunsrc;
54 	u32 table;
55 	struct seg6_iptunnel_encap tuninfo[];
56 };
57 
seg6_lwt_lwtunnel(struct lwtunnel_state * lwt)58 static inline struct seg6_lwt *seg6_lwt_lwtunnel(struct lwtunnel_state *lwt)
59 {
60 	return (struct seg6_lwt *)lwt->data;
61 }
62 
63 static inline struct seg6_iptunnel_encap *
seg6_encap_lwtunnel(struct lwtunnel_state * lwt)64 seg6_encap_lwtunnel(struct lwtunnel_state *lwt)
65 {
66 	return seg6_lwt_lwtunnel(lwt)->tuninfo;
67 }
68 
69 static const struct nla_policy seg6_iptunnel_policy[SEG6_IPTUNNEL_MAX + 1] = {
70 	[SEG6_IPTUNNEL_SRH]	= { .type = NLA_BINARY },
71 	[SEG6_IPTUNNEL_SRC]	= NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
72 	[SEG6_IPTUNNEL_TABLE]	= { .type = NLA_U32 },
73 };
74 
nla_put_srh(struct sk_buff * skb,int attrtype,struct seg6_iptunnel_encap * tuninfo)75 static int nla_put_srh(struct sk_buff *skb, int attrtype,
76 		       struct seg6_iptunnel_encap *tuninfo)
77 {
78 	struct seg6_iptunnel_encap *data;
79 	struct nlattr *nla;
80 	int len;
81 
82 	len = SEG6_IPTUN_ENCAP_SIZE(tuninfo);
83 
84 	nla = nla_reserve(skb, attrtype, len);
85 	if (!nla)
86 		return -EMSGSIZE;
87 
88 	data = nla_data(nla);
89 	memcpy(data, tuninfo, len);
90 
91 	return 0;
92 }
93 
set_tun_src(struct net * net,struct net_device * dev,struct in6_addr * daddr,struct in6_addr * saddr,struct in6_addr * route_tunsrc)94 static void set_tun_src(struct net *net, struct net_device *dev,
95 			struct in6_addr *daddr, struct in6_addr *saddr,
96 			struct in6_addr *route_tunsrc)
97 {
98 	struct seg6_pernet_data *sdata = seg6_pernet(net);
99 	struct in6_addr *tun_src;
100 
101 	/* Priority order to select tunnel source address:
102 	 *  1. per route source address (if configured)
103 	 *  2. per network namespace source address (if configured)
104 	 *  3. dynamic resolution
105 	 */
106 	if (route_tunsrc && !ipv6_addr_any(route_tunsrc)) {
107 		memcpy(saddr, route_tunsrc, sizeof(struct in6_addr));
108 	} else {
109 		rcu_read_lock();
110 		tun_src = rcu_dereference(sdata->tun_src);
111 
112 		if (!ipv6_addr_any(tun_src)) {
113 			memcpy(saddr, tun_src, sizeof(struct in6_addr));
114 		} else {
115 			ipv6_dev_get_saddr(net, dev, daddr,
116 					   IPV6_PREFER_SRC_PUBLIC, saddr);
117 		}
118 
119 		rcu_read_unlock();
120 	}
121 }
122 
123 /* Compute flowlabel for outer IPv6 header */
seg6_make_flowlabel(struct net * net,struct sk_buff * skb,struct ipv6hdr * inner_hdr)124 static __be32 seg6_make_flowlabel(struct net *net, struct sk_buff *skb,
125 				  struct ipv6hdr *inner_hdr)
126 {
127 	int do_flowlabel = net->ipv6.sysctl.seg6_flowlabel;
128 	__be32 flowlabel = 0;
129 	u32 hash;
130 
131 	if (do_flowlabel > 0) {
132 		hash = skb_get_hash(skb);
133 		hash = rol32(hash, 16);
134 		flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
135 	} else if (!do_flowlabel && skb->protocol == htons(ETH_P_IPV6)) {
136 		flowlabel = ip6_flowlabel(inner_hdr);
137 	}
138 	return flowlabel;
139 }
140 
__seg6_do_srh_encap(struct sk_buff * skb,struct ipv6_sr_hdr * osrh,int proto,struct dst_entry * cache_dst,struct in6_addr * route_tunsrc)141 static int __seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
142 			       int proto, struct dst_entry *cache_dst,
143 			       struct in6_addr *route_tunsrc)
144 {
145 	struct dst_entry *dst = skb_dst(skb);
146 	struct net_device *dev = dst_dev(dst);
147 	struct net *net = dev_net(dev);
148 	struct ipv6hdr *hdr, *inner_hdr;
149 	struct ipv6_sr_hdr *isrh;
150 	int hdrlen, tot_len, err;
151 	__be32 flowlabel;
152 
153 	hdrlen = (osrh->hdrlen + 1) << 3;
154 	tot_len = hdrlen + sizeof(*hdr);
155 
156 	err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb));
157 	if (unlikely(err))
158 		return err;
159 
160 	inner_hdr = ipv6_hdr(skb);
161 	flowlabel = seg6_make_flowlabel(net, skb, inner_hdr);
162 
163 	skb_push(skb, tot_len);
164 	skb_reset_network_header(skb);
165 	skb_mac_header_rebuild(skb);
166 	hdr = ipv6_hdr(skb);
167 
168 	/* inherit tc, flowlabel and hlim
169 	 * hlim will be decremented in ip6_forward() afterwards and
170 	 * decapsulation will overwrite inner hlim with outer hlim
171 	 */
172 
173 	if (skb->protocol == htons(ETH_P_IPV6)) {
174 		ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)),
175 			     flowlabel);
176 		hdr->hop_limit = inner_hdr->hop_limit;
177 	} else {
178 		ip6_flow_hdr(hdr, 0, flowlabel);
179 		hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));
180 
181 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
182 
183 		/* the control block has been erased, so we have to set the
184 		 * iif once again.
185 		 * We read the receiving interface index directly from the
186 		 * skb->skb_iif as it is done in the IPv4 receiving path (i.e.:
187 		 * ip_rcv_core(...)).
188 		 */
189 		IP6CB(skb)->iif = skb->skb_iif;
190 	}
191 
192 	hdr->nexthdr = NEXTHDR_ROUTING;
193 
194 	isrh = (void *)hdr + sizeof(*hdr);
195 	memcpy(isrh, osrh, hdrlen);
196 
197 	isrh->nexthdr = proto;
198 
199 	hdr->daddr = isrh->segments[isrh->first_segment];
200 	set_tun_src(net, dev, &hdr->daddr, &hdr->saddr, route_tunsrc);
201 
202 #ifdef CONFIG_IPV6_SEG6_HMAC
203 	if (sr_has_hmac(isrh)) {
204 		err = seg6_push_hmac(net, &hdr->saddr, isrh);
205 		if (unlikely(err))
206 			return err;
207 	}
208 #endif
209 
210 	hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
211 
212 	skb_postpush_rcsum(skb, hdr, tot_len);
213 
214 	return 0;
215 }
216 
217 /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */
seg6_do_srh_encap(struct sk_buff * skb,struct ipv6_sr_hdr * osrh,int proto)218 int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
219 {
220 	return __seg6_do_srh_encap(skb, osrh, proto, NULL, NULL);
221 }
222 EXPORT_SYMBOL_GPL(seg6_do_srh_encap);
223 
224 /* encapsulate an IPv6 packet within an outer IPv6 header with reduced SRH */
seg6_do_srh_encap_red(struct sk_buff * skb,struct ipv6_sr_hdr * osrh,int proto,struct dst_entry * cache_dst,struct in6_addr * route_tunsrc)225 static int seg6_do_srh_encap_red(struct sk_buff *skb,
226 				 struct ipv6_sr_hdr *osrh, int proto,
227 				 struct dst_entry *cache_dst,
228 				 struct in6_addr *route_tunsrc)
229 {
230 	__u8 first_seg = osrh->first_segment;
231 	struct dst_entry *dst = skb_dst(skb);
232 	struct net_device *dev = dst_dev(dst);
233 	struct net *net = dev_net(dev);
234 	struct ipv6hdr *hdr, *inner_hdr;
235 	int hdrlen = ipv6_optlen(osrh);
236 	int red_tlv_offset, tlv_offset;
237 	struct ipv6_sr_hdr *isrh;
238 	bool skip_srh = false;
239 	__be32 flowlabel;
240 	int tot_len, err;
241 	int red_hdrlen;
242 	int tlvs_len;
243 
244 	if (first_seg > 0) {
245 		red_hdrlen = hdrlen - sizeof(struct in6_addr);
246 	} else {
247 		/* NOTE: if tag/flags and/or other TLVs are introduced in the
248 		 * seg6_iptunnel infrastructure, they should be considered when
249 		 * deciding to skip the SRH.
250 		 */
251 		skip_srh = !sr_has_hmac(osrh);
252 
253 		red_hdrlen = skip_srh ? 0 : hdrlen;
254 	}
255 
256 	tot_len = red_hdrlen + sizeof(struct ipv6hdr);
257 
258 	err = skb_cow_head(skb, tot_len + dst_dev_overhead(cache_dst, skb));
259 	if (unlikely(err))
260 		return err;
261 
262 	inner_hdr = ipv6_hdr(skb);
263 	flowlabel = seg6_make_flowlabel(net, skb, inner_hdr);
264 
265 	skb_push(skb, tot_len);
266 	skb_reset_network_header(skb);
267 	skb_mac_header_rebuild(skb);
268 	hdr = ipv6_hdr(skb);
269 
270 	/* based on seg6_do_srh_encap() */
271 	if (skb->protocol == htons(ETH_P_IPV6)) {
272 		ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)),
273 			     flowlabel);
274 		hdr->hop_limit = inner_hdr->hop_limit;
275 	} else {
276 		ip6_flow_hdr(hdr, 0, flowlabel);
277 		hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));
278 
279 		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
280 		IP6CB(skb)->iif = skb->skb_iif;
281 	}
282 
283 	/* no matter if we have to skip the SRH or not, the first segment
284 	 * always comes in the pushed IPv6 header.
285 	 */
286 	hdr->daddr = osrh->segments[first_seg];
287 
288 	if (skip_srh) {
289 		hdr->nexthdr = proto;
290 
291 		set_tun_src(net, dev, &hdr->daddr, &hdr->saddr, route_tunsrc);
292 		goto out;
293 	}
294 
295 	/* we cannot skip the SRH, slow path */
296 
297 	hdr->nexthdr = NEXTHDR_ROUTING;
298 	isrh = (void *)hdr + sizeof(struct ipv6hdr);
299 
300 	if (unlikely(!first_seg)) {
301 		/* this is a very rare case; we have only one SID but
302 		 * we cannot skip the SRH since we are carrying some
303 		 * other info.
304 		 */
305 		memcpy(isrh, osrh, hdrlen);
306 		goto srcaddr;
307 	}
308 
309 	tlv_offset = sizeof(*osrh) + (first_seg + 1) * sizeof(struct in6_addr);
310 	red_tlv_offset = tlv_offset - sizeof(struct in6_addr);
311 
312 	memcpy(isrh, osrh, red_tlv_offset);
313 
314 	tlvs_len = hdrlen - tlv_offset;
315 	if (unlikely(tlvs_len > 0)) {
316 		const void *s = (const void *)osrh + tlv_offset;
317 		void *d = (void *)isrh + red_tlv_offset;
318 
319 		memcpy(d, s, tlvs_len);
320 	}
321 
322 	--isrh->first_segment;
323 	isrh->hdrlen -= 2;
324 
325 srcaddr:
326 	isrh->nexthdr = proto;
327 	set_tun_src(net, dev, &hdr->daddr, &hdr->saddr, route_tunsrc);
328 
329 #ifdef CONFIG_IPV6_SEG6_HMAC
330 	if (unlikely(!skip_srh && sr_has_hmac(isrh))) {
331 		err = seg6_push_hmac(net, &hdr->saddr, isrh);
332 		if (unlikely(err))
333 			return err;
334 	}
335 #endif
336 
337 out:
338 	hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
339 
340 	skb_postpush_rcsum(skb, hdr, tot_len);
341 
342 	return 0;
343 }
344 
__seg6_do_srh_inline(struct sk_buff * skb,struct ipv6_sr_hdr * osrh,struct dst_entry * cache_dst)345 static int __seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
346 				struct dst_entry *cache_dst)
347 {
348 	struct ipv6hdr *hdr, *oldhdr;
349 	struct ipv6_sr_hdr *isrh;
350 	int hdrlen, err;
351 
352 	hdrlen = (osrh->hdrlen + 1) << 3;
353 
354 	err = skb_cow_head(skb, hdrlen + dst_dev_overhead(cache_dst, skb));
355 	if (unlikely(err))
356 		return err;
357 
358 	oldhdr = ipv6_hdr(skb);
359 
360 	skb_pull(skb, sizeof(struct ipv6hdr));
361 	skb_postpull_rcsum(skb, skb_network_header(skb),
362 			   sizeof(struct ipv6hdr));
363 
364 	skb_push(skb, sizeof(struct ipv6hdr) + hdrlen);
365 	skb_reset_network_header(skb);
366 	skb_mac_header_rebuild(skb);
367 
368 	hdr = ipv6_hdr(skb);
369 
370 	memmove(hdr, oldhdr, sizeof(*hdr));
371 
372 	isrh = (void *)hdr + sizeof(*hdr);
373 	memcpy(isrh, osrh, hdrlen);
374 
375 	isrh->nexthdr = hdr->nexthdr;
376 	hdr->nexthdr = NEXTHDR_ROUTING;
377 
378 	isrh->segments[0] = hdr->daddr;
379 	hdr->daddr = isrh->segments[isrh->first_segment];
380 
381 #ifdef CONFIG_IPV6_SEG6_HMAC
382 	if (sr_has_hmac(isrh)) {
383 		struct net *net = skb_dst_dev_net(skb);
384 
385 		err = seg6_push_hmac(net, &hdr->saddr, isrh);
386 		if (unlikely(err))
387 			return err;
388 	}
389 #endif
390 
391 	hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
392 
393 	skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);
394 
395 	return 0;
396 }
397 
seg6_do_srh(struct sk_buff * skb,struct dst_entry * cache_dst)398 static int seg6_do_srh(struct sk_buff *skb, struct dst_entry *cache_dst)
399 {
400 	struct dst_entry *dst = skb_dst(skb);
401 	struct seg6_iptunnel_encap *tinfo;
402 	struct seg6_lwt *slwt;
403 	int proto, err = 0;
404 
405 	slwt = seg6_lwt_lwtunnel(dst->lwtstate);
406 	tinfo = slwt->tuninfo;
407 
408 	switch (tinfo->mode) {
409 	case SEG6_IPTUN_MODE_INLINE:
410 		if (skb->protocol != htons(ETH_P_IPV6))
411 			return -EINVAL;
412 
413 		err = __seg6_do_srh_inline(skb, tinfo->srh, cache_dst);
414 		if (err)
415 			return err;
416 		break;
417 	case SEG6_IPTUN_MODE_ENCAP:
418 	case SEG6_IPTUN_MODE_ENCAP_RED:
419 		err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6);
420 		if (err)
421 			return err;
422 
423 		if (skb->protocol == htons(ETH_P_IPV6))
424 			proto = IPPROTO_IPV6;
425 		else if (skb->protocol == htons(ETH_P_IP))
426 			proto = IPPROTO_IPIP;
427 		else
428 			return -EINVAL;
429 
430 		if (tinfo->mode == SEG6_IPTUN_MODE_ENCAP)
431 			err = __seg6_do_srh_encap(skb, tinfo->srh, proto,
432 						  cache_dst, &slwt->tunsrc);
433 		else
434 			err = seg6_do_srh_encap_red(skb, tinfo->srh, proto,
435 						    cache_dst, &slwt->tunsrc);
436 
437 		if (err)
438 			return err;
439 
440 		skb_set_inner_transport_header(skb, skb_transport_offset(skb));
441 		skb_set_inner_protocol(skb, skb->protocol);
442 		skb->protocol = htons(ETH_P_IPV6);
443 		break;
444 	case SEG6_IPTUN_MODE_L2ENCAP:
445 	case SEG6_IPTUN_MODE_L2ENCAP_RED:
446 		if (!skb_mac_header_was_set(skb))
447 			return -EINVAL;
448 
449 		if (pskb_expand_head(skb, skb->mac_len, 0, GFP_ATOMIC) < 0)
450 			return -ENOMEM;
451 
452 		skb_mac_header_rebuild(skb);
453 		skb_push(skb, skb->mac_len);
454 
455 		if (tinfo->mode == SEG6_IPTUN_MODE_L2ENCAP)
456 			err = __seg6_do_srh_encap(skb, tinfo->srh,
457 						  IPPROTO_ETHERNET, cache_dst,
458 						  &slwt->tunsrc);
459 		else
460 			err = seg6_do_srh_encap_red(skb, tinfo->srh,
461 						    IPPROTO_ETHERNET, cache_dst,
462 						    &slwt->tunsrc);
463 
464 		if (err)
465 			return err;
466 
467 		skb->protocol = htons(ETH_P_IPV6);
468 		break;
469 	}
470 
471 	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
472 	nf_reset_ct(skb);
473 
474 	return 0;
475 }
476 
477 /* insert an SRH within an IPv6 packet, just after the IPv6 header */
seg6_do_srh_inline(struct sk_buff * skb,struct ipv6_sr_hdr * osrh)478 int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
479 {
480 	return __seg6_do_srh_inline(skb, osrh, NULL);
481 }
482 EXPORT_SYMBOL_GPL(seg6_do_srh_inline);
483 
484 /* look up a route in a specific FIB table.
485  * Returns a refcounted dst, or NULL if the table does not exist.
486  */
seg6_table_lookup(struct net * net,struct sk_buff * skb,struct flowi6 * fl6,u32 tbl_id)487 static struct dst_entry *seg6_table_lookup(struct net *net,
488 					   struct sk_buff *skb,
489 					   struct flowi6 *fl6, u32 tbl_id)
490 {
491 	struct fib6_table *table;
492 	struct rt6_info *rt;
493 
494 	table = fib6_get_table(net, tbl_id);
495 	if (!table)
496 		return NULL;
497 
498 	rt = ip6_pol_route(net, table, 0, fl6, skb, RT6_LOOKUP_F_HAS_SADDR);
499 	return &rt->dst;
500 }
501 
seg6_init_flowi6(struct sk_buff * skb,struct ipv6hdr * hdr,struct flowi6 * fl6)502 static void seg6_init_flowi6(struct sk_buff *skb, struct ipv6hdr *hdr,
503 			     struct flowi6 *fl6)
504 {
505 	memset(fl6, 0, sizeof(*fl6));
506 
507 	fl6->daddr = hdr->daddr;
508 	fl6->saddr = hdr->saddr;
509 	fl6->flowlabel = ip6_flowinfo(hdr);
510 	fl6->flowi6_mark = skb->mark;
511 	fl6->flowi6_proto = hdr->nexthdr;
512 }
513 
514 /* look up the route for the first SID on the input path and set it on the skb.
515  * Returns the refcounted dst, or NULL if a reference could not be safely taken.
516  */
seg6_input_route(struct net * net,struct sk_buff * skb,struct seg6_lwt * slwt)517 static struct dst_entry *seg6_input_route(struct net *net,
518 					  struct sk_buff *skb,
519 					  struct seg6_lwt *slwt)
520 {
521 	u32 table = slwt->table;
522 
523 	if (table) {
524 		struct ipv6hdr *hdr = ipv6_hdr(skb);
525 		struct dst_entry *dst;
526 		struct flowi6 fl6;
527 
528 		seg6_init_flowi6(skb, hdr, &fl6);
529 		fl6.flowi6_iif = skb->dev->ifindex;
530 
531 		dst = seg6_table_lookup(net, skb, &fl6, table);
532 		if (!dst) {
533 			dst = &net->ipv6.ip6_blk_hole_entry->dst;
534 			dst_hold(dst);
535 		}
536 
537 		skb_dst_drop(skb);
538 		skb_dst_set(skb, dst);
539 	} else {
540 		ip6_route_input(skb);
541 
542 		/* ip6_route_input() sets a NOREF dst; force a refcount on it
543 		 * before caching or further use.
544 		 */
545 		skb_dst_force(skb);
546 	}
547 
548 	return skb_dst(skb);
549 }
550 
seg6_input_finish(struct net * net,struct sock * sk,struct sk_buff * skb)551 static int seg6_input_finish(struct net *net, struct sock *sk,
552 			     struct sk_buff *skb)
553 {
554 	return dst_input(skb);
555 }
556 
seg6_input_core(struct net * net,struct sock * sk,struct sk_buff * skb)557 static int seg6_input_core(struct net *net, struct sock *sk,
558 			   struct sk_buff *skb)
559 {
560 	struct dst_entry *orig_dst = skb_dst(skb);
561 	struct dst_entry *dst = NULL;
562 	struct lwtunnel_state *lwtst;
563 	struct seg6_lwt *slwt;
564 	int err;
565 
566 	/* We cannot dereference "orig_dst" once ip6_route_input() or
567 	 * skb_dst_drop() is called. However, in order to detect a dst loop, we
568 	 * need the address of its lwtstate. So, save the address of lwtstate
569 	 * now and use it later as a comparison.
570 	 */
571 	lwtst = orig_dst->lwtstate;
572 
573 	slwt = seg6_lwt_lwtunnel(lwtst);
574 
575 	local_bh_disable();
576 	dst = dst_cache_get(&slwt->cache_input);
577 	local_bh_enable();
578 
579 	err = seg6_do_srh(skb, dst);
580 	if (unlikely(err)) {
581 		dst_release(dst);
582 		goto drop;
583 	}
584 
585 	if (unlikely(!dst)) {
586 		dst = seg6_input_route(net, skb, slwt);
587 		if (!dst) {
588 			err = -ENETUNREACH;
589 			goto drop;
590 		}
591 
592 		/* cache only if we don't create a dst reference loop */
593 		if (!dst->error && lwtst != dst->lwtstate) {
594 			local_bh_disable();
595 			dst_cache_set_ip6(&slwt->cache_input, dst,
596 					  &ipv6_hdr(skb)->saddr);
597 			local_bh_enable();
598 		}
599 
600 		err = skb_cow_head(skb, LL_RESERVED_SPACE(dst_dev(dst)));
601 		if (unlikely(err))
602 			goto drop;
603 	} else {
604 		skb_dst_drop(skb);
605 		skb_dst_set(skb, dst);
606 	}
607 
608 	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
609 		return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
610 			       dev_net(skb->dev), NULL, skb, NULL,
611 			       skb_dst_dev(skb), seg6_input_finish);
612 
613 	return seg6_input_finish(dev_net(skb->dev), NULL, skb);
614 drop:
615 	kfree_skb(skb);
616 	return err;
617 }
618 
seg6_input_nf(struct sk_buff * skb)619 static int seg6_input_nf(struct sk_buff *skb)
620 {
621 	struct net_device *dev = skb_dst_dev(skb);
622 	struct net *net = dev_net(skb->dev);
623 
624 	switch (skb->protocol) {
625 	case htons(ETH_P_IP):
626 		return NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, NULL,
627 			       skb, NULL, dev, seg6_input_core);
628 	case htons(ETH_P_IPV6):
629 		return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, NULL,
630 			       skb, NULL, dev, seg6_input_core);
631 	}
632 
633 	return -EINVAL;
634 }
635 
seg6_input(struct sk_buff * skb)636 static int seg6_input(struct sk_buff *skb)
637 {
638 	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
639 		return seg6_input_nf(skb);
640 
641 	return seg6_input_core(dev_net(skb->dev), NULL, skb);
642 }
643 
644 /* look up the route for the first SID on the output path. Always returns a
645  * refcounted dst.
646  */
seg6_output_dst_lookup(struct net * net,struct sk_buff * skb,struct flowi6 * fl6,struct seg6_lwt * slwt)647 static struct dst_entry *seg6_output_dst_lookup(struct net *net,
648 						struct sk_buff *skb,
649 						struct flowi6 *fl6,
650 						struct seg6_lwt *slwt)
651 {
652 	struct dst_entry *dst;
653 
654 	if (slwt->table) {
655 		dst = seg6_table_lookup(net, skb, fl6, slwt->table);
656 		if (!dst) {
657 			dst = &net->ipv6.ip6_blk_hole_entry->dst;
658 			dst_hold(dst);
659 		}
660 	} else {
661 		dst = ip6_route_output(net, NULL, fl6);
662 	}
663 
664 	return dst;
665 }
666 
seg6_output_core(struct net * net,struct sock * sk,struct sk_buff * skb)667 static int seg6_output_core(struct net *net, struct sock *sk,
668 			    struct sk_buff *skb)
669 {
670 	struct dst_entry *orig_dst = skb_dst(skb);
671 	struct dst_entry *dst = NULL;
672 	struct seg6_lwt *slwt;
673 	int err;
674 
675 	slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
676 
677 	local_bh_disable();
678 	dst = dst_cache_get(&slwt->cache_output);
679 	local_bh_enable();
680 
681 	err = seg6_do_srh(skb, dst);
682 	if (unlikely(err))
683 		goto drop;
684 
685 	if (unlikely(!dst)) {
686 		struct ipv6hdr *hdr = ipv6_hdr(skb);
687 		struct flowi6 fl6;
688 
689 		seg6_init_flowi6(skb, hdr, &fl6);
690 
691 		dst = seg6_output_dst_lookup(net, skb, &fl6, slwt);
692 		if (dst->error) {
693 			err = dst->error;
694 			goto drop;
695 		}
696 
697 		/* cache only if we don't create a dst reference loop */
698 		if (orig_dst->lwtstate != dst->lwtstate) {
699 			local_bh_disable();
700 			dst_cache_set_ip6(&slwt->cache_output, dst, &fl6.saddr);
701 			local_bh_enable();
702 		}
703 
704 		err = skb_cow_head(skb, LL_RESERVED_SPACE(dst_dev(dst)));
705 		if (unlikely(err))
706 			goto drop;
707 	}
708 
709 	skb_dst_drop(skb);
710 	skb_dst_set(skb, dst);
711 
712 	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
713 		return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb,
714 			       NULL, dst_dev(dst), dst_output);
715 
716 	return dst_output(net, sk, skb);
717 drop:
718 	dst_release(dst);
719 	kfree_skb(skb);
720 	return err;
721 }
722 
seg6_output_nf(struct net * net,struct sock * sk,struct sk_buff * skb)723 static int seg6_output_nf(struct net *net, struct sock *sk, struct sk_buff *skb)
724 {
725 	struct net_device *dev = skb_dst_dev(skb);
726 
727 	switch (skb->protocol) {
728 	case htons(ETH_P_IP):
729 		return NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, sk, skb,
730 			       NULL, dev, seg6_output_core);
731 	case htons(ETH_P_IPV6):
732 		return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, sk, skb,
733 			       NULL, dev, seg6_output_core);
734 	}
735 
736 	return -EINVAL;
737 }
738 
seg6_output(struct net * net,struct sock * sk,struct sk_buff * skb)739 static int seg6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
740 {
741 	if (static_branch_unlikely(&nf_hooks_lwtunnel_enabled))
742 		return seg6_output_nf(net, sk, skb);
743 
744 	return seg6_output_core(net, sk, skb);
745 }
746 
seg6_build_state(struct net * net,struct nlattr * nla,unsigned int family,const void * cfg,struct lwtunnel_state ** ts,struct netlink_ext_ack * extack)747 static int seg6_build_state(struct net *net, struct nlattr *nla,
748 			    unsigned int family, const void *cfg,
749 			    struct lwtunnel_state **ts,
750 			    struct netlink_ext_ack *extack)
751 {
752 	struct nlattr *tb[SEG6_IPTUNNEL_MAX + 1];
753 	struct seg6_iptunnel_encap *tuninfo;
754 	struct lwtunnel_state *newts;
755 	int tuninfo_len, min_size;
756 	struct seg6_lwt *slwt;
757 	int err;
758 
759 	if (family != AF_INET && family != AF_INET6)
760 		return -EINVAL;
761 
762 	err = nla_parse_nested_deprecated(tb, SEG6_IPTUNNEL_MAX, nla,
763 					  seg6_iptunnel_policy, extack);
764 
765 	if (err < 0)
766 		return err;
767 
768 	if (!tb[SEG6_IPTUNNEL_SRH])
769 		return -EINVAL;
770 
771 	tuninfo = nla_data(tb[SEG6_IPTUNNEL_SRH]);
772 	tuninfo_len = nla_len(tb[SEG6_IPTUNNEL_SRH]);
773 
774 	/* tuninfo must contain at least the iptunnel encap structure,
775 	 * the SRH and one segment
776 	 */
777 	min_size = sizeof(*tuninfo) + sizeof(struct ipv6_sr_hdr) +
778 		   sizeof(struct in6_addr);
779 	if (tuninfo_len < min_size)
780 		return -EINVAL;
781 
782 	switch (tuninfo->mode) {
783 	case SEG6_IPTUN_MODE_INLINE:
784 		if (family != AF_INET6)
785 			return -EINVAL;
786 
787 		if (tb[SEG6_IPTUNNEL_SRC]) {
788 			NL_SET_ERR_MSG(extack, "incompatible mode for tunsrc");
789 			return -EINVAL;
790 		}
791 		break;
792 	case SEG6_IPTUN_MODE_ENCAP:
793 		break;
794 	case SEG6_IPTUN_MODE_L2ENCAP:
795 		break;
796 	case SEG6_IPTUN_MODE_ENCAP_RED:
797 		break;
798 	case SEG6_IPTUN_MODE_L2ENCAP_RED:
799 		break;
800 	default:
801 		return -EINVAL;
802 	}
803 
804 	/* verify that SRH is consistent */
805 	if (!seg6_validate_srh(tuninfo->srh, tuninfo_len - sizeof(*tuninfo), false))
806 		return -EINVAL;
807 
808 	newts = lwtunnel_state_alloc(tuninfo_len + sizeof(*slwt));
809 	if (!newts)
810 		return -ENOMEM;
811 
812 	slwt = seg6_lwt_lwtunnel(newts);
813 
814 	err = dst_cache_init(&slwt->cache_input, GFP_ATOMIC);
815 	if (err)
816 		goto err_free_newts;
817 
818 	err = dst_cache_init(&slwt->cache_output, GFP_ATOMIC);
819 	if (err)
820 		goto err_destroy_input;
821 
822 	memcpy(&slwt->tuninfo, tuninfo, tuninfo_len);
823 
824 	if (tb[SEG6_IPTUNNEL_SRC]) {
825 		slwt->tunsrc = nla_get_in6_addr(tb[SEG6_IPTUNNEL_SRC]);
826 
827 		if (ipv6_addr_any(&slwt->tunsrc) ||
828 		    ipv6_addr_is_multicast(&slwt->tunsrc) ||
829 		    ipv6_addr_loopback(&slwt->tunsrc)) {
830 			NL_SET_ERR_MSG(extack, "invalid tunsrc address");
831 			err = -EINVAL;
832 			goto err_destroy_output;
833 		}
834 	}
835 
836 	if (tb[SEG6_IPTUNNEL_TABLE]) {
837 		slwt->table = nla_get_u32(tb[SEG6_IPTUNNEL_TABLE]);
838 		if (!slwt->table) {
839 			NL_SET_ERR_MSG(extack, "invalid lookup table");
840 			err = -EINVAL;
841 			goto err_destroy_output;
842 		}
843 	}
844 
845 	newts->type = LWTUNNEL_ENCAP_SEG6;
846 	newts->flags |= LWTUNNEL_STATE_INPUT_REDIRECT;
847 
848 	if (tuninfo->mode != SEG6_IPTUN_MODE_L2ENCAP &&
849 	    tuninfo->mode != SEG6_IPTUN_MODE_L2ENCAP_RED)
850 		newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT;
851 
852 	newts->headroom = seg6_lwt_headroom(tuninfo);
853 
854 	*ts = newts;
855 
856 	return 0;
857 
858 err_destroy_output:
859 	dst_cache_destroy(&slwt->cache_output);
860 err_destroy_input:
861 	dst_cache_destroy(&slwt->cache_input);
862 err_free_newts:
863 	kfree(newts);
864 	return err;
865 }
866 
seg6_destroy_state(struct lwtunnel_state * lwt)867 static void seg6_destroy_state(struct lwtunnel_state *lwt)
868 {
869 	struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwt);
870 
871 	dst_cache_destroy(&slwt->cache_input);
872 	dst_cache_destroy(&slwt->cache_output);
873 }
874 
seg6_fill_encap_info(struct sk_buff * skb,struct lwtunnel_state * lwtstate)875 static int seg6_fill_encap_info(struct sk_buff *skb,
876 				struct lwtunnel_state *lwtstate)
877 {
878 	struct seg6_iptunnel_encap *tuninfo = seg6_encap_lwtunnel(lwtstate);
879 	struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwtstate);
880 
881 	if (nla_put_srh(skb, SEG6_IPTUNNEL_SRH, tuninfo))
882 		return -EMSGSIZE;
883 
884 	if (!ipv6_addr_any(&slwt->tunsrc) &&
885 	    nla_put_in6_addr(skb, SEG6_IPTUNNEL_SRC, &slwt->tunsrc))
886 		return -EMSGSIZE;
887 
888 	if (slwt->table &&
889 	    nla_put_u32(skb, SEG6_IPTUNNEL_TABLE, slwt->table))
890 		return -EMSGSIZE;
891 
892 	return 0;
893 }
894 
seg6_encap_nlsize(struct lwtunnel_state * lwtstate)895 static int seg6_encap_nlsize(struct lwtunnel_state *lwtstate)
896 {
897 	struct seg6_iptunnel_encap *tuninfo = seg6_encap_lwtunnel(lwtstate);
898 	struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwtstate);
899 	int nlsize;
900 
901 	nlsize = nla_total_size(SEG6_IPTUN_ENCAP_SIZE(tuninfo));
902 
903 	if (!ipv6_addr_any(&slwt->tunsrc))
904 		nlsize += nla_total_size(sizeof(slwt->tunsrc));
905 
906 	if (slwt->table)
907 		nlsize += nla_total_size(sizeof(u32));
908 
909 	return nlsize;
910 }
911 
seg6_encap_cmp(struct lwtunnel_state * a,struct lwtunnel_state * b)912 static int seg6_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
913 {
914 	struct seg6_iptunnel_encap *a_hdr = seg6_encap_lwtunnel(a);
915 	struct seg6_iptunnel_encap *b_hdr = seg6_encap_lwtunnel(b);
916 	struct seg6_lwt *a_slwt = seg6_lwt_lwtunnel(a);
917 	struct seg6_lwt *b_slwt = seg6_lwt_lwtunnel(b);
918 	int len = SEG6_IPTUN_ENCAP_SIZE(a_hdr);
919 
920 	if (len != SEG6_IPTUN_ENCAP_SIZE(b_hdr))
921 		return 1;
922 
923 	if (!ipv6_addr_equal(&a_slwt->tunsrc, &b_slwt->tunsrc))
924 		return 1;
925 
926 	if (a_slwt->table != b_slwt->table)
927 		return 1;
928 
929 	return memcmp(a_hdr, b_hdr, len);
930 }
931 
932 static const struct lwtunnel_encap_ops seg6_iptun_ops = {
933 	.build_state = seg6_build_state,
934 	.destroy_state = seg6_destroy_state,
935 	.output = seg6_output,
936 	.input = seg6_input,
937 	.fill_encap = seg6_fill_encap_info,
938 	.get_encap_size = seg6_encap_nlsize,
939 	.cmp_encap = seg6_encap_cmp,
940 	.owner = THIS_MODULE,
941 };
942 
seg6_iptunnel_init(void)943 int __init seg6_iptunnel_init(void)
944 {
945 	return lwtunnel_encap_add_ops(&seg6_iptun_ops, LWTUNNEL_ENCAP_SEG6);
946 }
947 
seg6_iptunnel_exit(void)948 void seg6_iptunnel_exit(void)
949 {
950 	lwtunnel_encap_del_ops(&seg6_iptun_ops, LWTUNNEL_ENCAP_SEG6);
951 }
952