File tree 9 files changed +526
-1
lines changed 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 16
16
17
17
#include <linux/net.h>
18
18
#include <linux/ipv6.h>
19
+ #include <net/lwtunnel.h>
20
+ #include <linux/seg6.h>
19
21
20
22
static inline void update_csum_diff4 (struct sk_buff * skb , __be32 from ,
21
23
__be32 to )
@@ -48,5 +50,9 @@ static inline struct seg6_pernet_data *seg6_pernet(struct net *net)
48
50
49
51
extern int seg6_init (void );
50
52
extern 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 );
51
57
52
58
#endif
Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ enum lwtunnel_encap_types {
9
9
LWTUNNEL_ENCAP_IP ,
10
10
LWTUNNEL_ENCAP_ILA ,
11
11
LWTUNNEL_ENCAP_IP6 ,
12
+ LWTUNNEL_ENCAP_SEG6 ,
12
13
__LWTUNNEL_ENCAP_MAX ,
13
14
};
14
15
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)
39
39
return "MPLS" ;
40
40
case LWTUNNEL_ENCAP_ILA :
41
41
return "ILA" ;
42
+ case LWTUNNEL_ENCAP_SEG6 :
43
+ return "SEG6" ;
42
44
case LWTUNNEL_ENCAP_IP6 :
43
45
case LWTUNNEL_ENCAP_IP :
44
46
case LWTUNNEL_ENCAP_NONE :
Original file line number Diff line number Diff line change @@ -289,4 +289,16 @@ config IPV6_PIMSM_V2
289
289
Support for IPv6 PIM multicast routing protocol PIM-SMv2.
290
290
If unsure, say N.
291
291
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
+
292
304
endif # 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 \
9
9
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
10
10
raw.o icmp.o mcast.o reassembly.o tcp_ipv6.o ping.o \
11
11
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
13
13
14
14
ipv6-offload := ip6_offload.o tcpv6_offload.o exthdrs_offload.o
15
15
Original file line number Diff line number Diff line change 26
26
#include <linux/seg6.h>
27
27
#include <linux/seg6_genl.h>
28
28
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
+
29
66
static struct genl_family seg6_genl_family ;
30
67
31
68
static const struct nla_policy seg6_genl_policy [SEG6_ATTR_MAX + 1 ] = {
@@ -198,17 +235,24 @@ int __init seg6_init(void)
198
235
if (err )
199
236
goto out_unregister_genl ;
200
237
238
+ err = seg6_iptunnel_init ();
239
+ if (err )
240
+ goto out_unregister_pernet ;
241
+
201
242
pr_info ("Segment Routing with IPv6\n" );
202
243
203
244
out :
204
245
return err ;
246
+ out_unregister_pernet :
247
+ unregister_pernet_subsys (& ip6_segments_ops );
205
248
out_unregister_genl :
206
249
genl_unregister_family (& seg6_genl_family );
207
250
goto out ;
208
251
}
209
252
210
253
void seg6_exit (void )
211
254
{
255
+ seg6_iptunnel_exit ();
212
256
unregister_pernet_subsys (& ip6_segments_ops );
213
257
genl_unregister_family (& seg6_genl_family );
214
258
}
You can’t perform that action at this time.
0 commit comments