Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vxlan: factor out VXLAN-GPE next protocol

The values are shared between VXLAN-GPE and NSH. Originally probably by
coincidence but I notified both working groups about this last year and they
seem to keep the values in sync since then.

Hopefully they'll get a single IANA registry for the values, too. (I asked
them for that.)

Factor out the code to be shared by the NSH implementation.

NSH and MPLS values are added in this patch, too. For MPLS, the drafts
incorrectly assign only a single value, while we have two MPLS ethertypes.
I raised the problem with both groups. For now, I assume the value is for
unicast.

Signed-off-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jiri Benc and committed by
David S. Miller
fa20e0e3 155e6f64

+56 -31
+7 -25
drivers/net/vxlan.c
··· 26 26 #include <net/inet_ecn.h> 27 27 #include <net/net_namespace.h> 28 28 #include <net/netns/generic.h> 29 + #include <net/tun_proto.h> 29 30 #include <net/vxlan.h> 30 31 31 32 #if IS_ENABLED(CONFIG_IPV6) ··· 1262 1261 if (gpe->oam_flag) 1263 1262 return false; 1264 1263 1265 - switch (gpe->next_protocol) { 1266 - case VXLAN_GPE_NP_IPV4: 1267 - *protocol = htons(ETH_P_IP); 1268 - break; 1269 - case VXLAN_GPE_NP_IPV6: 1270 - *protocol = htons(ETH_P_IPV6); 1271 - break; 1272 - case VXLAN_GPE_NP_ETHERNET: 1273 - *protocol = htons(ETH_P_TEB); 1274 - break; 1275 - default: 1264 + *protocol = tun_p_to_eth_p(gpe->next_protocol); 1265 + if (!*protocol) 1276 1266 return false; 1277 - } 1278 1267 1279 1268 unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS; 1280 1269 return true; ··· 1790 1799 struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)vxh; 1791 1800 1792 1801 gpe->np_applied = 1; 1793 - 1794 - switch (protocol) { 1795 - case htons(ETH_P_IP): 1796 - gpe->next_protocol = VXLAN_GPE_NP_IPV4; 1797 - return 0; 1798 - case htons(ETH_P_IPV6): 1799 - gpe->next_protocol = VXLAN_GPE_NP_IPV6; 1800 - return 0; 1801 - case htons(ETH_P_TEB): 1802 - gpe->next_protocol = VXLAN_GPE_NP_ETHERNET; 1803 - return 0; 1804 - } 1805 - return -EPFNOSUPPORT; 1802 + gpe->next_protocol = tun_p_from_eth_p(protocol); 1803 + if (!gpe->next_protocol) 1804 + return -EPFNOSUPPORT; 1805 + return 0; 1806 1806 } 1807 1807 1808 1808 static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
+49
include/net/tun_proto.h
··· 1 + #ifndef __NET_TUN_PROTO_H 2 + #define __NET_TUN_PROTO_H 3 + 4 + #include <linux/kernel.h> 5 + 6 + /* One byte protocol values as defined by VXLAN-GPE and NSH. These will 7 + * hopefully get a shared IANA registry. 8 + */ 9 + #define TUN_P_IPV4 0x01 10 + #define TUN_P_IPV6 0x02 11 + #define TUN_P_ETHERNET 0x03 12 + #define TUN_P_NSH 0x04 13 + #define TUN_P_MPLS_UC 0x05 14 + 15 + static inline __be16 tun_p_to_eth_p(u8 proto) 16 + { 17 + switch (proto) { 18 + case TUN_P_IPV4: 19 + return htons(ETH_P_IP); 20 + case TUN_P_IPV6: 21 + return htons(ETH_P_IPV6); 22 + case TUN_P_ETHERNET: 23 + return htons(ETH_P_TEB); 24 + case TUN_P_NSH: 25 + return htons(ETH_P_NSH); 26 + case TUN_P_MPLS_UC: 27 + return htons(ETH_P_MPLS_UC); 28 + } 29 + return 0; 30 + } 31 + 32 + static inline u8 tun_p_from_eth_p(__be16 proto) 33 + { 34 + switch (proto) { 35 + case htons(ETH_P_IP): 36 + return TUN_P_IPV4; 37 + case htons(ETH_P_IPV6): 38 + return TUN_P_IPV6; 39 + case htons(ETH_P_TEB): 40 + return TUN_P_ETHERNET; 41 + case htons(ETH_P_NSH): 42 + return TUN_P_NSH; 43 + case htons(ETH_P_MPLS_UC): 44 + return TUN_P_MPLS_UC; 45 + } 46 + return 0; 47 + } 48 + 49 + #endif
-6
include/net/vxlan.h
··· 168 168 #define VXLAN_GPE_USED_BITS (VXLAN_HF_VER | VXLAN_HF_NP | VXLAN_HF_OAM | \ 169 169 cpu_to_be32(0xff)) 170 170 171 - /* VXLAN-GPE header Next Protocol. */ 172 - #define VXLAN_GPE_NP_IPV4 0x01 173 - #define VXLAN_GPE_NP_IPV6 0x02 174 - #define VXLAN_GPE_NP_ETHERNET 0x03 175 - #define VXLAN_GPE_NP_NSH 0x04 176 - 177 171 struct vxlan_metadata { 178 172 u32 gbp; 179 173 };