summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-12-02 22:32:02 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-12-02 22:32:02 +0000
commit493c7f792592a87827b6be377d976af8fedb141b (patch)
tree4f6888ba1cac7700ccb8baf19688409bccc6c5de /usr.sbin
parent1916e895420faddd09b706d325fd4e26e36e86a1 (diff)
add support for VXLAN-GPE as per draft-ietf-nvo3-vxlan-gpe-08.
it's nicely backwards compatible, so we can use the same code for both vxlan and vxlan-gpe.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/tcpdump/print-gre.c111
-rw-r--r--usr.sbin/tcpdump/print-udp.c5
2 files changed, 82 insertions, 34 deletions
diff --git a/usr.sbin/tcpdump/print-gre.c b/usr.sbin/tcpdump/print-gre.c
index 542f73dcf0c..954d62f9786 100644
--- a/usr.sbin/tcpdump/print-gre.c
+++ b/usr.sbin/tcpdump/print-gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-gre.c,v 1.27 2019/05/26 22:42:42 dlg Exp $ */
+/* $OpenBSD: print-gre.c,v 1.28 2019/12/02 22:32:01 dlg Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -666,10 +666,30 @@ gre_sre_asn_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len)
}
}
+/*
+ * - RFC 7348 Virtual eXtensible Local Area Network (VXLAN)
+ * - draft-ietf-nvo3-vxlan-gpe-08 Generic Protocol Extension for VXLAN
+ */
+
struct vxlan_header {
uint16_t flags;
-#define VXLAN_I 0x0800
- uint16_t proto;
+#define VXLAN_VER 0x3000 /* GPE */
+#define VXLAN_VER_0 0x0000
+#define VXLAN_I 0x0800 /* Instance Bit */
+#define VXLAN_P 0x0400 /* GPE Next Protocol */
+#define VXLAN_B 0x0200 /* GPE BUM Traffic */
+#define VXLAN_O 0x0100 /* GPE OAM Flag */
+ uint8_t reserved;
+ uint8_t next_proto; /* GPE */
+#define VXLAN_PROTO_RESERVED 0x00
+#define VXLAN_PROTO_IPV4 0x01
+#define VXLAN_PROTO_IPV6 0x02
+#define VXLAN_PROTO_ETHERNET 0x03
+#define VXLAN_PROTO_NSH 0x04
+#define VXLAN_PROTO_MPLS 0x05
+#define VXLAN_PROTO_VBNG 0x07
+#define VXLAN_PROTO_GBP 0x80
+#define VXLAN_PROTO_IOAM 0x82
uint32_t vni;
#define VXLAN_VNI_SHIFT 8
#define VXLAN_VNI_MASK (0xffffffU << VXLAN_VNI_SHIFT)
@@ -680,49 +700,76 @@ void
vxlan_print(const u_char *p, u_int length)
{
const struct vxlan_header *vh;
- uint16_t flags, proto;
- uint32_t vni;
- size_t l;
+ uint16_t flags, ver;
+ uint8_t proto = VXLAN_PROTO_ETHERNET;
+ int l = snapend - p;
- l = snapend - p;
- if (l < sizeof(*vh)) {
- printf("[|vxlan]");
+ printf("VXLAN");
+
+ if (l < sizeof(*vh))
+ goto trunc;
+ if (length < sizeof(*vh)) {
+ printf(" ip truncated");
return;
}
+
vh = (const struct vxlan_header *)p;
+ p += sizeof(*vh);
+ length -= sizeof(*vh);
+
flags = ntohs(vh->flags);
- if (flags & ~VXLAN_I) {
- printf("vxlan-invalid-flags %04x", flags);
+ ver = flags & VXLAN_VER;
+ if (ver != VXLAN_VER_0) {
+ printf(" unknown version %u", ver >> 12);
return;
}
- proto = ntohs(vh->proto);
- if (proto != 0) {
- printf("vxlan-invalid-proto %04x", proto);
- return;
+ if (flags & VXLAN_I) {
+ uint32_t vni = (htonl(vh->vni) & VXLAN_VNI_MASK) >>
+ VXLAN_VNI_SHIFT;
+ printf(" vni %u", vni >> VXLAN_VNI_SHIFT);
}
- vni = ntohl(vh->vni);
- if (flags & VXLAN_I) {
- if (vni & VXLAN_VNI_RESERVED) {
- printf("vxlan-vni-reserved %02x",
- vni & VXLAN_VNI_RESERVED);
- return;
- }
+ if (flags & VXLAN_P)
+ proto = vh->next_proto;
- printf("vxlan %u: ", vni >> VXLAN_VNI_SHIFT);
- } else {
- if (vh->vni != 0) {
- printf("vxlan-invalid-vni %08x\n", vni);
- return;
- }
+ if (flags & VXLAN_B)
+ printf(" BUM");
- printf("vxlan: ");
+ if (flags & VXLAN_O) {
+ printf(" OAM (proto 0x%x, len %u)", proto, length);
+ return;
}
- p += sizeof(*vh);
- length -= sizeof(*vh);
+ printf(": ");
+
+ switch (proto) {
+ case VXLAN_PROTO_RESERVED:
+ printf("Reserved");
+ break;
+ case VXLAN_PROTO_IPV4:
+ ip_print(p, length);
+ break;
+ case VXLAN_PROTO_IPV6:
+ ip6_print(p, length);
+ break;
+ case VXLAN_PROTO_ETHERNET:
+ ether_tryprint(p, length, 0);
+ break;
+ case VXLAN_PROTO_NSH:
+ printf("NSH");
+ break;
+ case VXLAN_PROTO_MPLS:
+ mpls_print(p, length);
+ break;
+
+ default:
+ printf("Unassigned proto 0x%x", proto);
+ break;
+ }
- ether_tryprint(p, length, 0);
+ return;
+trunc:
+ printf(" [|vxlan]");
}
diff --git a/usr.sbin/tcpdump/print-udp.c b/usr.sbin/tcpdump/print-udp.c
index bb2d4878a75..fb4b2707772 100644
--- a/usr.sbin/tcpdump/print-udp.c
+++ b/usr.sbin/tcpdump/print-udp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-udp.c,v 1.52 2019/12/02 22:07:20 dlg Exp $ */
+/* $OpenBSD: print-udp.c,v 1.53 2019/12/02 22:32:01 dlg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
@@ -312,6 +312,7 @@ rtcp_print(const u_char *hdr, const u_char *ep)
#define UDPENCAP_PORT 4500 /*XXX*/
#define GRE_PORT 4754
#define VXLAN_PORT 4789
+#define VXLAN_GPE_PORT 4790
#define MULTICASTDNS_PORT 5353
#define MPLS_PORT 6635
@@ -559,7 +560,7 @@ udp_print(const u_char *bp, u_int length, const void *iph)
vqp_print(cp, length);
else if (ISPORT(GRE_PORT))
gre_print(cp, length);
- else if (ISPORT(VXLAN_PORT))
+ else if (ISPORT(VXLAN_PORT) || ISPORT(VXLAN_GPE_PORT))
vxlan_print(cp, length);
else if (ISPORT(MPLS_PORT))
mpls_print(cp, length);