This patch appends the VID to the ethernet address in mroute_addr. By including the VID in mroute_addr, the routing space is divided by VLAN. This means: - duplicate MAC addresses on different VLANs no longer conflict and - all unicast-traffic is constrained to whatever VLAN the traffic came from (i.e. cross-VLAN unicast routing is no longer possible).
(This patch doesn't take care of broadcast traffic. Broadcast traffic across VLANs is still be possible at this point.) --- mroute.c | 10 +++++++--- mroute.h | 8 +++++--- multi.c | 15 +++++++++++---- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/mroute.c b/mroute.c index 9d8fa66..1040b8f 100644 --- a/mroute.c +++ b/mroute.c @@ -169,7 +169,8 @@ mroute_extract_addr_ether (struct mroute_addr *src, struct mroute_addr *dest, struct mroute_addr *esrc, struct mroute_addr *edest, - const struct buffer *buf) + const struct buffer *buf, + int16_t vid) { unsigned int ret = 0; if (BLEN (buf) >= (int) sizeof (struct openvpn_ethhdr)) @@ -179,15 +180,17 @@ mroute_extract_addr_ether (struct mroute_addr *src, { src->type = MR_ADDR_ETHER; src->netbits = 0; - src->len = 6; + src->len = 8; memcpy (src->addr, eth->source, 6); + memcpy (src->addr + 6, &vid, 2); } if (dest) { dest->type = MR_ADDR_ETHER; dest->netbits = 0; - dest->len = 6; + dest->len = 8; memcpy (dest->addr, eth->dest, 6); + memcpy (dest->addr + 6, &vid, 2); /* ethernet broadcast/multicast packet? */ if (is_mac_mcast_addr (eth->dest)) @@ -303,6 +306,7 @@ mroute_addr_print_ex (const struct mroute_addr *ma, { case MR_ADDR_ETHER: buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc)); + buf_printf (&out, "@%d", *(int16_t*)(ma->addr + 6)); break; case MR_ADDR_IPV4: { diff --git a/mroute.h b/mroute.h index 9b9087d..ccf79ec 100644 --- a/mroute.h +++ b/mroute.h @@ -139,7 +139,8 @@ mroute_extract_addr_from_packet (struct mroute_addr *src, struct mroute_addr *esrc, struct mroute_addr *edest, const struct buffer *buf, - int tunnel_type) + int tunnel_type, + int16_t bcast_domain) { unsigned int mroute_extract_addr_ipv4 (struct mroute_addr *src, struct mroute_addr *dest, @@ -149,13 +150,14 @@ mroute_extract_addr_from_packet (struct mroute_addr *src, struct mroute_addr *dest, struct mroute_addr *esrc, struct mroute_addr *edest, - const struct buffer *buf); + const struct buffer *buf, + int16_t vid); unsigned int ret = 0; verify_align_4 (buf); if (tunnel_type == DEV_TYPE_TUN) ret = mroute_extract_addr_ipv4 (src, dest, buf); else if (tunnel_type == DEV_TYPE_TAP) - ret = mroute_extract_addr_ether (src, dest, esrc, edest, buf); + ret = mroute_extract_addr_ether (src, dest, esrc, edest, buf, bcast_domain); return ret; } diff --git a/multi.c b/multi.c index c2563a0..96644e5 100644 --- a/multi.c +++ b/multi.c @@ -1975,7 +1975,8 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins NULL, NULL, &c->c2.to_tun, - DEV_TYPE_TUN); + DEV_TYPE_TUN, + 0); /* drop packet if extract failed */ if (!(mroute_flags & MROUTE_EXTRACT_SUCCEEDED)) @@ -2033,10 +2034,13 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins } else if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TAP) { + int16_t vid = 0; #ifdef ENABLE_PF struct mroute_addr edest; mroute_addr_reset (&edest); #endif + if (m->top.options.vlan_tagging) + vid = c->options.vlan_tag; /* extract packet source and dest addresses */ mroute_flags = mroute_extract_addr_from_packet (&src, &dest, @@ -2047,7 +2051,8 @@ multi_process_incoming_link (struct multi_context *m, struct multi_instance *ins NULL, #endif &c->c2.to_tun, - DEV_TYPE_TAP); + DEV_TYPE_TAP, + vid); if (mroute_flags & MROUTE_EXTRACT_SUCCEEDED) { @@ -2198,6 +2203,7 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag unsigned int mroute_flags; struct mroute_addr src, dest; const int dev_type = TUNNEL_TYPE (m->top.c1.tuntap); + int16_t vid = 0; #ifdef ENABLE_PF struct mroute_addr esrc, *e1, *e2; @@ -2227,7 +2233,7 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag if (dev_type == DEV_TYPE_TAP && m->top.options.vlan_tagging) { - if (remove_vlan_identifier (&m->top.c2.buf) == -1) + if ((vid = remove_vlan_identifier (&m->top.c2.buf)) == -1) return false; } @@ -2240,7 +2246,8 @@ multi_process_incoming_tun (struct multi_context *m, const unsigned int mpp_flag #endif NULL, &m->top.c2.buf, - dev_type); + dev_type, + vid); if (mroute_flags & MROUTE_EXTRACT_SUCCEEDED) { -- 1.7.0