]> git.ipfire.org Git - people/ms/rstp.git/commitdiff
Track and cache bridge and port MAC addresses.
authorSrinivas Aji <Aji_Srinivas@emc.com>
Mon, 28 May 2007 18:30:40 +0000 (00:00 +0530)
committerSrinivas Aji <Aji_Srinivas@emc.com>
Wed, 27 Feb 2008 18:03:50 +0000 (23:33 +0530)
   Check for MAC address change when we get notifications.
   If we get a port notification and find that the port MAC address
   changed, we check if the bridge MAC address changed as well.
   This will be useful for modifying RSTPLIB to allow setting bridge
   address instead of trying to replicate the kernel bridge address
   computation.

Signed-off-by: Srinivas Aji <Aji_Srinivas@emc.com>
bridge_track.c

index e4b512d7de500c9fb11693aba96933470132c57a..9a1ed6e97e45badb3927766ebe49485049de3f13 100644 (file)
@@ -52,6 +52,7 @@ struct ifdata {
        struct ifdata *next;
        int up;
        char name[IFNAMSIZ];
+       unsigned char macaddr[6];
 
        int is_bridge;
        /* If bridge */
@@ -322,6 +323,7 @@ struct ifdata *create_if(int if_index, struct ifdata *br)
 
        /* TODO: purge use of name, due to issue with renameing */
        if_indextoname(if_index, p->name);
+       get_hwaddr(p->name, p->macaddr);
 
        if (p->is_bridge) {
                INFO("Add bridge %s", p->name);
@@ -384,6 +386,24 @@ void delete_if(struct ifdata *ifc)
        free(ifc);
 }
 
+/* New MAC address is stored in addr, which also holds the old value on entry.
+   Return nonzero if the address changed */
+static int check_mac_address(char *name, unsigned char *addr)
+{
+       unsigned char temp_addr[6];
+       if (get_hwaddr(name, temp_addr)) {
+               /* Error. Ignore the new value */
+               return 0;
+       }
+       if (memcmp(addr, temp_addr, sizeof(temp_addr)) == 0)
+               return 0;
+       else {
+               memcpy(addr, temp_addr, sizeof(temp_addr));
+               return 1;
+       }
+}
+
+
 static int stp_enabled(struct ifdata *br)
 {
        char path[40 + IFNAMSIZ];
@@ -411,6 +431,13 @@ void set_br_up(struct ifdata *br, int up)
        if (up != br->up)
                br->up = up;
        
+       if (check_mac_address(br->name, br->macaddr)) {
+               /* MAC address changed */
+               if (br->stp_up && stp_up) {
+                       /* Notify bridge address change */
+               }
+       }
+
        if (br->stp_up != stp_up) {
                if (stp_up)
                        init_bridge_stp(br);
@@ -426,6 +453,15 @@ void set_if_up(struct ifdata *ifc, int up)
        int duplex = -1;
        int notify_flags = 0;
        const int NOTIFY_UP = 1, NOTIFY_SPEED = 2, NOTIFY_DUPLEX = 4;
+
+       if (check_mac_address(ifc->name, ifc->macaddr)) {
+               /* MAC address changed */
+               if (check_mac_address(ifc->master->name, ifc->master->macaddr)
+                       && ifc->master->stp_up) {
+                       /* Notify bridge address change */
+               }
+       }
+
        if (!up) {              /* Down */
                if (ifc->up) {
                        ifc->up = up;
@@ -492,8 +528,7 @@ int bridge_notify(int br_index, int if_index, int newlink, int up)
                        return -1;
                }
                /* Bridge must be up if we get such notifications */
-               if (!br->up)
-                       set_br_up(br, 1);
+               set_br_up(br, 1);
        }
 
        struct ifdata *ifc = find_if(if_index);
@@ -532,8 +567,7 @@ int bridge_notify(int br_index, int if_index, int newlink, int up)
                        delete_if(ifc);
                        return 0;
                }
-               if (ifc->up != up)
-                       set_if_up(ifc, up);     /* And speed and duplex */
+               set_if_up(ifc, up);     /* And speed and duplex */
        } else {                /* No br_index */
                if (!newlink) {
                        /* DELLINK not from bridge means interface unregistered. */
@@ -555,7 +589,7 @@ int bridge_notify(int br_index, int if_index, int newlink, int up)
                                        }
                                }
                        }
-                       if (ifc && ifc->up != up) {
+                       if (ifc) {
                                if (ifc->is_bridge)
                                        set_br_up(ifc, up);
                                else
@@ -720,7 +754,7 @@ void /* for bridge id calculation */ STP_OUT_get_port_mac(IN int port_index,
        LOG("port index %d", port_index);
        struct ifdata *port = find_port(port_index);
        TST(port != NULL,);
-       get_hwaddr(port->name, mac);
+       memcpy(mac, port->macaddr, sizeof(port->macaddr));
 }
 
 unsigned long STP_OUT_get_port_oper_speed(IN unsigned int port_index)