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 9 : DEFINE_MTYPE_STATIC(ZEBRA, ZEVPN, "VNI hash");
59 9 : 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 : }
|