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