back to topotato report
topotato coverage report
Current view: top level - zebra - zebra_l2.c (source / functions) Hit Total Coverage
Test: test_demo.py::AllStartupTest Lines: 0 253 0.0 %
Date: 2023-02-24 18:37:51 Functions: 0 19 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Zebra Layer-2 interface handling 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             : 
      23             : #include <zebra.h>
      24             : 
      25             : #include "if.h"
      26             : #include "prefix.h"
      27             : #include "table.h"
      28             : #include "memory.h"
      29             : #include "log.h"
      30             : #include "linklist.h"
      31             : #include "stream.h"
      32             : #include "hash.h"
      33             : #include "jhash.h"
      34             : 
      35             : #include "zebra/rib.h"
      36             : #include "zebra/rt.h"
      37             : #include "zebra/zebra_ns.h"
      38             : #include "zebra/zserv.h"
      39             : #include "zebra/debug.h"
      40             : #include "zebra/interface.h"
      41             : #include "zebra/zebra_vrf.h"
      42             : #include "zebra/rt_netlink.h"
      43             : #include "zebra/interface.h"
      44             : #include "zebra/zebra_l2.h"
      45             : #include "zebra/zebra_vxlan.h"
      46             : #include "zebra/zebra_evpn_mh.h"
      47             : 
      48             : /* definitions */
      49             : 
      50             : /* static function declarations */
      51             : 
      52             : /* Private functions */
      53           0 : static void map_slaves_to_bridge(struct interface *br_if, int link,
      54             :                                  bool update_slave, uint8_t chgflags)
      55             : {
      56           0 :         struct vrf *vrf;
      57           0 :         struct interface *ifp;
      58           0 :         struct zebra_vrf *zvrf;
      59           0 :         struct zebra_ns *zns;
      60             : 
      61           0 :         zvrf = br_if->vrf->info;
      62           0 :         assert(zvrf);
      63           0 :         zns = zvrf->zns;
      64           0 :         assert(zns);
      65           0 :         RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
      66           0 :                 FOR_ALL_INTERFACES (vrf, ifp) {
      67           0 :                         struct zebra_if *zif;
      68           0 :                         struct zebra_l2info_brslave *br_slave;
      69             : 
      70           0 :                         if (ifp->ifindex == IFINDEX_INTERNAL || !ifp->info)
      71           0 :                                 continue;
      72           0 :                         if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
      73           0 :                                 continue;
      74             : 
      75             :                         /* NOTE: This assumes 'zebra_l2info_brslave' is the
      76             :                          * first field
      77             :                          * for any L2 interface.
      78             :                          */
      79           0 :                         zif = (struct zebra_if *)ifp->info;
      80           0 :                         br_slave = &zif->brslave_info;
      81             : 
      82           0 :                         if (link) {
      83           0 :                                 if (br_slave->bridge_ifindex == br_if->ifindex
      84           0 :                                     && br_slave->ns_id == zns->ns_id) {
      85           0 :                                         br_slave->br_if = br_if;
      86           0 :                                         if (update_slave) {
      87           0 :                                                 zebra_l2if_update_bridge_slave(
      88             :                                                         ifp,
      89             :                                                         br_slave->bridge_ifindex,
      90             :                                                         br_slave->ns_id,
      91             :                                                         chgflags);
      92             :                                         }
      93             :                                 }
      94             :                         } else {
      95           0 :                                 if (br_slave->br_if == br_if)
      96           0 :                                         br_slave->br_if = NULL;
      97             :                         }
      98             :                 }
      99             :         }
     100           0 : }
     101             : 
     102             : /* Public functions */
     103           0 : void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave,
     104             :                                   struct zebra_ns *zns)
     105             : {
     106           0 :         struct interface *br_if;
     107             : 
     108             :         /* TODO: Handle change of master */
     109           0 :         assert(zns);
     110           0 :         br_if = if_lookup_by_index_per_ns(zebra_ns_lookup(zns->ns_id),
     111           0 :                                           br_slave->bridge_ifindex);
     112           0 :         if (br_if)
     113           0 :                 br_slave->br_if = br_if;
     114           0 : }
     115             : 
     116           0 : void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
     117             : {
     118           0 :         br_slave->br_if = NULL;
     119           0 : }
     120             : 
     121             : /* If any of the bond members are in bypass state the bond is placed
     122             :  * in bypass state
     123             :  */
     124           0 : static void zebra_l2_bond_lacp_bypass_eval(struct zebra_if *bond_zif)
     125             : {
     126           0 :         struct listnode *node;
     127           0 :         struct zebra_if *bond_mbr;
     128           0 :         bool old_bypass = !!(bond_zif->flags & ZIF_FLAG_LACP_BYPASS);
     129           0 :         bool new_bypass = false;
     130             : 
     131           0 :         if (bond_zif->bond_info.mbr_zifs) {
     132           0 :                 for (ALL_LIST_ELEMENTS_RO(bond_zif->bond_info.mbr_zifs, node,
     133             :                                           bond_mbr)) {
     134           0 :                         if (bond_mbr->flags & ZIF_FLAG_LACP_BYPASS) {
     135             :                                 new_bypass = true;
     136             :                                 break;
     137             :                         }
     138             :                 }
     139             :         }
     140             : 
     141           0 :         if (old_bypass == new_bypass)
     142             :                 return;
     143             : 
     144           0 :         if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     145           0 :                 zlog_debug("bond %s lacp bypass changed to %s",
     146             :                            bond_zif->ifp->name, new_bypass ? "on" : "off");
     147             : 
     148           0 :         if (new_bypass)
     149           0 :                 bond_zif->flags |= ZIF_FLAG_LACP_BYPASS;
     150             :         else
     151           0 :                 bond_zif->flags &= ~ZIF_FLAG_LACP_BYPASS;
     152             : 
     153           0 :         if (bond_zif->es_info.es)
     154           0 :                 zebra_evpn_es_bypass_update(bond_zif->es_info.es, bond_zif->ifp,
     155             :                                             new_bypass);
     156             : }
     157             : 
     158             : /* Returns true if member was newly linked to bond */
     159           0 : void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id)
     160             : {
     161           0 :         struct interface *bond_if;
     162           0 :         struct zebra_if *bond_zif;
     163           0 :         struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info;
     164             : 
     165           0 :         bond_if = if_lookup_by_index(bond_slave->bond_ifindex, vrf_id);
     166           0 :         if (bond_if == bond_slave->bond_if)
     167             :                 return;
     168             : 
     169             :         /* unlink the slave from the old master */
     170           0 :         zebra_l2_unmap_slave_from_bond(zif);
     171             : 
     172             :         /* If the bond is present and ready link the bond-member
     173             :          * to it
     174             :          */
     175           0 :         if (bond_if && (bond_zif = bond_if->info)) {
     176           0 :                 if (bond_zif->bond_info.mbr_zifs) {
     177           0 :                         if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     178           0 :                                 zlog_debug("bond mbr %s linked to %s",
     179             :                                            zif->ifp->name, bond_if->name);
     180           0 :                         bond_slave->bond_if = bond_if;
     181             :                         /* link the slave to the new bond master */
     182           0 :                         listnode_add(bond_zif->bond_info.mbr_zifs, zif);
     183             :                         /* inherit protodown flags from the es-bond */
     184           0 :                         if (zebra_evpn_is_es_bond(bond_if))
     185           0 :                                 zebra_evpn_mh_update_protodown_bond_mbr(
     186             :                                         zif, false /*clear*/, __func__);
     187           0 :                         zebra_l2_bond_lacp_bypass_eval(bond_zif);
     188             :                 }
     189             :         } else {
     190           0 :                 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     191           0 :                         zlog_debug("bond mbr %s link to bond skipped",
     192             :                                    zif->ifp->name);
     193             :         }
     194             : }
     195             : 
     196           0 : void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif)
     197             : {
     198           0 :         struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info;
     199           0 :         struct zebra_if *bond_zif;
     200             : 
     201           0 :         if (!bond_slave->bond_if) {
     202           0 :                 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     203           0 :                         zlog_debug("bond mbr %s unlink from bond skipped",
     204             :                                    zif->ifp->name);
     205           0 :                 return;
     206             :         }
     207             : 
     208           0 :         if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     209           0 :                 zlog_debug("bond mbr %s un-linked from %s", zif->ifp->name,
     210             :                            bond_slave->bond_if->name);
     211             : 
     212             :         /* unlink the slave from the bond master */
     213           0 :         bond_zif = bond_slave->bond_if->info;
     214             :         /* clear protodown flags */
     215           0 :         if (zebra_evpn_is_es_bond(bond_zif->ifp))
     216           0 :                 zebra_evpn_mh_update_protodown_bond_mbr(zif, true /*clear*/,
     217             :                                                         __func__);
     218           0 :         listnode_delete(bond_zif->bond_info.mbr_zifs, zif);
     219           0 :         bond_slave->bond_if = NULL;
     220           0 :         zebra_l2_bond_lacp_bypass_eval(bond_zif);
     221             : }
     222             : 
     223           0 : void zebra_l2if_update_bond(struct interface *ifp, bool add)
     224             : {
     225           0 :         struct zebra_if *zif;
     226           0 :         struct zebra_l2info_bond *bond;
     227             : 
     228           0 :         zif = ifp->info;
     229           0 :         assert(zif);
     230           0 :         bond = &zif->bond_info;
     231             : 
     232           0 :         if (add) {
     233           0 :                 if (!bond->mbr_zifs) {
     234           0 :                         if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     235           0 :                                 zlog_debug("bond %s mbr list create",
     236             :                                            ifp->name);
     237           0 :                         bond->mbr_zifs = list_new();
     238             :                 }
     239             :         } else {
     240           0 :                 struct listnode *node;
     241           0 :                 struct listnode *nnode;
     242           0 :                 struct zebra_if *bond_mbr;
     243             : 
     244           0 :                 if (!bond->mbr_zifs)
     245             :                         return;
     246             : 
     247           0 :                 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     248           0 :                         zlog_debug("bond %s mbr list delete", ifp->name);
     249           0 :                 for (ALL_LIST_ELEMENTS(bond->mbr_zifs, node, nnode, bond_mbr))
     250           0 :                         zebra_l2_unmap_slave_from_bond(bond_mbr);
     251             : 
     252           0 :                 list_delete(&bond->mbr_zifs);
     253             :         }
     254             : }
     255             : 
     256             : /*
     257             :  * Handle Bridge interface add or update. Update relevant info,
     258             :  * map slaves (if any) to the bridge.
     259             :  */
     260           0 : void zebra_l2_bridge_add_update(struct interface *ifp,
     261             :                                 struct zebra_l2info_bridge *bridge_info,
     262             :                                 int add)
     263             : {
     264           0 :         struct zebra_if *zif;
     265             : 
     266           0 :         zif = ifp->info;
     267           0 :         assert(zif);
     268             : 
     269             :         /* Copy over the L2 information. */
     270           0 :         memcpy(&zif->l2info.br, bridge_info, sizeof(*bridge_info));
     271             : 
     272             :         /* Link all slaves to this bridge */
     273           0 :         map_slaves_to_bridge(ifp, 1, false, ZEBRA_BRIDGE_NO_ACTION);
     274           0 : }
     275             : 
     276             : /*
     277             :  * Handle Bridge interface delete.
     278             :  */
     279           0 : void zebra_l2_bridge_del(struct interface *ifp)
     280             : {
     281             :         /* Unlink all slaves to this bridge */
     282           0 :         map_slaves_to_bridge(ifp, 0, false, ZEBRA_BRIDGE_NO_ACTION);
     283           0 : }
     284             : 
     285           0 : void zebra_l2if_update_bridge(struct interface *ifp, uint8_t chgflags)
     286             : {
     287           0 :         if (!chgflags)
     288             :                 return;
     289           0 :         map_slaves_to_bridge(ifp, 1, true, chgflags);
     290             : }
     291             : 
     292             : /*
     293             :  * Update L2 info for a VLAN interface. Only relevant parameter is the
     294             :  * VLAN Id and this cannot change.
     295             :  */
     296           0 : void zebra_l2_vlanif_update(struct interface *ifp,
     297             :                             struct zebra_l2info_vlan *vlan_info)
     298             : {
     299           0 :         struct zebra_if *zif;
     300             : 
     301           0 :         zif = ifp->info;
     302           0 :         assert(zif);
     303             : 
     304             :         /* Copy over the L2 information. */
     305           0 :         memcpy(&zif->l2info.vl, vlan_info, sizeof(*vlan_info));
     306           0 : }
     307             : 
     308             : /*
     309             :  * Update L2 info for a GRE interface. This is called upon interface
     310             :  * addition as well as update. Upon add/update, need to inform
     311             :  * clients about GRE information.
     312             :  */
     313           0 : void zebra_l2_greif_add_update(struct interface *ifp,
     314             :                                struct zebra_l2info_gre *gre_info, int add)
     315             : {
     316           0 :         struct zebra_if *zif;
     317           0 :         struct in_addr old_vtep_ip;
     318             : 
     319           0 :         zif = ifp->info;
     320           0 :         assert(zif);
     321             : 
     322           0 :         if (add) {
     323           0 :                 memcpy(&zif->l2info.gre, gre_info, sizeof(*gre_info));
     324           0 :                 return;
     325             :         }
     326             : 
     327           0 :         old_vtep_ip = zif->l2info.gre.vtep_ip;
     328           0 :         if (IPV4_ADDR_SAME(&old_vtep_ip, &gre_info->vtep_ip))
     329             :                 return;
     330             : 
     331           0 :         zif->l2info.gre.vtep_ip = gre_info->vtep_ip;
     332             : }
     333             : 
     334             : /*
     335             :  * Update L2 info for a VxLAN interface. This is called upon interface
     336             :  * addition as well as update. Upon add, need to invoke the VNI create
     337             :  * function. Upon update, the params of interest are the local tunnel
     338             :  * IP and VLAN mapping, but the latter is handled separately.
     339             :  */
     340           0 : void zebra_l2_vxlanif_add_update(struct interface *ifp,
     341             :                                  struct zebra_l2info_vxlan *vxlan_info, int add)
     342             : {
     343           0 :         struct zebra_if *zif;
     344           0 :         struct in_addr old_vtep_ip;
     345           0 :         uint16_t chgflags = 0;
     346             : 
     347           0 :         zif = ifp->info;
     348           0 :         assert(zif);
     349             : 
     350           0 :         if (add) {
     351           0 :                 memcpy(&zif->l2info.vxl, vxlan_info, sizeof(*vxlan_info));
     352           0 :                 zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
     353           0 :                 zebra_vxlan_if_add(ifp);
     354           0 :                 return;
     355             :         }
     356             : 
     357           0 :         old_vtep_ip = zif->l2info.vxl.vtep_ip;
     358             : 
     359           0 :         if (!IPV4_ADDR_SAME(&old_vtep_ip, &vxlan_info->vtep_ip)) {
     360           0 :                 chgflags |= ZEBRA_VXLIF_LOCAL_IP_CHANGE;
     361           0 :                 zif->l2info.vxl.vtep_ip = vxlan_info->vtep_ip;
     362             :         }
     363             : 
     364           0 :         if (!IPV4_ADDR_SAME(&zif->l2info.vxl.mcast_grp,
     365             :                                 &vxlan_info->mcast_grp)) {
     366           0 :                 chgflags |= ZEBRA_VXLIF_MCAST_GRP_CHANGE;
     367           0 :                 zif->l2info.vxl.mcast_grp = vxlan_info->mcast_grp;
     368             :         }
     369             : 
     370           0 :         if (chgflags)
     371           0 :                 zebra_vxlan_if_update(ifp, chgflags);
     372             : }
     373             : 
     374             : /*
     375             :  * Handle change to VLAN to VNI mapping.
     376             :  */
     377           0 : void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
     378             :                                          vlanid_t access_vlan)
     379             : {
     380           0 :         struct zebra_if *zif;
     381           0 :         vlanid_t old_access_vlan;
     382             : 
     383           0 :         zif = ifp->info;
     384           0 :         assert(zif);
     385             : 
     386           0 :         old_access_vlan = zif->l2info.vxl.access_vlan;
     387           0 :         if (old_access_vlan == access_vlan)
     388             :                 return;
     389             : 
     390           0 :         zif->l2info.vxl.access_vlan = access_vlan;
     391             : 
     392           0 :         zebra_evpn_vl_vxl_deref(old_access_vlan, zif);
     393           0 :         zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
     394           0 :         zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_VLAN_CHANGE);
     395             : }
     396             : 
     397             : /*
     398             :  * Handle VxLAN interface delete.
     399             :  */
     400           0 : void zebra_l2_vxlanif_del(struct interface *ifp)
     401             : {
     402           0 :         struct zebra_if *zif;
     403             : 
     404           0 :         zif = ifp->info;
     405           0 :         assert(zif);
     406             : 
     407           0 :         zebra_evpn_vl_vxl_deref(zif->l2info.vxl.access_vlan, zif);
     408           0 :         zebra_vxlan_if_del(ifp);
     409           0 : }
     410             : 
     411             : /*
     412             :  * Map or unmap interface from bridge.
     413             :  * NOTE: It is currently assumped that an interface has to be unmapped
     414             :  * from a bridge before it can be mapped to another bridge.
     415             :  */
     416           0 : void zebra_l2if_update_bridge_slave(struct interface *ifp,
     417             :                                     ifindex_t bridge_ifindex, ns_id_t ns_id,
     418             :                                     uint8_t chgflags)
     419             : {
     420           0 :         struct zebra_if *zif;
     421           0 :         ifindex_t old_bridge_ifindex;
     422           0 :         ns_id_t old_ns_id;
     423           0 :         struct zebra_vrf *zvrf;
     424             : 
     425           0 :         zif = ifp->info;
     426           0 :         assert(zif);
     427             : 
     428           0 :         zvrf = ifp->vrf->info;
     429           0 :         if (!zvrf)
     430             :                 return;
     431             : 
     432           0 :         if (zif->zif_type == ZEBRA_IF_VXLAN
     433           0 :             && chgflags != ZEBRA_BRIDGE_NO_ACTION) {
     434           0 :                 if (chgflags & ZEBRA_BRIDGE_MASTER_MAC_CHANGE)
     435           0 :                         zebra_vxlan_if_update(ifp,
     436             :                                               ZEBRA_VXLIF_MASTER_MAC_CHANGE);
     437           0 :                 if (chgflags & ZEBRA_BRIDGE_MASTER_UP)
     438           0 :                         zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
     439             :         }
     440           0 :         old_bridge_ifindex = zif->brslave_info.bridge_ifindex;
     441           0 :         old_ns_id = zif->brslave_info.ns_id;
     442           0 :         if (old_bridge_ifindex == bridge_ifindex &&
     443             :             old_ns_id == zif->brslave_info.ns_id)
     444             :                 return;
     445             : 
     446           0 :         zif->brslave_info.ns_id = ns_id;
     447           0 :         zif->brslave_info.bridge_ifindex = bridge_ifindex;
     448             :         /* Set up or remove link with master */
     449           0 :         if (bridge_ifindex != IFINDEX_INTERNAL) {
     450           0 :                 zebra_l2_map_slave_to_bridge(&zif->brslave_info, zvrf->zns);
     451             :                 /* In the case of VxLAN, invoke the handler for EVPN. */
     452           0 :                 if (zif->zif_type == ZEBRA_IF_VXLAN)
     453           0 :                         zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
     454           0 :                 if (zif->es_info.es)
     455           0 :                         zebra_evpn_es_local_br_port_update(zif);
     456           0 :         } else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
     457             :                 /*
     458             :                  * In the case of VxLAN, invoke the handler for EVPN.
     459             :                  * Note that this should be done *prior*
     460             :                  * to unmapping the interface from the bridge.
     461             :                  */
     462           0 :                 if (zif->zif_type == ZEBRA_IF_VXLAN)
     463           0 :                         zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
     464           0 :                 if (zif->es_info.es)
     465           0 :                         zebra_evpn_es_local_br_port_update(zif);
     466           0 :                 zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);
     467             :         }
     468             : }
     469             : 
     470           0 : void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex,
     471             :                                   bool new_bypass)
     472             : {
     473           0 :         struct zebra_if *zif;
     474           0 :         ifindex_t old_bond_ifindex;
     475           0 :         bool old_bypass;
     476           0 :         struct zebra_l2info_bondslave *bond_mbr;
     477             : 
     478           0 :         zif = ifp->info;
     479           0 :         assert(zif);
     480             : 
     481           0 :         old_bypass = !!(zif->flags & ZIF_FLAG_LACP_BYPASS);
     482           0 :         if (old_bypass != new_bypass) {
     483           0 :                 if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
     484           0 :                         zlog_debug("bond-mbr %s lacp bypass changed to %s",
     485             :                                    zif->ifp->name, new_bypass ? "on" : "off");
     486             : 
     487           0 :                 if (new_bypass)
     488           0 :                         zif->flags |= ZIF_FLAG_LACP_BYPASS;
     489             :                 else
     490           0 :                         zif->flags &= ~ZIF_FLAG_LACP_BYPASS;
     491             : 
     492           0 :                 bond_mbr = &zif->bondslave_info;
     493           0 :                 if (bond_mbr->bond_if) {
     494           0 :                         struct zebra_if *bond_zif = bond_mbr->bond_if->info;
     495             : 
     496           0 :                         zebra_l2_bond_lacp_bypass_eval(bond_zif);
     497             :                 }
     498             :         }
     499             : 
     500           0 :         old_bond_ifindex = zif->bondslave_info.bond_ifindex;
     501           0 :         if (old_bond_ifindex == bond_ifindex)
     502             :                 return;
     503             : 
     504           0 :         zif->bondslave_info.bond_ifindex = bond_ifindex;
     505             : 
     506             :         /* Set up or remove link with master */
     507           0 :         if (bond_ifindex != IFINDEX_INTERNAL)
     508           0 :                 zebra_l2_map_slave_to_bond(zif, ifp->vrf->vrf_id);
     509           0 :         else if (old_bond_ifindex != IFINDEX_INTERNAL)
     510           0 :                 zebra_l2_unmap_slave_from_bond(zif);
     511             : }
     512             : 
     513           0 : void zebra_vlan_bitmap_compute(struct interface *ifp,
     514             :                 uint32_t vid_start, uint16_t vid_end)
     515             : {
     516           0 :         uint32_t vid;
     517           0 :         struct zebra_if *zif;
     518             : 
     519           0 :         zif = (struct zebra_if *)ifp->info;
     520           0 :         assert(zif);
     521             : 
     522           0 :         for (vid = vid_start; vid <= vid_end; ++vid)
     523           0 :                 bf_set_bit(zif->vlan_bitmap, vid);
     524           0 : }
     525             : 
     526           0 : void zebra_vlan_mbr_re_eval(struct interface *ifp, bitfield_t old_vlan_bitmap)
     527             : {
     528           0 :         uint32_t vid;
     529           0 :         struct zebra_if *zif;
     530             : 
     531           0 :         zif = (struct zebra_if *)ifp->info;
     532           0 :         assert(zif);
     533             : 
     534           0 :         if (!bf_cmp(zif->vlan_bitmap, old_vlan_bitmap))
     535             :                 /* no change */
     536             :                 return;
     537             : 
     538           0 :         bf_for_each_set_bit(zif->vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
     539             :                 /* if not already set create new reference */
     540           0 :                 if (!bf_test_index(old_vlan_bitmap, vid))
     541           0 :                         zebra_evpn_vl_mbr_ref(vid, zif);
     542             : 
     543             :                 /* also clear from the old vlan bitmap */
     544           0 :                 bf_release_index(old_vlan_bitmap, vid);
     545             :         }
     546             : 
     547             :         /* any bits remaining in the old vlan bitmap are stale references */
     548           0 :         bf_for_each_set_bit(old_vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) {
     549           0 :                 zebra_evpn_vl_mbr_deref(vid, zif);
     550             :         }
     551             : }

Generated by: LCOV version v1.16-topotato