back to topotato report
topotato coverage report
Current view: top level - zebra - zebra_evpn.c (source / functions) Hit Total Coverage
Test: test_demo.py::AllStartupTest Lines: 2 783 0.3 %
Date: 2023-02-24 18:37:51 Functions: 4 47 8.5 %

          Line data    Source code
       1             : /*
       2             :  * Zebra EVPN for VxLAN code
       3             :  * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
       4             :  *
       5             :  * This file is part of FRR.
       6             :  *
       7             :  * FRR is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * FRR is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with FRR; see the file COPYING.  If not, write to the Free
      19             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      20             :  * 02111-1307, USA.
      21             :  */
      22             : #include <zebra.h>
      23             : 
      24             : #include "hash.h"
      25             : #include "if.h"
      26             : #include "jhash.h"
      27             : #include "linklist.h"
      28             : #include "log.h"
      29             : #include "memory.h"
      30             : #include "prefix.h"
      31             : #include "stream.h"
      32             : #include "table.h"
      33             : #include "vlan.h"
      34             : #include "vxlan.h"
      35             : #ifdef GNU_LINUX
      36             : #include <linux/neighbour.h>
      37             : #endif
      38             : 
      39             : #include "zebra/zebra_router.h"
      40             : #include "zebra/debug.h"
      41             : #include "zebra/interface.h"
      42             : #include "zebra/rib.h"
      43             : #include "zebra/rt.h"
      44             : #include "zebra/rt_netlink.h"
      45             : #include "zebra/zebra_errors.h"
      46             : #include "zebra/zebra_l2.h"
      47             : #include "zebra/zebra_ns.h"
      48             : #include "zebra/zebra_vrf.h"
      49             : #include "zebra/zebra_vxlan.h"
      50             : #include "zebra/zebra_evpn.h"
      51             : #include "zebra/zebra_evpn_mac.h"
      52             : #include "zebra/zebra_evpn_neigh.h"
      53             : #include "zebra/zebra_vxlan_private.h"
      54             : #include "zebra/zebra_evpn_mh.h"
      55             : #include "zebra/zebra_evpn_vxlan.h"
      56             : #include "zebra/zebra_router.h"
      57             : 
      58           3 : DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN, "VNI hash");
      59           3 : DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN_VTEP, "VNI remote VTEP");
      60             : 
      61             : /* PMSI strings. */
      62             : #define VXLAN_FLOOD_STR_NO_INFO "-"
      63             : #define VXLAN_FLOOD_STR_DEFAULT VXLAN_FLOOD_STR_NO_INFO
      64             : static const struct message zvtep_flood_str[] = {
      65             :         {VXLAN_FLOOD_DISABLED, VXLAN_FLOOD_STR_NO_INFO},
      66             :         {VXLAN_FLOOD_PIM_SM, "PIM-SM"},
      67             :         {VXLAN_FLOOD_HEAD_END_REPL, "HER"},
      68             :         {0}
      69             : };
      70             : 
      71           0 : int advertise_gw_macip_enabled(struct zebra_evpn *zevpn)
      72             : {
      73           0 :         struct zebra_vrf *zvrf;
      74             : 
      75           0 :         zvrf = zebra_vrf_get_evpn();
      76           0 :         if (zvrf->advertise_gw_macip)
      77             :                 return 1;
      78             : 
      79           0 :         if (zevpn && zevpn->advertise_gw_macip)
      80           0 :                 return 1;
      81             : 
      82             :         return 0;
      83             : }
      84             : 
      85           0 : int advertise_svi_macip_enabled(struct zebra_evpn *zevpn)
      86             : {
      87           0 :         struct zebra_vrf *zvrf;
      88             : 
      89           0 :         zvrf = zebra_vrf_get_evpn();
      90           0 :         if (zvrf->advertise_svi_macip)
      91             :                 return 1;
      92             : 
      93           0 :         if (zevpn && zevpn->advertise_svi_macip)
      94           0 :                 return 1;
      95             : 
      96             :         return 0;
      97             : }
      98             : 
      99             : /*
     100             :  * Print a specific EVPN entry.
     101             :  */
     102           0 : void zebra_evpn_print(struct zebra_evpn *zevpn, void **ctxt)
     103             : {
     104             : 
     105           0 :         struct vty *vty = NULL;
     106           0 :         struct zebra_vtep *zvtep = NULL;
     107           0 :         uint32_t num_macs = 0;
     108           0 :         uint32_t num_neigh = 0;
     109           0 :         uint32_t num_vteps = 0;
     110           0 :         json_object *json = NULL;
     111           0 :         json_object *json_vtep_list = NULL;
     112           0 :         json_object *json_vtep = NULL;
     113             : 
     114           0 :         vty = ctxt[0];
     115           0 :         json = ctxt[1];
     116             : 
     117           0 :         if (json == NULL) {
     118           0 :                 vty_out(vty, "VNI: %u\n", zevpn->vni);
     119           0 :                 vty_out(vty, " Type: %s\n", "L2");
     120           0 :                 vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zevpn->vrf_id));
     121             :         } else {
     122           0 :                 json_object_int_add(json, "vni", zevpn->vni);
     123           0 :                 json_object_string_add(json, "type", "L2");
     124             : #if CONFDATE > 20240210
     125             : CPP_NOTICE("Drop `vrf` from JSON output")
     126             : #endif
     127           0 :                 json_object_string_add(json, "vrf",
     128             :                                        vrf_id_to_name(zevpn->vrf_id));
     129           0 :                 json_object_string_add(json, "tenantVrf",
     130             :                                        vrf_id_to_name(zevpn->vrf_id));
     131             :         }
     132             : 
     133           0 :         if (!zevpn->vxlan_if) { // unexpected
     134           0 :                 if (json == NULL)
     135           0 :                         vty_out(vty, " VxLAN interface: unknown\n");
     136             :                 else
     137           0 :                         json_object_string_add(json, "vxlanInterface",
     138             :                                                "unknown");
     139           0 :                 return;
     140             :         }
     141           0 :         num_macs = num_valid_macs(zevpn);
     142           0 :         num_neigh = hashcount(zevpn->neigh_table);
     143           0 :         if (json == NULL) {
     144           0 :                 vty_out(vty, " VxLAN interface: %s\n", zevpn->vxlan_if->name);
     145           0 :                 vty_out(vty, " VxLAN ifIndex: %u\n", zevpn->vxlan_if->ifindex);
     146           0 :                 vty_out(vty, " SVI interface: %s\n",
     147           0 :                         (zevpn->svi_if ? zevpn->svi_if->name : ""));
     148           0 :                 vty_out(vty, " SVI ifIndex: %u\n",
     149           0 :                         (zevpn->svi_if ? zevpn->svi_if->ifindex : 0));
     150           0 :                 vty_out(vty, " Local VTEP IP: %pI4\n",
     151             :                         &zevpn->local_vtep_ip);
     152           0 :                 vty_out(vty, " Mcast group: %pI4\n",
     153             :                                 &zevpn->mcast_grp);
     154             :         } else {
     155           0 :                 json_object_string_add(json, "vxlanInterface",
     156           0 :                                        zevpn->vxlan_if->name);
     157             : #if CONFDATE > 20240210
     158             : CPP_NOTICE("Drop `ifindex` from JSON output")
     159             : #endif
     160           0 :                 json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex);
     161           0 :                 json_object_int_add(json, "vxlanIfindex",
     162           0 :                                     zevpn->vxlan_if->ifindex);
     163           0 :                 if (zevpn->svi_if) {
     164           0 :                         json_object_string_add(json, "sviInterface",
     165           0 :                                                zevpn->svi_if->name);
     166           0 :                         json_object_int_add(json, "sviIfindex",
     167           0 :                                             zevpn->svi_if->ifindex);
     168             :                 }
     169           0 :                 json_object_string_addf(json, "vtepIp", "%pI4",
     170             :                                         &zevpn->local_vtep_ip);
     171           0 :                 json_object_string_addf(json, "mcastGroup", "%pI4",
     172             :                                         &zevpn->mcast_grp);
     173           0 :                 json_object_string_add(json, "advertiseGatewayMacip",
     174           0 :                                        zevpn->advertise_gw_macip ? "Yes"
     175             :                                                                  : "No");
     176           0 :                 json_object_string_add(json, "advertiseSviMacip",
     177           0 :                                        zevpn->advertise_svi_macip ? "Yes"
     178             :                                                                   : "No");
     179           0 :                 json_object_int_add(json, "numMacs", num_macs);
     180           0 :                 json_object_int_add(json, "numArpNd", num_neigh);
     181             :         }
     182           0 :         if (!zevpn->vteps) {
     183           0 :                 if (json == NULL)
     184           0 :                         vty_out(vty, " No remote VTEPs known for this VNI\n");
     185             :                 else
     186           0 :                         json_object_int_add(json, "numRemoteVteps", num_vteps);
     187             :         } else {
     188           0 :                 if (json == NULL)
     189           0 :                         vty_out(vty, " Remote VTEPs for this VNI:\n");
     190             :                 else
     191           0 :                         json_vtep_list = json_object_new_array();
     192           0 :                 for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
     193           0 :                         const char *flood_str = lookup_msg(
     194             :                                 zvtep_flood_str, zvtep->flood_control,
     195             :                                 VXLAN_FLOOD_STR_DEFAULT);
     196             : 
     197           0 :                         if (json == NULL) {
     198           0 :                                 vty_out(vty, "  %pI4 flood: %s\n",
     199             :                                                 &zvtep->vtep_ip,
     200             :                                                 flood_str);
     201             :                         } else {
     202           0 :                                 json_vtep = json_object_new_object();
     203           0 :                                 json_object_string_addf(json_vtep, "ip", "%pI4",
     204             :                                                         &zvtep->vtep_ip);
     205           0 :                                 json_object_string_add(json_vtep, "flood",
     206             :                                                        flood_str);
     207           0 :                                 json_object_array_add(json_vtep_list,
     208             :                                                       json_vtep);
     209             :                         }
     210           0 :                         num_vteps++;
     211             :                 }
     212           0 :                 if (json) {
     213           0 :                         json_object_int_add(json, "numRemoteVteps", num_vteps);
     214           0 :                         json_object_object_add(json, "remoteVteps",
     215             :                                                json_vtep_list);
     216             :                 }
     217             :         }
     218           0 :         if (json == NULL) {
     219           0 :                 vty_out(vty,
     220             :                         " Number of MACs (local and remote) known for this VNI: %u\n",
     221             :                         num_macs);
     222           0 :                 vty_out(vty,
     223             :                         " Number of ARPs (IPv4 and IPv6, local and remote) "
     224             :                         "known for this VNI: %u\n",
     225             :                         num_neigh);
     226           0 :                 vty_out(vty, " Advertise-gw-macip: %s\n",
     227           0 :                         zevpn->advertise_gw_macip ? "Yes" : "No");
     228           0 :                 vty_out(vty, " Advertise-svi-macip: %s\n",
     229           0 :                         zevpn->advertise_svi_macip ? "Yes" : "No");
     230             :         }
     231             : }
     232             : 
     233             : /*
     234             :  * Print an EVPN hash entry - called for display of all VNIs.
     235             :  */
     236           0 : void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
     237             : {
     238           0 :         struct vty *vty;
     239           0 :         struct zebra_evpn *zevpn;
     240           0 :         struct zebra_vtep *zvtep;
     241           0 :         uint32_t num_vteps = 0;
     242           0 :         uint32_t num_macs = 0;
     243           0 :         uint32_t num_neigh = 0;
     244           0 :         json_object *json = NULL;
     245           0 :         json_object *json_evpn = NULL;
     246           0 :         json_object *json_ip_str = NULL;
     247           0 :         json_object *json_vtep_list = NULL;
     248           0 :         char buf[PREFIX_STRLEN];
     249             : 
     250           0 :         vty = ctxt[0];
     251           0 :         json = ctxt[1];
     252             : 
     253           0 :         zevpn = (struct zebra_evpn *)bucket->data;
     254             : 
     255           0 :         zvtep = zevpn->vteps;
     256           0 :         while (zvtep) {
     257           0 :                 num_vteps++;
     258           0 :                 zvtep = zvtep->next;
     259             :         }
     260             : 
     261           0 :         num_macs = num_valid_macs(zevpn);
     262           0 :         num_neigh = hashcount(zevpn->neigh_table);
     263           0 :         if (json == NULL)
     264           0 :                 vty_out(vty, "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
     265             :                         zevpn->vni, "L2",
     266           0 :                         zevpn->vxlan_if ? zevpn->vxlan_if->name : "unknown",
     267             :                         num_macs, num_neigh, num_vteps,
     268             :                         vrf_id_to_name(zevpn->vrf_id));
     269             :         else {
     270           0 :                 char vni_str[VNI_STR_LEN];
     271           0 :                 snprintf(vni_str, VNI_STR_LEN, "%u", zevpn->vni);
     272           0 :                 json_evpn = json_object_new_object();
     273           0 :                 json_object_int_add(json_evpn, "vni", zevpn->vni);
     274           0 :                 json_object_string_add(json_evpn, "type", "L2");
     275           0 :                 json_object_string_add(json_evpn, "vxlanIf",
     276           0 :                                        zevpn->vxlan_if ? zevpn->vxlan_if->name
     277             :                                                       : "unknown");
     278           0 :                 json_object_int_add(json_evpn, "numMacs", num_macs);
     279           0 :                 json_object_int_add(json_evpn, "numArpNd", num_neigh);
     280           0 :                 json_object_int_add(json_evpn, "numRemoteVteps", num_vteps);
     281           0 :                 json_object_string_add(json_evpn, "tenantVrf",
     282             :                                        vrf_id_to_name(zevpn->vrf_id));
     283           0 :                 if (num_vteps) {
     284           0 :                         json_vtep_list = json_object_new_array();
     285           0 :                         for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
     286           0 :                                 json_ip_str = json_object_new_string(
     287           0 :                                         inet_ntop(AF_INET, &zvtep->vtep_ip, buf,
     288             :                                                   sizeof(buf)));
     289           0 :                                 json_object_array_add(json_vtep_list,
     290             :                                                       json_ip_str);
     291             :                         }
     292           0 :                         json_object_object_add(json_evpn, "remoteVteps",
     293             :                                                json_vtep_list);
     294             :                 }
     295           0 :                 json_object_object_add(json, vni_str, json_evpn);
     296             :         }
     297           0 : }
     298             : 
     299             : /*
     300             :  * Print an EVPN hash entry in detail - called for display of all EVPNs.
     301             :  */
     302           0 : void zebra_evpn_print_hash_detail(struct hash_bucket *bucket, void *data)
     303             : {
     304           0 :         struct vty *vty;
     305           0 :         struct zebra_evpn *zevpn;
     306           0 :         json_object *json_array = NULL;
     307           0 :         bool use_json = false;
     308           0 :         struct zebra_evpn_show *zes = data;
     309             : 
     310           0 :         vty = zes->vty;
     311           0 :         json_array = zes->json;
     312           0 :         use_json = zes->use_json;
     313             : 
     314           0 :         zevpn = (struct zebra_evpn *)bucket->data;
     315             : 
     316           0 :         zebra_vxlan_print_vni(vty, zes->zvrf, zevpn->vni, use_json, json_array);
     317             : 
     318           0 :         if (!use_json)
     319           0 :                 vty_out(vty, "\n");
     320           0 : }
     321             : 
     322           0 : int zebra_evpn_del_macip_for_intf(struct interface *ifp,
     323             :                                   struct zebra_evpn *zevpn)
     324             : {
     325           0 :         struct listnode *cnode = NULL, *cnnode = NULL;
     326           0 :         struct connected *c = NULL;
     327           0 :         struct ethaddr macaddr;
     328             : 
     329           0 :         memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
     330             : 
     331           0 :         for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
     332           0 :                 struct ipaddr ip;
     333             : 
     334           0 :                 memset(&ip, 0, sizeof(struct ipaddr));
     335           0 :                 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
     336           0 :                         continue;
     337             : 
     338           0 :                 if (c->address->family == AF_INET) {
     339           0 :                         ip.ipa_type = IPADDR_V4;
     340           0 :                         memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
     341             :                                sizeof(struct in_addr));
     342           0 :                 } else if (c->address->family == AF_INET6) {
     343           0 :                         ip.ipa_type = IPADDR_V6;
     344           0 :                         memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
     345             :                                sizeof(struct in6_addr));
     346             :                 } else {
     347           0 :                         continue;
     348             :                 }
     349             : 
     350           0 :                 zebra_evpn_gw_macip_del(ifp, zevpn, &ip);
     351             :         }
     352             : 
     353           0 :         return 0;
     354             : }
     355             : 
     356           0 : int zebra_evpn_add_macip_for_intf(struct interface *ifp,
     357             :                                   struct zebra_evpn *zevpn)
     358             : {
     359           0 :         struct listnode *cnode = NULL, *cnnode = NULL;
     360           0 :         struct connected *c = NULL;
     361           0 :         struct ethaddr macaddr;
     362             : 
     363           0 :         memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
     364             : 
     365           0 :         for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
     366           0 :                 struct ipaddr ip;
     367             : 
     368           0 :                 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
     369           0 :                         continue;
     370             : 
     371           0 :                 memset(&ip, 0, sizeof(struct ipaddr));
     372           0 :                 if (c->address->family == AF_INET) {
     373           0 :                         ip.ipa_type = IPADDR_V4;
     374           0 :                         memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
     375             :                                sizeof(struct in_addr));
     376           0 :                 } else if (c->address->family == AF_INET6) {
     377           0 :                         ip.ipa_type = IPADDR_V6;
     378           0 :                         memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
     379             :                                sizeof(struct in6_addr));
     380             :                 } else {
     381           0 :                         continue;
     382             :                 }
     383             : 
     384           0 :                 zebra_evpn_gw_macip_add(ifp, zevpn, &macaddr, &ip);
     385             :         }
     386           0 :         return 0;
     387             : }
     388             : 
     389           0 : static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
     390             :                                     uint16_t cmd)
     391             : {
     392           0 :         struct zserv *client = NULL;
     393           0 :         struct stream *s = NULL;
     394             : 
     395           0 :         client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
     396             :         /* BGP may not be running. */
     397           0 :         if (!client)
     398             :                 return 0;
     399             : 
     400           0 :         s = stream_new(ZEBRA_MAX_PACKET_SIZ);
     401             : 
     402           0 :         zclient_create_header(s, cmd, vrf_id);
     403           0 :         stream_put(s, p, sizeof(struct prefix));
     404             : 
     405             :         /* Write packet size. */
     406           0 :         stream_putw_at(s, 0, stream_get_endp(s));
     407             : 
     408           0 :         if (IS_ZEBRA_DEBUG_VXLAN)
     409           0 :                 zlog_debug("Send ip prefix %pFX %s on vrf %s", p,
     410             :                            (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
     411             :                            vrf_id_to_name(vrf_id));
     412             : 
     413           0 :         if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
     414           0 :                 client->prefixadd_cnt++;
     415             :         else
     416           0 :                 client->prefixdel_cnt++;
     417             : 
     418           0 :         return zserv_send_message(client, s);
     419             : }
     420             : 
     421           0 : int zebra_evpn_advertise_subnet(struct zebra_evpn *zevpn, struct interface *ifp,
     422             :                                 int advertise)
     423             : {
     424           0 :         struct listnode *cnode = NULL, *cnnode = NULL;
     425           0 :         struct connected *c = NULL;
     426           0 :         struct ethaddr macaddr;
     427             : 
     428           0 :         memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
     429             : 
     430           0 :         for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
     431           0 :                 struct prefix p;
     432             : 
     433           0 :                 memcpy(&p, c->address, sizeof(struct prefix));
     434             : 
     435             :                 /* skip link local address */
     436           0 :                 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
     437           0 :                         continue;
     438             : 
     439           0 :                 apply_mask(&p);
     440           0 :                 if (advertise)
     441           0 :                         ip_prefix_send_to_client(ifp->vrf->vrf_id, &p,
     442             :                                                  ZEBRA_IP_PREFIX_ROUTE_ADD);
     443             :                 else
     444           0 :                         ip_prefix_send_to_client(ifp->vrf->vrf_id, &p,
     445             :                                                  ZEBRA_IP_PREFIX_ROUTE_DEL);
     446             :         }
     447           0 :         return 0;
     448             : }
     449             : 
     450             : /*
     451             :  * zebra_evpn_gw_macip_add_to_client
     452             :  */
     453           0 : int zebra_evpn_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn,
     454             :                             struct ethaddr *macaddr, struct ipaddr *ip)
     455             : {
     456           0 :         struct zebra_mac *mac = NULL;
     457           0 :         struct zebra_if *zif = NULL;
     458           0 :         struct zebra_l2info_vxlan *vxl = NULL;
     459             : 
     460           0 :         zif = zevpn->vxlan_if->info;
     461           0 :         if (!zif)
     462             :                 return -1;
     463             : 
     464           0 :         vxl = &zif->l2info.vxl;
     465             : 
     466           0 :         zebra_evpn_mac_gw_macip_add(ifp, zevpn, ip, &mac, macaddr,
     467           0 :                                     vxl->access_vlan, true);
     468             : 
     469           0 :         return zebra_evpn_neigh_gw_macip_add(ifp, zevpn, ip, mac);
     470             : }
     471             : 
     472             : /*
     473             :  * zebra_evpn_gw_macip_del_from_client
     474             :  */
     475           0 : int zebra_evpn_gw_macip_del(struct interface *ifp, struct zebra_evpn *zevpn,
     476             :                             struct ipaddr *ip)
     477             : {
     478           0 :         struct zebra_neigh *n = NULL;
     479           0 :         struct zebra_mac *mac = NULL;
     480             : 
     481             :         /* If the neigh entry is not present nothing to do*/
     482           0 :         n = zebra_evpn_neigh_lookup(zevpn, ip);
     483           0 :         if (!n)
     484             :                 return 0;
     485             : 
     486             :         /* mac entry should be present */
     487           0 :         mac = zebra_evpn_mac_lookup(zevpn, &n->emac);
     488           0 :         if (!mac) {
     489           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
     490           0 :                         zlog_debug("MAC %pEA doesn't exist for neigh %pIA on VNI %u",
     491             :                                    &n->emac, ip, zevpn->vni);
     492           0 :                 return -1;
     493             :         }
     494             : 
     495             :         /* If the entry is not local nothing to do*/
     496           0 :         if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
     497             :                 return -1;
     498             : 
     499             :         /* only need to delete the entry from bgp if we sent it before */
     500           0 :         if (IS_ZEBRA_DEBUG_VXLAN)
     501           0 :                 zlog_debug(
     502             :                         "%u:SVI %s(%u) VNI %u, sending GW MAC %pEA IP %pIA del to BGP",
     503             :                         ifp->vrf->vrf_id, ifp->name, ifp->ifindex, zevpn->vni,
     504             :                         &n->emac, ip);
     505             : 
     506             :         /* Remove neighbor from BGP. */
     507           0 :         zebra_evpn_neigh_send_del_to_client(zevpn->vni, &n->ip, &n->emac,
     508             :                                             n->flags, ZEBRA_NEIGH_ACTIVE,
     509             :                                             false /*force*/);
     510             : 
     511             :         /* Delete this neighbor entry. */
     512           0 :         zebra_evpn_neigh_del(zevpn, n);
     513             : 
     514             :         /* see if the mac needs to be deleted as well*/
     515           0 :         if (mac)
     516           0 :                 zebra_evpn_deref_ip2mac(zevpn, mac);
     517             : 
     518           0 :         return 0;
     519             : }
     520             : 
     521           0 : void zebra_evpn_gw_macip_del_for_evpn_hash(struct hash_bucket *bucket,
     522             :                                            void *ctxt)
     523             : {
     524           0 :         struct zebra_evpn *zevpn = NULL;
     525           0 :         struct zebra_if *zif = NULL;
     526           0 :         struct zebra_l2info_vxlan zl2_info;
     527           0 :         struct interface *vlan_if = NULL;
     528           0 :         struct interface *vrr_if = NULL;
     529           0 :         struct interface *ifp;
     530             : 
     531             :         /* Add primary SVI MAC*/
     532           0 :         zevpn = (struct zebra_evpn *)bucket->data;
     533             : 
     534             :         /* Global (Zvrf) advertise-default-gw is disabled,
     535             :          * but zevpn advertise-default-gw is enabled
     536             :          */
     537           0 :         if (zevpn->advertise_gw_macip) {
     538           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
     539           0 :                         zlog_debug("VNI: %u GW-MACIP enabled, retain gw-macip",
     540             :                                    zevpn->vni);
     541           0 :                 return;
     542             :         }
     543             : 
     544           0 :         ifp = zevpn->vxlan_if;
     545           0 :         if (!ifp)
     546             :                 return;
     547           0 :         zif = ifp->info;
     548             : 
     549             :         /* If down or not mapped to a bridge, we're done. */
     550           0 :         if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
     551             :                 return;
     552             : 
     553           0 :         zl2_info = zif->l2info.vxl;
     554             : 
     555           0 :         vlan_if =
     556           0 :                 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
     557           0 :         if (!vlan_if)
     558             :                 return;
     559             : 
     560             :         /* Del primary MAC-IP */
     561           0 :         zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
     562             : 
     563             :         /* Del VRR MAC-IP - if any*/
     564           0 :         vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
     565           0 :         if (vrr_if)
     566           0 :                 zebra_evpn_del_macip_for_intf(vrr_if, zevpn);
     567             : 
     568             :         return;
     569             : }
     570             : 
     571           0 : void zebra_evpn_gw_macip_add_for_evpn_hash(struct hash_bucket *bucket,
     572             :                                            void *ctxt)
     573             : {
     574           0 :         struct zebra_evpn *zevpn = NULL;
     575           0 :         struct zebra_if *zif = NULL;
     576           0 :         struct zebra_l2info_vxlan zl2_info;
     577           0 :         struct interface *vlan_if = NULL;
     578           0 :         struct interface *vrr_if = NULL;
     579           0 :         struct interface *ifp = NULL;
     580             : 
     581           0 :         zevpn = (struct zebra_evpn *)bucket->data;
     582             : 
     583           0 :         ifp = zevpn->vxlan_if;
     584           0 :         if (!ifp)
     585             :                 return;
     586           0 :         zif = ifp->info;
     587             : 
     588             :         /* If down or not mapped to a bridge, we're done. */
     589           0 :         if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
     590             :                 return;
     591           0 :         zl2_info = zif->l2info.vxl;
     592             : 
     593           0 :         vlan_if =
     594           0 :                 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
     595           0 :         if (!vlan_if)
     596             :                 return;
     597             : 
     598             :         /* Add primary SVI MAC-IP */
     599           0 :         if (advertise_svi_macip_enabled(zevpn)
     600           0 :             || advertise_gw_macip_enabled(zevpn))
     601           0 :                 zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
     602             : 
     603           0 :         if (advertise_gw_macip_enabled(zevpn)) {
     604             :                 /* Add VRR MAC-IP - if any*/
     605           0 :                 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
     606           0 :                 if (vrr_if)
     607           0 :                         zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
     608             :         }
     609             : 
     610             :         return;
     611             : }
     612             : 
     613           0 : void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
     614             :                                             void *ctxt)
     615             : {
     616           0 :         struct zebra_evpn *zevpn = NULL;
     617           0 :         struct zebra_if *zif = NULL;
     618           0 :         struct zebra_l2info_vxlan zl2_info;
     619           0 :         struct interface *vlan_if = NULL;
     620           0 :         struct interface *ifp;
     621             : 
     622             :         /* Add primary SVI MAC*/
     623           0 :         zevpn = (struct zebra_evpn *)bucket->data;
     624           0 :         if (!zevpn)
     625             :                 return;
     626             : 
     627             :         /* Global(vrf) advertise-svi-ip disabled, but zevpn advertise-svi-ip
     628             :          * enabled
     629             :          */
     630           0 :         if (zevpn->advertise_svi_macip) {
     631           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
     632           0 :                         zlog_debug("VNI: %u SVI-MACIP enabled, retain svi-macip",
     633             :                                    zevpn->vni);
     634           0 :                 return;
     635             :         }
     636             : 
     637           0 :         ifp = zevpn->vxlan_if;
     638           0 :         if (!ifp)
     639             :                 return;
     640           0 :         zif = ifp->info;
     641             : 
     642             :         /* If down or not mapped to a bridge, we're done. */
     643           0 :         if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
     644             :                 return;
     645             : 
     646           0 :         zl2_info = zif->l2info.vxl;
     647             : 
     648           0 :         vlan_if =
     649           0 :                 zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
     650           0 :         if (!vlan_if)
     651             :                 return;
     652             : 
     653             :         /* Del primary MAC-IP */
     654           0 :         zebra_evpn_del_macip_for_intf(vlan_if, zevpn);
     655             : 
     656           0 :         return;
     657             : }
     658             : 
     659           0 : static int zebra_evpn_map_vlan_ns(struct ns *ns,
     660             :                                   void *_in_param,
     661             :                                   void **_p_zevpn)
     662             : {
     663           0 :         struct zebra_ns *zns = ns->info;
     664           0 :         struct route_node *rn;
     665           0 :         struct interface *br_if;
     666           0 :         struct zebra_evpn **p_zevpn = (struct zebra_evpn **)_p_zevpn;
     667           0 :         struct zebra_evpn *zevpn;
     668           0 :         struct interface *tmp_if = NULL;
     669           0 :         struct zebra_if *zif;
     670           0 :         struct zebra_l2info_vxlan *vxl = NULL;
     671           0 :         struct zebra_from_svi_param *in_param =
     672             :                 (struct zebra_from_svi_param *)_in_param;
     673             : 
     674           0 :         assert(p_zevpn && in_param);
     675             : 
     676           0 :         br_if = in_param->br_if;
     677           0 :         zif = in_param->zif;
     678           0 :         assert(zif);
     679           0 :         assert(br_if);
     680             : 
     681             :         /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
     682             :         /* TODO: Optimize with a hash. */
     683           0 :         for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
     684           0 :                 tmp_if = (struct interface *)rn->info;
     685           0 :                 if (!tmp_if)
     686           0 :                         continue;
     687           0 :                 zif = tmp_if->info;
     688           0 :                 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
     689           0 :                         continue;
     690           0 :                 if (!if_is_operative(tmp_if))
     691           0 :                         continue;
     692           0 :                 vxl = &zif->l2info.vxl;
     693             : 
     694           0 :                 if (zif->brslave_info.br_if != br_if)
     695           0 :                         continue;
     696             : 
     697           0 :                 if (!in_param->bridge_vlan_aware
     698           0 :                     || vxl->access_vlan == in_param->vid) {
     699           0 :                         zevpn = zebra_evpn_lookup(vxl->vni);
     700           0 :                         *p_zevpn = zevpn;
     701           0 :                         return NS_WALK_STOP;
     702             :                 }
     703             :         }
     704             : 
     705             :         return NS_WALK_CONTINUE;
     706             : }
     707             : 
     708             : /*
     709             :  * Map port or (port, VLAN) to an EVPN. This is invoked upon getting MAC
     710             :  * notifications, to see if they are of interest.
     711             :  */
     712           0 : struct zebra_evpn *zebra_evpn_map_vlan(struct interface *ifp,
     713             :                                        struct interface *br_if, vlanid_t vid)
     714             : {
     715           0 :         struct zebra_if *zif;
     716           0 :         struct zebra_l2info_bridge *br;
     717           0 :         struct zebra_evpn **p_zevpn;
     718           0 :         struct zebra_evpn *zevpn = NULL;
     719           0 :         struct zebra_from_svi_param in_param;
     720             : 
     721             :         /* Determine if bridge is VLAN-aware or not */
     722           0 :         zif = br_if->info;
     723           0 :         assert(zif);
     724           0 :         br = &zif->l2info.br;
     725           0 :         in_param.bridge_vlan_aware = br->vlan_aware;
     726           0 :         in_param.vid = vid;
     727           0 :         in_param.br_if = br_if;
     728           0 :         in_param.zif = zif;
     729           0 :         p_zevpn = &zevpn;
     730             : 
     731           0 :         ns_walk_func(zebra_evpn_map_vlan_ns,
     732             :                      (void *)&in_param,
     733             :                      (void **)p_zevpn);
     734           0 :         return zevpn;
     735             : }
     736             : 
     737           0 : static int zebra_evpn_from_svi_ns(struct ns *ns,
     738             :                                   void *_in_param,
     739             :                                   void **_p_zevpn)
     740             : {
     741           0 :         struct zebra_ns *zns = ns->info;
     742           0 :         struct route_node *rn;
     743           0 :         struct interface *br_if;
     744           0 :         struct zebra_evpn **p_zevpn = (struct zebra_evpn **)_p_zevpn;
     745           0 :         struct zebra_evpn *zevpn;
     746           0 :         struct interface *tmp_if = NULL;
     747           0 :         struct zebra_if *zif;
     748           0 :         struct zebra_l2info_vxlan *vxl = NULL;
     749           0 :         struct zebra_from_svi_param *in_param =
     750             :                 (struct zebra_from_svi_param *)_in_param;
     751           0 :         int found = 0;
     752             : 
     753           0 :         if (!in_param)
     754             :                 return NS_WALK_STOP;
     755           0 :         br_if = in_param->br_if;
     756           0 :         zif = in_param->zif;
     757           0 :         assert(zif);
     758             : 
     759             :         /* TODO: Optimize with a hash. */
     760           0 :         for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
     761           0 :                 tmp_if = (struct interface *)rn->info;
     762           0 :                 if (!tmp_if)
     763           0 :                         continue;
     764           0 :                 zif = tmp_if->info;
     765           0 :                 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
     766           0 :                         continue;
     767           0 :                 if (!if_is_operative(tmp_if))
     768           0 :                         continue;
     769           0 :                 vxl = &zif->l2info.vxl;
     770             : 
     771           0 :                 if (zif->brslave_info.br_if != br_if)
     772           0 :                         continue;
     773             : 
     774           0 :                 if (!in_param->bridge_vlan_aware
     775           0 :                     || vxl->access_vlan == in_param->vid) {
     776             :                         found = 1;
     777             :                         break;
     778             :                 }
     779             :         }
     780             : 
     781           0 :         if (!found)
     782             :                 return NS_WALK_CONTINUE;
     783             : 
     784           0 :         zevpn = zebra_evpn_lookup(vxl->vni);
     785           0 :         if (p_zevpn)
     786           0 :                 *p_zevpn = zevpn;
     787             :         return NS_WALK_STOP;
     788             : }
     789             : 
     790             : /*
     791             :  * Map SVI and associated bridge to an EVPN. This is invoked upon getting
     792             :  * neighbor notifications, to see if they are of interest.
     793             :  */
     794           0 : struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp,
     795             :                                        struct interface *br_if)
     796             : {
     797           0 :         struct zebra_l2info_bridge *br;
     798           0 :         struct zebra_evpn *zevpn = NULL;
     799           0 :         struct zebra_evpn **p_zevpn;
     800           0 :         struct zebra_if *zif;
     801           0 :         struct zebra_from_svi_param in_param;
     802             : 
     803           0 :         if (!br_if)
     804             :                 return NULL;
     805             : 
     806             :         /* Make sure the linked interface is a bridge. */
     807           0 :         if (!IS_ZEBRA_IF_BRIDGE(br_if))
     808             :                 return NULL;
     809             : 
     810             :         /* Determine if bridge is VLAN-aware or not */
     811           0 :         zif = br_if->info;
     812           0 :         assert(zif);
     813           0 :         br = &zif->l2info.br;
     814           0 :         in_param.bridge_vlan_aware = br->vlan_aware;
     815           0 :         in_param.vid = 0;
     816             : 
     817           0 :         if (in_param.bridge_vlan_aware) {
     818           0 :                 struct zebra_l2info_vlan *vl;
     819             : 
     820           0 :                 if (!IS_ZEBRA_IF_VLAN(ifp))
     821             :                         return NULL;
     822             : 
     823           0 :                 zif = ifp->info;
     824           0 :                 assert(zif);
     825           0 :                 vl = &zif->l2info.vl;
     826           0 :                 in_param.vid = vl->vid;
     827             :         }
     828             : 
     829           0 :         in_param.br_if = br_if;
     830           0 :         in_param.zif = zif;
     831           0 :         p_zevpn = &zevpn;
     832             :         /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
     833           0 :         ns_walk_func(zebra_evpn_from_svi_ns, (void *)&in_param,
     834             :                      (void **)p_zevpn);
     835           0 :         return zevpn;
     836             : }
     837             : 
     838           0 : static int zvni_map_to_macvlan_ns(struct ns *ns,
     839             :                                   void *_in_param,
     840             :                                   void **_p_ifp)
     841             : {
     842           0 :         struct zebra_ns *zns = ns->info;
     843           0 :         struct zebra_from_svi_param *in_param =
     844             :                 (struct zebra_from_svi_param *)_in_param;
     845           0 :         struct interface **p_ifp = (struct interface **)_p_ifp;
     846           0 :         struct route_node *rn;
     847           0 :         struct interface *tmp_if = NULL;
     848           0 :         struct zebra_if *zif;
     849             : 
     850           0 :         assert(in_param && p_ifp);
     851             : 
     852             :         /* Identify corresponding VLAN interface. */
     853           0 :         for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
     854           0 :                 tmp_if = (struct interface *)rn->info;
     855             :                 /* Check oper status of the SVI. */
     856           0 :                 if (!tmp_if || !if_is_operative(tmp_if))
     857           0 :                         continue;
     858           0 :                 zif = tmp_if->info;
     859             : 
     860           0 :                 if (!zif || zif->zif_type != ZEBRA_IF_MACVLAN)
     861           0 :                         continue;
     862             : 
     863           0 :                 if (zif->link == in_param->svi_if) {
     864           0 :                         *p_ifp = tmp_if;
     865           0 :                         return NS_WALK_STOP;
     866             :                 }
     867             :         }
     868             : 
     869             :         return NS_WALK_CONTINUE;
     870             : }
     871             : 
     872             : /* Map to MAC-VLAN interface corresponding to specified SVI interface.
     873             :  */
     874           0 : struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if,
     875             :                                             struct interface *svi_if)
     876             : {
     877           0 :         struct interface *tmp_if = NULL;
     878           0 :         struct zebra_if *zif;
     879           0 :         struct interface **p_ifp;
     880           0 :         struct zebra_from_svi_param in_param;
     881             : 
     882             :         /* Defensive check, caller expected to invoke only with valid bridge. */
     883           0 :         if (!br_if)
     884             :                 return NULL;
     885             : 
     886           0 :         if (!svi_if) {
     887           0 :                 zlog_debug("svi_if is not passed.");
     888           0 :                 return NULL;
     889             :         }
     890             : 
     891             :         /* Determine if bridge is VLAN-aware or not */
     892           0 :         zif = br_if->info;
     893           0 :         assert(zif);
     894             : 
     895           0 :         in_param.vid = 0;
     896           0 :         in_param.br_if = br_if;
     897           0 :         in_param.zif = NULL;
     898           0 :         in_param.svi_if = svi_if;
     899           0 :         p_ifp = &tmp_if;
     900             : 
     901             :         /* Identify corresponding VLAN interface. */
     902           0 :         ns_walk_func(zvni_map_to_macvlan_ns,
     903             :                      (void *)&in_param,
     904             :                      (void **)p_ifp);
     905           0 :         return tmp_if;
     906             : }
     907             : 
     908             : /*
     909             :  * Install MAC hash entry - called upon access VLAN change.
     910             :  */
     911           0 : void zebra_evpn_install_mac_hash(struct hash_bucket *bucket, void *ctxt)
     912             : {
     913           0 :         struct zebra_mac *mac;
     914           0 :         struct mac_walk_ctx *wctx = ctxt;
     915             : 
     916           0 :         mac = (struct zebra_mac *)bucket->data;
     917             : 
     918           0 :         if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
     919           0 :                 zebra_evpn_rem_mac_install(wctx->zevpn, mac, false);
     920           0 : }
     921             : 
     922             : /*
     923             :  * Read and populate local MACs and neighbors corresponding to this EVPN.
     924             :  */
     925           0 : void zebra_evpn_read_mac_neigh(struct zebra_evpn *zevpn, struct interface *ifp)
     926             : {
     927           0 :         struct zebra_ns *zns;
     928           0 :         struct zebra_vrf *zvrf;
     929           0 :         struct zebra_if *zif;
     930           0 :         struct interface *vlan_if;
     931           0 :         struct zebra_l2info_vxlan *vxl;
     932           0 :         struct interface *vrr_if;
     933             : 
     934           0 :         zif = ifp->info;
     935           0 :         vxl = &zif->l2info.vxl;
     936           0 :         zvrf = zebra_vrf_lookup_by_id(zevpn->vrf_id);
     937           0 :         if (!zvrf || !zvrf->zns)
     938             :                 return;
     939           0 :         zns = zvrf->zns;
     940             : 
     941           0 :         if (IS_ZEBRA_DEBUG_VXLAN)
     942           0 :                 zlog_debug(
     943             :                         "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
     944             :                         ifp->name, ifp->ifindex, zevpn->vni,
     945             :                         zif->brslave_info.bridge_ifindex);
     946             : 
     947           0 :         macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
     948           0 :         vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
     949           0 :         if (vlan_if) {
     950             :                 /* Add SVI MAC */
     951           0 :                 zebra_evpn_acc_bd_svi_mac_add(vlan_if);
     952             : 
     953             :                 /* Add SVI MAC-IP */
     954           0 :                 if (advertise_svi_macip_enabled(zevpn)
     955           0 :                     || advertise_gw_macip_enabled(zevpn))
     956           0 :                         zebra_evpn_add_macip_for_intf(vlan_if, zevpn);
     957             : 
     958             :                 /* Add VRR MAC-IP - if any*/
     959           0 :                 if (advertise_gw_macip_enabled(zevpn)) {
     960           0 :                         vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
     961           0 :                         if (vrr_if)
     962           0 :                                 zebra_evpn_add_macip_for_intf(vrr_if, zevpn);
     963             :                 }
     964             : 
     965           0 :                 neigh_read_for_vlan(zns, vlan_if);
     966             :         }
     967             : }
     968             : 
     969             : /*
     970             :  * Hash function for EVPN.
     971             :  */
     972           0 : unsigned int zebra_evpn_hash_keymake(const void *p)
     973             : {
     974           0 :         const struct zebra_evpn *zevpn = p;
     975             : 
     976           0 :         return (jhash_1word(zevpn->vni, 0));
     977             : }
     978             : 
     979             : /*
     980             :  * Compare 2 evpn hash entries.
     981             :  */
     982           0 : bool zebra_evpn_hash_cmp(const void *p1, const void *p2)
     983             : {
     984           0 :         const struct zebra_evpn *zevpn1 = p1;
     985           0 :         const struct zebra_evpn *zevpn2 = p2;
     986             : 
     987           0 :         return (zevpn1->vni == zevpn2->vni);
     988             : }
     989             : 
     990           0 : int zebra_evpn_list_cmp(void *p1, void *p2)
     991             : {
     992           0 :         const struct zebra_evpn *zevpn1 = p1;
     993           0 :         const struct zebra_evpn *zevpn2 = p2;
     994             : 
     995           0 :         if (zevpn1->vni == zevpn2->vni)
     996             :                 return 0;
     997           0 :         return (zevpn1->vni < zevpn2->vni) ? -1 : 1;
     998             : }
     999             : 
    1000             : /*
    1001             :  * Callback to allocate VNI hash entry.
    1002             :  */
    1003           0 : void *zebra_evpn_alloc(void *p)
    1004             : {
    1005           0 :         const struct zebra_evpn *tmp_vni = p;
    1006           0 :         struct zebra_evpn *zevpn;
    1007             : 
    1008           0 :         zevpn = XCALLOC(MTYPE_ZEVPN, sizeof(struct zebra_evpn));
    1009           0 :         zevpn->vni = tmp_vni->vni;
    1010           0 :         return ((void *)zevpn);
    1011             : }
    1012             : 
    1013             : /*
    1014             :  * Look up EVPN hash entry.
    1015             :  */
    1016           0 : struct zebra_evpn *zebra_evpn_lookup(vni_t vni)
    1017             : {
    1018           0 :         struct zebra_vrf *zvrf;
    1019           0 :         struct zebra_evpn tmp_vni;
    1020           0 :         struct zebra_evpn *zevpn = NULL;
    1021             : 
    1022           0 :         zvrf = zebra_vrf_get_evpn();
    1023           0 :         memset(&tmp_vni, 0, sizeof(tmp_vni));
    1024           0 :         tmp_vni.vni = vni;
    1025           0 :         zevpn = hash_lookup(zvrf->evpn_table, &tmp_vni);
    1026             : 
    1027           0 :         return zevpn;
    1028             : }
    1029             : 
    1030             : /*
    1031             :  * Add EVPN hash entry.
    1032             :  */
    1033           0 : struct zebra_evpn *zebra_evpn_add(vni_t vni)
    1034             : {
    1035           0 :         char buffer[80];
    1036           0 :         struct zebra_vrf *zvrf;
    1037           0 :         struct zebra_evpn tmp_zevpn;
    1038           0 :         struct zebra_evpn *zevpn = NULL;
    1039             : 
    1040           0 :         zvrf = zebra_vrf_get_evpn();
    1041           0 :         memset(&tmp_zevpn, 0, sizeof(tmp_zevpn));
    1042           0 :         tmp_zevpn.vni = vni;
    1043           0 :         zevpn = hash_get(zvrf->evpn_table, &tmp_zevpn, zebra_evpn_alloc);
    1044             : 
    1045           0 :         zebra_evpn_es_evi_init(zevpn);
    1046             : 
    1047           0 :         snprintf(buffer, sizeof(buffer), "Zebra EVPN MAC Table vni: %u", vni);
    1048             :         /* Create hash table for MAC */
    1049           0 :         zevpn->mac_table = zebra_mac_db_create(buffer);
    1050             : 
    1051           0 :         snprintf(buffer, sizeof(buffer), "Zebra EVPN Neighbor Table vni: %u",
    1052             :                  vni);
    1053             :         /* Create hash table for neighbors */
    1054           0 :         zevpn->neigh_table = zebra_neigh_db_create(buffer);
    1055             : 
    1056           0 :         return zevpn;
    1057             : }
    1058             : 
    1059             : /*
    1060             :  * Delete EVPN hash entry.
    1061             :  */
    1062           0 : int zebra_evpn_del(struct zebra_evpn *zevpn)
    1063             : {
    1064           0 :         struct zebra_vrf *zvrf;
    1065           0 :         struct zebra_evpn *tmp_zevpn;
    1066             : 
    1067           0 :         zvrf = zebra_vrf_get_evpn();
    1068             : 
    1069           0 :         zevpn->svi_if = NULL;
    1070             : 
    1071             :         /* Free the neighbor hash table. */
    1072           0 :         hash_free(zevpn->neigh_table);
    1073           0 :         zevpn->neigh_table = NULL;
    1074             : 
    1075             :         /* Free the MAC hash table. */
    1076           0 :         hash_free(zevpn->mac_table);
    1077           0 :         zevpn->mac_table = NULL;
    1078             : 
    1079             :         /* Remove references to the zevpn in the MH databases */
    1080           0 :         if (zevpn->vxlan_if)
    1081           0 :                 zebra_evpn_vxl_evpn_set(zevpn->vxlan_if->info, zevpn, false);
    1082           0 :         zebra_evpn_es_evi_cleanup(zevpn);
    1083             : 
    1084             :         /* Free the EVPN hash entry and allocated memory. */
    1085           0 :         tmp_zevpn = hash_release(zvrf->evpn_table, zevpn);
    1086           0 :         XFREE(MTYPE_ZEVPN, tmp_zevpn);
    1087             : 
    1088           0 :         return 0;
    1089             : }
    1090             : 
    1091             : /*
    1092             :  * Inform BGP about local EVPN addition.
    1093             :  */
    1094           0 : int zebra_evpn_send_add_to_client(struct zebra_evpn *zevpn)
    1095             : {
    1096           0 :         struct zserv *client;
    1097           0 :         struct stream *s;
    1098           0 :         ifindex_t svi_index;
    1099           0 :         int rc;
    1100             : 
    1101           0 :         client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
    1102             :         /* BGP may not be running. */
    1103           0 :         if (!client)
    1104             :                 return 0;
    1105             : 
    1106           0 :         svi_index = zevpn->svi_if ? zevpn->svi_if->ifindex : 0;
    1107             : 
    1108           0 :         s = stream_new(ZEBRA_MAX_PACKET_SIZ);
    1109             : 
    1110           0 :         zclient_create_header(s, ZEBRA_VNI_ADD, zebra_vrf_get_evpn_id());
    1111           0 :         stream_putl(s, zevpn->vni);
    1112           0 :         stream_put_in_addr(s, &zevpn->local_vtep_ip);
    1113           0 :         stream_put(s, &zevpn->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
    1114           0 :         stream_put_in_addr(s, &zevpn->mcast_grp);
    1115           0 :         stream_put(s, &svi_index, sizeof(ifindex_t));
    1116             : 
    1117             :         /* Write packet size. */
    1118           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    1119             : 
    1120           0 :         if (IS_ZEBRA_DEBUG_VXLAN)
    1121           0 :                 zlog_debug(
    1122             :                         "Send EVPN_ADD %u %pI4 tenant vrf %s(%u) SVI index %u to %s",
    1123             :                         zevpn->vni, &zevpn->local_vtep_ip,
    1124             :                         vrf_id_to_name(zevpn->vrf_id), zevpn->vrf_id,
    1125             :                         (zevpn->svi_if ? zevpn->svi_if->ifindex : 0),
    1126             :                         zebra_route_string(client->proto));
    1127             : 
    1128           0 :         client->vniadd_cnt++;
    1129           0 :         rc = zserv_send_message(client, s);
    1130             : 
    1131           0 :         if (!(zevpn->flags & ZEVPN_READY_FOR_BGP)) {
    1132           0 :                 zevpn->flags |= ZEVPN_READY_FOR_BGP;
    1133             :                 /* once the EVPN is sent the ES-EVIs can also be replayed
    1134             :                  * to BGP
    1135             :                  */
    1136           0 :                 zebra_evpn_update_all_es(zevpn);
    1137             :         }
    1138             :         return rc;
    1139             : }
    1140             : 
    1141             : /*
    1142             :  * Inform BGP about local EVPN deletion.
    1143             :  */
    1144           0 : int zebra_evpn_send_del_to_client(struct zebra_evpn *zevpn)
    1145             : {
    1146           0 :         struct zserv *client;
    1147           0 :         struct stream *s;
    1148             : 
    1149           0 :         client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
    1150             :         /* BGP may not be running. */
    1151           0 :         if (!client)
    1152             :                 return 0;
    1153             : 
    1154           0 :         if (zevpn->flags & ZEVPN_READY_FOR_BGP) {
    1155           0 :                 zevpn->flags &= ~ZEVPN_READY_FOR_BGP;
    1156             :                 /* the ES-EVIs must be removed from BGP before the EVPN is */
    1157           0 :                 zebra_evpn_update_all_es(zevpn);
    1158             :         }
    1159             : 
    1160           0 :         s = stream_new(ZEBRA_MAX_PACKET_SIZ);
    1161           0 :         stream_reset(s);
    1162             : 
    1163           0 :         zclient_create_header(s, ZEBRA_VNI_DEL, zebra_vrf_get_evpn_id());
    1164           0 :         stream_putl(s, zevpn->vni);
    1165             : 
    1166             :         /* Write packet size. */
    1167           0 :         stream_putw_at(s, 0, stream_get_endp(s));
    1168             : 
    1169           0 :         if (IS_ZEBRA_DEBUG_VXLAN)
    1170           0 :                 zlog_debug("Send EVPN_DEL %u to %s", zevpn->vni,
    1171             :                            zebra_route_string(client->proto));
    1172             : 
    1173           0 :         client->vnidel_cnt++;
    1174           0 :         return zserv_send_message(client, s);
    1175             : }
    1176             : 
    1177             : /*
    1178             :  * See if remote VTEP matches with prefix.
    1179             :  */
    1180           0 : static int zebra_evpn_vtep_match(struct in_addr *vtep_ip,
    1181             :                                  struct zebra_vtep *zvtep)
    1182             : {
    1183           0 :         return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
    1184             : }
    1185             : 
    1186             : /*
    1187             :  * Locate remote VTEP in EVPN hash table.
    1188             :  */
    1189           0 : struct zebra_vtep *zebra_evpn_vtep_find(struct zebra_evpn *zevpn,
    1190             :                                         struct in_addr *vtep_ip)
    1191             : {
    1192           0 :         struct zebra_vtep *zvtep;
    1193             : 
    1194           0 :         if (!zevpn)
    1195             :                 return NULL;
    1196             : 
    1197           0 :         for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
    1198           0 :                 if (zebra_evpn_vtep_match(vtep_ip, zvtep))
    1199             :                         break;
    1200             :         }
    1201             : 
    1202             :         return zvtep;
    1203             : }
    1204             : 
    1205             : /*
    1206             :  * Add remote VTEP to EVPN hash table.
    1207             :  */
    1208           0 : struct zebra_vtep *zebra_evpn_vtep_add(struct zebra_evpn *zevpn,
    1209             :                                        struct in_addr *vtep_ip,
    1210             :                                        int flood_control)
    1211             : 
    1212             : {
    1213           0 :         struct zebra_vtep *zvtep;
    1214             : 
    1215           0 :         zvtep = XCALLOC(MTYPE_ZEVPN_VTEP, sizeof(struct zebra_vtep));
    1216             : 
    1217           0 :         zvtep->vtep_ip = *vtep_ip;
    1218           0 :         zvtep->flood_control = flood_control;
    1219             : 
    1220           0 :         if (zevpn->vteps)
    1221           0 :                 zevpn->vteps->prev = zvtep;
    1222           0 :         zvtep->next = zevpn->vteps;
    1223           0 :         zevpn->vteps = zvtep;
    1224             : 
    1225           0 :         return zvtep;
    1226             : }
    1227             : 
    1228             : /*
    1229             :  * Remove remote VTEP from EVPN hash table.
    1230             :  */
    1231           0 : int zebra_evpn_vtep_del(struct zebra_evpn *zevpn, struct zebra_vtep *zvtep)
    1232             : {
    1233           0 :         if (zvtep->next)
    1234           0 :                 zvtep->next->prev = zvtep->prev;
    1235           0 :         if (zvtep->prev)
    1236           0 :                 zvtep->prev->next = zvtep->next;
    1237             :         else
    1238           0 :                 zevpn->vteps = zvtep->next;
    1239             : 
    1240           0 :         zvtep->prev = zvtep->next = NULL;
    1241           0 :         XFREE(MTYPE_ZEVPN_VTEP, zvtep);
    1242             : 
    1243           0 :         return 0;
    1244             : }
    1245             : 
    1246             : /*
    1247             :  * Delete all remote VTEPs for this EVPN (upon VNI delete). Also
    1248             :  * uninstall from kernel if asked to.
    1249             :  */
    1250           0 : int zebra_evpn_vtep_del_all(struct zebra_evpn *zevpn, int uninstall)
    1251             : {
    1252           0 :         struct zebra_vtep *zvtep, *zvtep_next;
    1253             : 
    1254           0 :         if (!zevpn)
    1255             :                 return -1;
    1256             : 
    1257           0 :         for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep_next) {
    1258           0 :                 zvtep_next = zvtep->next;
    1259           0 :                 if (uninstall)
    1260           0 :                         zebra_evpn_vtep_uninstall(zevpn, &zvtep->vtep_ip);
    1261           0 :                 zebra_evpn_vtep_del(zevpn, zvtep);
    1262             :         }
    1263             : 
    1264             :         return 0;
    1265             : }
    1266             : 
    1267             : /*
    1268             :  * Install remote VTEP into the kernel if the remote VTEP has asked
    1269             :  * for head-end-replication.
    1270             :  */
    1271           0 : int zebra_evpn_vtep_install(struct zebra_evpn *zevpn, struct zebra_vtep *zvtep)
    1272             : {
    1273           0 :         if (is_vxlan_flooding_head_end() &&
    1274           0 :             (zvtep->flood_control == VXLAN_FLOOD_HEAD_END_REPL)) {
    1275           0 :                 if (ZEBRA_DPLANE_REQUEST_FAILURE ==
    1276           0 :                     dplane_vtep_add(zevpn->vxlan_if,
    1277           0 :                                     &zvtep->vtep_ip, zevpn->vni))
    1278             :                         return -1;
    1279             :         }
    1280             : 
    1281             :         return 0;
    1282             : }
    1283             : 
    1284             : /*
    1285             :  * Uninstall remote VTEP from the kernel.
    1286             :  */
    1287           0 : int zebra_evpn_vtep_uninstall(struct zebra_evpn *zevpn, struct in_addr *vtep_ip)
    1288             : {
    1289           0 :         if (!zevpn->vxlan_if) {
    1290           0 :                 zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf",
    1291             :                            zevpn->vni, zevpn);
    1292           0 :                 return -1;
    1293             :         }
    1294             : 
    1295           0 :         if (ZEBRA_DPLANE_REQUEST_FAILURE ==
    1296           0 :             dplane_vtep_delete(zevpn->vxlan_if, vtep_ip, zevpn->vni))
    1297             :                 return -1;
    1298             : 
    1299             :         return 0;
    1300             : }
    1301             : 
    1302             : /*
    1303             :  * Install or uninstall flood entries in the kernel corresponding to
    1304             :  * remote VTEPs. This is invoked upon change to BUM handling.
    1305             :  */
    1306           0 : void zebra_evpn_handle_flooding_remote_vteps(struct hash_bucket *bucket,
    1307             :                                              void *zvrf)
    1308             : {
    1309           0 :         struct zebra_evpn *zevpn;
    1310           0 :         struct zebra_vtep *zvtep;
    1311             : 
    1312           0 :         zevpn = (struct zebra_evpn *)bucket->data;
    1313           0 :         if (!zevpn)
    1314             :                 return;
    1315             : 
    1316           0 :         for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
    1317           0 :                 if (is_vxlan_flooding_head_end())
    1318           0 :                         zebra_evpn_vtep_install(zevpn, zvtep);
    1319             :                 else
    1320           0 :                         zebra_evpn_vtep_uninstall(zevpn, &zvtep->vtep_ip);
    1321             :         }
    1322             : }
    1323             : 
    1324             : /*
    1325             :  * Cleanup EVPN/VTEP and update kernel
    1326             :  */
    1327           0 : void zebra_evpn_cleanup_all(struct hash_bucket *bucket, void *arg)
    1328             : {
    1329           0 :         struct zebra_evpn *zevpn = NULL;
    1330             : 
    1331           0 :         zevpn = (struct zebra_evpn *)bucket->data;
    1332             : 
    1333             :         /* Free up all neighbors and MACs, if any. */
    1334           0 :         zebra_evpn_neigh_del_all(zevpn, 1, 0, DEL_ALL_NEIGH);
    1335           0 :         zebra_evpn_mac_del_all(zevpn, 1, 0, DEL_ALL_MAC);
    1336             : 
    1337             :         /* Free up all remote VTEPs, if any. */
    1338           0 :         zebra_evpn_vtep_del_all(zevpn, 1);
    1339             : 
    1340             :         /* Delete the hash entry. */
    1341           0 :         zebra_evpn_del(zevpn);
    1342           0 : }
    1343             : 
    1344           0 : static void zebra_evpn_process_sync_macip_add(struct zebra_evpn *zevpn,
    1345             :                                               const struct ethaddr *macaddr,
    1346             :                                               uint16_t ipa_len,
    1347             :                                               const struct ipaddr *ipaddr,
    1348             :                                               uint8_t flags, uint32_t seq,
    1349             :                                               const esi_t *esi)
    1350             : {
    1351           0 :         char ipbuf[INET6_ADDRSTRLEN];
    1352           0 :         bool sticky;
    1353           0 :         bool remote_gw;
    1354           0 :         struct zebra_neigh *n = NULL;
    1355           0 :         struct zebra_mac *mac = NULL;
    1356             : 
    1357           0 :         sticky = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
    1358           0 :         remote_gw = !!CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
    1359             :         /* if sticky or remote-gw ignore updates from the peer */
    1360           0 :         if (sticky || remote_gw) {
    1361           0 :                 if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH
    1362           0 :                     || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
    1363           0 :                         zlog_debug(
    1364             :                                 "Ignore sync-macip vni %u mac %pEA%s%s%s%s",
    1365             :                                 zevpn->vni,
    1366             :                                 macaddr,
    1367             :                                 ipa_len ? " IP " : "",
    1368             :                                 ipa_len ? ipaddr2str(ipaddr, ipbuf,
    1369             :                                                      sizeof(ipbuf))
    1370             :                                         : "",
    1371             :                                 sticky ? " sticky" : "",
    1372             :                                 remote_gw ? " remote_gw" : "");
    1373           0 :                 return;
    1374             :         }
    1375             : 
    1376           0 :         if (!ipa_len) {
    1377             :                 /* MAC update */
    1378           0 :                 (void)zebra_evpn_proc_sync_mac_update(zevpn, macaddr, ipa_len,
    1379             :                                                       ipaddr, flags, seq, esi);
    1380             :         } else {
    1381             :                 /* MAC-IP update */
    1382           0 :                 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
    1383           0 :                 if (!mac) {
    1384           0 :                         mac = zebra_evpn_proc_sync_mac_update(zevpn, macaddr,
    1385             :                                                               ipa_len, ipaddr,
    1386             :                                                               flags, seq, esi);
    1387             :                 }
    1388           0 :                 if (!mac)
    1389             :                         return;
    1390             : 
    1391           0 :                 n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
    1392           0 :                 if (n
    1393           0 :                     && !zebra_evpn_neigh_is_bgp_seq_ok(zevpn, n, macaddr, seq,
    1394             :                                                        true))
    1395             :                         return;
    1396             : 
    1397           0 :                 zebra_evpn_proc_sync_neigh_update(zevpn, n, ipa_len, ipaddr,
    1398             :                                                   flags, seq, esi, mac);
    1399             :         }
    1400             : }
    1401             : 
    1402             : /************************** remote mac-ip handling **************************/
    1403             : /* Process a remote MACIP add from BGP. */
    1404           0 : void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
    1405             :                               uint16_t ipa_len, const struct ipaddr *ipaddr,
    1406             :                               uint8_t flags, uint32_t seq,
    1407             :                               struct in_addr vtep_ip, const esi_t *esi)
    1408             : {
    1409           0 :         struct zebra_evpn *zevpn;
    1410           0 :         struct zebra_vtep *zvtep;
    1411           0 :         struct zebra_mac *mac = NULL;
    1412           0 :         struct interface *ifp = NULL;
    1413           0 :         struct zebra_if *zif = NULL;
    1414           0 :         struct zebra_vrf *zvrf;
    1415             : 
    1416             :         /* Locate EVPN hash entry - expected to exist. */
    1417           0 :         zevpn = zebra_evpn_lookup(vni);
    1418           0 :         if (!zevpn) {
    1419           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
    1420           0 :                         zlog_debug("Unknown VNI %u upon remote MACIP ADD", vni);
    1421           0 :                 return;
    1422             :         }
    1423             : 
    1424           0 :         ifp = zevpn->vxlan_if;
    1425           0 :         if (ifp)
    1426           0 :                 zif = ifp->info;
    1427           0 :         if (!ifp || !if_is_operative(ifp) || !zif || !zif->brslave_info.br_if) {
    1428           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
    1429           0 :                         zlog_debug(
    1430             :                                 "Ignoring remote MACIP ADD VNI %u, invalid interface state or info",
    1431             :                                 vni);
    1432           0 :                 return;
    1433             :         }
    1434             : 
    1435             :         /* Type-2 routes from another PE can be interpreted as remote or
    1436             :          * SYNC based on the destination ES -
    1437             :          * SYNC - if ES is local
    1438             :          * REMOTE - if ES is not local
    1439             :          */
    1440           0 :         if (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) {
    1441           0 :                 struct zebra_evpn_es *es;
    1442             : 
    1443           0 :                 es = zebra_evpn_es_find(esi);
    1444           0 :                 if (es && (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)) {
    1445           0 :                         zebra_evpn_process_sync_macip_add(zevpn, macaddr,
    1446             :                                                           ipa_len, ipaddr,
    1447             :                                                           flags, seq, esi);
    1448             :                 } else {
    1449           0 :                         if (IS_ZEBRA_DEBUG_EVPN_MH_ES) {
    1450           0 :                                 char esi_str[ESI_STR_LEN];
    1451             : 
    1452           0 :                                 esi_to_str(esi, esi_str, sizeof(esi_str));
    1453           0 :                                 zlog_debug(
    1454             :                                         "Ignore sync-macip add; ES %s is not ready",
    1455             :                                         esi_str);
    1456             :                         }
    1457             :                 }
    1458             : 
    1459           0 :                 return;
    1460             :         }
    1461             : 
    1462             :         /* The remote VTEP specified should normally exist, but it is
    1463             :          * possible that when peering comes up, peer may advertise MACIP
    1464             :          * routes before advertising type-3 routes.
    1465             :          */
    1466           0 :         if (vtep_ip.s_addr) {
    1467           0 :                 zvtep = zebra_evpn_vtep_find(zevpn, &vtep_ip);
    1468           0 :                 if (!zvtep) {
    1469           0 :                         zvtep = zebra_evpn_vtep_add(zevpn, &vtep_ip,
    1470             :                                                     VXLAN_FLOOD_DISABLED);
    1471           0 :                         if (!zvtep) {
    1472           0 :                                 flog_err(
    1473             :                                         EC_ZEBRA_VTEP_ADD_FAILED,
    1474             :                                         "Failed to add remote VTEP, VNI %u zevpn %p upon remote MACIP ADD",
    1475             :                                         vni, zevpn);
    1476           0 :                                 return;
    1477             :                         }
    1478             : 
    1479           0 :                         zebra_evpn_vtep_install(zevpn, zvtep);
    1480             :                 }
    1481             :         }
    1482             : 
    1483           0 :         zvrf = zebra_vrf_get_evpn();
    1484           0 :         if (!zvrf)
    1485             :                 return;
    1486             : 
    1487           0 :         if (!ipa_len) {
    1488             :                 /* MAC update */
    1489           0 :                 zebra_evpn_mac_remote_macip_add(zevpn, zvrf, macaddr, vtep_ip,
    1490             :                                                 flags, seq, esi);
    1491             :         } else {
    1492             :                 /* MAC-IP update
    1493             :                  * Add auto MAC if it doesn't exist.
    1494             :                  */
    1495           0 :                 mac = zebra_evpn_mac_lookup(zevpn, macaddr);
    1496           0 :                 if (!mac) {
    1497           0 :                         mac = zebra_evpn_mac_add_auto(zevpn, macaddr);
    1498             : 
    1499           0 :                         if (IS_ZEBRA_DEBUG_VXLAN)
    1500           0 :                                 zlog_debug(
    1501             :                                         "Neigh %pIA: MAC %pEA not found, Auto MAC created",
    1502             :                                         ipaddr, macaddr);
    1503             :                 }
    1504             : 
    1505           0 :                 zebra_evpn_neigh_remote_macip_add(zevpn, zvrf, ipaddr, mac,
    1506             :                                                   vtep_ip, flags, seq);
    1507             :         }
    1508             : }
    1509             : 
    1510             : /* Process a remote MACIP delete from BGP. */
    1511           0 : void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
    1512             :                               uint16_t ipa_len, const struct ipaddr *ipaddr,
    1513             :                               struct in_addr vtep_ip)
    1514             : {
    1515           0 :         struct zebra_evpn *zevpn;
    1516           0 :         struct zebra_mac *mac = NULL;
    1517           0 :         struct zebra_neigh *n = NULL;
    1518           0 :         struct interface *ifp = NULL;
    1519           0 :         struct zebra_if *zif = NULL;
    1520           0 :         struct zebra_ns *zns;
    1521           0 :         struct zebra_l2info_vxlan *vxl;
    1522           0 :         struct zebra_vrf *zvrf;
    1523           0 :         char buf1[INET6_ADDRSTRLEN];
    1524             : 
    1525             :         /* Locate EVPN hash entry - expected to exist. */
    1526           0 :         zevpn = zebra_evpn_lookup(vni);
    1527           0 :         if (!zevpn) {
    1528           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
    1529           0 :                         zlog_debug("Unknown VNI %u upon remote MACIP DEL", vni);
    1530           0 :                 return;
    1531             :         }
    1532             : 
    1533           0 :         ifp = zevpn->vxlan_if;
    1534           0 :         if (ifp)
    1535           0 :                 zif = ifp->info;
    1536           0 :         if (!ifp || !if_is_operative(ifp) || !zif || !zif->brslave_info.br_if) {
    1537           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
    1538           0 :                         zlog_debug(
    1539             :                                 "Ignoring remote MACIP DEL VNI %u, invalid interface state or info",
    1540             :                                 vni);
    1541           0 :                 return;
    1542             :         }
    1543           0 :         zns = zebra_ns_lookup(NS_DEFAULT);
    1544           0 :         vxl = &zif->l2info.vxl;
    1545             : 
    1546           0 :         mac = zebra_evpn_mac_lookup(zevpn, macaddr);
    1547           0 :         if (ipa_len)
    1548           0 :                 n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
    1549             : 
    1550           0 :         if (n && !mac) {
    1551           0 :                 zlog_warn(
    1552             :                         "Failed to locate MAC %pEA for Neigh %pIA VNI %u upon remote MACIP DEL",
    1553             :                         macaddr, ipaddr, vni);
    1554           0 :                 return;
    1555             :         }
    1556             : 
    1557             :         /* If the remote mac or neighbor doesn't exist there is nothing
    1558             :          * more to do. Otherwise, uninstall the entry and then remove it.
    1559             :          */
    1560           0 :         if (!mac && !n) {
    1561           0 :                 if (IS_ZEBRA_DEBUG_VXLAN)
    1562           0 :                         zlog_debug(
    1563             :                                 "Failed to locate MAC %pEA & Neigh %pIA VNI %u upon remote MACIP DEL",
    1564             :                                 macaddr, ipaddr, vni);
    1565           0 :                 return;
    1566             :         }
    1567             : 
    1568           0 :         zvrf = zevpn->vxlan_if->vrf->info;
    1569             : 
    1570             :         /* Ignore the delete if this mac is a gateway mac-ip */
    1571           0 :         if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
    1572           0 :             && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
    1573           0 :                 zlog_warn(
    1574             :                         "Ignore remote MACIP DEL VNI %u MAC %pEA%s%s as MAC is already configured as gateway MAC",
    1575             :                         vni, macaddr,
    1576             :                         ipa_len ? " IP " : "",
    1577             :                         ipa_len ? ipaddr2str(ipaddr, buf1, sizeof(buf1)) : "");
    1578           0 :                 return;
    1579             :         }
    1580             : 
    1581             :         /* Uninstall remote neighbor or MAC. */
    1582           0 :         if (n)
    1583           0 :                 zebra_evpn_neigh_remote_uninstall(zevpn, zvrf, n, mac, ipaddr);
    1584             :         else {
    1585             :                 /* DAD: when MAC is freeze state as remote learn event,
    1586             :                  * remote mac-ip delete event is received will result in freeze
    1587             :                  * entry removal, first fetch kernel for the same entry present
    1588             :                  * as LOCAL and reachable, avoid deleting this entry instead
    1589             :                  * use kerenel local entry to update during unfreeze time.
    1590             :                  */
    1591           0 :                 if (zvrf->dad_freeze
    1592             :                     && CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)
    1593           0 :                     && CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
    1594           0 :                         if (IS_ZEBRA_DEBUG_VXLAN)
    1595           0 :                                 zlog_debug(
    1596             :                                         "%s: MAC %pEA (flags 0x%x) is remote and duplicate, read kernel for local entry",
    1597             :                                         __func__, macaddr, mac->flags);
    1598           0 :                         macfdb_read_specific_mac(zns, zif->brslave_info.br_if,
    1599           0 :                                                  macaddr, vxl->access_vlan);
    1600             :                 }
    1601             : 
    1602           0 :                 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
    1603           0 :                         if (!ipa_len)
    1604           0 :                                 zebra_evpn_sync_mac_del(mac);
    1605           0 :                 } else if (CHECK_FLAG(mac->flags, ZEBRA_NEIGH_REMOTE)) {
    1606           0 :                         zebra_evpn_rem_mac_del(zevpn, mac);
    1607             :                 }
    1608             :         }
    1609             : }
    1610             : 
    1611             : /************************** EVPN BGP config management ************************/
    1612           0 : void zebra_evpn_cfg_cleanup(struct hash_bucket *bucket, void *ctxt)
    1613             : {
    1614           0 :         struct zebra_evpn *zevpn = NULL;
    1615             : 
    1616           0 :         zevpn = (struct zebra_evpn *)bucket->data;
    1617           0 :         zevpn->advertise_gw_macip = 0;
    1618           0 :         zevpn->advertise_svi_macip = 0;
    1619           0 :         zevpn->advertise_subnet = 0;
    1620             : 
    1621           0 :         zebra_evpn_neigh_del_all(zevpn, 1, 0,
    1622             :                                  DEL_REMOTE_NEIGH | DEL_REMOTE_NEIGH_FROM_VTEP);
    1623           0 :         zebra_evpn_mac_del_all(zevpn, 1, 0,
    1624             :                                DEL_REMOTE_MAC | DEL_REMOTE_MAC_FROM_VTEP);
    1625           0 :         zebra_evpn_vtep_del_all(zevpn, 1);
    1626           0 : }

Generated by: LCOV version v1.16-topotato