decoder/vxlan: fix VXLAN port detection per RFC 7348

Simplify DecodeVXLANEnabledForPort() to only check destination port
to avoids false positives when identifying VXLAN traffic.

Per RFC 7348 §5, VXLAN identification is based solely on the outer UDP
destination port (4789), regardless of inner packet direction. The
outer UDP source port is used for load balancing via inner packet
hash and should not be considered for VXLAN detection. This ensures
correct VXLAN identification for all encapsulated traffic patterns.

Checking both source and destination ports could incorrectly classify
non-VXLAN UDP traffic as VXLAN when the source port happens to be 4789,
leading to false positives in VXLAN detection and potential decode errors.

(cherry picked from commit 7a04a032b9)
pull/14001/head
Fupeng Zhao 10 months ago committed by Victor Julien
parent 9a66ac0696
commit 693ca03379

@ -103,7 +103,7 @@ int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
}
/* Handle VXLAN if configured */
if (DecodeVXLANEnabledForPort(p->sp, p->dp) &&
if (DecodeVXLANEnabledForPort(p->dp) &&
unlikely(DecodeVXLAN(tv, dtv, p, p->payload, p->payload_len) == TM_ECODE_OK)) {
/* Here we have a VXLAN packet and don't need to handle app
* layer */

@ -59,17 +59,17 @@ typedef struct VXLANHeader_ {
uint8_t res;
} VXLANHeader;
bool DecodeVXLANEnabledForPort(const uint16_t sp, const uint16_t dp)
bool DecodeVXLANEnabledForPort(const uint16_t dp)
{
SCLogDebug("ports %u->%u ports %d %d %d %d", sp, dp, g_vxlan_ports[0], g_vxlan_ports[1],
g_vxlan_ports[2], g_vxlan_ports[3]);
SCLogDebug("checking dest port %u against ports %d %d %d %d", dp, g_vxlan_ports[0],
g_vxlan_ports[1], g_vxlan_ports[2], g_vxlan_ports[3]);
if (g_vxlan_enabled) {
for (int i = 0; i < g_vxlan_ports_idx; i++) {
if (g_vxlan_ports[i] == VXLAN_UNSET_PORT)
return false;
const int port = g_vxlan_ports[i];
if (port == (const int)sp || port == (const int)dp)
/* RFC 7348: VXLAN identification is based on destination port only */
if (g_vxlan_ports[i] == (const int)dp)
return true;
}
}

@ -28,6 +28,6 @@
void DecodeVXLANRegisterTests(void);
void DecodeVXLANConfig(void);
bool DecodeVXLANEnabledForPort(const uint16_t sp, const uint16_t dp);
bool DecodeVXLANEnabledForPort(const uint16_t dp);
#endif /* !SURICATA_DECODE_VXLAN_H */

Loading…
Cancel
Save