2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2020-03-28 01:14:45 +01:00
|
|
|
/*
|
|
|
|
* Zebra EVPN MH Data structures and definitions
|
|
|
|
*
|
|
|
|
* Copyright (C) 2019 Cumulus Networks, Inc.
|
|
|
|
* Anuradha Karuppiah
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _ZEBRA_EVPN_MH_H
|
|
|
|
#define _ZEBRA_EVPN_MH_H
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "if.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "bitfield.h"
|
|
|
|
#include "zebra_vxlan.h"
|
|
|
|
#include "zebra_vxlan_private.h"
|
2020-05-15 02:00:10 +02:00
|
|
|
#include "zebra_nhg.h"
|
2024-01-24 15:50:26 +01:00
|
|
|
#include "zebra_nb.h"
|
2020-03-28 01:14:45 +01:00
|
|
|
|
|
|
|
/* Ethernet Segment entry -
|
|
|
|
* - Local and remote ESs are maintained in a global RB tree,
|
|
|
|
* zmh_info->es_rb_tree using ESI as key
|
|
|
|
* - Local ESs are added via zebra config (ZEBRA_EVPNES_LOCAL) when an
|
|
|
|
* access port is associated with an ES-ID
|
|
|
|
* - Remotes ESs are added by BGP based on received/remote EAD/Type-1 routes
|
|
|
|
* (ZEBRA_EVPNES_REMOTE)
|
2022-05-12 03:25:47 +02:00
|
|
|
* - An ES can be simultaneously LOCAL and REMOTE; infact all LOCAL ESs are
|
2020-03-28 01:14:45 +01:00
|
|
|
* expected to have REMOTE ES peers.
|
|
|
|
*/
|
|
|
|
struct zebra_evpn_es {
|
|
|
|
esi_t esi;
|
|
|
|
char esi_str[ESI_STR_LEN];
|
|
|
|
|
|
|
|
/* ES flags */
|
|
|
|
uint32_t flags;
|
|
|
|
#define ZEBRA_EVPNES_LOCAL (1 << 0) /* configured in zebra */
|
|
|
|
#define ZEBRA_EVPNES_REMOTE (1 << 1) /* added by bgp */
|
|
|
|
#define ZEBRA_EVPNES_OPER_UP (1 << 2) /* es->ifp is oper-up */
|
|
|
|
#define ZEBRA_EVPNES_READY_FOR_BGP (1 << 3) /* ready to be sent to BGP */
|
|
|
|
#define ZEBRA_EVPNES_NHG_ACTIVE (1 << 4) /* NHG has been installed */
|
2020-05-09 01:41:43 +02:00
|
|
|
/* This flag is only applicable to local ESs and signifies that this
|
|
|
|
* VTEP is not the DF
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPNES_NON_DF (1 << 5)
|
2020-04-14 00:56:03 +02:00
|
|
|
/* When the ES becomes a bridge port we need to activate the BUM non-DF
|
|
|
|
* filter, SPH filter and backup NHG for fast-failover
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPNES_BR_PORT (1 << 6)
|
2020-08-05 16:13:55 +02:00
|
|
|
/* ES is in bypass mode i.e. must not be advertised. ES-bypass is set
|
|
|
|
* when the associated host bond goes into LACP bypass
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPNES_BYPASS (1 << 7)
|
2020-03-28 01:14:45 +01:00
|
|
|
|
|
|
|
/* memory used for adding the es to zmh_info->es_rb_tree */
|
|
|
|
RB_ENTRY(zebra_evpn_es) rb_node;
|
|
|
|
|
|
|
|
/* [EVPNES_LOCAL] memory used for linking the es to
|
|
|
|
* zmh_info->local_es_list
|
|
|
|
*/
|
|
|
|
struct listnode local_es_listnode;
|
|
|
|
|
|
|
|
/* [EVPNES_LOCAL] corresponding interface */
|
|
|
|
struct zebra_if *zif;
|
|
|
|
|
|
|
|
/* list of ES-EVIs associated with the ES */
|
|
|
|
struct list *es_evi_list;
|
|
|
|
|
|
|
|
/* [!EVPNES_LOCAL] List of remote VTEPs (zebra_evpn_es_vtep) */
|
|
|
|
struct list *es_vtep_list;
|
|
|
|
|
2020-03-29 17:43:55 +02:00
|
|
|
/* list of zebra_mac entries using this ES as destination */
|
|
|
|
struct list *mac_list;
|
2020-03-28 01:14:45 +01:00
|
|
|
|
|
|
|
/* Nexthop group id */
|
|
|
|
uint32_t nhg_id;
|
2020-05-09 01:41:43 +02:00
|
|
|
|
|
|
|
/* Preference config for BUM-DF election. Sent to BGP and
|
|
|
|
* advertised via the ESR
|
|
|
|
*/
|
|
|
|
uint16_t df_pref;
|
2020-06-14 21:13:23 +02:00
|
|
|
|
|
|
|
/* When a new ES is configured it is held in a non-DF state
|
|
|
|
* for 3 seconds. This allows the peer Type-4 routes to be
|
|
|
|
* imported before running the DF election.
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPN_MH_DF_DELAY_TIME 3 /* seconds */
|
2022-03-01 22:18:12 +01:00
|
|
|
struct event *df_delay_timer;
|
2020-03-28 01:14:45 +01:00
|
|
|
};
|
|
|
|
RB_HEAD(zebra_es_rb_head, zebra_evpn_es);
|
|
|
|
RB_PROTOTYPE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp);
|
|
|
|
|
|
|
|
/* ES per-EVI info
|
2020-07-23 23:51:10 +02:00
|
|
|
* - ES-EVIs are maintained per-EVPN (vni->es_evi_rb_tree)
|
|
|
|
* - Local ES-EVIs are linked to per-EVPN list for quick access
|
2020-03-28 01:14:45 +01:00
|
|
|
* - Although some infrastucture is present for remote ES-EVIs, currently
|
|
|
|
* BGP does NOT send remote ES-EVIs to zebra. This may change in the
|
|
|
|
* future (but must be changed thoughtfully and only if needed as ES-EVI
|
|
|
|
* can get prolific and come in the way of rapid failovers)
|
|
|
|
*/
|
|
|
|
struct zebra_evpn_es_evi {
|
|
|
|
struct zebra_evpn_es *es;
|
2021-08-19 22:08:53 +02:00
|
|
|
struct zebra_evpn *zevpn;
|
2020-03-28 01:14:45 +01:00
|
|
|
|
|
|
|
/* ES-EVI flags */
|
|
|
|
uint32_t flags;
|
|
|
|
/* local ES-EVI */
|
|
|
|
#define ZEBRA_EVPNES_EVI_LOCAL (1 << 0) /* created by zebra */
|
|
|
|
#define ZEBRA_EVPNES_EVI_READY_FOR_BGP (1 << 1) /* ready to be sent to BGP */
|
|
|
|
|
|
|
|
/* memory used for adding the es_evi to
|
2020-07-23 23:51:10 +02:00
|
|
|
* es_evi->zevpn->es_evi_rb_tree
|
2020-03-28 01:14:45 +01:00
|
|
|
*/
|
|
|
|
RB_ENTRY(zebra_evpn_es_evi) rb_node;
|
|
|
|
/* memory used for linking the es_evi to
|
2020-07-23 23:51:10 +02:00
|
|
|
* es_evi->zevpn->local_es_evi_list
|
2020-03-28 01:14:45 +01:00
|
|
|
*/
|
|
|
|
struct listnode l2vni_listnode;
|
|
|
|
/* memory used for linking the es_evi to
|
|
|
|
* es_evi->es->es_evi_list
|
|
|
|
*/
|
|
|
|
struct listnode es_listnode;
|
|
|
|
};
|
|
|
|
|
2020-05-27 03:42:00 +02:00
|
|
|
/* A single L2 nexthop is allocated across all ESs with the same PE/VTEP
|
|
|
|
* nexthop
|
|
|
|
*/
|
|
|
|
struct zebra_evpn_l2_nh {
|
|
|
|
struct in_addr vtep_ip;
|
|
|
|
|
|
|
|
/* MAC nexthop id */
|
|
|
|
uint32_t nh_id;
|
|
|
|
|
|
|
|
/* es_vtep entries using this nexthop */
|
|
|
|
uint32_t ref_cnt;
|
|
|
|
};
|
|
|
|
|
2020-03-28 01:14:45 +01:00
|
|
|
/* PE attached to an ES */
|
|
|
|
struct zebra_evpn_es_vtep {
|
|
|
|
struct zebra_evpn_es *es; /* parent ES */
|
|
|
|
struct in_addr vtep_ip;
|
|
|
|
|
2020-05-09 01:41:43 +02:00
|
|
|
uint32_t flags;
|
|
|
|
/* Rxed Type-4 route from this VTEP */
|
|
|
|
#define ZEBRA_EVPNES_VTEP_RXED_ESR (1 << 0)
|
2020-04-14 00:56:03 +02:00
|
|
|
#define ZEBRA_EVPNES_VTEP_DEL_IN_PROG (1 << 1)
|
2020-05-09 01:41:43 +02:00
|
|
|
|
2020-05-27 03:42:00 +02:00
|
|
|
/* MAC nexthop info */
|
|
|
|
struct zebra_evpn_l2_nh *nh;
|
|
|
|
|
2020-03-28 01:14:45 +01:00
|
|
|
/* memory used for adding the entry to es->es_vtep_list */
|
|
|
|
struct listnode es_listnode;
|
|
|
|
|
2020-05-09 01:41:43 +02:00
|
|
|
/* Parameters for DF election */
|
|
|
|
uint8_t df_alg;
|
2024-02-06 13:03:36 +01:00
|
|
|
uint16_t df_pref;
|
2020-05-09 01:41:43 +02:00
|
|
|
|
2021-08-19 22:13:39 +02:00
|
|
|
/* XXX - maintain a backpointer to struct zebra_vtep */
|
2020-03-28 01:14:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Local/access-side broadcast domain - zebra_evpn_access_bd is added to -
|
|
|
|
* zrouter->evpn_vlan_table (for VLAN aware bridges) OR
|
|
|
|
* zrouter->evpn_bridge_table (for VLAN unaware bridges)
|
|
|
|
* XXX - support for VLAN unaware bridges is yet to be flushed out
|
|
|
|
*/
|
|
|
|
struct zebra_evpn_access_bd {
|
|
|
|
vlanid_t vid;
|
|
|
|
|
2021-07-27 10:58:59 +02:00
|
|
|
ifindex_t bridge_ifindex;
|
|
|
|
struct zebra_if *bridge_zif; /* associated bridge */
|
|
|
|
|
2021-07-27 09:44:15 +02:00
|
|
|
vni_t vni; /* vni associated with the vxlan device */
|
2020-03-28 01:14:45 +01:00
|
|
|
struct zebra_if *vxlan_zif; /* vxlan device */
|
|
|
|
/* list of members associated with the BD i.e. (potential) ESs */
|
|
|
|
struct list *mbr_zifs;
|
2020-07-23 23:51:10 +02:00
|
|
|
/* presence of zevpn activates the EVI on all the ESs in mbr_zifs */
|
2021-08-19 22:08:53 +02:00
|
|
|
struct zebra_evpn *zevpn;
|
2020-11-02 19:53:50 +01:00
|
|
|
/* SVI associated with the VLAN */
|
|
|
|
struct zebra_if *vlan_zif;
|
2020-03-28 01:14:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* multihoming information stored in zrouter */
|
|
|
|
#define zmh_info (zrouter.mh_info)
|
|
|
|
struct zebra_evpn_mh_info {
|
2020-05-11 03:02:37 +02:00
|
|
|
uint32_t flags;
|
2020-05-09 03:47:52 +02:00
|
|
|
/* If the dataplane is not capable of handling a backup NHG on an access
|
|
|
|
* port we will need to explicitly failover each MAC entry on
|
|
|
|
* local ES down
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPN_MH_REDIRECT_OFF (1 << 0)
|
2020-05-11 03:02:37 +02:00
|
|
|
/* DAD support for EVPN-MH is yet to be added. So on detection of
|
|
|
|
* first local ES, DAD is turned off
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF (1 << 1)
|
2020-07-07 03:01:41 +02:00
|
|
|
/* If EVPN MH is enabled we only advertise REACHABLE neigh entries as Type-2
|
|
|
|
* routes. As there is no global config knob for enabling EVPN MH we turn
|
|
|
|
* this flag when the first local ES is detected.
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPN_MH_ADV_REACHABLE_NEIGH_ONLY (1 << 2)
|
2020-11-02 19:53:50 +01:00
|
|
|
/* If EVPN MH is enabled we advertise the SVI MAC address to avoid
|
|
|
|
* flooding of ARP replies rxed from the multi-homed host
|
|
|
|
*/
|
|
|
|
#define ZEBRA_EVPN_MH_ADV_SVI_MAC (1 << 3)
|
2020-05-11 03:02:37 +02:00
|
|
|
|
2020-03-28 01:14:45 +01:00
|
|
|
/* RB tree of Ethernet segments (used for EVPN-MH) */
|
|
|
|
struct zebra_es_rb_head es_rb_tree;
|
|
|
|
/* List of local ESs */
|
|
|
|
struct list *local_es_list;
|
|
|
|
|
|
|
|
/* EVPN MH broadcast domains indexed by the VID */
|
|
|
|
struct hash *evpn_vlan_table;
|
|
|
|
|
|
|
|
/* A base L2-VNI is maintained to derive parameters such as
|
|
|
|
* ES originator-IP.
|
|
|
|
* XXX: once single vxlan device model becomes available this will
|
|
|
|
* not be necessary
|
|
|
|
*/
|
2021-08-19 22:08:53 +02:00
|
|
|
struct zebra_evpn *es_base_evpn;
|
2020-03-28 01:14:45 +01:00
|
|
|
struct in_addr es_originator_ip;
|
|
|
|
|
|
|
|
/* L2 NH and NHG ids -
|
2020-05-15 02:00:10 +02:00
|
|
|
* Most significant 4 bits is type. Lower 28 bits is the value
|
2020-03-28 01:14:45 +01:00
|
|
|
* allocated from the nh_id_bitmap.
|
|
|
|
*/
|
|
|
|
bitfield_t nh_id_bitmap;
|
|
|
|
#define EVPN_NH_ID_MAX (16*1024)
|
|
|
|
#define EVPN_NH_ID_VAL_MASK 0xffffff
|
|
|
|
/* The purpose of using different types for NHG and NH is NOT to manage the
|
|
|
|
* id space separately. It is simply to make debugging easier.
|
|
|
|
*/
|
2020-05-15 02:00:10 +02:00
|
|
|
#define EVPN_NH_ID_TYPE_BIT (NHG_TYPE_L2_NH << NHG_ID_TYPE_POS)
|
|
|
|
#define EVPN_NHG_ID_TYPE_BIT (NHG_TYPE_L2 << NHG_ID_TYPE_POS)
|
2020-05-09 03:47:52 +02:00
|
|
|
/* L2-NHG table - key: nhg_id, data: zebra_evpn_es */
|
|
|
|
struct hash *nhg_table;
|
2020-05-27 03:42:00 +02:00
|
|
|
/* L2-NH table - key: vtep_up, data: zebra_evpn_nh */
|
|
|
|
struct hash *nh_ip_table;
|
2020-03-29 17:43:55 +02:00
|
|
|
|
|
|
|
/* XXX - re-visit the default hold timer value */
|
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>
2020-05-09 04:11:13 +02:00
|
|
|
int mac_hold_time;
|
|
|
|
#define ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF (18 * 60)
|
|
|
|
int neigh_hold_time;
|
|
|
|
#define ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF (18 * 60)
|
|
|
|
|
|
|
|
/* During this period access ports will be held in a protodown
|
|
|
|
* state
|
|
|
|
*/
|
|
|
|
int startup_delay_time; /* seconds */
|
|
|
|
#define ZEBRA_EVPN_MH_STARTUP_DELAY_DEF (3 * 60)
|
2022-03-01 22:18:12 +01:00
|
|
|
struct event *startup_delay_timer;
|
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>
2020-05-09 04:11:13 +02:00
|
|
|
|
|
|
|
/* Number of configured uplinks */
|
|
|
|
uint32_t uplink_cfg_cnt;
|
|
|
|
/* Number of operationally-up uplinks */
|
|
|
|
uint32_t uplink_oper_up_cnt;
|
|
|
|
|
|
|
|
/* These protodown bits are inherited by all ES bonds */
|
2022-01-26 06:07:57 +01:00
|
|
|
uint32_t protodown_rc;
|
2020-03-28 01:14:45 +01:00
|
|
|
};
|
|
|
|
|
2021-02-18 03:36:56 +01:00
|
|
|
/* returns TRUE if the EVPN is ready to be sent to BGP */
|
2021-08-19 22:08:53 +02:00
|
|
|
static inline bool zebra_evpn_send_to_client_ok(struct zebra_evpn *zevpn)
|
2021-02-18 03:36:56 +01:00
|
|
|
{
|
|
|
|
return !!(zevpn->flags & ZEVPN_READY_FOR_BGP);
|
|
|
|
}
|
|
|
|
|
2021-08-19 22:33:53 +02:00
|
|
|
static inline bool zebra_evpn_mac_is_es_local(struct zebra_mac *mac)
|
2020-03-28 01:14:45 +01:00
|
|
|
{
|
|
|
|
return mac->es && (mac->es->flags & ZEBRA_EVPNES_LOCAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns true if the id is of L2-NHG or L2-NH type */
|
|
|
|
static inline bool zebra_evpn_mh_is_fdb_nh(uint32_t id)
|
|
|
|
{
|
|
|
|
return ((id & EVPN_NHG_ID_TYPE_BIT) ||
|
|
|
|
(id & EVPN_NH_ID_TYPE_BIT));
|
|
|
|
}
|
|
|
|
|
2020-05-09 03:47:52 +02:00
|
|
|
static inline bool
|
|
|
|
zebra_evpn_es_local_mac_via_network_port(struct zebra_evpn_es *es)
|
|
|
|
{
|
|
|
|
return !(es->flags & ZEBRA_EVPNES_OPER_UP)
|
|
|
|
&& (zmh_info->flags & ZEBRA_EVPN_MH_REDIRECT_OFF);
|
|
|
|
}
|
|
|
|
|
2020-05-11 03:02:37 +02:00
|
|
|
static inline bool zebra_evpn_mh_do_dup_addr_detect(void)
|
|
|
|
{
|
|
|
|
return !(zmh_info->flags & ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF);
|
|
|
|
}
|
|
|
|
|
2020-07-07 03:01:41 +02:00
|
|
|
static inline bool zebra_evpn_mh_do_adv_reachable_neigh_only(void)
|
|
|
|
{
|
|
|
|
return !!(zmh_info->flags & ZEBRA_EVPN_MH_ADV_REACHABLE_NEIGH_ONLY);
|
|
|
|
}
|
|
|
|
|
2020-11-02 19:53:50 +01:00
|
|
|
static inline bool zebra_evpn_mh_do_adv_svi_mac(void)
|
|
|
|
{
|
|
|
|
return zmh_info && (zmh_info->flags & ZEBRA_EVPN_MH_ADV_SVI_MAC);
|
|
|
|
}
|
2020-07-07 03:01:41 +02:00
|
|
|
|
2020-03-28 01:14:45 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
extern esi_t *zero_esi;
|
|
|
|
extern void zebra_evpn_mh_init(void);
|
|
|
|
extern void zebra_evpn_mh_terminate(void);
|
|
|
|
extern bool zebra_evpn_is_if_es_capable(struct zebra_if *zif);
|
|
|
|
extern void zebra_evpn_if_init(struct zebra_if *zif);
|
|
|
|
extern void zebra_evpn_if_cleanup(struct zebra_if *zif);
|
2021-08-19 22:08:53 +02:00
|
|
|
extern void zebra_evpn_es_evi_init(struct zebra_evpn *zevpn);
|
|
|
|
extern void zebra_evpn_es_evi_cleanup(struct zebra_evpn *zevpn);
|
|
|
|
extern void zebra_evpn_vxl_evpn_set(struct zebra_if *zif,
|
|
|
|
struct zebra_evpn *zevpn, bool set);
|
|
|
|
extern void zebra_evpn_es_set_base_evpn(struct zebra_evpn *zevpn);
|
|
|
|
extern void zebra_evpn_es_clear_base_evpn(struct zebra_evpn *zevpn);
|
2021-07-27 09:44:15 +02:00
|
|
|
extern void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id,
|
|
|
|
struct zebra_if *vxlan_zif);
|
|
|
|
extern void zebra_evpn_vl_vxl_deref(uint16_t vid, vni_t vni_id,
|
|
|
|
struct zebra_if *vxlan_zif);
|
2020-03-28 01:14:45 +01:00
|
|
|
extern void zebra_evpn_vl_mbr_ref(uint16_t vid, struct zebra_if *zif);
|
|
|
|
extern void zebra_evpn_vl_mbr_deref(uint16_t vid, struct zebra_if *zif);
|
|
|
|
extern void zebra_evpn_es_send_all_to_client(bool add);
|
|
|
|
extern void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up);
|
|
|
|
extern void zebra_evpn_es_show(struct vty *vty, bool uj);
|
|
|
|
extern void zebra_evpn_es_show_detail(struct vty *vty, bool uj);
|
|
|
|
extern void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi);
|
2021-08-19 22:08:53 +02:00
|
|
|
extern void zebra_evpn_update_all_es(struct zebra_evpn *zevpn);
|
2020-03-28 01:14:45 +01:00
|
|
|
extern void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS);
|
2021-04-19 17:12:51 +02:00
|
|
|
int zebra_evpn_remote_es_add(const esi_t *esi, struct in_addr vtep_ip,
|
|
|
|
bool esr_rxed, uint8_t df_alg, uint16_t df_pref);
|
|
|
|
int zebra_evpn_remote_es_del(const esi_t *esi, struct in_addr vtep_ip);
|
2020-03-28 01:14:45 +01:00
|
|
|
extern void zebra_evpn_es_evi_show(struct vty *vty, bool uj, int detail);
|
|
|
|
extern void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj,
|
|
|
|
vni_t vni, int detail);
|
2021-08-19 22:33:53 +02:00
|
|
|
extern void zebra_evpn_es_mac_deref_entry(struct zebra_mac *mac);
|
|
|
|
extern bool zebra_evpn_es_mac_ref_entry(struct zebra_mac *mac,
|
2021-04-19 20:26:57 +02:00
|
|
|
struct zebra_evpn_es *es);
|
2021-08-19 22:33:53 +02:00
|
|
|
extern bool zebra_evpn_es_mac_ref(struct zebra_mac *mac, const esi_t *esi);
|
2021-04-19 17:12:51 +02:00
|
|
|
extern struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi);
|
2020-03-28 01:14:45 +01:00
|
|
|
extern void zebra_evpn_acc_vl_show(struct vty *vty, bool uj);
|
|
|
|
extern void zebra_evpn_acc_vl_show_detail(struct vty *vty, bool uj);
|
2021-08-02 20:38:26 +02:00
|
|
|
extern void zebra_evpn_if_es_print(struct vty *vty, json_object *json,
|
|
|
|
struct zebra_if *zif);
|
2021-07-27 10:58:59 +02:00
|
|
|
extern struct zebra_evpn_access_bd *
|
|
|
|
zebra_evpn_acc_vl_find(vlanid_t vid, struct interface *br_if);
|
2023-05-30 02:29:33 +02:00
|
|
|
struct zebra_evpn_access_bd *
|
|
|
|
zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex);
|
2021-07-27 10:58:59 +02:00
|
|
|
extern void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid,
|
|
|
|
struct interface *br_if);
|
2020-03-28 01:14:45 +01:00
|
|
|
extern void zebra_evpn_es_cleanup(void);
|
2020-03-29 17:43:55 +02:00
|
|
|
extern int zebra_evpn_mh_mac_holdtime_update(struct vty *vty,
|
|
|
|
uint32_t duration, bool set_default);
|
|
|
|
void zebra_evpn_mh_config_write(struct vty *vty);
|
|
|
|
int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty,
|
|
|
|
uint32_t duration, bool set_default);
|
2020-04-14 17:30:09 +02:00
|
|
|
void zebra_evpn_es_local_br_port_update(struct zebra_if *zif);
|
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>
2020-05-09 04:11:13 +02:00
|
|
|
extern int zebra_evpn_mh_startup_delay_update(struct vty *vty,
|
|
|
|
uint32_t duration,
|
|
|
|
bool set_default);
|
|
|
|
extern void zebra_evpn_mh_uplink_oper_update(struct zebra_if *zif);
|
|
|
|
extern void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif,
|
|
|
|
bool clear,
|
|
|
|
const char *caller);
|
|
|
|
extern bool zebra_evpn_is_es_bond(struct interface *ifp);
|
|
|
|
extern bool zebra_evpn_is_es_bond_member(struct interface *ifp);
|
|
|
|
extern void zebra_evpn_mh_print(struct vty *vty);
|
|
|
|
extern void zebra_evpn_mh_json(json_object *json);
|
2020-05-09 03:47:52 +02:00
|
|
|
extern bool zebra_evpn_nhg_is_local_es(uint32_t nhg_id,
|
|
|
|
struct zebra_evpn_es **local_es);
|
|
|
|
extern int zebra_evpn_mh_redirect_off(struct vty *vty, bool redirect_off);
|
2020-05-27 03:42:00 +02:00
|
|
|
extern void zebra_evpn_l2_nh_show(struct vty *vty, bool uj);
|
2020-11-02 19:53:50 +01:00
|
|
|
extern void zebra_evpn_acc_bd_svi_set(struct zebra_if *vlan_zif,
|
|
|
|
struct zebra_if *br_zif, bool is_up);
|
|
|
|
extern void zebra_evpn_acc_bd_svi_mac_add(struct interface *vlan_if);
|
2021-07-27 10:58:59 +02:00
|
|
|
extern void
|
|
|
|
zebra_evpn_access_bd_bridge_cleanup(vlanid_t vid, struct interface *br_if,
|
|
|
|
struct zebra_evpn_access_bd *acc_bd);
|
2020-08-05 16:13:55 +02:00
|
|
|
extern void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es,
|
|
|
|
struct interface *ifp, bool bypass);
|
2020-09-14 15:35:45 +02:00
|
|
|
extern void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS);
|
2021-08-10 23:31:34 +02:00
|
|
|
extern struct zebra_evpn_es_evi *
|
|
|
|
zebra_evpn_es_evi_find(struct zebra_evpn_es *es, struct zebra_evpn *zevpn);
|
2024-03-22 21:25:18 +01:00
|
|
|
extern int zebra_evpn_vl_vxl_bridge_lookup(uint16_t vid,
|
|
|
|
struct zebra_if *vxlan_zif);
|
2024-01-22 20:34:35 +01:00
|
|
|
void zebra_build_type3_esi(uint32_t lid, struct ethaddr *mac, esi_t *esi);
|
|
|
|
|
|
|
|
void zebra_evpn_es_sys_mac_update(struct zebra_if *zif, struct ethaddr *sysmac);
|
|
|
|
void zebra_evpn_es_lid_update(struct zebra_if *zif, uint32_t lid);
|
|
|
|
void zebra_evpn_es_type0_esi_update(struct zebra_if *zif, esi_t *esi);
|
|
|
|
|
2024-01-22 20:52:09 +01:00
|
|
|
void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref);
|
2024-01-22 21:21:04 +01:00
|
|
|
void zebra_evpn_es_bypass_cfg_update(struct zebra_if *zif, bool bypass);
|
2024-01-22 21:21:38 +01:00
|
|
|
void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set);
|
2024-01-22 20:52:09 +01:00
|
|
|
|
|
|
|
void zebra_evpn_mh_if_init(struct zebra_if *zif);
|
|
|
|
|
2020-03-28 01:14:45 +01:00
|
|
|
#endif /* _ZEBRA_EVPN_MH_H */
|