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


Reply via email to