Skip to content

Commit 96026bd

Browse files
committed
VXLAN: pick up some stuff from the OpenBSD tcpdump.
1 parent e0787e5 commit 96026bd

File tree

2 files changed

+83
-21
lines changed

2 files changed

+83
-21
lines changed

print-vxlan-gpe.c

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/* \summary: Generic Protocol Extension for VXLAN (VXLAN GPE) printer */
2525

26-
/* specification: draft-ietf-nvo3-vxlan-gpe-10 */
26+
/* specification: draft-ietf-nvo3-vxlan-gpe-12 */
2727

2828
#ifdef HAVE_CONFIG_H
2929
#include <config.h>
@@ -35,24 +35,38 @@
3535
#include "netdissect.h"
3636
#include "extract.h"
3737

38+
#define VXLAN_GPE_VER 0x30 /* GPE */
39+
#define VXLAN_GPE_SHIFT 4
40+
#define VXLAN_GPE_VER_0 0x0
41+
#define VXLAN_GPE_I 0x08 /* Instance Bit */
42+
#define VXLAN_GPE_P 0x04 /* GPE Next Protocol */
43+
#define VXLAN_GPE_B 0x02 /* GPE BUM Traffic */
44+
#define VXLAN_GPE_O 0x01 /* GPE OAM Flag */
45+
3846
static const struct tok vxlan_gpe_flags [] = {
39-
{ 0x08, "I" },
40-
{ 0x04, "P" },
41-
{ 0x02, "B" },
42-
{ 0x01, "O" },
47+
{ VXLAN_GPE_I, "I" },
48+
{ VXLAN_GPE_P, "P" },
49+
{ VXLAN_GPE_B, "B" },
50+
{ VXLAN_GPE_O, "O" },
4351
{ 0, NULL }
4452
};
4553

54+
#define VXLAN_GPE_PROTO_RESERVED 0x00
55+
#define VXLAN_GPE_PROTO_IPV4 0x01
56+
#define VXLAN_GPE_PROTO_IPV6 0x02
57+
#define VXLAN_GPE_PROTO_ETHERNET 0x03
58+
#define VXLAN_GPE_PROTO_NSH 0x04
59+
4660
#define VXLAN_GPE_HDR_LEN 8
4761

4862
/*
49-
* VXLAN GPE header, draft-ietf-nvo3-vxlan-gpe-01
63+
* VXLAN GPE header, draft-ietf-nvo3-vxlan-gpe-12
5064
* Generic Protocol Extension for VXLAN
5165
*
5266
* 0 1 2 3
5367
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
5468
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55-
* |R|R|Ver|I|P|R|O| Reserved |Next Protocol |
69+
* |R|R|Ver|I|P|B|O| Reserved |Next Protocol |
5670
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5771
* | VXLAN Network Identifier (VNI) | Reserved |
5872
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -61,10 +75,21 @@ static const struct tok vxlan_gpe_flags [] = {
6175
void
6276
vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len)
6377
{
64-
uint8_t flags;
78+
uint8_t flags, ver;
6579
uint8_t next_protocol;
66-
uint32_t vni;
6780

81+
/*
82+
* XXX - OpenBSD has a single dissector for VXLAN and VXLAN-GPE,
83+
* using the flag bits to distinguish between them.
84+
*
85+
* draft-ietf-nvo3-vxlan-gpe-12, the final VXLAN-GPE draft, says
86+
* that VXLAN-GPE uses port 4790, rather than VXLAN's port 4789,
87+
* and that the P flag bit must be set for VXLAN-GPE packets,
88+
* indicating that the header includes a "next protocol" field,
89+
* and that if a packet with the P it not set is received on
90+
* port 4790, "the "Next Protocol" field must be set to zero and
91+
* the payload MUST be ETHERNET(L2) as defined by [RFC7348]."
92+
*/
6893
ndo->ndo_protocol = "vxlan_gpe";
6994
ND_PRINT("VXLAN-GPE, ");
7095
if (len < VXLAN_GPE_HDR_LEN) {
@@ -75,48 +100,79 @@ vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len)
75100
flags = GET_U_1(bp);
76101
bp += 1;
77102
len -= 1;
103+
ver = (flags & VXLAN_GPE_VER) >> VXLAN_GPE_SHIFT;
104+
if (ver != VXLAN_GPE_VER_0) {
105+
ND_PRINT("unknown version %u", ver);
106+
goto invalid;
107+
}
78108
ND_PRINT("flags [%s], ",
79109
bittok2str_nosep(vxlan_gpe_flags, "none", flags));
80110

81111
/* Reserved */
82112
bp += 2;
83113
len -= 2;
84114

85-
next_protocol = GET_U_1(bp);
115+
/*
116+
* If the VXLAN_GPE_P flag bit isn't set, that means this is a VXLAN
117+
* packet, not a VXLAN-GPE packet, and thus has no "next protocol"
118+
* field; the payload is Ethernet.
119+
*/
120+
if (flags & VXLAN_GPE_P)
121+
next_protocol = GET_U_1(bp);
122+
else
123+
next_protocol = VXLAN_GPE_PROTO_ETHERNET;
86124
bp += 1;
87125
len -= 1;
88126

89-
vni = GET_BE_U_3(bp);
127+
/*
128+
* Both RFC 7348 and draft-ietf-nvo3-vxlan-gpe-12 say that the I flag
129+
* MUST be set.
130+
*/
131+
if (flags & VXLAN_GPE_I)
132+
ND_PRINT("vni %u", GET_BE_U_3(bp));
133+
else
134+
ND_PRINT("ERROR: I flag not set");
90135
bp += 3;
91136
len -= 3;
92137

138+
if (flags & VXLAN_GPE_B)
139+
printf(", BUM");
140+
141+
if (flags & VXLAN_GPE_O) {
142+
printf(", OAM (proto 0x%x, len %u)", next_protocol, len);
143+
return;
144+
}
145+
93146
/* Reserved */
94147
ND_TCHECK_1(bp);
95148
bp += 1;
96149
len -= 1;
97150

98-
ND_PRINT("vni %u", vni);
99151
ND_PRINT(ndo->ndo_vflag ? "\n " : ": ");
100152

101153
switch (next_protocol) {
102-
case 0x1:
154+
case VXLAN_GPE_PROTO_IPV4:
103155
ip_print(ndo, bp, len);
104156
break;
105-
case 0x2:
157+
case VXLAN_GPE_PROTO_IPV6:
106158
ip6_print(ndo, bp, len);
107159
break;
108-
case 0x3:
160+
case VXLAN_GPE_PROTO_ETHERNET:
109161
ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
110162
break;
111-
case 0x4:
163+
case VXLAN_GPE_PROTO_NSH:
112164
nsh_print(ndo, bp, len);
113165
break;
166+
/*
167+
* OpenBSD supports 0x05 for MPLS, which was in earlier drafts
168+
* of VXLAN GPE, but not in the final -12 draft.
169+
*/
114170
default:
115171
ND_PRINT("ERROR: unknown-next-protocol");
116172
goto invalid;
117173
}
118174

119-
return;
175+
return;
120176

121177
invalid:
122178
nd_print_invalid(ndo);

print-vxlan.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
#include "netdissect.h"
2828
#include "extract.h"
2929

30+
#define VXLAN_I 0x08 /* Instance Bit */
31+
3032
static const struct tok vxlan_flags [] = {
31-
{ 0x08, "I" },
33+
{ VXLAN_I, "I" },
3234
{ 0, NULL }
3335
};
3436
#define VXLAN_HDR_LEN 8
@@ -51,7 +53,6 @@ void
5153
vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len)
5254
{
5355
uint8_t flags;
54-
uint32_t vni;
5556

5657
ndo->ndo_protocol = "vxlan";
5758
nd_print_protocol_caps(ndo);
@@ -66,9 +67,14 @@ vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len)
6667
/* 1st Reserved */
6768
bp += 3;
6869

69-
vni = GET_BE_U_3(bp);
70+
/*
71+
* RFC 7348 says that the I flag MUST be set.
72+
*/
73+
if (flags & VXLAN_I)
74+
ND_PRINT("vni %u\n", GET_BE_U_3(bp));
75+
else
76+
ND_PRINT("ERROR: I flag not set\n");
7077
bp += 3;
71-
ND_PRINT("vni %u\n", vni);
7278

7379
/* 2nd Reserved */
7480
ND_TCHECK_1(bp);

0 commit comments

Comments
 (0)