[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <db494140b57342d987291873dbaa2f88b2d43644.1405097440.git.tgraf@suug.ch>
Date: Fri, 11 Jul 2014 18:59:50 +0200
From: Thomas Graf <tgraf@...g.ch>
To: netdev@...r.kernel.org
Cc: stephen@...workplumber.org, therbert@...gle.com,
nicolas.dichtel@...nd.com, pshelar@...ira.com,
xiyou.wangcong@...il.com, ogerlitz@...lanox.com,
dborkman@...hat.com, Madhu Challa <challa@...ronetworks.com>
Subject: [PATCH 2/2 net-next] vxlan: Minimal support for Generic Protocol Extension (VXLAN-gpe)
Check for the presence of the GPE bit and interpret the inner protocol
field accordingly. For now, only ethernet in VXLAN is supported. Other
protocol types will result in the packet being dropped.
Based on original work by Pritesh Kothari.
Cc: Madhu Challa <challa@...ronetworks.com>
Co-authored-by: Pritesh Kothari (pritkoth) <pritesh.kothari@...co.com>
Signed-off-by: Thomas Graf <tgraf@...g.ch>
---
drivers/net/vxlan.c | 55 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 43 insertions(+), 12 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 2e9fbcc..c9af24b 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -65,28 +65,39 @@
/* Base VXLAN header:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |R|R|R|R|I|R|R|R| Reserved |
+ * |R|R|R|R|I|P|R|R| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* I = 1 VXLAN Network Identifier (VNI) present
+ * P = 1 Generic Protocol Extension (VXLAN-gpe)
+ *
+ * VXLAN-gpe:
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|R|R|R|I|1|R|R| Reserved | Inner Protocol Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VXLAN Network Identifier (VNI) | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
+
/* VXLAN protocol header */
struct vxlanhdr {
#ifdef __LITTLE_ENDIAN_BITFIELD
- __u8 reserved_flags1:3,
+ __u8 reserved_flags1:2,
+ gpe:1,
vni_present:1,
reserved_flags2:4;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 reserved_flags2:4,
vni_present:1,
- reserved_flags1:3;
+ gpe:1,
+ reserved_flags1:2;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 vx_reserved1;
- __be16 vx_reserved2;
+ __be16 vx_inner_proto; /* Only valid if gpe flag is set */
__be32 vx_vni;
};
@@ -98,8 +109,9 @@ union vxlan_oct_hdr {
#define vxlan_flags(vxh) (((union vxlan_oct_hdr *)(vxh))->octets[0])
enum {
+ VXLAN_FLAG_GPE = 0x04,
VXLAN_FLAG_VNI = 0x08,
- VXLAN_FLAG_RESERVED = 0xF7,
+ VXLAN_FLAG_RESERVED = 0xF3,
};
/* UDP port for VXLAN traffic.
@@ -1162,6 +1174,26 @@ static void vxlan_igmp_leave(struct work_struct *work)
dev_put(vxlan->dev);
}
+static int vxlan_handle_extensions(struct sk_buff *skb, struct vxlanhdr *vxh)
+{
+ if (!vxh->vni_present) {
+ netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
+ vxlan_flags(vxh), ntohl(vxh->vx_vni));
+ return -EINVAL;
+ }
+
+ if (vxh->gpe) {
+ /* Only Ethernet in VXLAN supported for now */
+ if (vxh->vx_inner_proto != htons(ETH_P_TEB)) {
+ netdev_dbg(skb->dev, "unsupported inner vxlan proto %#x vni %#x\n",
+ ntohs(vxh->vx_inner_proto), ntohl(vxh->vx_vni));
+ return -EPFNOSUPPORT;
+ }
+ }
+
+ return 0;
+}
+
/* Callback from net/ipv4/udp.c to receive packets */
static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
{
@@ -1173,11 +1205,10 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto error;
vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
- if (!vxh->vni_present) {
- netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n",
- vxlan_flags(vxh), ntohl(vxh->vx_vni));
- goto error;
- }
+
+ if (unlikely(vxlan_flags(vxh) != VXLAN_FLAG_VNI))
+ if (vxlan_handle_extensions(skb, vxh) < 0)
+ goto error;
if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
goto drop;
@@ -1648,7 +1679,7 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxlan_flags(vxh) = VXLAN_FLAG_VNI;
vxh->vx_reserved1 = 0;
- vxh->vx_reserved2 = 0;
+ vxh->vx_inner_proto = 0;
vxh->vx_vni = vni;
__skb_push(skb, sizeof(*uh));
@@ -1722,7 +1753,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
vxlan_flags(vxh) = VXLAN_FLAG_VNI;
vxh->vx_reserved1 = 0;
- vxh->vx_reserved2 = 0;
+ vxh->vx_inner_proto = 0;
vxh->vx_vni = vni;
__skb_push(skb, sizeof(*uh));
--
1.9.3
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists