From 017b118568d5c033520128a776ad9b810cddccfd Mon Sep 17 00:00:00 2001 From: Srinivas Aji Date: Tue, 29 May 2007 00:00:40 +0530 Subject: [PATCH] Track and cache bridge and port MAC addresses. 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 --- bridge_track.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/bridge_track.c b/bridge_track.c index e4b512d..9a1ed6e 100644 --- a/bridge_track.c +++ b/bridge_track.c @@ -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) -- 2.39.2