diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/netdev_features.h | 4 | ||||
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | include/linux/skbuff.h | 4 | ||||
-rw-r--r-- | include/net/fou.h | 38 | ||||
-rw-r--r-- | include/net/gue.h | 103 | ||||
-rw-r--r-- | include/uapi/linux/if_tunnel.h | 1 |
6 files changed, 144 insertions, 7 deletions
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h index dcfdecbfa0b7..8c94b07e654a 100644 --- a/include/linux/netdev_features.h +++ b/include/linux/netdev_features.h | |||
@@ -48,8 +48,9 @@ enum { | |||
48 | NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */ | 48 | NETIF_F_GSO_UDP_TUNNEL_BIT, /* ... UDP TUNNEL with TSO */ |
49 | NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,/* ... UDP TUNNEL with TSO & CSUM */ | 49 | NETIF_F_GSO_UDP_TUNNEL_CSUM_BIT,/* ... UDP TUNNEL with TSO & CSUM */ |
50 | NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */ | 50 | NETIF_F_GSO_MPLS_BIT, /* ... MPLS segmentation */ |
51 | NETIF_F_GSO_TUNNEL_REMCSUM_BIT, /* ... TUNNEL with TSO & REMCSUM */ | ||
51 | /**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */ | 52 | /**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */ |
52 | NETIF_F_GSO_MPLS_BIT, | 53 | NETIF_F_GSO_TUNNEL_REMCSUM_BIT, |
53 | 54 | ||
54 | NETIF_F_FCOE_CRC_BIT, /* FCoE CRC32 */ | 55 | NETIF_F_FCOE_CRC_BIT, /* FCoE CRC32 */ |
55 | NETIF_F_SCTP_CSUM_BIT, /* SCTP checksum offload */ | 56 | NETIF_F_SCTP_CSUM_BIT, /* SCTP checksum offload */ |
@@ -119,6 +120,7 @@ enum { | |||
119 | #define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL) | 120 | #define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL) |
120 | #define NETIF_F_GSO_UDP_TUNNEL_CSUM __NETIF_F(GSO_UDP_TUNNEL_CSUM) | 121 | #define NETIF_F_GSO_UDP_TUNNEL_CSUM __NETIF_F(GSO_UDP_TUNNEL_CSUM) |
121 | #define NETIF_F_GSO_MPLS __NETIF_F(GSO_MPLS) | 122 | #define NETIF_F_GSO_MPLS __NETIF_F(GSO_MPLS) |
123 | #define NETIF_F_GSO_TUNNEL_REMCSUM __NETIF_F(GSO_TUNNEL_REMCSUM) | ||
122 | #define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER) | 124 | #define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER) |
123 | #define NETIF_F_HW_VLAN_STAG_RX __NETIF_F(HW_VLAN_STAG_RX) | 125 | #define NETIF_F_HW_VLAN_STAG_RX __NETIF_F(HW_VLAN_STAG_RX) |
124 | #define NETIF_F_HW_VLAN_STAG_TX __NETIF_F(HW_VLAN_STAG_TX) | 126 | #define NETIF_F_HW_VLAN_STAG_TX __NETIF_F(HW_VLAN_STAG_TX) |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5ed05bd764dc..4767f546d7c0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -3584,6 +3584,7 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type) | |||
3584 | BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT)); | 3584 | BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT)); |
3585 | BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT)); | 3585 | BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT)); |
3586 | BUILD_BUG_ON(SKB_GSO_MPLS != (NETIF_F_GSO_MPLS >> NETIF_F_GSO_SHIFT)); | 3586 | BUILD_BUG_ON(SKB_GSO_MPLS != (NETIF_F_GSO_MPLS >> NETIF_F_GSO_SHIFT)); |
3587 | BUILD_BUG_ON(SKB_GSO_TUNNEL_REMCSUM != (NETIF_F_GSO_TUNNEL_REMCSUM >> NETIF_F_GSO_SHIFT)); | ||
3587 | 3588 | ||
3588 | return (features & feature) == feature; | 3589 | return (features & feature) == feature; |
3589 | } | 3590 | } |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5ad9675b6fe1..74ed34413969 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -373,6 +373,7 @@ enum { | |||
373 | 373 | ||
374 | SKB_GSO_MPLS = 1 << 12, | 374 | SKB_GSO_MPLS = 1 << 12, |
375 | 375 | ||
376 | SKB_GSO_TUNNEL_REMCSUM = 1 << 13, | ||
376 | }; | 377 | }; |
377 | 378 | ||
378 | #if BITS_PER_LONG > 32 | 379 | #if BITS_PER_LONG > 32 |
@@ -603,7 +604,8 @@ struct sk_buff { | |||
603 | #endif | 604 | #endif |
604 | __u8 ipvs_property:1; | 605 | __u8 ipvs_property:1; |
605 | __u8 inner_protocol_type:1; | 606 | __u8 inner_protocol_type:1; |
606 | /* 4 or 6 bit hole */ | 607 | __u8 remcsum_offload:1; |
608 | /* 3 or 5 bit hole */ | ||
607 | 609 | ||
608 | #ifdef CONFIG_NET_SCHED | 610 | #ifdef CONFIG_NET_SCHED |
609 | __u16 tc_index; /* traffic control index */ | 611 | __u16 tc_index; /* traffic control index */ |
diff --git a/include/net/fou.h b/include/net/fou.h new file mode 100644 index 000000000000..25b26ffcf1df --- /dev/null +++ b/include/net/fou.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef __NET_FOU_H | ||
2 | #define __NET_FOU_H | ||
3 | |||
4 | #include <linux/skbuff.h> | ||
5 | |||
6 | #include <net/flow.h> | ||
7 | #include <net/gue.h> | ||
8 | #include <net/ip_tunnels.h> | ||
9 | #include <net/udp.h> | ||
10 | |||
11 | int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e, | ||
12 | u8 *protocol, struct flowi4 *fl4); | ||
13 | int gue_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e, | ||
14 | u8 *protocol, struct flowi4 *fl4); | ||
15 | |||
16 | static size_t fou_encap_hlen(struct ip_tunnel_encap *e) | ||
17 | { | ||
18 | return sizeof(struct udphdr); | ||
19 | } | ||
20 | |||
21 | static size_t gue_encap_hlen(struct ip_tunnel_encap *e) | ||
22 | { | ||
23 | size_t len; | ||
24 | bool need_priv = false; | ||
25 | |||
26 | len = sizeof(struct udphdr) + sizeof(struct guehdr); | ||
27 | |||
28 | if (e->flags & TUNNEL_ENCAP_FLAG_REMCSUM) { | ||
29 | len += GUE_PLEN_REMCSUM; | ||
30 | need_priv = true; | ||
31 | } | ||
32 | |||
33 | len += need_priv ? GUE_LEN_PRIV : 0; | ||
34 | |||
35 | return len; | ||
36 | } | ||
37 | |||
38 | #endif | ||
diff --git a/include/net/gue.h b/include/net/gue.h index b6c332788084..3f28ec7f1c7f 100644 --- a/include/net/gue.h +++ b/include/net/gue.h | |||
@@ -1,23 +1,116 @@ | |||
1 | #ifndef __NET_GUE_H | 1 | #ifndef __NET_GUE_H |
2 | #define __NET_GUE_H | 2 | #define __NET_GUE_H |
3 | 3 | ||
4 | /* Definitions for the GUE header, standard and private flags, lengths | ||
5 | * of optional fields are below. | ||
6 | * | ||
7 | * Diagram of GUE header: | ||
8 | * | ||
9 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
10 | * |Ver|C| Hlen | Proto/ctype | Standard flags |P| | ||
11 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
12 | * | | | ||
13 | * ~ Fields (optional) ~ | ||
14 | * | | | ||
15 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
16 | * | Private flags (optional, P bit is set) | | ||
17 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
18 | * | | | ||
19 | * ~ Private fields (optional) ~ | ||
20 | * | | | ||
21 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
22 | * | ||
23 | * C bit indicates contol message when set, data message when unset. | ||
24 | * For a control message, proto/ctype is interpreted as a type of | ||
25 | * control message. For data messages, proto/ctype is the IP protocol | ||
26 | * of the next header. | ||
27 | * | ||
28 | * P bit indicates private flags field is present. The private flags | ||
29 | * may refer to options placed after this field. | ||
30 | */ | ||
31 | |||
4 | struct guehdr { | 32 | struct guehdr { |
5 | union { | 33 | union { |
6 | struct { | 34 | struct { |
7 | #if defined(__LITTLE_ENDIAN_BITFIELD) | 35 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
8 | __u8 hlen:4, | 36 | __u8 hlen:5, |
9 | version:4; | 37 | control:1, |
38 | version:2; | ||
10 | #elif defined (__BIG_ENDIAN_BITFIELD) | 39 | #elif defined (__BIG_ENDIAN_BITFIELD) |
11 | __u8 version:4, | 40 | __u8 version:2, |
12 | hlen:4; | 41 | control:1, |
42 | hlen:5; | ||
13 | #else | 43 | #else |
14 | #error "Please fix <asm/byteorder.h>" | 44 | #error "Please fix <asm/byteorder.h>" |
15 | #endif | 45 | #endif |
16 | __u8 next_hdr; | 46 | __u8 proto_ctype; |
17 | __u16 flags; | 47 | __u16 flags; |
18 | }; | 48 | }; |
19 | __u32 word; | 49 | __u32 word; |
20 | }; | 50 | }; |
21 | }; | 51 | }; |
22 | 52 | ||
53 | /* Standard flags in GUE header */ | ||
54 | |||
55 | #define GUE_FLAG_PRIV htons(1<<0) /* Private flags are in options */ | ||
56 | #define GUE_LEN_PRIV 4 | ||
57 | |||
58 | #define GUE_FLAGS_ALL (GUE_FLAG_PRIV) | ||
59 | |||
60 | /* Private flags in the private option extension */ | ||
61 | |||
62 | #define GUE_PFLAG_REMCSUM htonl(1 << 31) | ||
63 | #define GUE_PLEN_REMCSUM 4 | ||
64 | |||
65 | #define GUE_PFLAGS_ALL (GUE_PFLAG_REMCSUM) | ||
66 | |||
67 | /* Functions to compute options length corresponding to flags. | ||
68 | * If we ever have a lot of flags this can be potentially be | ||
69 | * converted to a more optimized algorithm (table lookup | ||
70 | * for instance). | ||
71 | */ | ||
72 | static inline size_t guehdr_flags_len(__be16 flags) | ||
73 | { | ||
74 | return ((flags & GUE_FLAG_PRIV) ? GUE_LEN_PRIV : 0); | ||
75 | } | ||
76 | |||
77 | static inline size_t guehdr_priv_flags_len(__be32 flags) | ||
78 | { | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | /* Validate standard and private flags. Returns non-zero (meaning invalid) | ||
83 | * if there is an unknown standard or private flags, or the options length for | ||
84 | * the flags exceeds the options length specific in hlen of the GUE header. | ||
85 | */ | ||
86 | static inline int validate_gue_flags(struct guehdr *guehdr, | ||
87 | size_t optlen) | ||
88 | { | ||
89 | size_t len; | ||
90 | __be32 flags = guehdr->flags; | ||
91 | |||
92 | if (flags & ~GUE_FLAGS_ALL) | ||
93 | return 1; | ||
94 | |||
95 | len = guehdr_flags_len(flags); | ||
96 | if (len > optlen) | ||
97 | return 1; | ||
98 | |||
99 | if (flags & GUE_FLAG_PRIV) { | ||
100 | /* Private flags are last four bytes accounted in | ||
101 | * guehdr_flags_len | ||
102 | */ | ||
103 | flags = *(__be32 *)((void *)&guehdr[1] + len - GUE_LEN_PRIV); | ||
104 | |||
105 | if (flags & ~GUE_PFLAGS_ALL) | ||
106 | return 1; | ||
107 | |||
108 | len += guehdr_priv_flags_len(flags); | ||
109 | if (len > optlen) | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
23 | #endif | 116 | #endif |
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 280d9e092283..bd3cc11a431f 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h | |||
@@ -69,6 +69,7 @@ enum tunnel_encap_types { | |||
69 | 69 | ||
70 | #define TUNNEL_ENCAP_FLAG_CSUM (1<<0) | 70 | #define TUNNEL_ENCAP_FLAG_CSUM (1<<0) |
71 | #define TUNNEL_ENCAP_FLAG_CSUM6 (1<<1) | 71 | #define TUNNEL_ENCAP_FLAG_CSUM6 (1<<1) |
72 | #define TUNNEL_ENCAP_FLAG_REMCSUM (1<<2) | ||
72 | 73 | ||
73 | /* SIT-mode i_flags */ | 74 | /* SIT-mode i_flags */ |
74 | #define SIT_ISATAP 0x0001 | 75 | #define SIT_ISATAP 0x0001 |