23
23
24
24
/* \summary: Generic Protocol Extension for VXLAN (VXLAN GPE) printer */
25
25
26
- /* specification: draft-ietf-nvo3-vxlan-gpe-10 */
26
+ /* specification: draft-ietf-nvo3-vxlan-gpe-12 */
27
27
28
28
#ifdef HAVE_CONFIG_H
29
29
#include <config.h>
35
35
#include "netdissect.h"
36
36
#include "extract.h"
37
37
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
+
38
46
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" },
43
51
{ 0 , NULL }
44
52
};
45
53
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
+
46
60
#define VXLAN_GPE_HDR_LEN 8
47
61
48
62
/*
49
- * VXLAN GPE header, draft-ietf-nvo3-vxlan-gpe-01
63
+ * VXLAN GPE header, draft-ietf-nvo3-vxlan-gpe-12
50
64
* Generic Protocol Extension for VXLAN
51
65
*
52
66
* 0 1 2 3
53
67
* 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
54
68
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
- * |R|R|Ver|I|P|R |O| Reserved |Next Protocol |
69
+ * |R|R|Ver|I|P|B |O| Reserved |Next Protocol |
56
70
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
71
* | VXLAN Network Identifier (VNI) | Reserved |
58
72
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -61,10 +75,21 @@ static const struct tok vxlan_gpe_flags [] = {
61
75
void
62
76
vxlan_gpe_print (netdissect_options * ndo , const u_char * bp , u_int len )
63
77
{
64
- uint8_t flags ;
78
+ uint8_t flags , ver ;
65
79
uint8_t next_protocol ;
66
- uint32_t vni ;
67
80
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
+ */
68
93
ndo -> ndo_protocol = "vxlan_gpe" ;
69
94
ND_PRINT ("VXLAN-GPE, " );
70
95
if (len < VXLAN_GPE_HDR_LEN ) {
@@ -75,48 +100,79 @@ vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len)
75
100
flags = GET_U_1 (bp );
76
101
bp += 1 ;
77
102
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
+ }
78
108
ND_PRINT ("flags [%s], " ,
79
109
bittok2str_nosep (vxlan_gpe_flags , "none" , flags ));
80
110
81
111
/* Reserved */
82
112
bp += 2 ;
83
113
len -= 2 ;
84
114
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 ;
86
124
bp += 1 ;
87
125
len -= 1 ;
88
126
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" );
90
135
bp += 3 ;
91
136
len -= 3 ;
92
137
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
+
93
146
/* Reserved */
94
147
ND_TCHECK_1 (bp );
95
148
bp += 1 ;
96
149
len -= 1 ;
97
150
98
- ND_PRINT ("vni %u" , vni );
99
151
ND_PRINT (ndo -> ndo_vflag ? "\n " : ": " );
100
152
101
153
switch (next_protocol ) {
102
- case 0x1 :
154
+ case VXLAN_GPE_PROTO_IPV4 :
103
155
ip_print (ndo , bp , len );
104
156
break ;
105
- case 0x2 :
157
+ case VXLAN_GPE_PROTO_IPV6 :
106
158
ip6_print (ndo , bp , len );
107
159
break ;
108
- case 0x3 :
160
+ case VXLAN_GPE_PROTO_ETHERNET :
109
161
ether_print (ndo , bp , len , ND_BYTES_AVAILABLE_AFTER (bp ), NULL , NULL );
110
162
break ;
111
- case 0x4 :
163
+ case VXLAN_GPE_PROTO_NSH :
112
164
nsh_print (ndo , bp , len );
113
165
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
+ */
114
170
default :
115
171
ND_PRINT ("ERROR: unknown-next-protocol" );
116
172
goto invalid ;
117
173
}
118
174
119
- return ;
175
+ return ;
120
176
121
177
invalid :
122
178
nd_print_invalid (ndo );
0 commit comments