mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 14:17:20 +00:00
Merge pull request #8554 from mjstapp/evpn_workqueue
lib,zebra: move some evpn dplane installation to the zebra workqueue
This commit is contained in:
commit
1dce93dabb
@ -1,4 +1,4 @@
|
||||
# Canonical Zserv route types information registry for Quagga.
|
||||
# Canonical Zserv route types information registry for FRR.
|
||||
#
|
||||
# Used to construct route_types.c and route_types.h
|
||||
#
|
||||
@ -60,7 +60,7 @@ ZEBRA_ROUTE_PIM, pim, pimd, 'P', 0, 0, 0, "PIM", pimd
|
||||
ZEBRA_ROUTE_EIGRP, eigrp, eigrpd, 'E', 1, 0, 1, "EIGRP", eigrpd
|
||||
ZEBRA_ROUTE_NHRP, nhrp, nhrpd, 'N', 1, 1, 1, "NHRP", nhrpd
|
||||
# HSLS and OLSR both are AFI independent (so: 1, 1), however
|
||||
# we want to disable for them for general Quagga distribution.
|
||||
# we want to disable for them for general FRR distribution.
|
||||
# This at least makes it trivial for users of these protocols
|
||||
# to 'switch on' redist support (direct numeric entry remaining
|
||||
# possible).
|
||||
|
@ -365,6 +365,10 @@ def test_ip_pe1_learn():
|
||||
"run the IP learn test for PE1"
|
||||
|
||||
tgen = get_topogen()
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
host1 = tgen.gears["host1"]
|
||||
pe1 = tgen.gears["PE1"]
|
||||
pe2 = tgen.gears["PE2"]
|
||||
@ -380,6 +384,10 @@ def test_ip_pe2_learn():
|
||||
"run the IP learn test for PE2"
|
||||
|
||||
tgen = get_topogen()
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
host2 = tgen.gears["host2"]
|
||||
pe1 = tgen.gears["PE1"]
|
||||
pe2 = tgen.gears["PE2"]
|
||||
|
45
zebra/rib.h
45
zebra/rib.h
@ -177,15 +177,16 @@ struct route_entry {
|
||||
|
||||
/* meta-queue structure:
|
||||
* sub-queue 0: nexthop group objects
|
||||
* sub-queue 1: connected
|
||||
* sub-queue 2: kernel
|
||||
* sub-queue 3: static
|
||||
* sub-queue 4: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP
|
||||
* sub-queue 5: iBGP, eBGP
|
||||
* sub-queue 6: any other origin (if any) typically those that
|
||||
* sub-queue 1: EVPN/VxLAN objects
|
||||
* sub-queue 2: connected
|
||||
* sub-queue 3: kernel
|
||||
* sub-queue 4: static
|
||||
* sub-queue 5: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP
|
||||
* sub-queue 6: iBGP, eBGP
|
||||
* sub-queue 7: any other origin (if any) typically those that
|
||||
* don't generate routes
|
||||
*/
|
||||
#define MQ_SIZE 7
|
||||
#define MQ_SIZE 8
|
||||
struct meta_queue {
|
||||
struct list *subq[MQ_SIZE];
|
||||
uint32_t size; /* sum of lengths of all subqueues */
|
||||
@ -446,6 +447,36 @@ extern int rib_queue_nhg_ctx_add(struct nhg_ctx *ctx);
|
||||
/* Enqueue incoming nhg from proto daemon for processing */
|
||||
extern int rib_queue_nhe_add(struct nhg_hash_entry *nhe);
|
||||
|
||||
/* Enqueue evpn route for processing */
|
||||
int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
|
||||
const struct ipaddr *vtep_ip,
|
||||
const struct prefix *host_prefix);
|
||||
int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id,
|
||||
const struct ipaddr *vtep_ip,
|
||||
const struct prefix *host_prefix);
|
||||
/* Enqueue EVPN remote ES for processing */
|
||||
int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi,
|
||||
const struct in_addr *vtep_ip,
|
||||
bool esr_rxed, uint8_t df_alg,
|
||||
uint16_t df_pref);
|
||||
int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi,
|
||||
const struct in_addr *vtep_ip);
|
||||
/* Enqueue EVPN remote macip update for processing */
|
||||
int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
|
||||
const struct ipaddr *ip,
|
||||
struct in_addr vtep_ip);
|
||||
int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
|
||||
const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq,
|
||||
struct in_addr vtep_ip,
|
||||
const esi_t *esi);
|
||||
/* Enqueue VXLAN remote vtep update for processing */
|
||||
int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip,
|
||||
int flood_control);
|
||||
int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip);
|
||||
|
||||
extern void meta_queue_free(struct meta_queue *mq);
|
||||
extern int zebra_rib_labeled_unicast(struct route_entry *re);
|
||||
extern struct route_table *rib_table_ipv6;
|
||||
|
@ -93,10 +93,10 @@ extern void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
|
||||
struct interface *br_if);
|
||||
extern void macfdb_read_specific_mac(struct zebra_ns *zns,
|
||||
struct interface *br_if,
|
||||
struct ethaddr *mac, vlanid_t vid);
|
||||
const struct ethaddr *mac, vlanid_t vid);
|
||||
extern void neigh_read(struct zebra_ns *zns);
|
||||
extern void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *ifp);
|
||||
extern void neigh_read_specific_ip(struct ipaddr *ip,
|
||||
extern void neigh_read_specific_ip(const struct ipaddr *ip,
|
||||
struct interface *vlan_if);
|
||||
extern void route_read(struct zebra_ns *zns);
|
||||
extern int kernel_upd_mac_nh(uint32_t nh_id, struct in_addr vtep_ip);
|
||||
|
@ -3466,10 +3466,9 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
|
||||
|
||||
/* Request for MAC FDB for a specific MAC address in VLAN from the kernel */
|
||||
static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns,
|
||||
int family,
|
||||
int type,
|
||||
int family, int type,
|
||||
struct interface *br_if,
|
||||
struct ethaddr *mac,
|
||||
const struct ethaddr *mac,
|
||||
vlanid_t vid)
|
||||
{
|
||||
struct {
|
||||
@ -3506,7 +3505,7 @@ static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns,
|
||||
|
||||
int netlink_macfdb_read_specific_mac(struct zebra_ns *zns,
|
||||
struct interface *br_if,
|
||||
struct ethaddr *mac, vlanid_t vid)
|
||||
const struct ethaddr *mac, vlanid_t vid)
|
||||
{
|
||||
int ret = 0;
|
||||
struct zebra_dplane_info dp_info;
|
||||
@ -3946,7 +3945,8 @@ int netlink_neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if)
|
||||
* read using netlink interface.
|
||||
*/
|
||||
static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns,
|
||||
int type, struct ipaddr *ip,
|
||||
int type,
|
||||
const struct ipaddr *ip,
|
||||
ifindex_t ifindex)
|
||||
{
|
||||
struct {
|
||||
@ -3983,8 +3983,8 @@ static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns,
|
||||
return netlink_request(&zns->netlink_cmd, &req);
|
||||
}
|
||||
|
||||
int netlink_neigh_read_specific_ip(struct ipaddr *ip,
|
||||
struct interface *vlan_if)
|
||||
int netlink_neigh_read_specific_ip(const struct ipaddr *ip,
|
||||
struct interface *vlan_if)
|
||||
{
|
||||
int ret = 0;
|
||||
struct zebra_ns *zns;
|
||||
|
@ -99,8 +99,9 @@ extern int netlink_neigh_read_for_vlan(struct zebra_ns *zns,
|
||||
struct interface *vlan_if);
|
||||
extern int netlink_macfdb_read_specific_mac(struct zebra_ns *zns,
|
||||
struct interface *br_if,
|
||||
struct ethaddr *mac, uint16_t vid);
|
||||
extern int netlink_neigh_read_specific_ip(struct ipaddr *ip,
|
||||
const struct ethaddr *mac,
|
||||
uint16_t vid);
|
||||
extern int netlink_neigh_read_specific_ip(const struct ipaddr *ip,
|
||||
struct interface *vlan_if);
|
||||
extern vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id);
|
||||
|
||||
|
@ -46,9 +46,9 @@ void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
|
||||
}
|
||||
|
||||
void macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if,
|
||||
struct ethaddr *mac, vlanid_t vid)
|
||||
const struct ethaddr *mac, vlanid_t vid)
|
||||
{
|
||||
netlink_macfdb_read_specific_mac(zns, br_if, mac, vid);
|
||||
netlink_macfdb_read_specific_mac(zns, br_if, mac, vid);
|
||||
}
|
||||
|
||||
void neigh_read(struct zebra_ns *zns)
|
||||
@ -61,7 +61,7 @@ void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if)
|
||||
netlink_neigh_read_for_vlan(zns, vlan_if);
|
||||
}
|
||||
|
||||
void neigh_read_specific_ip(struct ipaddr *ip, struct interface *vlan_if)
|
||||
void neigh_read_specific_ip(const struct ipaddr *ip, struct interface *vlan_if)
|
||||
{
|
||||
netlink_neigh_read_specific_ip(ip, vlan_if);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ void macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
|
||||
}
|
||||
|
||||
void macfdb_read_specific_mac(struct zebra_ns *zns, struct interface *br_if,
|
||||
struct ethaddr *mac, vlanid_t vid)
|
||||
const struct ethaddr *mac, vlanid_t vid)
|
||||
{
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ void neigh_read_for_vlan(struct zebra_ns *zns, struct interface *vlan_if)
|
||||
{
|
||||
}
|
||||
|
||||
void neigh_read_specific_ip(struct ipaddr *ip, struct interface *vlan_if)
|
||||
void neigh_read_specific_ip(const struct ipaddr *ip, struct interface *vlan_if)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -3653,8 +3653,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
|
||||
[ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
|
||||
[ZEBRA_REMOTE_ES_VTEP_ADD] = zebra_evpn_proc_remote_es,
|
||||
[ZEBRA_REMOTE_ES_VTEP_DEL] = zebra_evpn_proc_remote_es,
|
||||
[ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,
|
||||
[ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
|
||||
[ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add_zapi,
|
||||
[ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del_zapi,
|
||||
[ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
|
||||
[ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
|
||||
[ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection,
|
||||
|
@ -3640,14 +3640,10 @@ enum zebra_dplane_result dplane_neigh_ip_update(enum dplane_op_e op,
|
||||
uint16_t state = 0;
|
||||
uint32_t update_flags;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
|
||||
char buf1[PREFIX_STRLEN], buf2[PREFIX_STRLEN];
|
||||
if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
|
||||
zlog_debug("%s: init link ctx %s: ifp %s, link_ip %pIA ip %pIA",
|
||||
__func__, dplane_op2str(op), ifp->name, link_ip, ip);
|
||||
|
||||
ipaddr2str(link_ip, buf1, sizeof(buf1));
|
||||
ipaddr2str(ip, buf2, sizeof(buf2));
|
||||
zlog_debug("init link ctx %s: ifp %s, ip %s link %s",
|
||||
dplane_op2str(op), ifp->name, buf1, buf2);
|
||||
}
|
||||
if (ndm_state == ZEBRA_NEIGH_STATE_REACHABLE)
|
||||
state = DPLANE_NUD_REACHABLE;
|
||||
else if (ndm_state == ZEBRA_NEIGH_STATE_FAILED)
|
||||
|
@ -1330,10 +1330,12 @@ void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg)
|
||||
zebra_evpn_del(zevpn);
|
||||
}
|
||||
|
||||
static void
|
||||
zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi)
|
||||
static void zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn,
|
||||
const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len,
|
||||
const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq,
|
||||
const esi_t *esi)
|
||||
{
|
||||
struct sync_mac_ip_ctx ctx;
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
@ -1380,10 +1382,10 @@ zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
|
||||
|
||||
/************************** remote mac-ip handling **************************/
|
||||
/* Process a remote MACIP add from BGP. */
|
||||
void process_remote_macip_add(vni_t vni, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq,
|
||||
struct in_addr vtep_ip, esi_t *esi)
|
||||
struct in_addr vtep_ip, const esi_t *esi)
|
||||
{
|
||||
zebra_evpn_t *zevpn;
|
||||
zebra_vtep_t *zvtep;
|
||||
@ -1447,18 +1449,19 @@ void process_remote_macip_add(vni_t vni, struct ethaddr *macaddr,
|
||||
return;
|
||||
|
||||
|
||||
if (process_mac_remote_macip_add(zevpn, zvrf, macaddr, ipa_len, ipaddr,
|
||||
&mac, vtep_ip, flags, seq, esi)
|
||||
if (zebra_evpn_mac_remote_macip_add(zevpn, zvrf, macaddr, ipa_len,
|
||||
ipaddr, &mac, vtep_ip, flags, seq,
|
||||
esi)
|
||||
!= 0)
|
||||
return;
|
||||
|
||||
process_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac, vtep_ip, flags,
|
||||
seq);
|
||||
zebra_evpn_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac, vtep_ip,
|
||||
flags, seq);
|
||||
}
|
||||
|
||||
/* Process a remote MACIP delete from BGP. */
|
||||
void process_remote_macip_del(vni_t vni, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, const struct ipaddr *ipaddr,
|
||||
struct in_addr vtep_ip)
|
||||
{
|
||||
zebra_evpn_t *zevpn;
|
||||
|
@ -204,12 +204,12 @@ int zebra_evpn_vtep_uninstall(zebra_evpn_t *zevpn, struct in_addr *vtep_ip);
|
||||
void zebra_evpn_handle_flooding_remote_vteps(struct hash_bucket *bucket,
|
||||
void *zvrf);
|
||||
void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg);
|
||||
void process_remote_macip_add(vni_t vni, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq,
|
||||
struct in_addr vtep_ip, esi_t *esi);
|
||||
void process_remote_macip_del(vni_t vni, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
struct in_addr vtep_ip, const esi_t *esi);
|
||||
void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, const struct ipaddr *ipaddr,
|
||||
struct in_addr vtep_ip);
|
||||
void zebra_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt);
|
||||
|
||||
|
@ -986,8 +986,9 @@ void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt)
|
||||
/*
|
||||
* Inform BGP about local MACIP.
|
||||
*/
|
||||
int zebra_evpn_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
|
||||
struct ipaddr *ip, uint8_t flags,
|
||||
int zebra_evpn_macip_send_msg_to_client(vni_t vni,
|
||||
const struct ethaddr *macaddr,
|
||||
const struct ipaddr *ip, uint8_t flags,
|
||||
uint32_t seq, int state,
|
||||
struct zebra_evpn_es *es, uint16_t cmd)
|
||||
{
|
||||
@ -1095,7 +1096,8 @@ static void *zebra_evpn_mac_alloc(void *p)
|
||||
/*
|
||||
* Add MAC entry.
|
||||
*/
|
||||
zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr)
|
||||
zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn,
|
||||
const struct ethaddr *macaddr)
|
||||
{
|
||||
zebra_mac_t tmp_mac;
|
||||
zebra_mac_t *mac = NULL;
|
||||
@ -1254,7 +1256,8 @@ void zebra_evpn_mac_del_all(zebra_evpn_t *zevpn, int uninstall, int upd_client,
|
||||
/*
|
||||
* Look up MAC hash entry.
|
||||
*/
|
||||
zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevpn, struct ethaddr *mac)
|
||||
zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevpn,
|
||||
const struct ethaddr *mac)
|
||||
{
|
||||
zebra_mac_t tmp;
|
||||
zebra_mac_t *pmac;
|
||||
@ -1269,7 +1272,7 @@ zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevpn, struct ethaddr *mac)
|
||||
/*
|
||||
* Inform BGP about local MAC addition.
|
||||
*/
|
||||
int zebra_evpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
|
||||
int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint32_t mac_flags, uint32_t seq,
|
||||
struct zebra_evpn_es *es)
|
||||
{
|
||||
@ -1303,7 +1306,7 @@ int zebra_evpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
|
||||
/*
|
||||
* Inform BGP about local MAC deletion.
|
||||
*/
|
||||
int zebra_evpn_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
|
||||
int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint32_t flags, bool force)
|
||||
{
|
||||
if (!force) {
|
||||
@ -1563,7 +1566,7 @@ void zebra_evpn_sync_mac_del(zebra_mac_t *mac)
|
||||
static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn,
|
||||
zebra_mac_t *mac, uint32_t seq,
|
||||
uint16_t ipa_len,
|
||||
struct ipaddr *ipaddr,
|
||||
const struct ipaddr *ipaddr,
|
||||
bool sync)
|
||||
{
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
@ -1627,11 +1630,10 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn,
|
||||
return true;
|
||||
}
|
||||
|
||||
zebra_mac_t *
|
||||
zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi,
|
||||
struct sync_mac_ip_ctx *ctx)
|
||||
zebra_mac_t *zebra_evpn_proc_sync_mac_update(
|
||||
zebra_evpn_t *zevpn, const struct ethaddr *macaddr, uint16_t ipa_len,
|
||||
const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq,
|
||||
const esi_t *esi, struct sync_mac_ip_ctx *ctx)
|
||||
{
|
||||
zebra_mac_t *mac;
|
||||
bool inform_bgp = false;
|
||||
@ -1958,11 +1960,13 @@ void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket,
|
||||
zebra_evpn_print_mac_hash_detail(bucket, ctxt);
|
||||
}
|
||||
|
||||
int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
struct ethaddr *macaddr, uint16_t ipa_len,
|
||||
struct ipaddr *ipaddr, zebra_mac_t **macp,
|
||||
struct in_addr vtep_ip, uint8_t flags,
|
||||
uint32_t seq, esi_t *esi)
|
||||
int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len,
|
||||
const struct ipaddr *ipaddr,
|
||||
zebra_mac_t **macp, struct in_addr vtep_ip,
|
||||
uint8_t flags, uint32_t seq,
|
||||
const esi_t *esi)
|
||||
{
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
bool sticky;
|
||||
@ -2127,7 +2131,7 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
|
||||
int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
|
||||
struct interface *ifp,
|
||||
struct ethaddr *macaddr, vlanid_t vid,
|
||||
const struct ethaddr *macaddr, vlanid_t vid,
|
||||
bool sticky, bool local_inactive,
|
||||
bool dp_static, zebra_mac_t *mac)
|
||||
{
|
||||
@ -2447,8 +2451,8 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac,
|
||||
}
|
||||
|
||||
int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
|
||||
struct ipaddr *ip, zebra_mac_t **macp,
|
||||
struct ethaddr *macaddr, vlanid_t vlan_id,
|
||||
const struct ipaddr *ip, zebra_mac_t **macp,
|
||||
const struct ethaddr *macaddr, vlanid_t vlan_id,
|
||||
bool def_gw)
|
||||
{
|
||||
zebra_mac_t *mac;
|
||||
|
@ -229,11 +229,14 @@ int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevi, zebra_mac_t *mac,
|
||||
int zebra_evpn_rem_mac_install(zebra_evpn_t *zevi, zebra_mac_t *mac,
|
||||
bool was_static);
|
||||
void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevi, zebra_mac_t *mac);
|
||||
zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevi, struct ethaddr *mac);
|
||||
zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevi, struct ethaddr *macaddr);
|
||||
zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevi,
|
||||
const struct ethaddr *mac);
|
||||
zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevi,
|
||||
const struct ethaddr *macaddr);
|
||||
int zebra_evpn_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac);
|
||||
int zebra_evpn_macip_send_msg_to_client(uint32_t id, struct ethaddr *macaddr,
|
||||
struct ipaddr *ip, uint8_t flags,
|
||||
int zebra_evpn_macip_send_msg_to_client(uint32_t id,
|
||||
const struct ethaddr *macaddr,
|
||||
const struct ipaddr *ip, uint8_t flags,
|
||||
uint32_t seq, int state,
|
||||
struct zebra_evpn_es *es, uint16_t cmd);
|
||||
void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
|
||||
@ -246,38 +249,39 @@ void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
|
||||
|
||||
void zebra_evpn_mac_del_all(zebra_evpn_t *zevi, int uninstall, int upd_client,
|
||||
uint32_t flags);
|
||||
int zebra_evpn_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
|
||||
int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint32_t mac_flags, uint32_t seq,
|
||||
struct zebra_evpn_es *es);
|
||||
int zebra_evpn_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
|
||||
int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr,
|
||||
uint32_t flags, bool force);
|
||||
void zebra_evpn_send_mac_list_to_client(zebra_evpn_t *zevi);
|
||||
zebra_mac_t *
|
||||
zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevi, struct ethaddr *macaddr,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi,
|
||||
struct sync_mac_ip_ctx *ctx);
|
||||
zebra_mac_t *zebra_evpn_proc_sync_mac_update(
|
||||
zebra_evpn_t *zevi, const struct ethaddr *macaddr, uint16_t ipa_len,
|
||||
const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq,
|
||||
const esi_t *esi, struct sync_mac_ip_ctx *ctx);
|
||||
void zebra_evpn_sync_mac_del(zebra_mac_t *mac);
|
||||
void zebra_evpn_rem_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac);
|
||||
void zebra_evpn_print_dad_mac_hash(struct hash_bucket *bucket, void *ctxt);
|
||||
void zebra_evpn_print_dad_mac_hash_detail(struct hash_bucket *bucket,
|
||||
void *ctxt);
|
||||
int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
struct ethaddr *macaddr, uint16_t ipa_len,
|
||||
struct ipaddr *ipaddr, zebra_mac_t **macp,
|
||||
struct in_addr vtep_ip, uint8_t flags,
|
||||
uint32_t seq, esi_t *esi);
|
||||
int zebra_evpn_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
const struct ethaddr *macaddr,
|
||||
uint16_t ipa_len,
|
||||
const struct ipaddr *ipaddr,
|
||||
zebra_mac_t **macp, struct in_addr vtep_ip,
|
||||
uint8_t flags, uint32_t seq,
|
||||
const esi_t *esi);
|
||||
|
||||
int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
|
||||
struct interface *ifp,
|
||||
struct ethaddr *macaddr, vlanid_t vid,
|
||||
const struct ethaddr *macaddr, vlanid_t vid,
|
||||
bool sticky, bool local_inactive,
|
||||
bool dp_static, zebra_mac_t *mac);
|
||||
int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac,
|
||||
bool clear_static);
|
||||
int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
|
||||
struct ipaddr *ip, zebra_mac_t **macp,
|
||||
struct ethaddr *macaddr, vlanid_t vlan_id,
|
||||
const struct ipaddr *ip, zebra_mac_t **macp,
|
||||
const struct ethaddr *macaddr, vlanid_t vlan_id,
|
||||
bool def_gw);
|
||||
void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn);
|
||||
void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn);
|
||||
|
@ -1747,7 +1747,7 @@ static int zebra_es_rb_cmp(const struct zebra_evpn_es *es1,
|
||||
RB_GENERATE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp);
|
||||
|
||||
/* Lookup ES */
|
||||
struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi)
|
||||
struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi)
|
||||
{
|
||||
struct zebra_evpn_es tmp;
|
||||
|
||||
@ -1758,7 +1758,7 @@ struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi)
|
||||
/* A new local es is created when a local-es-id and sysmac is configured
|
||||
* against an interface.
|
||||
*/
|
||||
static struct zebra_evpn_es *zebra_evpn_es_new(esi_t *esi)
|
||||
static struct zebra_evpn_es *zebra_evpn_es_new(const esi_t *esi)
|
||||
{
|
||||
struct zebra_evpn_es *es;
|
||||
|
||||
@ -2392,7 +2392,7 @@ static int zebra_evpn_type3_esi_update(struct zebra_if *zif, uint32_t lid,
|
||||
return zebra_evpn_local_es_update(zif, &esi);
|
||||
}
|
||||
|
||||
static int zebra_evpn_remote_es_del(esi_t *esi, struct in_addr vtep_ip)
|
||||
int zebra_evpn_remote_es_del(const esi_t *esi, struct in_addr vtep_ip)
|
||||
{
|
||||
char buf[ESI_STR_LEN];
|
||||
struct zebra_evpn_es *es;
|
||||
@ -2432,9 +2432,8 @@ static void zebra_evpn_remote_es_flush(struct zebra_evpn_es **esp)
|
||||
zebra_evpn_es_remote_info_re_eval(esp);
|
||||
}
|
||||
|
||||
static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip,
|
||||
bool esr_rxed, uint8_t df_alg,
|
||||
uint16_t df_pref)
|
||||
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)
|
||||
{
|
||||
char buf[ESI_STR_LEN];
|
||||
struct zebra_evpn_es *es;
|
||||
@ -2498,10 +2497,10 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS)
|
||||
: false;
|
||||
STREAM_GETC(s, df_alg);
|
||||
STREAM_GETW(s, df_pref);
|
||||
zebra_evpn_remote_es_add(&esi, vtep_ip, esr_rxed, df_alg,
|
||||
df_pref);
|
||||
zebra_rib_queue_evpn_rem_es_add(&esi, &vtep_ip, esr_rxed,
|
||||
df_alg, df_pref);
|
||||
} else {
|
||||
zebra_evpn_remote_es_del(&esi, vtep_ip);
|
||||
zebra_rib_queue_evpn_rem_es_del(&esi, &vtep_ip);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
@ -2542,7 +2541,7 @@ bool zebra_evpn_es_mac_ref_entry(zebra_mac_t *mac, struct zebra_evpn_es *es)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi)
|
||||
bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, const esi_t *esi)
|
||||
{
|
||||
struct zebra_evpn_es *es;
|
||||
|
||||
@ -3901,12 +3900,12 @@ void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS)
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
|
||||
zlog_debug("evpn remote nh %d %pIA rmac %pEA add",
|
||||
vrf_id, &nh, &rmac);
|
||||
zebra_vxlan_evpn_vrf_route_add(vrf_id, &rmac, &nh,
|
||||
zebra_rib_queue_evpn_route_add(vrf_id, &rmac, &nh,
|
||||
(struct prefix *)&dummy_prefix);
|
||||
} else {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
|
||||
zlog_debug("evpn remote nh %d %pIA del", vrf_id, &nh);
|
||||
zebra_vxlan_evpn_vrf_route_del(vrf_id, &nh,
|
||||
zebra_rib_queue_evpn_route_del(vrf_id, &nh,
|
||||
(struct prefix *)&dummy_prefix);
|
||||
}
|
||||
}
|
||||
|
@ -330,14 +330,17 @@ 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);
|
||||
extern void zebra_evpn_update_all_es(zebra_evpn_t *zevpn);
|
||||
extern void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS);
|
||||
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);
|
||||
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);
|
||||
extern void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac);
|
||||
extern bool zebra_evpn_es_mac_ref_entry(zebra_mac_t *mac,
|
||||
struct zebra_evpn_es *es);
|
||||
extern bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi);
|
||||
extern struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi);
|
||||
struct zebra_evpn_es *es);
|
||||
extern bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, const esi_t *esi);
|
||||
extern struct zebra_evpn_es *zebra_evpn_es_find(const esi_t *esi);
|
||||
extern void zebra_evpn_interface_init(void);
|
||||
extern int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp);
|
||||
extern void zebra_evpn_acc_vl_show(struct vty *vty, bool uj);
|
||||
|
@ -204,7 +204,7 @@ static void *zebra_evpn_neigh_alloc(void *p)
|
||||
}
|
||||
|
||||
static void zebra_evpn_local_neigh_ref_mac(zebra_neigh_t *n,
|
||||
struct ethaddr *macaddr,
|
||||
const struct ethaddr *macaddr,
|
||||
zebra_mac_t *mac,
|
||||
bool send_mac_update)
|
||||
{
|
||||
@ -284,8 +284,8 @@ static void zebra_evpn_sync_neigh_dp_install(zebra_neigh_t *n,
|
||||
/*
|
||||
* Inform BGP about local neighbor addition.
|
||||
*/
|
||||
int zebra_evpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
|
||||
struct ethaddr *macaddr,
|
||||
int zebra_evpn_neigh_send_add_to_client(vni_t vni, const struct ipaddr *ip,
|
||||
const struct ethaddr *macaddr,
|
||||
zebra_mac_t *zmac, uint32_t neigh_flags,
|
||||
uint32_t seq)
|
||||
{
|
||||
@ -497,7 +497,7 @@ static void zebra_evpn_local_neigh_deref_mac(zebra_neigh_t *n,
|
||||
}
|
||||
|
||||
bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
struct ethaddr *macaddr, uint32_t seq,
|
||||
const struct ethaddr *macaddr, uint32_t seq,
|
||||
bool sync)
|
||||
{
|
||||
uint32_t tmp_seq;
|
||||
@ -543,8 +543,8 @@ bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
* Add neighbor entry.
|
||||
*/
|
||||
static zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn,
|
||||
struct ipaddr *ip,
|
||||
struct ethaddr *mac,
|
||||
const struct ipaddr *ip,
|
||||
const struct ethaddr *mac,
|
||||
zebra_mac_t *zmac, uint32_t n_flags)
|
||||
{
|
||||
zebra_neigh_t tmp_n;
|
||||
@ -615,8 +615,8 @@ void zebra_evpn_sync_neigh_del(zebra_neigh_t *n)
|
||||
|
||||
zebra_neigh_t *
|
||||
zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi,
|
||||
uint16_t ipa_len, const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, const esi_t *esi,
|
||||
struct sync_mac_ip_ctx *ctx)
|
||||
{
|
||||
struct interface *ifp = NULL;
|
||||
@ -895,7 +895,8 @@ void zebra_evpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall,
|
||||
/*
|
||||
* Look up neighbor hash entry.
|
||||
*/
|
||||
zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip)
|
||||
zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn,
|
||||
const struct ipaddr *ip)
|
||||
{
|
||||
zebra_neigh_t tmp;
|
||||
zebra_neigh_t *n;
|
||||
@ -1254,9 +1255,9 @@ zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr,
|
||||
}
|
||||
|
||||
int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
|
||||
struct ipaddr *ip, struct ethaddr *macaddr,
|
||||
bool is_router, bool local_inactive,
|
||||
bool dp_static)
|
||||
const struct ipaddr *ip,
|
||||
const struct ethaddr *macaddr, bool is_router,
|
||||
bool local_inactive, bool dp_static)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
zebra_neigh_t *n = NULL;
|
||||
@ -1596,7 +1597,8 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
|
||||
}
|
||||
|
||||
int zebra_evpn_remote_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
|
||||
struct ipaddr *ip, struct ethaddr *macaddr,
|
||||
const struct ipaddr *ip,
|
||||
const struct ethaddr *macaddr,
|
||||
uint16_t state)
|
||||
{
|
||||
zebra_neigh_t *n = NULL;
|
||||
@ -2046,10 +2048,11 @@ void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
|
||||
zebra_evpn_print_neigh_hash_detail(bucket, ctxt);
|
||||
}
|
||||
|
||||
void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
struct ipaddr *ipaddr, zebra_mac_t *mac,
|
||||
struct in_addr vtep_ip, uint8_t flags,
|
||||
uint32_t seq)
|
||||
void zebra_evpn_neigh_remote_macip_add(zebra_evpn_t *zevpn,
|
||||
struct zebra_vrf *zvrf,
|
||||
const struct ipaddr *ipaddr,
|
||||
zebra_mac_t *mac, struct in_addr vtep_ip,
|
||||
uint8_t flags, uint32_t seq)
|
||||
{
|
||||
zebra_neigh_t *n;
|
||||
int update_neigh = 0;
|
||||
@ -2240,7 +2243,8 @@ int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
|
||||
|
||||
void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn,
|
||||
struct zebra_vrf *zvrf, zebra_neigh_t *n,
|
||||
zebra_mac_t *mac, struct ipaddr *ipaddr)
|
||||
zebra_mac_t *mac,
|
||||
const struct ipaddr *ipaddr)
|
||||
{
|
||||
if (zvrf->dad_freeze && CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)
|
||||
&& CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
|
||||
@ -2273,7 +2277,7 @@ void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn,
|
||||
}
|
||||
}
|
||||
|
||||
int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip)
|
||||
int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, const struct ipaddr *ip)
|
||||
{
|
||||
zebra_neigh_t *n;
|
||||
zebra_mac_t *zmac;
|
||||
@ -2298,7 +2302,7 @@ int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip)
|
||||
}
|
||||
|
||||
/* If it is a remote entry, the kernel has aged this out or someone has
|
||||
* deleted it, it needs to be re-installed as Quagga is the owner.
|
||||
* deleted it, it needs to be re-installed as FRR is the owner.
|
||||
*/
|
||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
|
||||
zebra_evpn_rem_neigh_install(zevpn, n, false /*was_static*/);
|
||||
|
@ -217,26 +217,27 @@ int remote_neigh_count(zebra_mac_t *zmac);
|
||||
int zebra_evpn_rem_neigh_install(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
bool was_static);
|
||||
void zebra_evpn_install_neigh_hash(struct hash_bucket *bucket, void *ctxt);
|
||||
int zebra_evpn_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
|
||||
struct ethaddr *macaddr,
|
||||
int zebra_evpn_neigh_send_add_to_client(vni_t vni, const struct ipaddr *ip,
|
||||
const struct ethaddr *macaddr,
|
||||
zebra_mac_t *zmac, uint32_t neigh_flags,
|
||||
uint32_t seq);
|
||||
int zebra_evpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
|
||||
struct ethaddr *macaddr, uint32_t flags,
|
||||
int state, bool force);
|
||||
bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
struct ethaddr *macaddr, uint32_t seq,
|
||||
const struct ethaddr *macaddr, uint32_t seq,
|
||||
bool sync);
|
||||
int zebra_evpn_neigh_del(zebra_evpn_t *zevpn, zebra_neigh_t *n);
|
||||
void zebra_evpn_sync_neigh_del(zebra_neigh_t *n);
|
||||
zebra_neigh_t *
|
||||
zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
uint16_t ipa_len, struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi,
|
||||
uint16_t ipa_len, const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq, const esi_t *esi,
|
||||
struct sync_mac_ip_ctx *ctx);
|
||||
void zebra_evpn_neigh_del_all(zebra_evpn_t *zevpn, int uninstall,
|
||||
int upd_client, uint32_t flags);
|
||||
zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn, struct ipaddr *ip);
|
||||
zebra_neigh_t *zebra_evpn_neigh_lookup(zebra_evpn_t *zevpn,
|
||||
const struct ipaddr *ip);
|
||||
|
||||
int zebra_evpn_rem_neigh_install(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
bool was_static);
|
||||
@ -251,11 +252,12 @@ void zebra_evpn_process_neigh_on_local_mac_change(zebra_evpn_t *zevpn,
|
||||
void zebra_evpn_process_neigh_on_remote_mac_del(zebra_evpn_t *zevpn,
|
||||
zebra_mac_t *zmac);
|
||||
int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
|
||||
struct ipaddr *ip, struct ethaddr *macaddr,
|
||||
bool is_router, bool local_inactive,
|
||||
bool dp_static);
|
||||
const struct ipaddr *ip,
|
||||
const struct ethaddr *macaddr, bool is_router,
|
||||
bool local_inactive, bool dp_static);
|
||||
int zebra_evpn_remote_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp,
|
||||
struct ipaddr *ip, struct ethaddr *macaddr,
|
||||
const struct ipaddr *ip,
|
||||
const struct ethaddr *macaddr,
|
||||
uint16_t state);
|
||||
void zebra_evpn_send_neigh_to_client(zebra_evpn_t *zevpn);
|
||||
void zebra_evpn_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt);
|
||||
@ -266,16 +268,18 @@ void zebra_evpn_print_neigh_hash_detail(struct hash_bucket *bucket, void *ctxt);
|
||||
void zebra_evpn_print_dad_neigh_hash(struct hash_bucket *bucket, void *ctxt);
|
||||
void zebra_evpn_print_dad_neigh_hash_detail(struct hash_bucket *bucket,
|
||||
void *ctxt);
|
||||
void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
struct ipaddr *ipaddr, zebra_mac_t *mac,
|
||||
struct in_addr vtep_ip, uint8_t flags,
|
||||
uint32_t seq);
|
||||
void zebra_evpn_neigh_remote_macip_add(zebra_evpn_t *zevpn,
|
||||
struct zebra_vrf *zvrf,
|
||||
const struct ipaddr *ipaddr,
|
||||
zebra_mac_t *mac, struct in_addr vtep_ip,
|
||||
uint8_t flags, uint32_t seq);
|
||||
int zebra_evpn_neigh_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn,
|
||||
struct ipaddr *ip, zebra_mac_t *mac);
|
||||
void zebra_evpn_neigh_remote_uninstall(zebra_evpn_t *zevpn,
|
||||
struct zebra_vrf *zvrf, zebra_neigh_t *n,
|
||||
zebra_mac_t *mac, struct ipaddr *ipaddr);
|
||||
int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, struct ipaddr *ip);
|
||||
zebra_mac_t *mac,
|
||||
const struct ipaddr *ipaddr);
|
||||
int zebra_evpn_neigh_del_ip(zebra_evpn_t *zevpn, const struct ipaddr *ip);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -56,13 +56,14 @@
|
||||
#include "zebra/zebra_vxlan.h"
|
||||
#include "zebra/zapi_msg.h"
|
||||
#include "zebra/zebra_dplane.h"
|
||||
#include "zebra/zebra_evpn_mh.h"
|
||||
|
||||
DEFINE_MGROUP(ZEBRA, "zebra");
|
||||
|
||||
DEFINE_MTYPE(ZEBRA, RE, "Route Entry");
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, RIB_DEST, "RIB destination");
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, RIB_UPDATE_CTX, "Rib update context object");
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, WQ_NHG_WRAPPER, "WQ nhg wrapper");
|
||||
DEFINE_MTYPE_STATIC(ZEBRA, WQ_WRAPPER, "WQ wrapper");
|
||||
|
||||
/*
|
||||
* Event, list, and mutex for delivery of dataplane results
|
||||
@ -74,7 +75,7 @@ static struct dplane_ctx_q rib_dplane_q;
|
||||
DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
|
||||
(rn, reason));
|
||||
|
||||
/* Should we allow non Quagga processes to delete our routes */
|
||||
/* Should we allow non FRR processes to delete our routes */
|
||||
extern int allow_delete;
|
||||
|
||||
/* Each route type's string and default distance value. */
|
||||
@ -83,41 +84,44 @@ static const struct {
|
||||
uint8_t distance;
|
||||
uint8_t meta_q_map;
|
||||
} route_info[ZEBRA_ROUTE_MAX] = {
|
||||
[ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Uneeded for nhg's */, 0},
|
||||
[ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 6},
|
||||
[ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 2},
|
||||
[ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 1},
|
||||
[ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 3},
|
||||
[ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 4},
|
||||
[ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 4},
|
||||
[ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 4},
|
||||
[ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 4},
|
||||
[ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 4},
|
||||
[ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 5},
|
||||
[ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 6},
|
||||
[ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 4},
|
||||
[ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 4},
|
||||
[ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 6},
|
||||
[ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 6},
|
||||
[ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 3},
|
||||
[ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 6},
|
||||
[ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 5},
|
||||
[ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 5},
|
||||
[ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 5},
|
||||
[ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 5},
|
||||
[ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 5},
|
||||
[ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 4},
|
||||
[ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 6},
|
||||
[ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 6},
|
||||
[ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 6},
|
||||
[ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 4},
|
||||
[ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 6},
|
||||
[ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 6},
|
||||
[ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */, 0},
|
||||
[ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 7},
|
||||
[ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 3},
|
||||
[ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 2},
|
||||
[ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 4},
|
||||
[ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 5},
|
||||
[ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 5},
|
||||
[ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 5},
|
||||
[ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 5},
|
||||
[ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 5},
|
||||
[ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 6},
|
||||
[ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 7},
|
||||
[ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 5},
|
||||
[ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 5},
|
||||
[ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 7},
|
||||
[ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 7},
|
||||
[ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 4},
|
||||
[ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 7},
|
||||
[ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 6},
|
||||
[ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 6},
|
||||
[ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 6},
|
||||
[ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 6},
|
||||
[ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 6},
|
||||
[ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 5},
|
||||
[ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 7},
|
||||
[ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 7},
|
||||
[ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 7},
|
||||
[ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 5},
|
||||
[ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 7},
|
||||
[ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 7},
|
||||
/* Any new route type added to zebra, should be mirrored here */
|
||||
|
||||
/* no entry/default: 150 */
|
||||
};
|
||||
|
||||
/* EVPN/VXLAN subqueue is number 1 */
|
||||
#define META_QUEUE_EVPN 1
|
||||
|
||||
/* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update
|
||||
* from the OS, and an 'nhe' is a nhe update.
|
||||
*/
|
||||
@ -132,6 +136,29 @@ struct wq_nhg_wrapper {
|
||||
#define WQ_NHG_WRAPPER_TYPE_CTX 0x01
|
||||
#define WQ_NHG_WRAPPER_TYPE_NHG 0x02
|
||||
|
||||
/* Wrapper structs for evpn/vxlan workqueue items. */
|
||||
struct wq_evpn_wrapper {
|
||||
int type;
|
||||
bool add_p;
|
||||
vrf_id_t vrf_id;
|
||||
bool esr_rxed;
|
||||
uint8_t df_alg;
|
||||
uint16_t df_pref;
|
||||
uint32_t flags;
|
||||
uint32_t seq;
|
||||
esi_t esi;
|
||||
vni_t vni;
|
||||
struct ipaddr ip;
|
||||
struct ethaddr macaddr;
|
||||
struct prefix prefix;
|
||||
struct in_addr vtep_ip;
|
||||
};
|
||||
|
||||
#define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01
|
||||
#define WQ_EVPN_WRAPPER_TYPE_REM_ES 0x02
|
||||
#define WQ_EVPN_WRAPPER_TYPE_REM_MACIP 0x03
|
||||
#define WQ_EVPN_WRAPPER_TYPE_REM_VTEP 0x04
|
||||
|
||||
/* %pRN is already a printer for route_nodes that just prints the prefix */
|
||||
#ifdef _FRR_ATTRIBUTE_PRINTFRR
|
||||
#pragma FRR printfrr_ext "%pZN" (struct route_node *)
|
||||
@ -2315,6 +2342,62 @@ done:
|
||||
dplane_ctx_fini(&ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a node from the EVPN/VXLAN subqueue.
|
||||
*/
|
||||
static void process_subq_evpn(struct listnode *lnode)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
/* In general, the list node points to a wrapper object
|
||||
* holding the info necessary to make some update.
|
||||
*/
|
||||
w = listgetdata(lnode);
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
if (w->type == WQ_EVPN_WRAPPER_TYPE_VRFROUTE) {
|
||||
if (w->add_p)
|
||||
zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->macaddr,
|
||||
&w->ip, &w->prefix);
|
||||
else
|
||||
zebra_vxlan_evpn_vrf_route_del(w->vrf_id, &w->ip,
|
||||
&w->prefix);
|
||||
} else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_ES) {
|
||||
if (w->add_p)
|
||||
zebra_evpn_remote_es_add(&w->esi, w->ip.ipaddr_v4,
|
||||
w->esr_rxed, w->df_alg,
|
||||
w->df_pref);
|
||||
else
|
||||
zebra_evpn_remote_es_del(&w->esi, w->ip.ipaddr_v4);
|
||||
} else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_MACIP) {
|
||||
uint16_t ipa_len = 0;
|
||||
|
||||
if (w->ip.ipa_type == IPADDR_V4)
|
||||
ipa_len = IPV4_MAX_BYTELEN;
|
||||
else if (w->ip.ipa_type == IPADDR_V6)
|
||||
ipa_len = IPV6_MAX_BYTELEN;
|
||||
|
||||
if (w->add_p)
|
||||
zebra_evpn_rem_macip_add(w->vni, &w->macaddr, ipa_len,
|
||||
&w->ip, w->flags, w->seq,
|
||||
w->vtep_ip, &w->esi);
|
||||
else
|
||||
zebra_evpn_rem_macip_del(w->vni, &w->macaddr, ipa_len,
|
||||
&w->ip, w->vtep_ip);
|
||||
} else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_VTEP) {
|
||||
if (w->add_p)
|
||||
zebra_vxlan_remote_vtep_add(w->vrf_id, w->vni,
|
||||
w->vtep_ip, w->flags);
|
||||
else
|
||||
zebra_vxlan_remote_vtep_del(w->vrf_id, w->vni,
|
||||
w->vtep_ip);
|
||||
}
|
||||
|
||||
|
||||
XFREE(MTYPE_WQ_WRAPPER, w);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the nexthop-group workqueue subqueue
|
||||
*/
|
||||
@ -2355,8 +2438,7 @@ static void process_subq_nhg(struct listnode *lnode)
|
||||
/* Process incoming nhg update, probably from a proto daemon */
|
||||
newnhe = zebra_nhg_proto_add(nhe->id, nhe->type,
|
||||
nhe->zapi_instance,
|
||||
nhe->zapi_session,
|
||||
&nhe->nhg, 0);
|
||||
nhe->zapi_session, &nhe->nhg, 0);
|
||||
|
||||
/* Report error to daemon via ZAPI */
|
||||
if (newnhe == NULL)
|
||||
@ -2368,7 +2450,7 @@ static void process_subq_nhg(struct listnode *lnode)
|
||||
zebra_nhg_free(nhe);
|
||||
}
|
||||
|
||||
XFREE(MTYPE_WQ_NHG_WRAPPER, w);
|
||||
XFREE(MTYPE_WQ_WRAPPER, w);
|
||||
}
|
||||
|
||||
static void process_subq_route(struct listnode *lnode, uint8_t qindex)
|
||||
@ -2411,9 +2493,9 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
|
||||
route_unlock_node(rnode);
|
||||
}
|
||||
|
||||
/* Take a list of route_node structs and return 1, if there was a record
|
||||
* picked from it and processed by rib_process(). Don't process more,
|
||||
* than one RN record; operate only in the specified sub-queue.
|
||||
/*
|
||||
* Examine the specified subqueue; process one entry and return 1 if
|
||||
* there is a node, return 0 otherwise.
|
||||
*/
|
||||
static unsigned int process_subq(struct list *subq, uint8_t qindex)
|
||||
{
|
||||
@ -2422,7 +2504,9 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex)
|
||||
if (!lnode)
|
||||
return 0;
|
||||
|
||||
if (qindex == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
|
||||
if (qindex == META_QUEUE_EVPN)
|
||||
process_subq_evpn(lnode);
|
||||
else if (qindex == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
|
||||
process_subq_nhg(lnode);
|
||||
else
|
||||
process_subq_route(lnode, qindex);
|
||||
@ -2432,7 +2516,7 @@ static unsigned int process_subq(struct list *subq, uint8_t qindex)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Dispatch the meta queue by picking, processing and unlocking the next RN from
|
||||
/* Dispatch the meta queue by picking and processing the next node from
|
||||
* a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and
|
||||
* data is pointed to the meta queue structure.
|
||||
*/
|
||||
@ -2538,7 +2622,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
|
||||
if (!ctx)
|
||||
return -1;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_NHG_WRAPPER, sizeof(struct wq_nhg_wrapper));
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_nhg_wrapper));
|
||||
|
||||
w->type = WQ_NHG_WRAPPER_TYPE_CTX;
|
||||
w->u.ctx = ctx;
|
||||
@ -2564,7 +2648,7 @@ static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data)
|
||||
if (!nhe)
|
||||
return -1;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_NHG_WRAPPER, sizeof(struct wq_nhg_wrapper));
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_nhg_wrapper));
|
||||
|
||||
w->type = WQ_NHG_WRAPPER_TYPE_NHG;
|
||||
w->u.nhe = nhe;
|
||||
@ -2579,6 +2663,14 @@ static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rib_meta_queue_evpn_add(struct meta_queue *mq, void *data)
|
||||
{
|
||||
listnode_add(mq->subq[META_QUEUE_EVPN], data);
|
||||
mq->size++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mq_add_handler(void *data,
|
||||
int (*mq_add_func)(struct meta_queue *mq, void *data))
|
||||
{
|
||||
@ -2640,6 +2732,225 @@ int rib_queue_nhe_add(struct nhg_hash_entry *nhe)
|
||||
return mq_add_handler(nhe, rib_meta_queue_nhg_add);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enqueue evpn route for processing
|
||||
*/
|
||||
int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
|
||||
const struct ipaddr *vtep_ip,
|
||||
const struct prefix *host_prefix)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE;
|
||||
w->add_p = true;
|
||||
w->vrf_id = vrf_id;
|
||||
w->macaddr = *rmac;
|
||||
w->ip = *vtep_ip;
|
||||
w->prefix = *host_prefix;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__,
|
||||
vrf_id, vtep_ip, host_prefix);
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
int zebra_rib_queue_evpn_route_del(vrf_id_t vrf_id,
|
||||
const struct ipaddr *vtep_ip,
|
||||
const struct prefix *host_prefix)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE;
|
||||
w->add_p = false;
|
||||
w->vrf_id = vrf_id;
|
||||
w->ip = *vtep_ip;
|
||||
w->prefix = *host_prefix;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug("%s: (%u)%pIA, host prefix %pFX enqueued", __func__,
|
||||
vrf_id, vtep_ip, host_prefix);
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
/* Enqueue EVPN remote ES for processing */
|
||||
int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi,
|
||||
const struct in_addr *vtep_ip,
|
||||
bool esr_rxed, uint8_t df_alg,
|
||||
uint16_t df_pref)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
char buf[ESI_STR_LEN];
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_REM_ES;
|
||||
w->add_p = true;
|
||||
w->esi = *esi;
|
||||
w->ip.ipa_type = IPADDR_V4;
|
||||
w->ip.ipaddr_v4 = *vtep_ip;
|
||||
w->esr_rxed = esr_rxed;
|
||||
w->df_alg = df_alg;
|
||||
w->df_pref = df_pref;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__, vtep_ip,
|
||||
esi_to_str(esi, buf, sizeof(buf)));
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi,
|
||||
const struct in_addr *vtep_ip)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
char buf[ESI_STR_LEN];
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_REM_ES;
|
||||
w->add_p = false;
|
||||
w->esi = *esi;
|
||||
w->ip.ipa_type = IPADDR_V4;
|
||||
w->ip.ipaddr_v4 = *vtep_ip;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
|
||||
if (memcmp(esi, zero_esi, sizeof(esi_t)) != 0)
|
||||
esi_to_str(esi, buf, sizeof(buf));
|
||||
else
|
||||
strlcpy(buf, "-", sizeof(buf));
|
||||
|
||||
zlog_debug("%s: vtep %pI4, esi %s enqueued", __func__, vtep_ip,
|
||||
buf);
|
||||
}
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enqueue EVPN remote macip update for processing
|
||||
*/
|
||||
int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
|
||||
const struct ipaddr *ipaddr,
|
||||
uint8_t flags, uint32_t seq,
|
||||
struct in_addr vtep_ip, const esi_t *esi)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
char buf[ESI_STR_LEN];
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP;
|
||||
w->add_p = true;
|
||||
w->vni = vni;
|
||||
w->macaddr = *macaddr;
|
||||
w->ip = *ipaddr;
|
||||
w->flags = flags;
|
||||
w->seq = seq;
|
||||
w->vtep_ip = vtep_ip;
|
||||
w->esi = *esi;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
|
||||
if (memcmp(esi, zero_esi, sizeof(esi_t)) != 0)
|
||||
esi_to_str(esi, buf, sizeof(buf));
|
||||
else
|
||||
strlcpy(buf, "-", sizeof(buf));
|
||||
|
||||
zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__,
|
||||
macaddr, &vtep_ip, buf);
|
||||
}
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
|
||||
const struct ipaddr *ip,
|
||||
struct in_addr vtep_ip)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP;
|
||||
w->add_p = false;
|
||||
w->vni = vni;
|
||||
w->macaddr = *macaddr;
|
||||
w->ip = *ip;
|
||||
w->vtep_ip = vtep_ip;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__,
|
||||
macaddr, &vtep_ip);
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enqueue remote VTEP address for processing
|
||||
*/
|
||||
int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip, int flood_control)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_REM_VTEP;
|
||||
w->add_p = true;
|
||||
w->vrf_id = vrf_id;
|
||||
w->vni = vni;
|
||||
w->vtep_ip = vtep_ip;
|
||||
w->flags = flood_control;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__, vrf_id,
|
||||
&vtep_ip);
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip)
|
||||
{
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
|
||||
|
||||
w->type = WQ_EVPN_WRAPPER_TYPE_REM_VTEP;
|
||||
w->add_p = false;
|
||||
w->vrf_id = vrf_id;
|
||||
w->vni = vni;
|
||||
w->vtep_ip = vtep_ip;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug("%s: vrf %u, vtep %pI4 enqueued", __func__, vrf_id,
|
||||
&vtep_ip);
|
||||
|
||||
return mq_add_handler(w, rib_meta_queue_evpn_add);
|
||||
}
|
||||
|
||||
/* Clean up the EVPN meta-queue list */
|
||||
static void evpn_meta_queue_free(struct list *l)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct wq_evpn_wrapper *w;
|
||||
|
||||
/* Free the node wrapper object, and the struct it wraps */
|
||||
while ((node = listhead(l)) != NULL) {
|
||||
w = node->data;
|
||||
node->data = NULL;
|
||||
|
||||
XFREE(MTYPE_WQ_WRAPPER, w);
|
||||
|
||||
list_delete_node(l, node);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up the nhg meta-queue list */
|
||||
static void nhg_meta_queue_free(struct list *l)
|
||||
{
|
||||
@ -2656,7 +2967,7 @@ static void nhg_meta_queue_free(struct list *l)
|
||||
else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG)
|
||||
zebra_nhg_free(w->u.nhe);
|
||||
|
||||
XFREE(MTYPE_WQ_NHG_WRAPPER, w);
|
||||
XFREE(MTYPE_WQ_WRAPPER, w);
|
||||
|
||||
list_delete_node(l, node);
|
||||
}
|
||||
@ -2688,6 +2999,8 @@ void meta_queue_free(struct meta_queue *mq)
|
||||
/* Some subqueues may need cleanup - nhgs for example */
|
||||
if (i == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
|
||||
nhg_meta_queue_free(mq->subq[i]);
|
||||
else if (i == META_QUEUE_EVPN)
|
||||
evpn_meta_queue_free(mq->subq[i]);
|
||||
|
||||
list_delete(&mq->subq[i]);
|
||||
}
|
||||
@ -2763,7 +3076,7 @@ rib_dest_t *zebra_rib_create_dest(struct route_node *rn)
|
||||
* dest is created on-demand by rib_link() and is kept around at least
|
||||
* as long as there are ribs hanging off it (@see rib_gc_dest()).
|
||||
*
|
||||
* Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):
|
||||
* Refcounting (aka "locking" throughout the Zebra and FRR code):
|
||||
*
|
||||
* - route_nodes: refcounted by:
|
||||
* - dest attached to route_node:
|
||||
@ -3518,7 +3831,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||
&(tmp_nh->gate.ipv6),
|
||||
sizeof(struct in6_addr));
|
||||
}
|
||||
zebra_vxlan_evpn_vrf_route_del(re->vrf_id,
|
||||
zebra_rib_queue_evpn_route_del(re->vrf_id,
|
||||
&vtep_ip, p);
|
||||
}
|
||||
}
|
||||
|
@ -3820,10 +3820,6 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
|
||||
uint16_t l = 0, ipa_len;
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
|
||||
memset(&macaddr, 0, sizeof(struct ethaddr));
|
||||
memset(&ip, 0, sizeof(struct ipaddr));
|
||||
memset(&vtep_ip, 0, sizeof(struct in_addr));
|
||||
|
||||
s = msg;
|
||||
|
||||
while (l < hdr->length) {
|
||||
@ -3844,7 +3840,8 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
|
||||
ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
|
||||
&vtep_ip, zebra_route_string(client->proto));
|
||||
|
||||
process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
|
||||
/* Enqueue to workqueue for processing */
|
||||
zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
@ -3870,10 +3867,6 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
|
||||
esi_t esi;
|
||||
char esi_buf[ESI_STR_LEN];
|
||||
|
||||
memset(&macaddr, 0, sizeof(struct ethaddr));
|
||||
memset(&ip, 0, sizeof(struct ipaddr));
|
||||
memset(&vtep_ip, 0, sizeof(struct in_addr));
|
||||
|
||||
if (!EVPN_ENABLED(zvrf)) {
|
||||
zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
|
||||
return;
|
||||
@ -3882,6 +3875,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
|
||||
s = msg;
|
||||
|
||||
while (l < hdr->length) {
|
||||
|
||||
int res_length = zebra_vxlan_remote_macip_helper(
|
||||
true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
|
||||
&flags, &seq, &esi);
|
||||
@ -3907,8 +3901,9 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
|
||||
zebra_route_string(client->proto));
|
||||
}
|
||||
|
||||
process_remote_macip_add(vni, &macaddr, ipa_len, &ip,
|
||||
flags, seq, vtep_ip, &esi);
|
||||
/* Enqueue to workqueue for processing */
|
||||
zebra_rib_queue_evpn_rem_macip_add(vni, &macaddr, &ip, flags,
|
||||
seq, vtep_ip, &esi);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
@ -4204,27 +4199,23 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
|
||||
/*
|
||||
* Handle message from client to delete a remote VTEP for an EVPN.
|
||||
*/
|
||||
void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
|
||||
void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
unsigned short l = 0;
|
||||
vni_t vni;
|
||||
struct in_addr vtep_ip;
|
||||
zebra_evpn_t *zevpn;
|
||||
zebra_vtep_t *zvtep;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zif;
|
||||
|
||||
if (!is_evpn_enabled()) {
|
||||
zlog_debug(
|
||||
"%s: EVPN is not enabled yet we have received a vtep del command",
|
||||
"%s: EVPN is not enabled yet we have received a VTEP DEL msg",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EVPN_ENABLED(zvrf)) {
|
||||
zlog_debug("Recv MACIP DEL for non-EVPN VRF %u",
|
||||
zvrf_id(zvrf));
|
||||
zlog_debug("Recv VTEP DEL zapi for non-EVPN VRF %u",
|
||||
zvrf_id(zvrf));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4244,76 +4235,182 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
|
||||
l += 4;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug("Recv VTEP_DEL %pI4 VNI %u from %s",
|
||||
zlog_debug("Recv VTEP DEL %pI4 VNI %u from %s",
|
||||
&vtep_ip, vni,
|
||||
zebra_route_string(client->proto));
|
||||
|
||||
/* Locate VNI hash entry - expected to exist. */
|
||||
zevpn = zebra_evpn_lookup(vni);
|
||||
if (!zevpn) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"Failed to locate VNI hash upon remote VTEP DEL, VNI %u",
|
||||
vni);
|
||||
continue;
|
||||
}
|
||||
|
||||
ifp = zevpn->vxlan_if;
|
||||
if (!ifp) {
|
||||
zlog_debug(
|
||||
"VNI %u hash %p doesn't have intf upon remote VTEP DEL",
|
||||
zevpn->vni, zevpn);
|
||||
continue;
|
||||
}
|
||||
zif = ifp->info;
|
||||
|
||||
/* If down or not mapped to a bridge, we're done. */
|
||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||
continue;
|
||||
|
||||
/* If the remote VTEP does not exist, there's nothing more to
|
||||
* do.
|
||||
* Otherwise, uninstall any remote MACs pointing to this VTEP
|
||||
* and
|
||||
* then, the VTEP entry itself and remove it.
|
||||
*/
|
||||
zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
|
||||
if (!zvtep)
|
||||
continue;
|
||||
|
||||
zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
|
||||
zebra_evpn_vtep_del(zevpn, zvtep);
|
||||
/* Enqueue for processing */
|
||||
zebra_rib_queue_evpn_rem_vtep_del(zvrf_id(zvrf), vni, vtep_ip);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle message from client to delete a remote VTEP for an EVPN.
|
||||
*/
|
||||
void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip)
|
||||
{
|
||||
zebra_evpn_t *zevpn;
|
||||
zebra_vtep_t *zvtep;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zif;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
if (!is_evpn_enabled()) {
|
||||
zlog_debug("%s: Can't process vtep del: EVPN is not enabled",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
zvrf = zebra_vrf_lookup_by_id(vrf_id);
|
||||
if (!zvrf)
|
||||
return;
|
||||
|
||||
if (!EVPN_ENABLED(zvrf)) {
|
||||
zlog_debug("Can't process VTEP DEL for non-EVPN VRF %u",
|
||||
zvrf_id(zvrf));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Locate VNI hash entry - expected to exist. */
|
||||
zevpn = zebra_evpn_lookup(vni);
|
||||
if (!zevpn) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"Failed to locate VNI hash for remote VTEP DEL, VNI %u",
|
||||
vni);
|
||||
return;
|
||||
}
|
||||
|
||||
ifp = zevpn->vxlan_if;
|
||||
if (!ifp) {
|
||||
zlog_debug(
|
||||
"VNI %u hash %p doesn't have intf upon remote VTEP DEL",
|
||||
zevpn->vni, zevpn);
|
||||
return;
|
||||
}
|
||||
zif = ifp->info;
|
||||
|
||||
/* If down or not mapped to a bridge, we're done. */
|
||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||
return;
|
||||
|
||||
/* If the remote VTEP does not exist, there's nothing more to
|
||||
* do.
|
||||
* Otherwise, uninstall any remote MACs pointing to this VTEP
|
||||
* and then, the VTEP entry itself and remove it.
|
||||
*/
|
||||
zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
|
||||
if (!zvtep)
|
||||
return;
|
||||
|
||||
zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
|
||||
zebra_evpn_vtep_del(zevpn, zvtep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle message from client to add a remote VTEP for an EVPN.
|
||||
*/
|
||||
void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
|
||||
void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip, int flood_control)
|
||||
{
|
||||
zebra_evpn_t *zevpn;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zif;
|
||||
zebra_vtep_t *zvtep;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
if (!is_evpn_enabled()) {
|
||||
zlog_debug("%s: EVPN not enabled: can't process a VTEP ADD",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
zvrf = zebra_vrf_lookup_by_id(vrf_id);
|
||||
if (!zvrf)
|
||||
return;
|
||||
|
||||
if (!EVPN_ENABLED(zvrf)) {
|
||||
zlog_debug("Can't process VTEP ADD for non-EVPN VRF %u",
|
||||
zvrf_id(zvrf));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Locate VNI hash entry - expected to exist. */
|
||||
zevpn = zebra_evpn_lookup(vni);
|
||||
if (!zevpn) {
|
||||
flog_err(
|
||||
EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to locate EVPN hash upon remote VTEP ADD, VNI %u",
|
||||
vni);
|
||||
return;
|
||||
}
|
||||
|
||||
ifp = zevpn->vxlan_if;
|
||||
if (!ifp) {
|
||||
flog_err(
|
||||
EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"VNI %u hash %p doesn't have intf upon remote VTEP ADD",
|
||||
zevpn->vni, zevpn);
|
||||
return;
|
||||
}
|
||||
|
||||
zif = ifp->info;
|
||||
|
||||
/* If down or not mapped to a bridge, we're done. */
|
||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||
return;
|
||||
|
||||
zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
|
||||
if (zvtep) {
|
||||
/* If the remote VTEP already exists check if
|
||||
* the flood mode has changed
|
||||
*/
|
||||
if (zvtep->flood_control != flood_control) {
|
||||
if (zvtep->flood_control == VXLAN_FLOOD_DISABLED)
|
||||
/* old mode was head-end-replication but
|
||||
* is no longer; get rid of the HER fdb
|
||||
* entry installed before
|
||||
*/
|
||||
zebra_evpn_vtep_uninstall(zevpn, &vtep_ip);
|
||||
zvtep->flood_control = flood_control;
|
||||
zebra_evpn_vtep_install(zevpn, zvtep);
|
||||
}
|
||||
} else {
|
||||
zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip, flood_control);
|
||||
if (zvtep)
|
||||
zebra_evpn_vtep_install(zevpn, zvtep);
|
||||
else
|
||||
flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to add remote VTEP, VNI %u zevpn %p",
|
||||
vni, zevpn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle message from client to add a remote VTEP for an EVPN.
|
||||
*/
|
||||
void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
unsigned short l = 0;
|
||||
vni_t vni;
|
||||
struct in_addr vtep_ip;
|
||||
zebra_evpn_t *zevpn;
|
||||
struct interface *ifp;
|
||||
struct zebra_if *zif;
|
||||
int flood_control;
|
||||
zebra_vtep_t *zvtep;
|
||||
|
||||
if (!is_evpn_enabled()) {
|
||||
zlog_debug(
|
||||
"%s: EVPN not enabled yet we received a vtep_add zapi call",
|
||||
"%s: EVPN not enabled yet we received a VTEP ADD zapi msg",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EVPN_ENABLED(zvrf)) {
|
||||
zlog_debug("Recv MACIP ADD for non-EVPN VRF %u",
|
||||
zvrf_id(zvrf));
|
||||
zlog_debug("Recv VTEP ADD zapi for non-EVPN VRF %u",
|
||||
zvrf_id(zvrf));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4328,62 +4425,13 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
|
||||
l += IPV4_MAX_BYTELEN + 4;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug("Recv VTEP_ADD %pI4 VNI %u flood %d from %s",
|
||||
&vtep_ip, vni, flood_control,
|
||||
zebra_route_string(client->proto));
|
||||
zlog_debug("Recv VTEP ADD %pI4 VNI %u flood %d from %s",
|
||||
&vtep_ip, vni, flood_control,
|
||||
zebra_route_string(client->proto));
|
||||
|
||||
/* Locate VNI hash entry - expected to exist. */
|
||||
zevpn = zebra_evpn_lookup(vni);
|
||||
if (!zevpn) {
|
||||
flog_err(
|
||||
EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to locate EVPN hash upon remote VTEP ADD, VNI %u",
|
||||
vni);
|
||||
continue;
|
||||
}
|
||||
|
||||
ifp = zevpn->vxlan_if;
|
||||
if (!ifp) {
|
||||
flog_err(
|
||||
EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"VNI %u hash %p doesn't have intf upon remote VTEP ADD",
|
||||
zevpn->vni, zevpn);
|
||||
continue;
|
||||
}
|
||||
|
||||
zif = ifp->info;
|
||||
|
||||
/* If down or not mapped to a bridge, we're done. */
|
||||
if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
|
||||
continue;
|
||||
|
||||
zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
|
||||
if (zvtep) {
|
||||
/* If the remote VTEP already exists check if
|
||||
* the flood mode has changed
|
||||
*/
|
||||
if (zvtep->flood_control != flood_control) {
|
||||
if (zvtep->flood_control
|
||||
== VXLAN_FLOOD_DISABLED)
|
||||
/* old mode was head-end-replication but
|
||||
* is no longer; get rid of the HER fdb
|
||||
* entry installed before
|
||||
*/
|
||||
zebra_evpn_vtep_uninstall(zevpn,
|
||||
&vtep_ip);
|
||||
zvtep->flood_control = flood_control;
|
||||
zebra_evpn_vtep_install(zevpn, zvtep);
|
||||
}
|
||||
} else {
|
||||
zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip,
|
||||
flood_control);
|
||||
if (zvtep)
|
||||
zebra_evpn_vtep_install(zevpn, zvtep);
|
||||
else
|
||||
flog_err(EC_ZEBRA_VTEP_ADD_FAILED,
|
||||
"Failed to add remote VTEP, VNI %u zevpn %p",
|
||||
vni, zevpn);
|
||||
}
|
||||
/* Enqueue for processing */
|
||||
zebra_rib_queue_evpn_rem_vtep_add(zvrf_id(zvrf), vni, vtep_ip,
|
||||
flood_control);
|
||||
}
|
||||
|
||||
stream_failure:
|
||||
@ -4398,7 +4446,7 @@ stream_failure:
|
||||
* 3. vrr interface (MACVLAN) associated to a SVI
|
||||
* We advertise macip routes for an interface if it is associated to VxLan vlan
|
||||
*/
|
||||
int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
|
||||
int zebra_vxlan_add_del_gw_macip(struct interface *ifp, const struct prefix *p,
|
||||
int add)
|
||||
{
|
||||
struct ipaddr ip;
|
||||
|
@ -72,8 +72,12 @@ is_vxlan_flooding_head_end(void)
|
||||
/* ZAPI message handlers */
|
||||
extern void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_remote_vtep_add_zapi(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_remote_vtep_del_zapi(ZAPI_HANDLER_ARGS);
|
||||
void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip, int flood_control);
|
||||
extern void zebra_vxlan_remote_vtep_del(vrf_id_t vrf_id, vni_t vni,
|
||||
struct in_addr vtep_ip);
|
||||
extern void zebra_vxlan_flood_control(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS);
|
||||
@ -157,8 +161,8 @@ extern void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json);
|
||||
extern void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, bool use_json);
|
||||
extern void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
|
||||
json_object *json_vrfs);
|
||||
extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
|
||||
int add);
|
||||
extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp,
|
||||
const struct prefix *p, int add);
|
||||
extern int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if);
|
||||
extern int zebra_vxlan_svi_down(struct interface *ifp,
|
||||
struct interface *link_if);
|
||||
|
Loading…
Reference in New Issue
Block a user