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