diff options
| author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-05-08 19:11:13 -0700 |
|---|---|---|
| committer | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-10-27 09:34:09 -0700 |
| commit | c36e442c4b2ab64dd060e81a48578e6bdabb90d3 (patch) | |
| tree | c23191eb17e3bd3df69d5570966674a918b11a1f /zebra/zebra_l2.c | |
| parent | dd511712271ae352b25288ecab318f885ade00d6 (diff) | |
zebra: uplink tracking and startup delay for EVPN-MH
Local ethernet segments are held in a protodown or error-disabled state
if access to the VxLAN overlay is not ready -
1. When FRR comes up the local-ESs/access-port are kept protodown
for the startup-delay duration. During this time the underlay and
EVPN routes via it are expected to converge.
2. When all the uplinks/core-links attached to the underlay go down
the access-ports are similarly protodowned.
The ES-bond protodown state is propagated to each ES-bond member
and programmed in the dataplane/kernel (per-bond-member).
Configuring uplinks -
vtysh -c "conf t" vtysh -c "interface swp4" vtysh -c "evpn mh uplink"
Configuring startup delay -
vtysh -c "conf t" vtysh -c "evpn mh startup-delay 100"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
EVPN protodown display -
========================
root@torm-11:mgmt:~# vtysh -c "show evpn"
L2 VNIs: 10
L3 VNIs: 3
Advertise gateway mac-ip: No
Advertise svi mac-ip: No
Duplicate address detection: Disable
Detection max-moves 5, time 180
EVPN MH:
mac-holdtime: 60s, neigh-holdtime: 60s
startup-delay: 180s, start-delay-timer: 00:01:14 <<<<<<<<<<<<
uplink-cfg-cnt: 4, uplink-active-cnt: 4
protodown: startup-delay <<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ES-bond protodown display -
===========================
root@torm-11:mgmt:~# vtysh -c "show interface hostbond1"
Interface hostbond1 is up, line protocol is down
Link ups: 0 last: (never)
Link downs: 1 last: 2020/04/26 20:38:03.53
PTM status: disabled
vrf: default
OS Description: Local Node/s torm-11 and Ports swp5 <==> Remote Node/s hostd-11 and Ports swp1
index 58 metric 0 mtu 9152 speed 4294967295
flags: <UP,BROADCAST,MULTICAST>
Type: Ethernet
HWaddr: 00:02:00:00:00:35
Interface Type bond
Master interface: bridge
EVPN-MH: ES id 1 ES sysmac 00:00:00:00:01:11
protodown: off rc: startup-delay <<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ES-bond member protodown display -
==================================
root@torm-11:mgmt:~# vtysh -c "show interface swp5"
Interface swp5 is up, line protocol is down
Link ups: 0 last: (never)
Link downs: 3 last: 2020/04/26 20:38:03.52
PTM status: disabled
vrf: default
index 7 metric 0 mtu 9152 speed 10000
flags: <UP,BROADCAST,MULTICAST>
Type: Ethernet
HWaddr: 00:02:00:00:00:35
Interface Type Other
Master interface: hostbond1
protodown: on rc: startup-delay <<<<<<<<<<<<<<<<
root@torm-11:mgmt:~#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Diffstat (limited to 'zebra/zebra_l2.c')
| -rw-r--r-- | zebra/zebra_l2.c | 102 |
1 files changed, 89 insertions, 13 deletions
diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 19d8bfd733..c1ad91c8ca 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -41,6 +41,7 @@ #include "zebra/zebra_memory.h" #include "zebra/zebra_vrf.h" #include "zebra/rt_netlink.h" +#include "zebra/interface.h" #include "zebra/zebra_l2.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_evpn_mh.h" @@ -109,24 +110,99 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave) br_slave->br_if = NULL; } -void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, - vrf_id_t vrf_id) +void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id) { struct interface *bond_if; + struct zebra_if *bond_zif; + struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info; - /* TODO: Handle change of master */ bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex); - if (bond_if) - bond_slave->bond_if = bond_if; - else - bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex, - vrf_id); + if (bond_if == bond_slave->bond_if) + return; + + /* unlink the slave from the old master */ + zebra_l2_unmap_slave_from_bond(zif); + + /* If the bond is present and ready link the bond-member + * to it + */ + if (bond_if && (bond_zif = bond_if->info)) { + if (bond_zif->bond_info.mbr_zifs) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s linked to %s", + zif->ifp->name, bond_if->name); + bond_slave->bond_if = bond_if; + /* link the slave to the new bond master */ + listnode_add(bond_zif->bond_info.mbr_zifs, zif); + /* inherit protodown flags from the es-bond */ + if (zebra_evpn_is_es_bond(bond_if)) + zebra_evpn_mh_update_protodown_bond_mbr( + zif, false /*clear*/, __func__); + } + } else { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s link to bond skipped", + zif->ifp->name); + } +} + +void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif) +{ + struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info; + struct zebra_if *bond_zif; + + if (!bond_slave->bond_if) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s unlink from bond skipped", + zif->ifp->name); + return; + } + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond mbr %s un-linked from %s", zif->ifp->name, + bond_slave->bond_if->name); + + /* unlink the slave from the bond master */ + bond_zif = bond_slave->bond_if->info; + /* clear protodown flags */ + if (zebra_evpn_is_es_bond(bond_zif->ifp)) + zebra_evpn_mh_update_protodown_bond_mbr(zif, true /*clear*/, + __func__); + listnode_delete(bond_zif->bond_info.mbr_zifs, zif); + bond_slave->bond_if = NULL; } -void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave) +void zebra_l2if_update_bond(struct interface *ifp, bool add) { - if (bond_slave != NULL) - bond_slave->bond_if = NULL; + struct zebra_if *zif; + struct zebra_l2info_bond *bond; + + zif = ifp->info; + assert(zif); + bond = &zif->bond_info; + + if (add) { + if (!bond->mbr_zifs) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond %s mbr list create", + ifp->name); + bond->mbr_zifs = list_new(); + } + } else { + struct listnode *node; + struct listnode *nnode; + struct zebra_if *bond_mbr; + + if (!bond->mbr_zifs) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bond %s mbr list delete", ifp->name); + for (ALL_LIST_ELEMENTS(bond->mbr_zifs, node, nnode, bond_mbr)) + zebra_l2_unmap_slave_from_bond(bond_mbr); + + list_delete(&bond->mbr_zifs); + } } /* @@ -318,9 +394,9 @@ void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex) /* Set up or remove link with master */ if (bond_ifindex != IFINDEX_INTERNAL) - zebra_l2_map_slave_to_bond(&zif->bondslave_info, ifp->vrf_id); + zebra_l2_map_slave_to_bond(zif, ifp->vrf_id); else if (old_bond_ifindex != IFINDEX_INTERNAL) - zebra_l2_unmap_slave_from_bond(&zif->bondslave_info); + zebra_l2_unmap_slave_from_bond(zif); } void zebra_vlan_bitmap_compute(struct interface *ifp, |
