diff options
Diffstat (limited to 'zebra/zebra_vxlan.c')
| -rw-r--r-- | zebra/zebra_vxlan.c | 169 |
1 files changed, 84 insertions, 85 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 28bed846cf..424c00d5eb 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1992,7 +1992,10 @@ static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt) } /* - * handle transition of vni from l2 to l3 and vice versa + * Handle transition of vni from l2 to l3 and vice versa. + * This function handles only the L2VNI add/delete part of + * the above transition. + * L3VNI add/delete is handled by the calling functions. */ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, int add) @@ -2033,11 +2036,71 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni, return -1; } } else { - /* TODO_MITESH: This needs to be thought through. We don't have - * enough information at this point to reprogram the vni as - * l2-vni. One way is to store the required info in l3-vni and - * used it solely for this purpose - */ + struct zebra_ns *zns; + struct route_node *rn; + struct interface *ifp; + struct zebra_if *zif; + struct zebra_l2info_vxlan *vxl; + struct interface *vlan_if; + bool found = false; + + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("Adding L2-VNI %u - transition from L3-VNI", + vni); + + /* Find VxLAN interface for this VNI. */ + zns = zebra_ns_lookup(NS_DEFAULT); + for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { + ifp = (struct interface *)rn->info; + if (!ifp) + continue; + zif = ifp->info; + if (!zif || zif->zif_type != ZEBRA_IF_VXLAN) + continue; + + vxl = &zif->l2info.vxl; + if (vxl->vni == vni) { + found = true; + break; + } + } + + if (!found) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_err( + "Adding L2-VNI - Failed to find VxLAN interface for VNI %u", + vni); + return -1; + } + + /* Create VNI hash entry for L2VNI */ + zevpn = zebra_evpn_lookup(vni); + if (zevpn) + return 0; + + zevpn = zebra_evpn_add(vni); + if (!zevpn) { + flog_err(EC_ZEBRA_VNI_ADD_FAILED, + "Adding L2-VNI - Failed to add VNI hash, VNI %u", + vni); + + return -1; + } + + /* Find bridge interface for the VNI */ + vlan_if = zvni_map_to_svi(vxl->access_vlan, + zif->brslave_info.br_if); + if (vlan_if) + zevpn->vrf_id = vlan_if->vrf_id; + + zevpn->vxlan_if = ifp; + zevpn->local_vtep_ip = vxl->vtep_ip; + + /* Inform BGP if the VNI is up and mapped to a bridge. */ + if (if_is_operative(ifp) && zif->brslave_info.br_if) { + zebra_evpn_send_add_to_client(zevpn); + zebra_evpn_read_mac_neigh(zevpn, ifp); + } } return 0; @@ -3270,7 +3333,7 @@ int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni) zevpn = zebra_evpn_lookup(vni); if (!zevpn) { - zlog_warn("VNI %u does not exist\n", vni); + zlog_warn("VNI %u does not exist", vni); return CMD_WARNING; } @@ -3678,13 +3741,13 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH) zlog_debug( - "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s%s%s-> L2-VNI %u", + "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s%s%s%s-> L2-VNI %u", ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, state, is_ext ? "ext-learned " : "", is_router ? "router " : "", local_inactive ? "local_inactive " : "", - zevpn->vni); + dp_static ? "peer_sync " : "", zevpn->vni); /* Is this about a local neighbor or a remote one? */ if (!is_ext) @@ -4008,7 +4071,6 @@ int zebra_vxlan_dp_network_mac_add(struct interface *ifp, * 1. readd the remote MAC if we have it * 2. local MAC with does ES may also need to be re-installed */ -static int zebra_vxlan_do_local_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac); int zebra_vxlan_dp_network_mac_del(struct interface *ifp, struct interface *br_if, struct ethaddr *macaddr, vlanid_t vid) @@ -4059,72 +4121,7 @@ int zebra_vxlan_dp_network_mac_del(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) zlog_debug("dpDel local-nw-MAC %pEA VNI %u", macaddr, vni); - zebra_vxlan_do_local_mac_del(zevpn, mac); - } - - return 0; -} - -static int zebra_vxlan_do_local_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac) -{ - bool old_bgp_ready; - bool new_bgp_ready; - - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("DEL MAC %pEA VNI %u seq %u flags 0x%x nbr count %u", - &mac->macaddr, zevpn->vni, mac->loc_seq, mac->flags, - listcount(mac->neigh_list)); - - old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); - if (zebra_evpn_mac_is_static(mac)) { - /* this is a synced entry and can only be removed when the - * es-peers stop advertising it. - */ - memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); - - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) - zlog_debug( - "re-add sync-mac vni %u mac %pEA es %s seq %d f 0x%x", - zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->loc_seq, - mac->flags); - - /* inform-bgp about change in local-activity if any */ - if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE)) { - SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE); - new_bgp_ready = - zebra_evpn_mac_is_ready_for_bgp(mac->flags); - zebra_evpn_mac_send_add_del_to_client( - mac, old_bgp_ready, new_bgp_ready); - } - - /* re-install the entry in the kernel */ - zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */, - false /* force_clear_static */, - __func__); - - return 0; - } - - /* Update all the neigh entries associated with this mac */ - zebra_evpn_process_neigh_on_local_mac_del(zevpn, mac); - - /* Remove MAC from BGP. */ - zebra_evpn_mac_send_del_to_client(zevpn->vni, &mac->macaddr, mac->flags, - false /* force */); - - zebra_evpn_es_mac_deref_entry(mac); - - /* - * If there are no neigh associated with the mac delete the mac - * else mark it as AUTO for forward reference - */ - if (!listcount(mac->neigh_list)) { - zebra_evpn_mac_del(zevpn, mac); - } else { - UNSET_FLAG(mac->flags, ZEBRA_MAC_ALL_LOCAL_FLAGS); - UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY); - SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + return zebra_evpn_del_local_mac(zevpn, mac); } return 0; @@ -4161,7 +4158,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if, if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return 0; - return zebra_vxlan_do_local_mac_del(zevpn, mac); + return zebra_evpn_del_local_mac(zevpn, mac); } /* @@ -5201,6 +5198,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, if (add) { + /* Remove L2VNI if present */ zebra_vxlan_handle_vni_transition(zvrf, vni, add); /* check if the vni is already present under zvrf */ @@ -5295,6 +5293,7 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf, vni_t vni, zvrf->l3vni = 0; zl3vni_del(zl3vni); + /* Add L2VNI for this VNI */ zebra_vxlan_handle_vni_transition(zvrf, vni, add); } return 0; @@ -6050,9 +6049,9 @@ static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp); } -static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *backet, void *arg) +static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg) { - zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data; + zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)bucket->data; /* increment the ref count against (*,G) to prevent them from being * deleted @@ -6061,9 +6060,9 @@ static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *backet, void *arg) ++vxlan_sg->ref_cnt; } -static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *backet, void *arg) +static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *bucket, void *arg) { - zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data; + zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)bucket->data; /* decrement the dummy ref count against (*,G) to delete them */ if (vxlan_sg->sg.src.s_addr == INADDR_ANY) { @@ -6074,9 +6073,9 @@ static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *backet, void *arg) } } -static void zebra_vxlan_sg_cleanup(struct hash_bucket *backet, void *arg) +static void zebra_vxlan_sg_cleanup(struct hash_bucket *bucket, void *arg) { - zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data; + zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)bucket->data; zebra_vxlan_sg_del(vxlan_sg); } @@ -6094,9 +6093,9 @@ static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf) hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_xg_post_cleanup, NULL); } -static void zebra_vxlan_sg_replay_send(struct hash_bucket *backet, void *arg) +static void zebra_vxlan_sg_replay_send(struct hash_bucket *bucket, void *arg) { - zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data; + zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)bucket->data; zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg, vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD); |
