Skip to content

Commit

Permalink
bgpd: Add code to track the addition/removal of mac addresses
Browse files Browse the repository at this point in the history
When a mac address is added/changed/deleted track it.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
  • Loading branch information
donaldsharp committed Dec 12, 2018
1 parent 48ecf8f commit 6a69ac5
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
132 changes: 132 additions & 0 deletions bgpd/bgp_mac.c
Expand Up @@ -32,6 +32,7 @@
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"


DEFINE_MTYPE_STATIC(BGPD, BSM, "Mac Hash Entry"); DEFINE_MTYPE_STATIC(BGPD, BSM, "Mac Hash Entry");
DEFINE_MTYPE_STATIC(BGPD, BSM_STRING, "Mac Hash Entry Interface String");


struct bgp_self_mac { struct bgp_self_mac {
struct ethaddr macaddr; struct ethaddr macaddr;
Expand Down Expand Up @@ -76,6 +77,137 @@ void bgp_mac_finish(void)
hash_free(bm->self_mac_hash); hash_free(bm->self_mac_hash);
} }


static void bgp_mac_hash_interface_string_del(void *val)
{
char *data = val;

XFREE(MTYPE_BSM_STRING, data);
}

static void *bgp_mac_hash_alloc(void *p)
{
const struct bgp_self_mac *orig = p;
struct bgp_self_mac *bsm;

bsm = XCALLOC(MTYPE_BSM, sizeof(struct bgp_self_mac));
memcpy(&bsm->macaddr, &orig->macaddr, ETH_ALEN);

bsm->ifp_list = list_new();
bsm->ifp_list->del = bgp_mac_hash_interface_string_del;

return bsm;
}

struct bgp_mac_find_internal {
struct bgp_self_mac *bsm;
const char *ifname;
};

static void bgp_mac_find_ifp_internal(struct hash_backet *backet, void *arg)
{
struct bgp_mac_find_internal *bmfi = arg;
struct bgp_self_mac *bsm = backet->data;
struct listnode *node;
char *name;

for (ALL_LIST_ELEMENTS_RO(bsm->ifp_list, node, name)) {
if (strcmp(name, bmfi->ifname) == 0) {
bmfi->bsm = bsm;
return;
}
}
}

static struct bgp_self_mac *bgp_mac_find_interface_name(const char *ifname)
{
struct bgp_mac_find_internal bmfi;

bmfi.bsm = NULL;
bmfi.ifname = ifname;
hash_iterate(bm->self_mac_hash, bgp_mac_find_ifp_internal, &bmfi);

return bmfi.bsm;
}

static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname)
{
struct listnode *node;
char *name;

for (ALL_LIST_ELEMENTS_RO(bsm->ifp_list, node, name)) {
if (strcmp(name, ifname) == 0)
break;
}

if (node) {
list_delete_node(bsm->ifp_list, node);
XFREE(MTYPE_BSM_STRING, name);
}

if (bsm->ifp_list->count == 0) {
hash_release(bm->self_mac_hash, bsm);
list_delete(&bsm->ifp_list);
XFREE(MTYPE_BSM, bsm);

/* Code to rescan tables */
}
}

void bgp_mac_add_mac_entry(struct interface *ifp)
{
struct bgp_self_mac lookup;
struct bgp_self_mac *bsm;
struct bgp_self_mac *old_bsm;
char *ifname;

memcpy(&lookup.macaddr, &ifp->hw_addr, ETH_ALEN);
bsm = hash_get(bm->self_mac_hash, &lookup, bgp_mac_hash_alloc);

/*
* Does this happen to be a move
*/
old_bsm = bgp_mac_find_interface_name(ifp->name);
ifname = XSTRDUP(MTYPE_BSM_STRING, ifp->name);

if (bsm->ifp_list->count == 0) {

listnode_add(bsm->ifp_list, ifname);
if (old_bsm)
bgp_mac_remove_ifp_internal(old_bsm, ifname);
} else {
/*
* If old mac address is the same as the new,
* then there is nothing to do here
*/
if (old_bsm == bsm)
return;

if (old_bsm)
bgp_mac_remove_ifp_internal(old_bsm, ifp->name);

listnode_add(bsm->ifp_list, ifname);
}

/* Code to rescan */
}

void bgp_mac_del_mac_entry(struct interface *ifp)
{
struct bgp_self_mac lookup;
struct bgp_self_mac *bsm;

memcpy(&lookup.macaddr, &ifp->hw_addr, ETH_ALEN);
bsm = hash_lookup(bm->self_mac_hash, &lookup);
if (!bsm)
return;

/*
* Write code to allow old mac address to no-longer
* win if we happen to have received it from a peer.
*/
bgp_mac_remove_ifp_internal(bsm, ifp->name);
}

static void bgp_mac_show_mac_entry(struct hash_backet *backet, void *arg) static void bgp_mac_show_mac_entry(struct hash_backet *backet, void *arg)
{ {
struct vty *vty = arg; struct vty *vty = arg;
Expand Down
8 changes: 8 additions & 0 deletions bgpd/bgp_mac.h
Expand Up @@ -23,5 +23,13 @@
void bgp_mac_init(void); void bgp_mac_init(void);
void bgp_mac_finish(void); void bgp_mac_finish(void);


/*
* Functions to add/delete the mac entry from the appropriate
* bgp hash's. Additionally to do some additional processing
* to allow the win/loss to be processed.
*/
void bgp_mac_add_mac_entry(struct interface *ifp);
void bgp_mac_del_mac_entry(struct interface *ifp);

void bgp_mac_dump_table(struct vty *vty); void bgp_mac_dump_table(struct vty *vty);
#endif #endif
9 changes: 9 additions & 0 deletions bgpd/bgp_zebra.c
Expand Up @@ -59,6 +59,7 @@
#include "bgpd/bgp_labelpool.h" #include "bgpd/bgp_labelpool.h"
#include "bgpd/bgp_pbr.h" #include "bgpd/bgp_pbr.h"
#include "bgpd/bgp_evpn_private.h" #include "bgpd/bgp_evpn_private.h"
#include "bgpd/bgp_mac.h"


/* All information about zebra. */ /* All information about zebra. */
struct zclient *zclient = NULL; struct zclient *zclient = NULL;
Expand Down Expand Up @@ -221,6 +222,8 @@ static int bgp_interface_add(int command, struct zclient *zclient,
if (!bgp) if (!bgp)
return 0; return 0;


bgp_mac_add_mac_entry(ifp);

bgp_update_interface_nbrs(bgp, ifp, ifp); bgp_update_interface_nbrs(bgp, ifp, ifp);
return 0; return 0;
} }
Expand All @@ -245,6 +248,8 @@ static int bgp_interface_delete(int command, struct zclient *zclient,
if (bgp) if (bgp)
bgp_update_interface_nbrs(bgp, ifp, NULL); bgp_update_interface_nbrs(bgp, ifp, NULL);


bgp_mac_del_mac_entry(ifp);

if_set_index(ifp, IFINDEX_INTERNAL); if_set_index(ifp, IFINDEX_INTERNAL);
return 0; return 0;
} }
Expand All @@ -267,6 +272,8 @@ static int bgp_interface_up(int command, struct zclient *zclient,
if (!ifp) if (!ifp)
return 0; return 0;


bgp_mac_add_mac_entry(ifp);

if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name); zlog_debug("Rx Intf up VRF %u IF %s", vrf_id, ifp->name);


Expand Down Expand Up @@ -300,6 +307,8 @@ static int bgp_interface_down(int command, struct zclient *zclient,
if (!ifp) if (!ifp)
return 0; return 0;


bgp_mac_del_mac_entry(ifp);

if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name); zlog_debug("Rx Intf down VRF %u IF %s", vrf_id, ifp->name);


Expand Down

0 comments on commit 6a69ac5

Please sign in to comment.