2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2017-05-15 07:31:08 +02:00
|
|
|
/*
|
|
|
|
* Zebra Layer-2 interface Data structures and definitions
|
|
|
|
* Copyright (C) 2016, 2017 Cumulus Networks, Inc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _ZEBRA_L2_H
|
|
|
|
#define _ZEBRA_L2_H
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "if.h"
|
|
|
|
#include "vlan.h"
|
|
|
|
#include "vxlan.h"
|
2021-04-18 12:11:14 +02:00
|
|
|
#include "zebra/zebra_vrf.h"
|
2017-05-15 07:31:08 +02:00
|
|
|
|
2019-03-25 15:11:55 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2021-08-17 10:42:51 +02:00
|
|
|
#define ZEBRA_BRIDGE_NO_ACTION (0)
|
|
|
|
#define ZEBRA_BRIDGE_MASTER_MAC_CHANGE (1 << 1)
|
zebra: refresh vxlan evpn contexts, when bridge interface goes up
When using bgp evpn rt5 setup, after BGP configuration has been
loaded, if the user attempts to detach and reattach the bridged
vxlan interface from the bridge, then BGP loses its BGP EVPN
contexts, and a refresh of BGP configuration is necessary to
maintain consistency between linux configuration and BGP EVPN
contexts (RIB). The following command can lead to inconsistency:
ip netns exec cust1 ip link set dev vxlan1000 nomaster
ip netns exec cust1 ip link set dev vxlan1000 master br1000
consecutive to the, BGP l2vpn evpn RIB is empty, and the way to
solve this until now is to reconfigure EVPN like this:
vrf cust1
no vni 1000
vni 1000
exit-vrf
Actually, the link information is correctly handled. In fact,
at the time of link event, the lower link status of the bridge
interface was not yet up, thus preventing from establishing
BGP EVPN contexts. In fact, when a bridge interface does not
have any slave interface, the link status of the bridge interface
is down. That change of status comes a bit after, and is not
detected by slave interfaces, as this event is not intercepted.
This commit intercepts the bridge link up event, and triggers
a check on slaved vxlan interfaces.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2021-08-17 10:56:32 +02:00
|
|
|
#define ZEBRA_BRIDGE_MASTER_UP (1 << 2)
|
2021-08-17 10:42:51 +02:00
|
|
|
|
2017-05-15 07:31:08 +02:00
|
|
|
/* zebra L2 interface information - bridge slave (linkage to bridge) */
|
|
|
|
struct zebra_l2info_brslave {
|
|
|
|
ifindex_t bridge_ifindex; /* Bridge Master */
|
|
|
|
struct interface *br_if; /* Pointer to master */
|
2019-10-03 17:11:37 +02:00
|
|
|
ns_id_t ns_id; /* network namespace where bridge is */
|
2017-05-15 07:31:08 +02:00
|
|
|
};
|
|
|
|
|
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
|
|
|
struct zebra_l2info_bond {
|
|
|
|
struct list *mbr_zifs; /* slaves using this bond as a master */
|
|
|
|
};
|
|
|
|
|
2021-07-27 09:47:52 +02:00
|
|
|
struct zebra_l2_bridge_vlan {
|
|
|
|
vlanid_t vid;
|
|
|
|
struct zebra_evpn_access_bd *access_bd;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct zebra_l2_bridge_if_ctx {
|
|
|
|
/* input */
|
|
|
|
struct zebra_if *zif;
|
2021-07-27 18:29:00 +02:00
|
|
|
int (*func)(struct zebra_if *zif, struct zebra_l2_bridge_vlan *vlan,
|
|
|
|
void *arg);
|
2021-07-27 09:47:52 +02:00
|
|
|
|
|
|
|
/* input-output */
|
|
|
|
void *arg;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct zebra_l2_bridge_if {
|
|
|
|
uint8_t vlan_aware;
|
|
|
|
struct zebra_if *br_zif;
|
|
|
|
struct hash *vlan_table;
|
|
|
|
};
|
|
|
|
|
2017-05-15 07:31:08 +02:00
|
|
|
/* zebra L2 interface information - bridge interface */
|
|
|
|
struct zebra_l2info_bridge {
|
2021-07-27 09:47:52 +02:00
|
|
|
struct zebra_l2_bridge_if bridge;
|
2017-05-15 07:31:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* zebra L2 interface information - VLAN interface */
|
|
|
|
struct zebra_l2info_vlan {
|
|
|
|
vlanid_t vid; /* VLAN id */
|
|
|
|
};
|
|
|
|
|
2019-12-19 18:33:56 +01:00
|
|
|
/* zebra L2 interface information - GRE interface */
|
|
|
|
struct zebra_l2info_gre {
|
|
|
|
struct in_addr vtep_ip; /* IFLA_GRE_LOCAL */
|
|
|
|
struct in_addr vtep_ip_remote; /* IFLA_GRE_REMOTE */
|
|
|
|
uint32_t ikey;
|
|
|
|
uint32_t okey;
|
|
|
|
ifindex_t ifindex_link; /* Interface index of interface
|
|
|
|
* linked with GRE
|
|
|
|
*/
|
|
|
|
ns_id_t link_nsid;
|
|
|
|
};
|
|
|
|
|
2021-07-27 09:44:15 +02:00
|
|
|
struct zebra_vxlan_vni {
|
2022-12-10 00:51:22 +01:00
|
|
|
vni_t vni; /* VNI */
|
2021-07-27 09:44:15 +02:00
|
|
|
vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */
|
|
|
|
struct in_addr mcast_grp;
|
|
|
|
};
|
|
|
|
|
2021-07-27 18:29:00 +02:00
|
|
|
enum {
|
2021-07-27 09:44:15 +02:00
|
|
|
ZEBRA_VXLAN_IF_VNI = 0, /* per vni vxlan if */
|
2022-12-10 00:51:22 +01:00
|
|
|
ZEBRA_VXLAN_IF_SVD /* single vxlan device */
|
2021-07-27 18:29:00 +02:00
|
|
|
};
|
2021-07-27 09:44:15 +02:00
|
|
|
|
|
|
|
struct zebra_vxlan_if_vlan_ctx {
|
|
|
|
vlanid_t vid;
|
|
|
|
struct zebra_vxlan_vni *vni;
|
|
|
|
};
|
|
|
|
|
2021-10-08 16:27:50 +02:00
|
|
|
struct zebra_vxlan_if_update_ctx {
|
|
|
|
uint16_t chgflags;
|
|
|
|
struct in_addr old_vtep_ip;
|
|
|
|
struct zebra_vxlan_vni old_vni;
|
|
|
|
struct hash *old_vni_table;
|
|
|
|
};
|
|
|
|
|
2021-07-27 09:44:15 +02:00
|
|
|
struct zebra_vxlan_if_ctx {
|
|
|
|
/* input */
|
|
|
|
struct zebra_if *zif;
|
2021-07-27 18:29:00 +02:00
|
|
|
int (*func)(struct zebra_if *zif, struct zebra_vxlan_vni *vni,
|
|
|
|
void *arg);
|
2021-07-27 09:44:15 +02:00
|
|
|
|
|
|
|
/* input-output */
|
|
|
|
void *arg;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct zebra_vxlan_vni_info {
|
2021-07-27 18:29:00 +02:00
|
|
|
int iftype;
|
2021-07-27 09:44:15 +02:00
|
|
|
union {
|
|
|
|
struct zebra_vxlan_vni vni; /* per vni vxlan device vni info */
|
|
|
|
struct hash
|
|
|
|
*vni_table; /* table of vni's assocated with this if */
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2017-05-15 07:31:08 +02:00
|
|
|
/* zebra L2 interface information - VXLAN interface */
|
|
|
|
struct zebra_l2info_vxlan {
|
2021-07-27 09:44:15 +02:00
|
|
|
struct zebra_vxlan_vni_info vni_info;
|
2017-05-15 07:31:08 +02:00
|
|
|
struct in_addr vtep_ip; /* Local tunnel IP */
|
2019-09-24 10:44:58 +02:00
|
|
|
ifindex_t ifindex_link; /* Interface index of interface
|
|
|
|
* linked with VXLAN
|
|
|
|
*/
|
|
|
|
ns_id_t link_nsid;
|
2017-05-15 07:31:08 +02:00
|
|
|
};
|
|
|
|
|
2018-11-10 21:54:43 +01:00
|
|
|
struct zebra_l2info_bondslave {
|
|
|
|
ifindex_t bond_ifindex; /* Bridge Master */
|
|
|
|
struct interface *bond_if; /* Pointer to master */
|
|
|
|
};
|
|
|
|
|
2017-05-15 07:31:08 +02:00
|
|
|
union zebra_l2if_info {
|
|
|
|
struct zebra_l2info_bridge br;
|
|
|
|
struct zebra_l2info_vlan vl;
|
|
|
|
struct zebra_l2info_vxlan vxl;
|
2019-12-19 18:33:56 +01:00
|
|
|
struct zebra_l2info_gre gre;
|
2017-05-15 07:31:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* NOTE: These macros are to be invoked only in the "correct" context.
|
|
|
|
* IOW, the macro VNI_FROM_ZEBRA_IF() will assume the interface is
|
|
|
|
* of type ZEBRA_IF_VXLAN.
|
|
|
|
*/
|
2021-07-27 09:44:15 +02:00
|
|
|
#define VNI_INFO_FROM_ZEBRA_IF(zif) (&((zif)->l2info.vxl.vni_info))
|
|
|
|
#define IS_ZEBRA_VXLAN_IF_SVD(zif) \
|
|
|
|
((zif)->l2info.vxl.vni_info.iftype == ZEBRA_VXLAN_IF_SVD)
|
|
|
|
#define IS_ZEBRA_VXLAN_IF_VNI(zif) \
|
|
|
|
((zif)->l2info.vxl.vni_info.iftype == ZEBRA_VXLAN_IF_VNI)
|
2017-05-15 07:31:08 +02:00
|
|
|
#define VLAN_ID_FROM_ZEBRA_IF(zif) (zif)->l2info.vl.vid
|
|
|
|
|
2021-07-27 09:47:52 +02:00
|
|
|
#define BRIDGE_FROM_ZEBRA_IF(zif) (&((zif)->l2info.br.bridge))
|
|
|
|
#define IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif) \
|
|
|
|
((zif)->l2info.br.bridge.vlan_aware == 1)
|
2017-05-15 07:31:08 +02:00
|
|
|
|
zebra: map vxlan interface to bridge interface with correct ns id
an incoming bridge index has been found, that is linked with vxlan
interface, and the search for that bridge interface is done. In
vrf-lite, the search is done across the same default namespace, because
bridge and vxlan may not be in the same vrf. But this behaviour is wrong
when using vrf netns backend, as the bridge and the vxlan have to be in
the same vrf ( hence in the same network namespace). To comply with
that, use the netnamespace of the vxlan interface. Like that, the
appropriate nsid is passed as parameter, and consequently, the search is
correct, and the mac address passed to BGP will be ok too.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2019-10-01 11:07:13 +02:00
|
|
|
extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave,
|
|
|
|
struct zebra_ns *zns);
|
2017-05-15 07:31:08 +02:00
|
|
|
extern void
|
|
|
|
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave);
|
|
|
|
extern void zebra_l2_bridge_add_update(struct interface *ifp,
|
2023-04-15 14:04:51 +02:00
|
|
|
struct zebra_l2info_bridge *bridge_info);
|
2017-05-15 07:31:08 +02:00
|
|
|
extern void zebra_l2_bridge_del(struct interface *ifp);
|
|
|
|
extern void zebra_l2_vlanif_update(struct interface *ifp,
|
|
|
|
struct zebra_l2info_vlan *vlan_info);
|
2019-12-19 18:33:56 +01:00
|
|
|
extern void zebra_l2_greif_add_update(struct interface *ifp,
|
|
|
|
struct zebra_l2info_gre *vxlan_info,
|
|
|
|
int add);
|
2017-05-15 07:31:08 +02:00
|
|
|
extern void zebra_l2_vxlanif_add_update(struct interface *ifp,
|
|
|
|
struct zebra_l2info_vxlan *vxlan_info,
|
|
|
|
int add);
|
|
|
|
extern void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
|
|
|
|
vlanid_t access_vlan);
|
2019-12-19 18:33:56 +01:00
|
|
|
extern void zebra_l2_greif_del(struct interface *ifp);
|
2017-05-15 07:31:08 +02:00
|
|
|
extern void zebra_l2_vxlanif_del(struct interface *ifp);
|
|
|
|
extern void zebra_l2if_update_bridge_slave(struct interface *ifp,
|
2019-10-03 17:11:37 +02:00
|
|
|
ifindex_t bridge_ifindex,
|
2021-08-17 10:42:51 +02:00
|
|
|
ns_id_t ns_id, uint8_t chgflags);
|
2017-05-15 07:31:08 +02:00
|
|
|
|
2018-11-10 21:54:43 +01:00
|
|
|
extern void zebra_l2if_update_bond_slave(struct interface *ifp,
|
2020-08-05 16:13:55 +02:00
|
|
|
ifindex_t bond_ifindex, bool bypass);
|
2020-03-28 01:14:45 +01:00
|
|
|
extern void zebra_vlan_bitmap_compute(struct interface *ifp,
|
|
|
|
uint32_t vid_start, uint16_t vid_end);
|
|
|
|
extern void zebra_vlan_mbr_re_eval(struct interface *ifp,
|
|
|
|
bitfield_t vlan_bitmap);
|
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 void zebra_l2if_update_bond(struct interface *ifp, bool add);
|
2021-08-17 10:42:51 +02:00
|
|
|
extern void zebra_l2if_update_bridge(struct interface *ifp, uint8_t chgflags);
|
2019-03-25 15:11:55 +01:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-05-15 07:31:08 +02:00
|
|
|
#endif /* _ZEBRA_L2_H */
|