mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 17:02:54 +00:00
bgpd: Mac rescan on interface up/down efficency improvements
On interface up/down, bgp stores the mac address of the interface in a bgp_mac_hash table entry and then initiates a rescan of the evpn l2vpn table. The problem with this scan is that it is looking at every item in the table when only 1 mac has changed. So every up/down event causes some major trauma in the bgp_update processing. Modify the mac scanning such that we know the mac that is changed and as such we should reprocess those entries only. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
cd4ee3395c
commit
78869ebff4
@ -133,7 +133,8 @@ static struct bgp_self_mac *bgp_mac_find_interface_name(const char *ifname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
|
static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
|
||||||
struct bgp_table *table)
|
struct bgp_table *table,
|
||||||
|
struct ethaddr *macaddr)
|
||||||
{
|
{
|
||||||
struct bgp_node *prn, *rn;
|
struct bgp_node *prn, *rn;
|
||||||
struct bgp_path_info *pi;
|
struct bgp_path_info *pi;
|
||||||
@ -146,11 +147,21 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (rn = bgp_table_top(sub); rn; rn = bgp_route_next(rn)) {
|
for (rn = bgp_table_top(sub); rn; rn = bgp_route_next(rn)) {
|
||||||
|
bool rn_affected;
|
||||||
|
struct prefix_evpn *pevpn = (struct prefix_evpn *)&rn->p;
|
||||||
struct prefix_rd prd;
|
struct prefix_rd prd;
|
||||||
uint32_t num_labels = 0;
|
uint32_t num_labels = 0;
|
||||||
mpls_label_t *label_pnt = NULL;
|
mpls_label_t *label_pnt = NULL;
|
||||||
struct bgp_route_evpn evpn;
|
struct bgp_route_evpn evpn;
|
||||||
|
|
||||||
|
if (pevpn->family == AF_EVPN &&
|
||||||
|
pevpn->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
|
||||||
|
memcmp(&rn->p.u.prefix_evpn.macip_addr.mac,
|
||||||
|
macaddr, ETH_ALEN) == 0)
|
||||||
|
rn_affected = true;
|
||||||
|
else
|
||||||
|
rn_affected = false;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
for (pi = rn->info; pi; pi = pi->next) {
|
for (pi = rn->info; pi; pi = pi->next) {
|
||||||
if (pi->peer == peer)
|
if (pi->peer == peer)
|
||||||
@ -160,6 +171,14 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
|
|||||||
if (!pi)
|
if (!pi)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the mac address is not the same then
|
||||||
|
* we don't care and since we are looking
|
||||||
|
*/
|
||||||
|
if ((memcmp(&pi->attr->rmac, macaddr, ETH_ALEN) != 0) &&
|
||||||
|
!rn_affected)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (pi->extra)
|
if (pi->extra)
|
||||||
num_labels = pi->extra->num_labels;
|
num_labels = pi->extra->num_labels;
|
||||||
if (num_labels)
|
if (num_labels)
|
||||||
@ -184,7 +203,7 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_mac_rescan_evpn_table(struct bgp *bgp)
|
static void bgp_mac_rescan_evpn_table(struct bgp *bgp, struct ethaddr *macaddr)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
@ -214,12 +233,12 @@ static void bgp_mac_rescan_evpn_table(struct bgp *bgp)
|
|||||||
if (bgp_debug_update(peer, NULL, NULL, 1))
|
if (bgp_debug_update(peer, NULL, NULL, 1))
|
||||||
zlog_debug("Processing EVPN MAC interface change on peer %s",
|
zlog_debug("Processing EVPN MAC interface change on peer %s",
|
||||||
peer->host);
|
peer->host);
|
||||||
bgp_process_mac_rescan_table(bgp, peer, table);
|
bgp_process_mac_rescan_table(bgp, peer, table, macaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_mac_rescan_all_evpn_tables(void)
|
static void bgp_mac_rescan_all_evpn_tables(struct ethaddr *macaddr)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
@ -228,11 +247,12 @@ static void bgp_mac_rescan_all_evpn_tables(void)
|
|||||||
struct bgp_table *table = bgp->rib[AFI_L2VPN][SAFI_EVPN];
|
struct bgp_table *table = bgp->rib[AFI_L2VPN][SAFI_EVPN];
|
||||||
|
|
||||||
if (table)
|
if (table)
|
||||||
bgp_mac_rescan_evpn_table(bgp);
|
bgp_mac_rescan_evpn_table(bgp, macaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname)
|
static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname,
|
||||||
|
struct ethaddr *macaddr)
|
||||||
{
|
{
|
||||||
struct listnode *node = NULL;
|
struct listnode *node = NULL;
|
||||||
char *name;
|
char *name;
|
||||||
@ -252,7 +272,7 @@ static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname)
|
|||||||
list_delete(&bsm->ifp_list);
|
list_delete(&bsm->ifp_list);
|
||||||
XFREE(MTYPE_BSM, bsm);
|
XFREE(MTYPE_BSM, bsm);
|
||||||
|
|
||||||
bgp_mac_rescan_all_evpn_tables();
|
bgp_mac_rescan_all_evpn_tables(macaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +296,8 @@ void bgp_mac_add_mac_entry(struct interface *ifp)
|
|||||||
|
|
||||||
listnode_add(bsm->ifp_list, ifname);
|
listnode_add(bsm->ifp_list, ifname);
|
||||||
if (old_bsm)
|
if (old_bsm)
|
||||||
bgp_mac_remove_ifp_internal(old_bsm, ifname);
|
bgp_mac_remove_ifp_internal(old_bsm, ifname,
|
||||||
|
&old_bsm->macaddr);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* If old mac address is the same as the new,
|
* If old mac address is the same as the new,
|
||||||
@ -286,12 +307,13 @@ void bgp_mac_add_mac_entry(struct interface *ifp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (old_bsm)
|
if (old_bsm)
|
||||||
bgp_mac_remove_ifp_internal(old_bsm, ifp->name);
|
bgp_mac_remove_ifp_internal(old_bsm, ifp->name,
|
||||||
|
&old_bsm->macaddr);
|
||||||
|
|
||||||
listnode_add(bsm->ifp_list, ifname);
|
listnode_add(bsm->ifp_list, ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_mac_rescan_all_evpn_tables();
|
bgp_mac_rescan_all_evpn_tables(&bsm->macaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgp_mac_del_mac_entry(struct interface *ifp)
|
void bgp_mac_del_mac_entry(struct interface *ifp)
|
||||||
@ -308,7 +330,7 @@ void bgp_mac_del_mac_entry(struct interface *ifp)
|
|||||||
* Write code to allow old mac address to no-longer
|
* Write code to allow old mac address to no-longer
|
||||||
* win if we happen to have received it from a peer.
|
* win if we happen to have received it from a peer.
|
||||||
*/
|
*/
|
||||||
bgp_mac_remove_ifp_internal(bsm, ifp->name);
|
bgp_mac_remove_ifp_internal(bsm, ifp->name, &bsm->macaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This API checks MAC address against any of local
|
/* This API checks MAC address against any of local
|
||||||
|
Loading…
Reference in New Issue
Block a user