File tree Expand file tree Collapse file tree 9 files changed +526
-1
lines changed
Expand file tree Collapse file tree 9 files changed +526
-1
lines changed Original file line number Diff line number Diff line change 1+ #ifndef _LINUX_SEG6_IPTUNNEL_H
2+ #define _LINUX_SEG6_IPTUNNEL_H
3+
4+ #include <uapi/linux/seg6_iptunnel.h>
5+
6+ #endif
Original file line number Diff line number Diff line change 1616
1717#include <linux/net.h>
1818#include <linux/ipv6.h>
19+ #include <net/lwtunnel.h>
20+ #include <linux/seg6.h>
1921
2022static inline void update_csum_diff4 (struct sk_buff * skb , __be32 from ,
2123 __be32 to )
@@ -48,5 +50,9 @@ static inline struct seg6_pernet_data *seg6_pernet(struct net *net)
4850
4951extern int seg6_init (void );
5052extern void seg6_exit (void );
53+ extern int seg6_iptunnel_init (void );
54+ extern void seg6_iptunnel_exit (void );
55+
56+ extern bool seg6_validate_srh (struct ipv6_sr_hdr * srh , int len );
5157
5258#endif
Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ enum lwtunnel_encap_types {
99 LWTUNNEL_ENCAP_IP ,
1010 LWTUNNEL_ENCAP_ILA ,
1111 LWTUNNEL_ENCAP_IP6 ,
12+ LWTUNNEL_ENCAP_SEG6 ,
1213 __LWTUNNEL_ENCAP_MAX ,
1314};
1415
Original file line number Diff line number Diff line change 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+ #ifndef _UAPI_LINUX_SEG6_IPTUNNEL_H
15+ #define _UAPI_LINUX_SEG6_IPTUNNEL_H
16+
17+ enum {
18+ SEG6_IPTUNNEL_UNSPEC ,
19+ SEG6_IPTUNNEL_SRH ,
20+ __SEG6_IPTUNNEL_MAX ,
21+ };
22+ #define SEG6_IPTUNNEL_MAX (__SEG6_IPTUNNEL_MAX - 1)
23+
24+ struct seg6_iptunnel_encap {
25+ int mode ;
26+ struct ipv6_sr_hdr srh [0 ];
27+ };
28+
29+ #define SEG6_IPTUN_ENCAP_SIZE (x ) ((sizeof(*x)) + (((x)->srh->hdrlen + 1) << 3))
30+
31+ enum {
32+ SEG6_IPTUN_MODE_INLINE ,
33+ SEG6_IPTUN_MODE_ENCAP ,
34+ };
35+
36+ static inline size_t seg6_lwt_headroom (struct seg6_iptunnel_encap * tuninfo )
37+ {
38+ int encap = (tuninfo -> mode == SEG6_IPTUN_MODE_ENCAP );
39+
40+ return ((tuninfo -> srh -> hdrlen + 1 ) << 3 ) +
41+ (encap * sizeof (struct ipv6hdr ));
42+ }
43+
44+ #endif
Original file line number Diff line number Diff line change @@ -39,6 +39,8 @@ static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type)
3939 return "MPLS" ;
4040 case LWTUNNEL_ENCAP_ILA :
4141 return "ILA" ;
42+ case LWTUNNEL_ENCAP_SEG6 :
43+ return "SEG6" ;
4244 case LWTUNNEL_ENCAP_IP6 :
4345 case LWTUNNEL_ENCAP_IP :
4446 case LWTUNNEL_ENCAP_NONE :
Original file line number Diff line number Diff line change @@ -289,4 +289,16 @@ config IPV6_PIMSM_V2
289289 Support for IPv6 PIM multicast routing protocol PIM-SMv2.
290290 If unsure, say N.
291291
292+ config IPV6_SEG6_INLINE
293+ bool "IPv6: direct Segment Routing Header insertion "
294+ depends on IPV6
295+ ---help---
296+ Support for direct insertion of the Segment Routing Header,
297+ also known as inline mode. Be aware that direct insertion of
298+ extension headers (as opposed to encapsulation) may break
299+ multiple mechanisms such as PMTUD or IPSec AH. Use this feature
300+ only if you know exactly what you are doing.
301+
302+ If unsure, say N.
303+
292304endif # IPV6
Original file line number Diff line number Diff line change @@ -9,7 +9,7 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
99 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
1010 raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
1111 exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o \
12- udp_offload.o seg6.o
12+ udp_offload.o seg6.o seg6_iptunnel.o
1313
1414ipv6-offload := ip6_offload.o tcpv6_offload.o exthdrs_offload.o
1515
Original file line number Diff line number Diff line change 2626#include <linux/seg6.h>
2727#include <linux/seg6_genl.h>
2828
29+ bool seg6_validate_srh (struct ipv6_sr_hdr * srh , int len )
30+ {
31+ int trailing ;
32+ unsigned int tlv_offset ;
33+
34+ if (srh -> type != IPV6_SRCRT_TYPE_4 )
35+ return false;
36+
37+ if (((srh -> hdrlen + 1 ) << 3 ) != len )
38+ return false;
39+
40+ if (srh -> segments_left != srh -> first_segment )
41+ return false;
42+
43+ tlv_offset = sizeof (* srh ) + ((srh -> first_segment + 1 ) << 4 );
44+
45+ trailing = len - tlv_offset ;
46+ if (trailing < 0 )
47+ return false;
48+
49+ while (trailing ) {
50+ struct sr6_tlv * tlv ;
51+ unsigned int tlv_len ;
52+
53+ tlv = (struct sr6_tlv * )((unsigned char * )srh + tlv_offset );
54+ tlv_len = sizeof (* tlv ) + tlv -> len ;
55+
56+ trailing -= tlv_len ;
57+ if (trailing < 0 )
58+ return false;
59+
60+ tlv_offset += tlv_len ;
61+ }
62+
63+ return true;
64+ }
65+
2966static struct genl_family seg6_genl_family ;
3067
3168static const struct nla_policy seg6_genl_policy [SEG6_ATTR_MAX + 1 ] = {
@@ -198,17 +235,24 @@ int __init seg6_init(void)
198235 if (err )
199236 goto out_unregister_genl ;
200237
238+ err = seg6_iptunnel_init ();
239+ if (err )
240+ goto out_unregister_pernet ;
241+
201242 pr_info ("Segment Routing with IPv6\n" );
202243
203244out :
204245 return err ;
246+ out_unregister_pernet :
247+ unregister_pernet_subsys (& ip6_segments_ops );
205248out_unregister_genl :
206249 genl_unregister_family (& seg6_genl_family );
207250 goto out ;
208251}
209252
210253void seg6_exit (void )
211254{
255+ seg6_iptunnel_exit ();
212256 unregister_pernet_subsys (& ip6_segments_ops );
213257 genl_unregister_family (& seg6_genl_family );
214258}
You can’t perform that action at this time.
0 commit comments