]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vxlan.c
bgpd: EVPN route handling
[mirror_frr.git] / zebra / zebra_vxlan.c
CommitLineData
13d60d35 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
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#include "vlan.h"
35#include "vxlan.h"
36
37#include "zebra/rib.h"
38#include "zebra/rt.h"
39#include "zebra/zebra_ns.h"
40#include "zebra/zserv.h"
41#include "zebra/debug.h"
42#include "zebra/interface.h"
43#include "zebra/zebra_vrf.h"
44#include "zebra/rt_netlink.h"
45#include "zebra/zebra_vxlan_private.h"
46#include "zebra/zebra_vxlan.h"
47#include "zebra/zebra_memory.h"
48#include "zebra/zebra_l2.h"
49
50DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
51DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
2232a77c 52DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
53DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
13d60d35 54
55/* definitions */
56
57
58/* static function declarations */
cec2e17d 59static void
60zvni_print_neigh (zebra_neigh_t *n, void *ctxt);
61static void
62zvni_print_neigh_hash (struct hash_backet *backet, void *ctxt);
63static void
64zvni_print_neigh_hash_all_vni (struct hash_backet *backet, void *ctxt);
65static void
66zvni_print_mac (zebra_mac_t *mac, void *ctxt);
67static void
68zvni_print_mac_hash (struct hash_backet *backet, void *ctxt);
69static void
70zvni_print_mac_hash_all_vni (struct hash_backet *backet, void *ctxt);
71static void
72zvni_print (zebra_vni_t *zvni, void *ctxt);
73static void
74zvni_print_hash (struct hash_backet *backet, void *ctxt);
75
2232a77c 76static int
77zvni_macip_send_msg_to_client (struct zebra_vrf *zvrf, vni_t vni,
78 struct ethaddr *macaddr,
79 struct ipaddr *ip,
80 u_int16_t cmd);
81static unsigned int
82neigh_hash_keymake (void *p);
83static int
84neigh_cmp (const void *p1, const void *p2);
85static void *
86zvni_neigh_alloc (void *p);
87static zebra_neigh_t *
88zvni_neigh_add (zebra_vni_t *zvni, struct ipaddr *ip);
89static int
90zvni_neigh_del (zebra_vni_t *zvni, zebra_neigh_t *n);
91static int
92zvni_neigh_del_hash_entry (struct hash_backet *backet, void *arg);
93static void
94zvni_neigh_del_from_vtep (zebra_vni_t *zvni, int uninstall,
95 struct in_addr *r_vtep_ip);
96static void
97zvni_neigh_del_all (struct zebra_vrf *zvrf, zebra_vni_t *zvni,
98 int uninstall, int upd_client, u_int32_t flags);
99static zebra_neigh_t *
100zvni_neigh_lookup (zebra_vni_t *zvni, struct ipaddr *ip);
101static int
102zvni_neigh_send_add_to_client (struct zebra_vrf *zvrf, vni_t vni,
103 struct ipaddr *ip, struct ethaddr *macaddr);
104static int
105zvni_neigh_send_del_to_client (struct zebra_vrf *zvrf, vni_t vni,
106 struct ipaddr *ip, struct ethaddr *macaddr);
107static int
108zvni_neigh_install (zebra_vni_t *zvni, zebra_neigh_t *n);
109static int
110zvni_neigh_uninstall (zebra_vni_t *zvni, zebra_neigh_t *n);
111static zebra_vni_t *
112zvni_map_svi (struct interface *ifp, struct interface *br_if);
113static struct interface *
114zvni_map_to_svi (struct zebra_vrf *zvrf, vlanid_t vid,
115 struct interface *br_if);
116
117static unsigned int
118mac_hash_keymake (void *p);
119static int
120mac_cmp (const void *p1, const void *p2);
121static void *
122zvni_mac_alloc (void *p);
123static zebra_mac_t *
124zvni_mac_add (zebra_vni_t *zvni, struct ethaddr *macaddr);
125static int
126zvni_mac_del (zebra_vni_t *zvni, zebra_mac_t *mac);
127static int
128zvni_mac_del_hash_entry (struct hash_backet *backet, void *arg);
129static void
130zvni_mac_del_from_vtep (zebra_vni_t *zvni, int uninstall,
131 struct in_addr *r_vtep_ip);
132static void
133zvni_mac_del_all (struct zebra_vrf *zvrf, zebra_vni_t *zvni,
134 int uninstall, int upd_client, u_int32_t flags);
135static zebra_mac_t *
136zvni_mac_lookup (zebra_vni_t *zvni, struct ethaddr *macaddr);
137static int
138zvni_mac_send_add_to_client (struct zebra_vrf *zvrf, vni_t vni,
139 struct ethaddr *macaddr);
140static int
141zvni_mac_send_del_to_client (struct zebra_vrf *zvrf, vni_t vni,
142 struct ethaddr *macaddr);
143static zebra_vni_t *
144zvni_map_vlan (struct interface *ifp, struct interface *br_if, vlanid_t vid);
145static int
146zvni_mac_install (zebra_vni_t *zvni, zebra_mac_t *mac);
147static int
148zvni_mac_uninstall (zebra_vni_t *zvni, zebra_mac_t *mac, int local);
149static void
150zvni_install_mac_hash (struct hash_backet *backet, void *ctxt);
151
13d60d35 152static unsigned int
153vni_hash_keymake (void *p);
154static int
155vni_hash_cmp (const void *p1, const void *p2);
156static void *
157zvni_alloc (void *p);
158static zebra_vni_t *
159zvni_lookup (struct zebra_vrf *zvrf, vni_t vni);
160static zebra_vni_t *
161zvni_add (struct zebra_vrf *zvrf, vni_t vni);
162static int
163zvni_del (struct zebra_vrf *zvrf, zebra_vni_t *zvni);
164static int
165zvni_send_add_to_client (struct zebra_vrf *zvrf, zebra_vni_t *zvni);
166static int
167zvni_send_del_to_client (struct zebra_vrf *zvrf, vni_t vni);
168static void
169zvni_build_hash_table (struct zebra_vrf *zvrf);
170static int
171zvni_vtep_match (struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
172static zebra_vtep_t *
173zvni_vtep_find (zebra_vni_t *zvni, struct in_addr *vtep_ip);
174static zebra_vtep_t *
175zvni_vtep_add (zebra_vni_t *zvni, struct in_addr *vtep_ip);
176static int
177zvni_vtep_del (zebra_vni_t *zvni, zebra_vtep_t *zvtep);
178static int
179zvni_vtep_del_all (zebra_vni_t *zvni, int uninstall);
180static int
181zvni_vtep_install (zebra_vni_t *zvni, struct in_addr *vtep_ip);
182static int
183zvni_vtep_uninstall (zebra_vni_t *zvni, struct in_addr *vtep_ip);
184
185
186/* Private functions */
187
cec2e17d 188/*
189 * Helper function to determine maximum width of neighbor IP address for
190 * display - just because we're dealing with IPv6 addresses that can
191 * widely vary.
192 */
193static void
194zvni_find_neigh_addr_width (struct hash_backet *backet, void *ctxt)
195{
196 zebra_neigh_t *n;
197 char buf[INET6_ADDRSTRLEN];
198 struct neigh_walk_ctx *wctx = ctxt;
199 int width;
200
201 n = (zebra_neigh_t *) backet->data;
202 if (!n)
203 return;
204
205 ipaddr2str (&n->ip, buf, sizeof(buf)),
206 width = strlen (buf);
207 if (width > wctx->addr_width)
208 wctx->addr_width = width;
209}
210
211/*
212 * Print a specific neighbor entry.
213 */
214static void
215zvni_print_neigh (zebra_neigh_t *n, void *ctxt)
216{
217 struct vty *vty;
218 char buf1[ETHER_ADDR_STRLEN];
219 char buf2[INET6_ADDRSTRLEN];
220
221 ipaddr2str (&n->ip, buf2, sizeof(buf2)),
222 vty = (struct vty *) ctxt;
223 vty_out(vty, "IP: %s%s",
224 ipaddr2str (&n->ip, buf2, sizeof(buf2)), VTY_NEWLINE);
225 vty_out(vty, " MAC: %s", prefix_mac2str (&n->emac, buf1, sizeof (buf1)));
226 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
227 vty_out(vty, " Remote VTEP: %s", inet_ntoa (n->r_vtep_ip));
228 vty_out(vty, "%s", VTY_NEWLINE);
229}
230
231/*
232 * Print neighbor hash entry - called for display of all neighbors.
233 */
234static void
235zvni_print_neigh_hash (struct hash_backet *backet, void *ctxt)
236{
237 struct vty *vty;
238 zebra_neigh_t *n;
239 char buf1[ETHER_ADDR_STRLEN];
240 char buf2[INET6_ADDRSTRLEN];
241 struct neigh_walk_ctx *wctx = ctxt;
242
243 vty = wctx->vty;
244 n = (zebra_neigh_t *) backet->data;
245 if (!n)
246 return;
247
248 prefix_mac2str (&n->emac, buf1, sizeof (buf1));
249 ipaddr2str (&n->ip, buf2, sizeof(buf2));
250 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) &&
251 !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP))
252 {
253 vty_out(vty, "%*s %-6s %-17s %s",
254 -wctx->addr_width, buf2, "local", buf1, VTY_NEWLINE);
255 wctx->count++;
256 }
257 else
258 {
259 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
260 {
261 if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))
262 {
263 if (wctx->count == 0)
264 vty_out(vty, "%*s %-6s %-17s %-21s%s",
265 -wctx->addr_width, "Neighbor", "Type", "MAC",
266 "Remote VTEP", VTY_NEWLINE);
267 vty_out(vty, "%*s %-6s %-17s %-21s%s",
268 -wctx->addr_width, buf2, "remote", buf1,
269 inet_ntoa (n->r_vtep_ip), VTY_NEWLINE);
270 wctx->count++;
271 }
272 }
273 else
274 {
275 vty_out(vty, "%*s %-6s %-17s %-21s%s",
276 -wctx->addr_width, buf2, "remote", buf1,
277 inet_ntoa (n->r_vtep_ip), VTY_NEWLINE);
278 wctx->count++;
279 }
280 }
281}
282
283/*
284 * Print neighbors for all VNI.
285 */
286static void
287zvni_print_neigh_hash_all_vni (struct hash_backet *backet, void *ctxt)
288{
289 struct vty *vty;
290 zebra_vni_t *zvni;
291 u_int32_t num_neigh;
292 struct neigh_walk_ctx wctx;
293
294 vty = (struct vty *) ctxt;
295 zvni = (zebra_vni_t *) backet->data;
296 if (!zvni)
297 return;
298
299 num_neigh = hashcount(zvni->neigh_table);
300 vty_out(vty, "%sVNI %u #ARP (IPv4 and IPv6, local and remote) %u%s%s",
301 VTY_NEWLINE, zvni->vni, num_neigh, VTY_NEWLINE, VTY_NEWLINE);
302 if (!num_neigh)
303 return;
304
305 /* Since we have IPv6 addresses to deal with which can vary widely in
306 * size, we try to be a bit more elegant in display by first computing
307 * the maximum width.
308 */
309 memset (&wctx, 0, sizeof (struct neigh_walk_ctx));
310 wctx.zvni = zvni;
311 wctx.vty = vty;
312 wctx.addr_width = 15;
313 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
314
315 vty_out(vty, "%*s %-6s %-17s %-21s%s",
316 -wctx.addr_width, "IP", "Type", "MAC",
317 "Remote VTEP", VTY_NEWLINE);
318 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
319}
320
321/*
322 * Print a specific MAC entry.
323 */
324static void
325zvni_print_mac (zebra_mac_t *mac, void *ctxt)
326{
327 struct vty *vty;
328 char buf1[20];
329
330 vty = (struct vty *) ctxt;
331 vty_out(vty, "MAC: %s%s",
332 prefix_mac2str (&mac->macaddr, buf1, sizeof (buf1)), VTY_NEWLINE);
333 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
334 {
335 struct zebra_ns *zns;
336 struct interface *ifp;
337 ifindex_t ifindex;
338
339 ifindex = mac->fwd_info.local.ifindex;
340 zns = zebra_ns_lookup (NS_DEFAULT);
341 ifp = if_lookup_by_index_per_ns (zns, ifindex);
342 if (!ifp) // unexpected
343 return;
344 vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
345 if (mac->fwd_info.local.vid)
346 vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
347 }
348 else
349 {
350 vty_out(vty, " Remote VTEP: %s",
351 inet_ntoa (mac->fwd_info.r_vtep_ip));
352 }
353 vty_out(vty, " ARP ref: %u", mac->neigh_refcnt);
354 vty_out(vty, "%s", VTY_NEWLINE);
355}
356
357/*
358 * Print MAC hash entry - called for display of all MACs.
359 */
360static void
361zvni_print_mac_hash (struct hash_backet *backet, void *ctxt)
362{
363 struct vty *vty;
364 zebra_mac_t *mac;
365 char buf1[20];
366 struct mac_walk_ctx *wctx = ctxt;
367
368 vty = wctx->vty;
369 mac = (zebra_mac_t *) backet->data;
370 if (!mac)
371 return;
372
373 prefix_mac2str (&mac->macaddr, buf1, sizeof (buf1));
374 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) &&
375 !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP))
376 {
377 struct zebra_ns *zns;
378 ifindex_t ifindex;
379 struct interface *ifp;
380 vlanid_t vid;
381
382 zns = zebra_ns_lookup (NS_DEFAULT);
383 ifindex = mac->fwd_info.local.ifindex;
384 ifp = if_lookup_by_index_per_ns (zns, ifindex);
385 if (!ifp) // unexpected
386 return;
387 vid = mac->fwd_info.local.vid;
388 vty_out(vty, "%-17s %-6s %-21s",
389 buf1, "local", ifp->name);
390 if (vid)
391 vty_out(vty, " %-5u", vid);
392 vty_out(vty, "%s", VTY_NEWLINE);
393 wctx->count++;
394 }
395 else
396 {
397 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)
398 {
399 if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
400 &wctx->r_vtep_ip))
401 {
402 if (wctx->count == 0)
403 {
404 vty_out(vty, "%sVNI %u%s%s",
405 VTY_NEWLINE, wctx->zvni->vni,VTY_NEWLINE, VTY_NEWLINE);
406 vty_out(vty, "%-17s %-6s %-21s %-5s%s",
407 "MAC", "Type", "Intf/Remote VTEP",
408 "VLAN", VTY_NEWLINE);
409 }
410 vty_out(vty, "%-17s %-6s %-21s%s",
411 buf1, "remote",
412 inet_ntoa (mac->fwd_info.r_vtep_ip),
413 VTY_NEWLINE);
414 wctx->count++;
415 }
416 }
417 else
418 {
419 vty_out(vty, "%-17s %-6s %-21s%s",
420 buf1, "remote",
421 inet_ntoa (mac->fwd_info.r_vtep_ip), VTY_NEWLINE);
422 wctx->count++;
423 }
424 }
425
426}
427
428/*
429 * Print MACs for all VNI.
430 */
431static void
432zvni_print_mac_hash_all_vni (struct hash_backet *backet, void *ctxt)
433{
434 struct vty *vty;
435 zebra_vni_t *zvni;
436 u_int32_t num_macs;
437 struct mac_walk_ctx *wctx = ctxt;
438
439 vty = (struct vty *) wctx->vty;
440
441 zvni = (zebra_vni_t *) backet->data;
442 if (!zvni)
443 return;
444 wctx->zvni = zvni;
445
446 /*We are iterating over a new VNI, set the count to 0*/
447 wctx->count = 0;
448
449 num_macs = hashcount(zvni->mac_table);
450 if (!num_macs)
451 return;
452 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP))
453 {
454 vty_out(vty, "%sVNI %u #MACs (local and remote) %u%s%s",
455 VTY_NEWLINE, zvni->vni, num_macs, VTY_NEWLINE, VTY_NEWLINE);
456 vty_out(vty, "%-17s %-6s %-21s %-5s%s",
457 "MAC", "Type", "Intf/Remote VTEP", "VLAN", VTY_NEWLINE);
458 }
459
460 hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
461}
462
463/*
464 * Print a specific VNI entry.
465 */
466static void
467zvni_print (zebra_vni_t *zvni, void *ctxt)
468{
469 struct vty *vty;
470 zebra_vtep_t *zvtep;
471 u_int32_t num_macs;
472 u_int32_t num_neigh;
473
474 vty = (struct vty *) ctxt;
475
476 vty_out(vty, "VNI: %u%s", zvni->vni, VTY_NEWLINE);
477 if (!zvni->vxlan_if)
478 { // unexpected
479 vty_out(vty, " VxLAN interface: unknown%s", VTY_NEWLINE);
480 return;
481 }
482 vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s%s",
483 zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
484 inet_ntoa(zvni->local_vtep_ip), VTY_NEWLINE);
485
486 if (!zvni->vteps)
487 {
488 vty_out(vty, " No remote VTEPs known for this VNI%s", VTY_NEWLINE);
489 }
490 else
491 {
492 vty_out(vty, " Remote VTEPs for this VNI:%s", VTY_NEWLINE);
493 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next)
494 vty_out(vty, " %s%s",
495 inet_ntoa (zvtep->vtep_ip), VTY_NEWLINE);
496 }
497 num_macs = hashcount(zvni->mac_table);
498 vty_out(vty, " Number of MACs (local and remote) known for this VNI: %u%s",
499 num_macs, VTY_NEWLINE);
500 num_neigh = hashcount(zvni->neigh_table);
501 vty_out(vty, " Number of ARPs (IPv4 and IPv6, local and remote) "
502 "known for this VNI: %u%s", num_neigh, VTY_NEWLINE);
503}
504
505/*
506 * Print a VNI hash entry - called for display of all VNIs.
507 */
508static void
509zvni_print_hash (struct hash_backet *backet, void *ctxt)
510{
511 struct vty *vty;
512 zebra_vni_t *zvni;
513 zebra_vtep_t *zvtep;
514 u_int32_t num_vteps = 0;
515 u_int32_t num_macs = 0;
516 u_int32_t num_neigh = 0;
517
518 vty = (struct vty *) ctxt;
519 zvni = (zebra_vni_t *) backet->data;
520 if (!zvni)
521 return;
522
523 zvtep = zvni->vteps;
524 while (zvtep)
525 {
526 num_vteps++;
527 zvtep = zvtep->next;
528 }
529
530 num_macs = hashcount(zvni->mac_table);
531 num_neigh = hashcount(zvni->neigh_table);
532 vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u%s",
533 zvni->vni,
534 zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
535 inet_ntoa(zvni->local_vtep_ip),
536 num_macs, num_neigh, num_vteps, VTY_NEWLINE);
537}
538
13d60d35 539/*
2232a77c 540 * Inform BGP about local MACIP.
541 */
542static int
543zvni_macip_send_msg_to_client (struct zebra_vrf *zvrf, vni_t vni,
544 struct ethaddr *macaddr,
545 struct ipaddr *ip,
546 u_int16_t cmd)
547{
548 struct zserv *client;
549 struct stream *s;
550 int ipa_len;
551 char buf[ETHER_ADDR_STRLEN];
552 char buf2[INET6_ADDRSTRLEN];
553
554 client = zebra_find_client (ZEBRA_ROUTE_BGP);
555 /* BGP may not be running. */
556 if (!client)
557 return 0;
558
559 s = client->obuf;
560 stream_reset (s);
561
562 zserv_create_header (s, cmd, zvrf_id (zvrf));
563 stream_putl (s, vni);
564 stream_put (s, macaddr->octet, ETHER_ADDR_LEN);
565 if (ip)
566 {
567 ipa_len = 0;
568 if (IS_IPADDR_V4(ip))
569 ipa_len = IPV4_MAX_BYTELEN;
570 else if (IS_IPADDR_V6(ip))
571 ipa_len = IPV6_MAX_BYTELEN;
572
573 stream_putl (s, ipa_len); /* IP address length */
574 if (ipa_len)
575 stream_put (s, &ip->ip.addr, ipa_len); /* IP address */
576 }
577 else
578 stream_putl (s, 0); /* Just MAC. */
579
580 /* Write packet size. */
581 stream_putw_at (s, 0, stream_get_endp (s));
582
583 if (IS_ZEBRA_DEBUG_VXLAN)
584 zlog_debug ("%u:Send MACIP %s MAC %s IP %s VNI %u to %s",
585 zvrf_id (zvrf), (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
586 prefix_mac2str (macaddr, buf, sizeof (buf)),
587 ipaddr2str (ip, buf2, sizeof(buf2)), vni,
588 zebra_route_string (client->proto));
589
590 if (cmd == ZEBRA_MACIP_ADD)
591 client->macipadd_cnt++;
592 else
593 client->macipdel_cnt++;
594
595 return zebra_server_send_message(client);
596}
597
598/*
599 * Make hash key for neighbors.
13d60d35 600 */
601static unsigned int
2232a77c 602neigh_hash_keymake (void *p)
13d60d35 603{
2232a77c 604 zebra_neigh_t *n = p;
605 struct ipaddr *ip = &n->ip;
13d60d35 606
2232a77c 607 if (IS_IPADDR_V4(ip))
608 return jhash_1word (ip->ipaddr_v4.s_addr, 0);
609
610 return jhash2 (ip->ipaddr_v6.s6_addr32,
611 ZEBRA_NUM_OF(ip->ipaddr_v6.s6_addr32), 0);
13d60d35 612}
613
614/*
2232a77c 615 * Compare two neighbor hash structures.
13d60d35 616 */
617static int
2232a77c 618neigh_cmp (const void *p1, const void *p2)
13d60d35 619{
2232a77c 620 const zebra_neigh_t *n1 = p1;
621 const zebra_neigh_t *n2 = p2;
13d60d35 622
2232a77c 623 if (n1 == NULL && n2 == NULL)
624 return 1;
625
626 if (n1 == NULL || n2 == NULL)
627 return 0;
628
629 return (memcmp(&n1->ip, &n2->ip, sizeof (struct ipaddr)) == 0);
13d60d35 630}
631
632/*
2232a77c 633 * Callback to allocate neighbor hash entry.
13d60d35 634 */
635static void *
2232a77c 636zvni_neigh_alloc (void *p)
13d60d35 637{
2232a77c 638 const zebra_neigh_t *tmp_n = p;
639 zebra_neigh_t *n;
13d60d35 640
2232a77c 641 n = XCALLOC (MTYPE_NEIGH, sizeof(zebra_neigh_t));
642 *n = *tmp_n;
643
644 return ((void *)n);
13d60d35 645}
646
647/*
2232a77c 648 * Add neighbor entry.
13d60d35 649 */
2232a77c 650static zebra_neigh_t *
651zvni_neigh_add (zebra_vni_t *zvni, struct ipaddr *ip)
13d60d35 652{
2232a77c 653 zebra_neigh_t tmp_n;
654 zebra_neigh_t *n = NULL;
13d60d35 655
2232a77c 656 memset (&tmp_n, 0, sizeof (zebra_neigh_t));
657 memcpy (&tmp_n.ip, ip, sizeof (struct ipaddr));
658 n = hash_get (zvni->neigh_table, &tmp_n, zvni_neigh_alloc);
659 assert (n);
13d60d35 660
2232a77c 661 return n;
13d60d35 662}
663
664/*
2232a77c 665 * Delete neighbor entry.
13d60d35 666 */
2232a77c 667static int
668zvni_neigh_del (zebra_vni_t *zvni, zebra_neigh_t *n)
13d60d35 669{
2232a77c 670 zebra_neigh_t *tmp_n;
13d60d35 671
2232a77c 672 /* Free the VNI hash entry and allocated memory. */
673 tmp_n = hash_release (zvni->neigh_table, n);
674 if (tmp_n)
675 XFREE(MTYPE_NEIGH, tmp_n);
13d60d35 676
2232a77c 677 return 0;
13d60d35 678}
679
680/*
2232a77c 681 * Free neighbor hash entry (callback)
13d60d35 682 */
683static int
2232a77c 684zvni_neigh_del_hash_entry (struct hash_backet *backet, void *arg)
13d60d35 685{
2232a77c 686 struct neigh_walk_ctx *wctx = arg;
687 zebra_neigh_t *n = backet->data;
688
689 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL)) ||
690 ((wctx->flags & DEL_REMOTE_NEIGH) && (n->flags & ZEBRA_NEIGH_REMOTE)) ||
691 ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP) &&
692 (n->flags & ZEBRA_NEIGH_REMOTE) &&
693 IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)
694 ))
695 {
696 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
697 zvni_neigh_send_del_to_client (wctx->zvrf, wctx->zvni->vni, &n->ip,
698 &n->emac);
13d60d35 699
2232a77c 700 if (wctx->uninstall)
701 zvni_neigh_uninstall (wctx->zvni, n);
13d60d35 702
2232a77c 703 return zvni_neigh_del (wctx->zvni, n);
704 }
13d60d35 705
706 return 0;
707}
708
709/*
2232a77c 710 * Delete all neighbor entries from specific VTEP for a particular VNI.
13d60d35 711 */
2232a77c 712static void
713zvni_neigh_del_from_vtep (zebra_vni_t *zvni, int uninstall,
714 struct in_addr *r_vtep_ip)
13d60d35 715{
2232a77c 716 struct neigh_walk_ctx wctx;
13d60d35 717
2232a77c 718 if (!zvni->neigh_table)
719 return;
13d60d35 720
2232a77c 721 memset (&wctx, 0, sizeof (struct neigh_walk_ctx));
722 wctx.zvni = zvni;
723 wctx.uninstall = uninstall;
724 wctx.flags = DEL_REMOTE_NEIGH_FROM_VTEP;
725 wctx.r_vtep_ip = *r_vtep_ip;
13d60d35 726
2232a77c 727 hash_iterate (zvni->neigh_table,
728 (void (*) (struct hash_backet *, void *))
729 zvni_neigh_del_hash_entry, &wctx);
730}
13d60d35 731
2232a77c 732/*
733 * Delete all neighbor entries for this VNI.
734 */
735static void
736zvni_neigh_del_all (struct zebra_vrf *zvrf, zebra_vni_t *zvni,
737 int uninstall, int upd_client, u_int32_t flags)
738{
739 struct neigh_walk_ctx wctx;
13d60d35 740
2232a77c 741 if (!zvni->neigh_table)
742 return;
13d60d35 743
2232a77c 744 memset (&wctx, 0, sizeof (struct neigh_walk_ctx));
745 wctx.zvni = zvni;
746 wctx.zvrf = zvrf;
747 wctx.uninstall = uninstall;
748 wctx.upd_client = upd_client;
749 wctx.flags = flags;
750
751 hash_iterate (zvni->neigh_table,
752 (void (*) (struct hash_backet *, void *))
753 zvni_neigh_del_hash_entry, &wctx);
13d60d35 754}
755
756/*
2232a77c 757 * Look up neighbor hash entry.
758 */
759static zebra_neigh_t *
760zvni_neigh_lookup (zebra_vni_t *zvni, struct ipaddr *ip)
761{
762 zebra_neigh_t tmp;
763 zebra_neigh_t *n;
764
765 memset (&tmp, 0, sizeof(tmp));
766 memcpy (&tmp.ip, ip, sizeof (struct ipaddr));
767 n = hash_lookup (zvni->neigh_table, &tmp);
768
769 return n;
770}
771
772/*
773 * Inform BGP about local neighbor addition.
13d60d35 774 */
775static int
2232a77c 776zvni_neigh_send_add_to_client (struct zebra_vrf *zvrf, vni_t vni,
777 struct ipaddr *ip, struct ethaddr *macaddr)
13d60d35 778{
2232a77c 779 return zvni_macip_send_msg_to_client (zvrf, vni, macaddr, ip,
780 ZEBRA_MACIP_ADD);
781}
13d60d35 782
2232a77c 783/*
784 * Inform BGP about local neighbor deletion.
785 */
786static int
787zvni_neigh_send_del_to_client (struct zebra_vrf *zvrf, vni_t vni,
788 struct ipaddr *ip, struct ethaddr *macaddr)
789{
790 return zvni_macip_send_msg_to_client (zvrf, vni, macaddr, ip,
791 ZEBRA_MACIP_DEL);
792}
793
794/*
795 * Install remote neighbor into the kernel.
796 */
797static int
798zvni_neigh_install (zebra_vni_t *zvni, zebra_neigh_t *n)
799{
800 struct zebra_vrf *zvrf;
801 struct zebra_if *zif;
802 struct zebra_l2info_vxlan *vxl;
803 struct interface *vlan_if;
804
805 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
13d60d35 806 return 0;
807
2232a77c 808 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
809 assert(zvrf);
810 zif = zvni->vxlan_if->info;
811 if (!zif)
812 return -1;
813 vxl = &zif->l2info.vxl;
13d60d35 814
2232a77c 815 vlan_if = zvni_map_to_svi (zvrf, vxl->access_vlan,
816 zif->brslave_info.br_if);
817 if (!vlan_if)
818 return -1;
13d60d35 819
2232a77c 820 return kernel_add_neigh (vlan_if, &n->ip, &n->emac);
821}
13d60d35 822
2232a77c 823/*
824 * Uninstall remote neighbor from the kernel.
825 */
826static int
827zvni_neigh_uninstall (zebra_vni_t *zvni, zebra_neigh_t *n)
828{
829 struct zebra_vrf *zvrf;
830 struct zebra_if *zif;
831 struct zebra_l2info_vxlan *vxl;
832 struct interface *vlan_if;
13d60d35 833
2232a77c 834 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
835 return 0;
836
837 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
838 assert(zvrf);
839 if (!zvni->vxlan_if)
840 {
841 zlog_err ("VNI %u hash %p couldn't be uninstalled - no intf",
842 zvni->vni, zvni);
843 return -1;
844 }
845
846 zif = zvni->vxlan_if->info;
847 if (!zif)
848 return -1;
849 vxl = &zif->l2info.vxl;
850 vlan_if = zvni_map_to_svi (zvrf, vxl->access_vlan,
851 zif->brslave_info.br_if);
852 if (!vlan_if)
853 return -1;
854
855 return kernel_del_neigh (vlan_if, &n->ip);
13d60d35 856}
857
858/*
2232a77c 859 * Install neighbor hash entry - called upon access VLAN change.
13d60d35 860 */
861static void
2232a77c 862zvni_install_neigh_hash (struct hash_backet *backet, void *ctxt)
13d60d35 863{
2232a77c 864 zebra_neigh_t *n;
865 struct neigh_walk_ctx *wctx = ctxt;
13d60d35 866
2232a77c 867 n = (zebra_neigh_t *) backet->data;
868 if (!n)
869 return;
13d60d35 870
2232a77c 871 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
872 zvni_neigh_install (wctx->zvni, n);
873}
13d60d35 874
2232a77c 875/*
876 * Make hash key for MAC.
877 */
878static unsigned int
879mac_hash_keymake (void *p)
880{
881 zebra_mac_t *pmac = p;
882 char *pnt = (char *) pmac->macaddr.octet;
883 unsigned int key = 0;
884 int c = 0;
885
886 key += pnt[c];
887 key += pnt[c + 1];
888 key += pnt[c + 2];
889 key += pnt[c + 3];
890 key += pnt[c + 4];
891 key += pnt[c + 5];
892
893 return (key);
894}
13d60d35 895
2232a77c 896/*
897 * Compare two MAC addresses.
898 */
899static int
900mac_cmp (const void *p1, const void *p2)
901{
902 const zebra_mac_t *pmac1 = p1;
903 const zebra_mac_t *pmac2 = p2;
904
905 if (pmac1 == NULL && pmac2 == NULL)
906 return 1;
907
908 if (pmac1 == NULL || pmac2 == NULL)
909 return 0;
910
911 return(memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETHER_ADDR_LEN) == 0);
912}
913
914/*
915 * Callback to allocate MAC hash entry.
916 */
917static void *
918zvni_mac_alloc (void *p)
919{
920 const zebra_mac_t *tmp_mac = p;
921 zebra_mac_t *mac;
922
923 mac = XCALLOC (MTYPE_MAC, sizeof(zebra_mac_t));
924 *mac = *tmp_mac;
925
926 return ((void *)mac);
927}
928
929/*
930 * Add MAC entry.
931 */
932static zebra_mac_t *
933zvni_mac_add (zebra_vni_t *zvni, struct ethaddr *macaddr)
934{
935 zebra_mac_t tmp_mac;
936 zebra_mac_t *mac = NULL;
937
938 memset (&tmp_mac, 0, sizeof (zebra_mac_t));
939 memcpy(&tmp_mac.macaddr, macaddr, ETHER_ADDR_LEN);
940 mac = hash_get (zvni->mac_table, &tmp_mac, zvni_mac_alloc);
941 assert (mac);
942
943 return mac;
944}
945
946/*
947 * Delete MAC entry.
948 */
949static int
950zvni_mac_del (zebra_vni_t *zvni, zebra_mac_t *mac)
951{
952 zebra_mac_t *tmp_mac;
953
954 /* Free the VNI hash entry and allocated memory. */
955 tmp_mac = hash_release (zvni->mac_table, mac);
956 if (tmp_mac)
957 XFREE(MTYPE_MAC, tmp_mac);
958
959 return 0;
960}
961
962/*
963 * Free MAC hash entry (callback)
964 */
965static int
966zvni_mac_del_hash_entry (struct hash_backet *backet, void *arg)
967{
968 struct mac_walk_ctx *wctx = arg;
969 zebra_mac_t *mac = backet->data;
970
971 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL)) ||
972 ((wctx->flags & DEL_REMOTE_MAC) && (mac->flags & ZEBRA_MAC_REMOTE)) ||
973 ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP) &&
974 (mac->flags & ZEBRA_MAC_REMOTE) &&
975 IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip)
976 ))
977 {
978 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL))
979 {
980 zvni_mac_send_del_to_client (wctx->zvrf, wctx->zvni->vni,
981 &mac->macaddr);
982 }
983
984 if (wctx->uninstall)
985 zvni_mac_uninstall (wctx->zvni, mac, 0);
986
987 return zvni_mac_del (wctx->zvni, mac);
988 }
989
990 return 0;
991}
992
993/*
994 * Delete all MAC entries from specific VTEP for a particular VNI.
995 */
996static void
997zvni_mac_del_from_vtep (zebra_vni_t *zvni, int uninstall,
998 struct in_addr *r_vtep_ip)
999{
1000 struct mac_walk_ctx wctx;
1001
1002 if (!zvni->mac_table)
1003 return;
1004
1005 memset (&wctx, 0, sizeof (struct mac_walk_ctx));
1006 wctx.zvni = zvni;
1007 wctx.uninstall = uninstall;
1008 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
1009 wctx.r_vtep_ip = *r_vtep_ip;
1010
1011 hash_iterate (zvni->mac_table,
1012 (void (*) (struct hash_backet *, void *))
1013 zvni_mac_del_hash_entry, &wctx);
1014}
1015
1016/*
1017 * Delete all MAC entries for this VNI.
1018 */
1019static void
1020zvni_mac_del_all (struct zebra_vrf *zvrf, zebra_vni_t *zvni,
1021 int uninstall, int upd_client, u_int32_t flags)
1022{
1023 struct mac_walk_ctx wctx;
1024
1025 if (!zvni->mac_table)
1026 return;
1027
1028 memset (&wctx, 0, sizeof (struct mac_walk_ctx));
1029 wctx.zvni = zvni;
1030 wctx.zvrf = zvrf;
1031 wctx.uninstall = uninstall;
1032 wctx.upd_client = upd_client;
1033 wctx.flags = flags;
1034
1035 hash_iterate (zvni->mac_table,
1036 (void (*) (struct hash_backet *, void *))
1037 zvni_mac_del_hash_entry, &wctx);
1038}
1039
1040/*
1041 * Look up MAC hash entry.
1042 */
1043static zebra_mac_t *
1044zvni_mac_lookup (zebra_vni_t *zvni, struct ethaddr *mac)
1045{
1046 zebra_mac_t tmp;
1047 zebra_mac_t *pmac;
1048
1049 memset(&tmp, 0, sizeof(tmp));
1050 memcpy(&tmp.macaddr, mac, ETHER_ADDR_LEN);
1051 pmac = hash_lookup (zvni->mac_table, &tmp);
1052
1053 return pmac;
1054}
1055
1056/*
1057 * Inform BGP about local MAC addition.
1058 */
1059static int
1060zvni_mac_send_add_to_client (struct zebra_vrf *zvrf, vni_t vni,
1061 struct ethaddr *macaddr)
1062{
1063 return zvni_macip_send_msg_to_client (zvrf, vni, macaddr, NULL,
1064 ZEBRA_MACIP_ADD);
1065}
1066
1067/*
1068 * Inform BGP about local MAC deletion.
1069 */
1070static int
1071zvni_mac_send_del_to_client (struct zebra_vrf *zvrf, vni_t vni,
1072 struct ethaddr *macaddr)
1073{
1074 return zvni_macip_send_msg_to_client (zvrf, vni, macaddr, NULL,
1075 ZEBRA_MACIP_DEL);
1076}
1077
1078/*
1079 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
1080 * notifications, to see if there are of interest.
1081 * TODO: Need to make this as a hash table.
1082 */
1083static zebra_vni_t *
1084zvni_map_vlan (struct interface *ifp, struct interface *br_if, vlanid_t vid)
1085{
1086 struct zebra_vrf *zvrf;
1087 struct listnode *node;
1088 struct interface *tmp_if;
1089 struct zebra_if *zif;
1090 struct zebra_l2info_bridge *br;
1091 struct zebra_l2info_vxlan *vxl;
1092 u_char bridge_vlan_aware;
1093 zebra_vni_t *zvni;
1094
1095 /* Locate VRF corresponding to interface. */
1096 zvrf = vrf_info_lookup(ifp->vrf_id);
1097 assert(zvrf);
1098
1099 /* Determine if bridge is VLAN-aware or not */
1100 zif = br_if->info;
1101 assert (zif);
1102 br = &zif->l2info.br;
1103 bridge_vlan_aware = br->vlan_aware;
1104
1105 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1106 /* TODO: Optimize with a hash. */
1107 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (zvrf_id (zvrf)), node, tmp_if))
1108 {
1109 zif = tmp_if->info;
1110 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1111 continue;
1112 if (!if_is_operative (tmp_if))
1113 continue;
1114 vxl = &zif->l2info.vxl;
1115
1116 if (zif->brslave_info.br_if != br_if)
1117 continue;
1118
1119 if (!bridge_vlan_aware)
1120 break;
1121
1122 if (vxl->access_vlan == vid)
1123 break;
1124 }
1125
1126 if (!tmp_if)
1127 return NULL;
1128
1129 zvni = zvni_lookup (zvrf, vxl->vni);
1130 return zvni;
1131}
1132
1133/*
1134 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1135 * neighbor notifications, to see if they are of interest.
1136 * TODO: Need to make this as a hash table.
1137 */
1138static zebra_vni_t *
1139zvni_map_svi (struct interface *ifp, struct interface *br_if)
1140{
1141 struct zebra_vrf *zvrf;
1142 struct listnode *node;
1143 struct interface *tmp_if;
1144 struct zebra_if *zif;
1145 struct zebra_l2info_bridge *br;
1146 struct zebra_l2info_vxlan *vxl;
1147 u_char bridge_vlan_aware;
1148 vlanid_t vid = 0;
1149 zebra_vni_t *zvni;
1150
1151 /* Make sure the linked interface is a bridge. */
1152 if (!IS_ZEBRA_IF_BRIDGE (br_if))
1153 return NULL;
1154
1155 /* Locate VRF corresponding to interface. */
1156 zvrf = vrf_info_lookup(ifp->vrf_id);
1157 assert(zvrf);
1158
1159 /* Determine if bridge is VLAN-aware or not */
1160 zif = br_if->info;
1161 assert (zif);
1162 br = &zif->l2info.br;
1163 bridge_vlan_aware = br->vlan_aware;
1164 if (bridge_vlan_aware)
1165 {
1166 struct zebra_l2info_vlan *vl;
1167
1168 if (!IS_ZEBRA_IF_VLAN(ifp))
1169 return NULL;
1170
1171 zif = ifp->info;
1172 assert (zif);
1173 vl = &zif->l2info.vl;
1174 vid = vl->vid;
1175 }
1176
1177 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1178 /* TODO: Optimize with a hash. */
1179 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (zvrf_id (zvrf)), node, tmp_if))
1180 {
1181 zif = tmp_if->info;
1182 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1183 continue;
1184 if (!if_is_operative (tmp_if))
1185 continue;
1186 vxl = &zif->l2info.vxl;
1187
1188 if (zif->brslave_info.br_if != br_if)
1189 continue;
1190
1191 if (!bridge_vlan_aware)
1192 break;
1193
1194 if (vxl->access_vlan == vid)
1195 break;
1196 }
1197
1198 if (!tmp_if)
1199 return NULL;
1200
1201 zvni = zvni_lookup (zvrf, vxl->vni);
1202 return zvni;
1203}
1204
1205/* Map to SVI on bridge corresponding to specified VLAN. This can be one
1206 * of two cases:
1207 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1208 * linked to the bridge
1209 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1210 * itself
1211 */
1212static struct interface *
1213zvni_map_to_svi (struct zebra_vrf *zvrf, vlanid_t vid,
1214 struct interface *br_if)
1215{
1216 struct listnode *node;
1217 struct interface *tmp_if;
1218 struct zebra_if *zif;
1219 struct zebra_l2info_bridge *br;
1220 struct zebra_l2info_vlan *vl;
1221 u_char bridge_vlan_aware;
1222
1223 /* Determine if bridge is VLAN-aware or not */
1224 zif = br_if->info;
1225 assert (zif);
1226 br = &zif->l2info.br;
1227 bridge_vlan_aware = br->vlan_aware;
1228
1229 /* Check oper status of the SVI. */
1230 if (!bridge_vlan_aware)
1231 return if_is_operative (br_if) ? br_if : NULL;
1232
1233 /* Identify corresponding VLAN interface. */
1234 /* TODO: Optimize with a hash. */
1235 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (zvrf_id (zvrf)), node, tmp_if))
1236 {
1237 /* Check oper status of the SVI. */
1238 if (!if_is_operative (tmp_if))
1239 continue;
1240 zif = tmp_if->info;
1241 if (!zif ||
1242 zif->zif_type != ZEBRA_IF_VLAN ||
1243 zif->link != br_if)
1244 continue;
1245 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
1246
1247 if (vl->vid == vid)
1248 break;
1249 }
1250
1251 return tmp_if;
1252}
1253
1254/*
1255 * Install remote MAC into the kernel.
1256 */
1257static int
1258zvni_mac_install (zebra_vni_t *zvni, zebra_mac_t *mac)
1259{
1260 struct zebra_if *zif;
1261 struct zebra_l2info_vxlan *vxl;
1262
1263 if (!(mac->flags & ZEBRA_MAC_REMOTE))
1264 return 0;
1265
1266 zif = zvni->vxlan_if->info;
1267 if (!zif)
1268 return -1;
1269 vxl = &zif->l2info.vxl;
1270
1271 return kernel_add_mac (zvni->vxlan_if, vxl->access_vlan,
1272 &mac->macaddr, mac->fwd_info.r_vtep_ip);
1273}
1274
1275/*
1276 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1277 * moves to remote, we have to uninstall any existing local entry first.
1278 */
1279static int
1280zvni_mac_uninstall (zebra_vni_t *zvni, zebra_mac_t *mac, int local)
1281{
1282 struct zebra_if *zif;
1283 struct zebra_l2info_vxlan *vxl;
1284 struct in_addr vtep_ip = { .s_addr = 0 };
1285 struct zebra_ns *zns;
1286 struct interface *ifp;
1287
1288 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
1289 return 0;
1290
1291 if (!zvni->vxlan_if)
1292 {
1293 zlog_err ("VNI %u hash %p couldn't be uninstalled - no intf",
1294 zvni->vni, zvni);
1295 return -1;
1296 }
1297
1298 zif = zvni->vxlan_if->info;
1299 if (!zif)
1300 return -1;
1301 vxl = &zif->l2info.vxl;
1302
1303 if (local)
1304 {
1305 zns = zebra_ns_lookup (NS_DEFAULT);
1306 ifp = if_lookup_by_index_per_ns (zns, mac->fwd_info.local.ifindex);
1307 if (!ifp) // unexpected
1308 return -1;
1309 }
1310 else
1311 {
1312 ifp = zvni->vxlan_if;
1313 vtep_ip = mac->fwd_info.r_vtep_ip;
1314 }
1315
1316 return kernel_del_mac (ifp, vxl->access_vlan,
1317 &mac->macaddr, vtep_ip, local);
1318}
1319
1320/*
1321 * Install MAC hash entry - called upon access VLAN change.
1322 */
1323static void
1324zvni_install_mac_hash (struct hash_backet *backet, void *ctxt)
1325{
1326 zebra_mac_t *mac;
1327 struct mac_walk_ctx *wctx = ctxt;
1328
1329 mac = (zebra_mac_t *) backet->data;
1330 if (!mac)
1331 return;
1332
1333 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
1334 zvni_mac_install (wctx->zvni, mac);
1335}
1336
1337/*
1338 * Decrement neighbor refcount of MAC; uninstall and free it if
1339 * appropriate.
1340 */
1341static void
1342zvni_deref_ip2mac (zebra_vni_t *zvni, zebra_mac_t *mac, int uninstall)
1343{
1344 if (mac->neigh_refcnt)
1345 mac->neigh_refcnt--;
1346
1347 if (!CHECK_FLAG (mac->flags, ZEBRA_MAC_AUTO) ||
1348 mac->neigh_refcnt > 0)
1349 return;
1350
1351 if (uninstall)
1352 zvni_mac_uninstall (zvni, mac, 0);
1353
1354 zvni_mac_del (zvni, mac);
1355}
1356
1357/*
1358 * Read and populate local MACs and neighbors corresponding to this VNI.
1359 */
1360static void
1361zvni_read_mac_neigh (struct zebra_vrf *zvrf, zebra_vni_t *zvni,
1362 struct interface *ifp)
1363{
1364 struct zebra_if *zif;
1365 struct interface *vlan_if;
1366 struct zebra_l2info_vxlan *vxl;
1367
1368 zif = ifp->info;
1369 vxl = &zif->l2info.vxl;
1370
1371 if (IS_ZEBRA_DEBUG_VXLAN)
1372 zlog_debug ("%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1373 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
1374 zif->brslave_info.bridge_ifindex);
1375
1376 macfdb_read_for_bridge (zvrf->zns, ifp, zif->brslave_info.br_if);
1377 vlan_if = zvni_map_to_svi (zvrf, vxl->access_vlan,
1378 zif->brslave_info.br_if);
1379 if (vlan_if)
1380 neigh_read_for_vlan (zvrf->zns, vlan_if);
1381}
1382
1383/*
1384 * Hash function for VNI.
1385 */
1386static unsigned int
1387vni_hash_keymake (void *p)
1388{
1389 const zebra_vni_t *zvni = p;
1390
1391 return (jhash_1word(zvni->vni, 0));
1392}
1393
1394/*
1395 * Compare 2 VNI hash entries.
1396 */
1397static int
1398vni_hash_cmp (const void *p1, const void *p2)
1399{
1400 const zebra_vni_t *zvni1 = p1;
1401 const zebra_vni_t *zvni2 = p2;
1402
1403 return (zvni1->vni == zvni2->vni);
1404}
1405
1406/*
1407 * Callback to allocate VNI hash entry.
1408 */
1409static void *
1410zvni_alloc (void *p)
1411{
1412 const zebra_vni_t *tmp_vni = p;
1413 zebra_vni_t *zvni;
1414
1415 zvni = XCALLOC (MTYPE_ZVNI, sizeof(zebra_vni_t));
1416 zvni->vni = tmp_vni->vni;
1417 return ((void *)zvni);
1418}
1419
1420/*
1421 * Look up VNI hash entry.
1422 */
1423static zebra_vni_t *
1424zvni_lookup (struct zebra_vrf *zvrf, vni_t vni)
1425{
1426 zebra_vni_t tmp_vni;
1427 zebra_vni_t *zvni = NULL;
1428
1429 memset (&tmp_vni, 0, sizeof (zebra_vni_t));
1430 tmp_vni.vni = vni;
1431 zvni = hash_lookup (zvrf->vni_table, &tmp_vni);
1432
1433 return zvni;
1434}
1435
1436/*
1437 * Add VNI hash entry.
1438 */
1439static zebra_vni_t *
1440zvni_add (struct zebra_vrf *zvrf, vni_t vni)
1441{
1442 zebra_vni_t tmp_zvni;
1443 zebra_vni_t *zvni = NULL;
1444
1445 memset (&tmp_zvni, 0, sizeof (zebra_vni_t));
1446 tmp_zvni.vni = vni;
1447 zvni = hash_get (zvrf->vni_table, &tmp_zvni, zvni_alloc);
1448 assert (zvni);
1449
1450 /* Create hash table for MAC */
1451 zvni->mac_table = hash_create(mac_hash_keymake,
1452 mac_cmp,
1453 "Zebra VNI MAC Table");
1454
1455 /* Create hash table for neighbors */
1456 zvni->neigh_table = hash_create(neigh_hash_keymake,
1457 neigh_cmp,
1458 "Zebra VNI Neighbor Table");
1459
1460 return zvni;
1461}
1462
1463/*
1464 * Delete VNI hash entry.
1465 */
1466static int
1467zvni_del (struct zebra_vrf *zvrf, zebra_vni_t *zvni)
1468{
1469 zebra_vni_t *tmp_zvni;
1470
1471 zvni->vxlan_if = NULL;
1472
1473 /* Free the neighbor hash table. */
1474 hash_free(zvni->neigh_table);
1475 zvni->neigh_table = NULL;
1476
1477 /* Free the MAC hash table. */
1478 hash_free(zvni->mac_table);
1479 zvni->mac_table = NULL;
1480
1481 /* Free the VNI hash entry and allocated memory. */
1482 tmp_zvni = hash_release (zvrf->vni_table, zvni);
1483 if (tmp_zvni)
1484 XFREE(MTYPE_ZVNI, tmp_zvni);
1485
1486 return 0;
1487}
1488
1489/*
1490 * Inform BGP about local VNI addition.
1491 */
1492static int
1493zvni_send_add_to_client (struct zebra_vrf *zvrf,
1494 zebra_vni_t *zvni)
1495{
1496 struct zserv *client;
1497 struct stream *s;
1498
1499 client = zebra_find_client (ZEBRA_ROUTE_BGP);
1500 /* BGP may not be running. */
1501 if (!client)
1502 return 0;
1503
1504 s = client->obuf;
1505 stream_reset (s);
1506
1507 zserv_create_header (s, ZEBRA_VNI_ADD, zvrf_id (zvrf));
1508 stream_putl (s, zvni->vni);
1509 stream_put_in_addr (s, &zvni->local_vtep_ip);
1510
1511 /* Write packet size. */
1512 stream_putw_at (s, 0, stream_get_endp (s));
1513
1514 if (IS_ZEBRA_DEBUG_VXLAN)
1515 zlog_debug ("%u:Send VNI_ADD %u %s to %s",
1516 zvrf_id (zvrf), zvni->vni,
1517 inet_ntoa(zvni->local_vtep_ip),
1518 zebra_route_string (client->proto));
1519
1520 client->vniadd_cnt++;
1521 return zebra_server_send_message(client);
1522}
1523
1524/*
1525 * Inform BGP about local VNI deletion.
1526 */
1527static int
1528zvni_send_del_to_client (struct zebra_vrf *zvrf, vni_t vni)
1529{
1530 struct zserv *client;
1531 struct stream *s;
1532
1533 client = zebra_find_client (ZEBRA_ROUTE_BGP);
1534 /* BGP may not be running. */
1535 if (!client)
1536 return 0;
1537
1538 s = client->obuf;
1539 stream_reset (s);
1540
1541 zserv_create_header (s, ZEBRA_VNI_DEL, zvrf_id (zvrf));
1542 stream_putl (s, vni);
1543
1544 /* Write packet size. */
1545 stream_putw_at (s, 0, stream_get_endp (s));
1546
1547 if (IS_ZEBRA_DEBUG_VXLAN)
1548 zlog_debug ("%u:Send VNI_DEL %u to %s", zvrf_id (zvrf), vni,
1549 zebra_route_string (client->proto));
1550
1551 client->vnidel_cnt++;
1552 return zebra_server_send_message(client);
1553}
1554
1555/*
1556 * Build the VNI hash table by going over the VxLAN interfaces. This
1557 * is called when EVPN (advertise-all-vni) is enabled.
1558 */
1559static void
1560zvni_build_hash_table (struct zebra_vrf *zvrf)
1561{
1562 struct listnode *node;
1563 struct interface *ifp;
1564
1565 /* Walk VxLAN interfaces and create VNI hash. */
1566 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (zvrf_id (zvrf)), node, ifp))
1567 {
1568 struct zebra_if *zif;
1569 struct zebra_l2info_vxlan *vxl;
1570 zebra_vni_t *zvni;
1571 vni_t vni;
1572
1573 zif = ifp->info;
1574 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1575 continue;
1576 vxl = &zif->l2info.vxl;
1577
1578 vni = vxl->vni;
1579
1580 if (IS_ZEBRA_DEBUG_VXLAN)
1581 zlog_debug ("%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
1582 zvrf_id (zvrf), ifp->name, ifp->ifindex, vni,
1583 inet_ntoa (vxl->vtep_ip));
1584
1585 /* VNI hash entry is not expected to exist. */
1586 zvni = zvni_lookup (zvrf, vni);
1587 if (zvni)
1588 {
1589 zlog_err ("VNI hash already present for VRF %d IF %s(%u) VNI %u",
1590 zvrf_id (zvrf), ifp->name, ifp->ifindex, vni);
1591 continue;
1592 }
1593
1594 zvni = zvni_add (zvrf, vni);
1595 if (!zvni)
1596 {
1597 zlog_err ("Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
1598 zvrf_id (zvrf), ifp->name, ifp->ifindex, vni);
1599 return;
1600 }
1601
1602 zvni->local_vtep_ip = vxl->vtep_ip;
1603 zvni->vxlan_if = ifp;
1604
1605 /* Inform BGP if interface is up and mapped to bridge. */
1606 if (if_is_operative (ifp) &&
1607 zif->brslave_info.br_if)
1608 zvni_send_add_to_client (zvrf, zvni);
1609 }
1610}
1611
1612/*
1613 * See if remote VTEP matches with prefix.
1614 */
1615static int
1616zvni_vtep_match (struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
1617{
1618 return (IPV4_ADDR_SAME (vtep_ip, &zvtep->vtep_ip));
1619}
1620
1621/*
1622 * Locate remote VTEP in VNI hash table.
1623 */
1624static zebra_vtep_t *
1625zvni_vtep_find (zebra_vni_t *zvni, struct in_addr *vtep_ip)
1626{
1627 zebra_vtep_t *zvtep;
1628
1629 if (!zvni)
1630 return NULL;
1631
1632 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next)
1633 {
1634 if (zvni_vtep_match (vtep_ip, zvtep))
1635 break;
1636 }
1637
1638 return zvtep;
1639}
1640
1641/*
1642 * Add remote VTEP to VNI hash table.
1643 */
1644static zebra_vtep_t *
1645zvni_vtep_add (zebra_vni_t *zvni, struct in_addr *vtep_ip)
1646{
1647 zebra_vtep_t *zvtep;
1648
1649 zvtep = XCALLOC (MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
1650 if (!zvtep)
1651 {
1652 zlog_err ("Failed to alloc VTEP entry, VNI %u", zvni->vni);
1653 return NULL;
1654 }
1655
1656 zvtep->vtep_ip = *vtep_ip;
1657
1658 if (zvni->vteps)
1659 zvni->vteps->prev = zvtep;
1660 zvtep->next = zvni->vteps;
1661 zvni->vteps = zvtep;
1662
1663 return zvtep;
1664}
1665
1666/*
1667 * Remove remote VTEP from VNI hash table.
1668 */
1669static int
1670zvni_vtep_del (zebra_vni_t *zvni, zebra_vtep_t *zvtep)
1671{
1672 if (zvtep->next)
1673 zvtep->next->prev = zvtep->prev;
1674 if (zvtep->prev)
1675 zvtep->prev->next = zvtep->next;
1676 else
1677 zvni->vteps = zvtep->next;
1678
1679 zvtep->prev = zvtep->next = NULL;
1680 XFREE (MTYPE_ZVNI_VTEP, zvtep);
1681
1682 return 0;
1683}
1684
1685/*
1686 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
1687 * uninstall from kernel if asked to.
1688 */
1689static int
1690zvni_vtep_del_all (zebra_vni_t *zvni, int uninstall)
1691{
1692 zebra_vtep_t *zvtep, *zvtep_next;
1693
1694 if (!zvni)
1695 return -1;
1696
1697 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next)
1698 {
1699 zvtep_next = zvtep->next;
1700 if (uninstall)
1701 zvni_vtep_uninstall (zvni, &zvtep->vtep_ip);
1702 zvni_vtep_del (zvni, zvtep);
1703 }
1704
1705 return 0;
1706}
1707
1708/*
1709 * Install remote VTEP into the kernel.
1710 */
1711static int
1712zvni_vtep_install (zebra_vni_t *zvni, struct in_addr *vtep_ip)
1713{
1714 return kernel_add_vtep (zvni->vni, zvni->vxlan_if, vtep_ip);
1715}
1716
1717/*
1718 * Uninstall remote VTEP from the kernel.
1719 */
1720static int
1721zvni_vtep_uninstall (zebra_vni_t *zvni, struct in_addr *vtep_ip)
1722{
1723 if (!zvni->vxlan_if)
1724 {
1725 zlog_err ("VNI %u hash %p couldn't be uninstalled - no intf",
1726 zvni->vni, zvni);
1727 return -1;
1728 }
1729
1730 return kernel_del_vtep (zvni->vni, zvni->vxlan_if, vtep_ip);
1731}
1732
1733/*
1734 * Cleanup VNI/VTEP and update kernel
1735 */
1736static void
1737zvni_cleanup_all (struct hash_backet *backet, void *zvrf)
1738{
1739 zebra_vni_t *zvni;
1740
1741 zvni = (zebra_vni_t *) backet->data;
1742 if (!zvni)
1743 return;
1744
1745 /* Free up all neighbors and MACs, if any. */
1746 zvni_neigh_del_all (zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
1747 zvni_mac_del_all (zvrf, zvni, 1, 0, DEL_ALL_MAC);
1748
1749 /* Free up all remote VTEPs, if any. */
1750 zvni_vtep_del_all (zvni, 1);
1751
1752 /* Delete the hash entry. */
1753 zvni_del (zvrf, zvni);
1754}
1755
1756
1757/* Public functions */
1758
cec2e17d 1759/*
1760 * Display Neighbors for a VNI (VTY command handler).
1761 */
1762void
1763zebra_vxlan_print_neigh_vni (struct vty *vty, struct zebra_vrf *zvrf, vni_t vni)
1764{
1765 zebra_vni_t *zvni;
1766 u_int32_t num_neigh;
1767 struct neigh_walk_ctx wctx;
1768
1769 if (!EVPN_ENABLED(zvrf))
1770 return;
1771 zvni = zvni_lookup (zvrf, vni);
1772 if (!zvni)
1773 {
1774 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
1775 return;
1776 }
1777 num_neigh = hashcount(zvni->neigh_table);
1778 if (!num_neigh)
1779 return;
1780
1781 /* Since we have IPv6 addresses to deal with which can vary widely in
1782 * size, we try to be a bit more elegant in display by first computing
1783 * the maximum width.
1784 */
1785 memset (&wctx, 0, sizeof (struct neigh_walk_ctx));
1786 wctx.zvni = zvni;
1787 wctx.vty = vty;
1788 wctx.addr_width = 15;
1789 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
1790
1791 vty_out(vty, "Number of ARPs (local and remote) known for this VNI: %u%s",
1792 num_neigh, VTY_NEWLINE);
1793 vty_out(vty, "%*s %-6s %-17s %-21s%s",
1794 -wctx.addr_width, "IP", "Type", "MAC",
1795 "Remote VTEP", VTY_NEWLINE);
1796
1797 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
1798}
1799
1800/*
1801 * Display neighbors across all VNIs (VTY command handler).
1802 */
1803void
1804zebra_vxlan_print_neigh_all_vni (struct vty *vty, struct zebra_vrf *zvrf)
1805{
1806 if (!EVPN_ENABLED(zvrf))
1807 return;
1808 hash_iterate(zvrf->vni_table, zvni_print_neigh_hash_all_vni, vty);
1809}
1810
1811/*
1812 * Display specific neighbor for a VNI, if present (VTY command handler).
1813 */
1814void
1815zebra_vxlan_print_specific_neigh_vni (struct vty *vty, struct zebra_vrf *zvrf,
1816 vni_t vni, struct ipaddr *ip)
1817{
1818 zebra_vni_t *zvni;
1819 zebra_neigh_t *n;
1820
1821 if (!EVPN_ENABLED(zvrf))
1822 return;
1823 zvni = zvni_lookup (zvrf, vni);
1824 if (!zvni)
1825 {
1826 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
1827 return;
1828 }
1829 n = zvni_neigh_lookup (zvni, ip);
1830 if (!n)
1831 {
1832 vty_out (vty, "%% Requested neighbor does not exist in VNI %u%s",
1833 vni, VTY_NEWLINE);
1834 return;
1835 }
1836
1837 zvni_print_neigh (n, vty);
1838}
1839
1840/*
1841 * Display neighbors for a VNI from specific VTEP (VTY command handler).
1842 * By definition, these are remote neighbors.
1843 */
1844void
1845zebra_vxlan_print_neigh_vni_vtep (struct vty *vty, struct zebra_vrf *zvrf,
1846 vni_t vni, struct in_addr vtep_ip)
1847{
1848 zebra_vni_t *zvni;
1849 u_int32_t num_neigh;
1850 struct neigh_walk_ctx wctx;
1851
1852 if (!EVPN_ENABLED(zvrf))
1853 return;
1854 zvni = zvni_lookup (zvrf, vni);
1855 if (!zvni)
1856 {
1857 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
1858 return;
1859 }
1860 num_neigh = hashcount(zvni->neigh_table);
1861 if (!num_neigh)
1862 return;
1863
1864 memset (&wctx, 0, sizeof (struct neigh_walk_ctx));
1865 wctx.zvni = zvni;
1866 wctx.vty = vty;
1867 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
1868 wctx.r_vtep_ip = vtep_ip;
1869
1870 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
1871}
1872
1873/*
1874 * Display MACs for a VNI (VTY command handler).
1875 */
1876void
1877zebra_vxlan_print_macs_vni (struct vty *vty, struct zebra_vrf *zvrf, vni_t vni)
1878{
1879 zebra_vni_t *zvni;
1880 u_int32_t num_macs;
1881 struct mac_walk_ctx wctx;
1882
1883 if (!EVPN_ENABLED(zvrf))
1884 return;
1885 zvni = zvni_lookup (zvrf, vni);
1886 if (!zvni)
1887 {
1888 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
1889 return;
1890 }
1891 num_macs = hashcount(zvni->mac_table);
1892 if (!num_macs)
1893 return;
1894
1895 memset (&wctx, 0, sizeof (struct mac_walk_ctx));
1896 wctx.zvni = zvni;
1897 wctx.vty = vty;
1898
1899 vty_out(vty, "Number of MACs (local and remote) known for this VNI: %u%s",
1900 num_macs, VTY_NEWLINE);
1901 vty_out(vty, "%-17s %-6s %-21s %-5s%s",
1902 "MAC", "Type", "Intf/Remote VTEP", "VLAN", VTY_NEWLINE);
1903
1904 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
1905}
1906
1907/*
1908 * Display MACs for all VNIs (VTY command handler).
1909 */
1910void
1911zebra_vxlan_print_macs_all_vni (struct vty *vty, struct zebra_vrf *zvrf)
1912{
1913 struct mac_walk_ctx wctx;
1914
1915 if (!EVPN_ENABLED(zvrf))
1916 return;
1917 memset (&wctx, 0, sizeof (struct mac_walk_ctx));
1918 wctx.vty = vty;
1919 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
1920}
1921
1922/*
1923 * Display MACs for all VNIs (VTY command handler).
1924 */
1925void
1926zebra_vxlan_print_macs_all_vni_vtep (struct vty *vty, struct zebra_vrf *zvrf,
1927 struct in_addr vtep_ip)
1928{
1929 struct mac_walk_ctx wctx;
1930
1931 if (!EVPN_ENABLED(zvrf))
1932 return;
1933 memset (&wctx, 0, sizeof (struct mac_walk_ctx));
1934 wctx.vty = vty;
1935 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
1936 wctx.r_vtep_ip = vtep_ip;
1937 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
1938}
1939
1940/*
1941 * Display specific MAC for a VNI, if present (VTY command handler).
1942 */
1943void
1944zebra_vxlan_print_specific_mac_vni (struct vty *vty, struct zebra_vrf *zvrf,
1945 vni_t vni, struct ethaddr *macaddr)
1946{
1947 zebra_vni_t *zvni;
1948 zebra_mac_t *mac;
1949
1950 if (!EVPN_ENABLED(zvrf))
1951 return;
1952 zvni = zvni_lookup (zvrf, vni);
1953 if (!zvni)
1954 {
1955 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
1956 return;
1957 }
1958 mac = zvni_mac_lookup (zvni, macaddr);
1959 if (!mac)
1960 {
1961 vty_out (vty, "%% Requested MAC does not exist in VNI %u%s",
1962 vni, VTY_NEWLINE);
1963 return;
1964 }
1965
1966 zvni_print_mac (mac, vty);
1967}
1968
1969/*
1970 * Display MACs for a VNI from specific VTEP (VTY command handler).
1971 */
1972void
1973zebra_vxlan_print_macs_vni_vtep (struct vty *vty, struct zebra_vrf *zvrf,
1974 vni_t vni, struct in_addr vtep_ip)
1975{
1976 zebra_vni_t *zvni;
1977 u_int32_t num_macs;
1978 struct mac_walk_ctx wctx;
1979
1980 if (!EVPN_ENABLED(zvrf))
1981 return;
1982 zvni = zvni_lookup (zvrf, vni);
1983 if (!zvni)
1984 {
1985 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
1986 return;
1987 }
1988 num_macs = hashcount(zvni->mac_table);
1989 if (!num_macs)
1990 return;
1991 memset (&wctx, 0, sizeof (struct mac_walk_ctx));
1992 wctx.zvni = zvni;
1993 wctx.vty = vty;
1994 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
1995 wctx.r_vtep_ip = vtep_ip;
1996 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
1997}
1998
1999
2000/*
2001 * Display VNI information (VTY command handler).
2002 */
2003void
2004zebra_vxlan_print_vni (struct vty *vty, struct zebra_vrf *zvrf, vni_t vni)
2005{
2006 zebra_vni_t *zvni;
2007
2008 if (!EVPN_ENABLED(zvrf))
2009 return;
2010 zvni = zvni_lookup (zvrf, vni);
2011 if (!zvni)
2012 {
2013 vty_out (vty, "%% VNI %u does not exist%s", vni, VTY_NEWLINE);
2014 return;
2015 }
2016 zvni_print (zvni, (void *)vty);
2017}
2018
2019/*
2020 * Display VNI hash table (VTY command handler).
2021 */
2022void
2023zebra_vxlan_print_vnis (struct vty *vty, struct zebra_vrf *zvrf)
2024{
2025 u_int32_t num_vnis;
2026
2027 if (!EVPN_ENABLED(zvrf))
2028 return;
2029 num_vnis = hashcount(zvrf->vni_table);
2030 if (!num_vnis)
2031 return;
2032 vty_out(vty, "Number of VNIs: %u%s", num_vnis, VTY_NEWLINE);
2033 vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s%s",
2034 "VNI", "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
2035 "# Remote VTEPs", VTY_NEWLINE);
2036 hash_iterate(zvrf->vni_table, zvni_print_hash, vty);
2037}
2038
2232a77c 2039/*
2040 * Handle neighbor delete (on a VLAN device / L3 interface) from the
2041 * kernel. This may result in either the neighbor getting deleted from
2042 * our database or being re-added to the kernel (if it is a valid
2043 * remote neighbor).
2044 */
2045int
2046zebra_vxlan_local_neigh_del (struct interface *ifp,
2047 struct interface *link_if,
2048 struct ipaddr *ip)
2049{
2050 zebra_vni_t *zvni;
2051 zebra_neigh_t *n;
2052 struct zebra_vrf *zvrf;
2053 char buf[INET6_ADDRSTRLEN];
2054
2055 /* We are only interested in neighbors on an SVI that resides on top
2056 * of a VxLAN bridge.
2057 */
2058 zvni = zvni_map_svi (ifp, link_if);
2059 if (!zvni)
2060 return 0;
2061 if (!zvni->vxlan_if)
2062 {
2063 zlog_err ("VNI %u hash %p doesn't have intf upon local neighbor DEL",
2064 zvni->vni, zvni);
2065 return -1;
2066 }
2067
2068 if (IS_ZEBRA_DEBUG_VXLAN)
2069 zlog_debug ("%u:Del neighbor %s intf %s(%u) -> VNI %u",
2070 ifp->vrf_id, ipaddr2str (ip, buf, sizeof(buf)),
2071 ifp->name, ifp->ifindex, zvni->vni);
2072
2073 /* If entry doesn't exist, nothing to do. */
2074 n = zvni_neigh_lookup (zvni, ip);
2075 if (!n)
2076 return 0;
2077
2078 /* If it is a remote entry, the kernel has aged this out or someone has
2079 * deleted it, it needs to be re-installed as Quagga is the owner.
2080 */
2081 if (CHECK_FLAG (n->flags, ZEBRA_NEIGH_REMOTE))
2082 {
2083 zvni_neigh_install (zvni, n);
2084 return 0;
2085 }
2086
2087 /* Locate VRF corresponding to interface. */
2088 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2089 assert(zvrf);
2090
2091 /* Remove neighbor from BGP. */
2092 zvni_neigh_send_del_to_client (zvrf, zvni->vni, &n->ip, &n->emac);
2093
2094 /* Delete this neighbor entry. */
2095 zvni_neigh_del (zvni, n);
2096
2097 return 0;
2098}
2099
2100/*
2101 * Handle neighbor add or update (on a VLAN device / L3 interface)
2102 * from the kernel.
2103 */
2104int
2105zebra_vxlan_local_neigh_add_update (struct interface *ifp,
2106 struct interface *link_if,
2107 struct ipaddr *ip,
2108 struct ethaddr *macaddr,
2109 u_int16_t state,
2110 u_char ext_learned)
2111{
2112 zebra_vni_t *zvni;
2113 zebra_neigh_t *n;
2114 struct zebra_vrf *zvrf;
2115 char buf[ETHER_ADDR_STRLEN];
2116 char buf2[INET6_ADDRSTRLEN];
2117 int send_upd = 1, send_del = 0;
2118
2119 /* We are only interested in neighbors on an SVI that resides on top
2120 * of a VxLAN bridge.
2121 */
2122 zvni = zvni_map_svi (ifp, link_if);
2123 if (!zvni)
2124 return 0;
2125
2126 /* Locate VRF corresponding to interface. */
2127 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2128 assert(zvrf);
2129
2130 if (IS_ZEBRA_DEBUG_VXLAN)
2131 zlog_debug ("%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
2132 "%s-> VNI %u",
2133 ifp->vrf_id, ipaddr2str (ip, buf2, sizeof(buf2)),
2134 prefix_mac2str (macaddr, buf, sizeof (buf)),
2135 ifp->name, ifp->ifindex, state,
2136 ext_learned ? "ext-learned " : "", zvni->vni);
2137
2138 /* If same entry already exists, it might be a change or it might be a
2139 * move from remote to local.
2140 */
2141 n = zvni_neigh_lookup (zvni, ip);
2142 if (n)
2143 {
2144 if (CHECK_FLAG (n->flags, ZEBRA_NEIGH_LOCAL))
2145 {
2146 if (memcmp (n->emac.octet, macaddr->octet, ETHER_ADDR_LEN) == 0)
2147 {
2148 if (n->ifindex == ifp->ifindex)
2149 /* we're not interested in whatever has changed. */
2150 return 0;
2151 /* client doesn't care about a purely local change. */
2152 send_upd = 0;
2153 }
2154 else
2155 /* If the MAC has changed, issue a delete first as this means a
2156 * different MACIP route.
2157 */
2158 send_del = 1;
2159 }
2160 else if (ext_learned)
2161 /* The neighbor is remote and that is the notification we got. */
2162 {
2163 /* TODO: Evaluate if we need to do anything here. */
2164 return 0;
2165 }
2166 else
2167 /* Neighbor has moved from remote to local. */
2168 {
2169 UNSET_FLAG (n->flags, ZEBRA_NEIGH_REMOTE);
2170 n->r_vtep_ip.s_addr = 0;
2171 }
2172 }
2173 else
2174 {
2175 n = zvni_neigh_add (zvni, ip);
2176 if (!n)
2177 {
2178 zlog_err ("%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2179 ifp->vrf_id, ipaddr2str (ip, buf2, sizeof(buf2)),
2180 prefix_mac2str (macaddr, buf, sizeof (buf)),
2181 ifp->name, ifp->ifindex, zvni->vni);
2182 return -1;
2183 }
2184 }
2185
2186 /* Issue delete for older info, if needed. */
2187 if (send_del)
2188 zvni_neigh_send_del_to_client (zvrf, zvni->vni, &n->ip, &n->emac);
2189
2190 /* Set "local" forwarding info. */
2191 SET_FLAG (n->flags, ZEBRA_NEIGH_LOCAL);
2192 memcpy (&n->emac, macaddr, ETHER_ADDR_LEN);
2193 n->ifindex = ifp->ifindex;
2194
2195 /* Inform BGP if required. */
2196 if (send_upd)
2197 return zvni_neigh_send_add_to_client (zvrf, zvni->vni, ip, macaddr);
2198
2199 return 0;
2200}
2201
2202/*
2203 * Handle message from client to delete a remote MACIP for a VNI.
2204 */
2205int zebra_vxlan_remote_macip_del (struct zserv *client, int sock,
2206 u_short length, struct zebra_vrf *zvrf)
2207{
2208 struct stream *s;
2209 vni_t vni;
2210 struct ethaddr macaddr;
2211 struct ipaddr ip;
2212 struct in_addr vtep_ip;
2213 zebra_vni_t *zvni;
2214 zebra_mac_t *mac;
2215 zebra_neigh_t *n;
2216 u_short l = 0, ipa_len;
2217 char buf[ETHER_ADDR_STRLEN];
2218 char buf1[INET6_ADDRSTRLEN];
2219
2220 s = client->ibuf;
2221
2222 while (l < length)
2223 {
2224 /* Obtain each remote MACIP and process. */
2225 /* Message contains VNI, followed by MAC followed by IP (if any)
2226 * followed by remote VTEP IP.
2227 */
2228 mac = NULL;
2229 n = NULL;
2230 memset (&ip, 0, sizeof (ip));
2231 vni = (vni_t) stream_getl (s);
2232 stream_get (&macaddr.octet, s, ETHER_ADDR_LEN);
2233 ipa_len = stream_getl (s);
2234 if (ipa_len)
2235 {
2236 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4: IPADDR_V6;
2237 stream_get (&ip.ip.addr, s, ipa_len);
2238 }
2239 l += 4 + ETHER_ADDR_LEN + 4 + ipa_len;
2240 vtep_ip.s_addr = stream_get_ipv4(s);
2241 l += IPV4_MAX_BYTELEN;
2242
2243 if (IS_ZEBRA_DEBUG_VXLAN)
2244 zlog_debug ("%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
2245 zvrf_id (zvrf),
2246 prefix_mac2str (&macaddr, buf, sizeof (buf)),
2247 ipaddr2str (&ip, buf1, sizeof (buf1)),
2248 vni, inet_ntoa (vtep_ip),
2249 zebra_route_string (client->proto));
2250
2251 /* Locate VNI hash entry - expected to exist. */
2252 zvni = zvni_lookup (zvrf, vni);
2253 if (!zvni)
2254 {
2255 if (IS_ZEBRA_DEBUG_VXLAN)
2256 zlog_debug ("Failed to locate VNI hash upon remote MACIP DEL, "
2257 "VRF %d VNI %u", zvrf_id (zvrf), vni);
2258 continue;
2259 }
2260 if (!zvni->vxlan_if)
2261 {
2262 zlog_err ("VNI %u hash %p doesn't have intf upon remote MACIP DEL",
2263 vni, zvni);
2264 continue;
2265 }
2266
2267 /* The remote VTEP specified is normally expected to exist, but it is
2268 * possible that the peer may delete the VTEP before deleting any MACs
2269 * referring to the VTEP, in which case the handler (see remote_vtep_del)
2270 * would have already deleted the MACs.
2271 */
2272 if (!zvni_vtep_find (zvni, &vtep_ip))
2273 continue;
2274
2275 /* If the local VxLAN interface is not up (should be a transient
2276 * event), there's nothing more to do.
2277 */
2278 if (!if_is_operative (zvni->vxlan_if))
2279 continue;
2280
2281 mac = zvni_mac_lookup (zvni, &macaddr);
2282 if (ipa_len)
2283 n = zvni_neigh_lookup (zvni, &ip);
2284
2285 if (n && !mac)
2286 {
2287 zlog_err ("failed to locate MAC %s for neigh %s in VRF %u VNI %u",
2288 prefix_mac2str (&macaddr, buf, sizeof (buf)),
2289 ipaddr2str (&ip, buf1, sizeof (buf1)),
2290 zvrf_id (zvrf), vni);
2291 continue;
2292 }
2293
2294 /* If the remote mac or neighbor doesn't exist there is nothing more
2295 * to do. Otherwise, uninstall the entry and then remove it.
2296 */
2297 if (!mac && !n)
2298 continue;
2299
2300 /* Uninstall remote neighbor or MAC. */
2301 if (n)
2302 {
2303 /* When the MAC changes for an IP, it is possible the client may
2304 * update the new MAC before trying to delete the "old" neighbor
2305 * (as these are two different MACIP routes). Do the delete only
2306 * if the MAC matches.
2307 */
2308 if (CHECK_FLAG (n->flags, ZEBRA_NEIGH_REMOTE) &&
2309 (memcmp (n->emac.octet, macaddr.octet, ETHER_ADDR_LEN) == 0))
2310 {
2311 zvni_neigh_uninstall (zvni, n);
2312 zvni_neigh_del (zvni, n);
2313 zvni_deref_ip2mac (zvni, mac, 1);
2314 }
2315 }
2316 else
2317 {
2318 if (CHECK_FLAG (mac->flags, ZEBRA_MAC_REMOTE))
2319 {
2320 if (!mac->neigh_refcnt)
2321 {
2322 zvni_mac_uninstall (zvni, mac, 0);
2323 zvni_mac_del (zvni, mac);
2324 }
2325 else
2326 SET_FLAG (mac->flags, ZEBRA_MAC_AUTO);
2327 }
2328 }
2329 }
2330
2331 return 0;
2332}
2333
2334/*
2335 * Handle message from client to add a remote MACIP for a VNI. This
2336 * could be just the add of a MAC address or the add of a neighbor
2337 * (IP+MAC).
2338 */
2339int
2340zebra_vxlan_remote_macip_add (struct zserv *client, int sock,
2341 u_short length, struct zebra_vrf *zvrf)
2342{
2343 struct stream *s;
2344 vni_t vni;
2345 struct ethaddr macaddr;
2346 struct ipaddr ip;
2347 struct in_addr vtep_ip;
2348 zebra_vni_t *zvni;
2349 zebra_vtep_t *zvtep;
2350 zebra_mac_t *mac, *old_mac;
2351 zebra_neigh_t *n;
2352 u_short l = 0, ipa_len;
2353 int update_mac = 0, update_neigh = 0;
2354 char buf[ETHER_ADDR_STRLEN];
2355 char buf1[INET6_ADDRSTRLEN];
2356
2357 assert (EVPN_ENABLED (zvrf));
2358
2359 s = client->ibuf;
2360
2361 while (l < length)
2362 {
2363 /* Obtain each remote MACIP and process. */
2364 /* Message contains VNI, followed by MAC followed by IP (if any)
2365 * followed by remote VTEP IP.
2366 */
2367 update_mac = update_neigh = 0;
2368 mac = NULL;
2369 n = NULL;
2370 memset (&ip, 0, sizeof (ip));
2371 vni = (vni_t) stream_getl (s);
2372 stream_get (&macaddr.octet, s, ETHER_ADDR_LEN);
2373 ipa_len = stream_getl (s);
2374 if (ipa_len)
2375 {
2376 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4: IPADDR_V6;
2377 stream_get (&ip.ip.addr, s, ipa_len);
2378 }
2379 l += 4 + ETHER_ADDR_LEN + 4 + ipa_len;
2380 vtep_ip.s_addr = stream_get_ipv4 (s);
2381 l += IPV4_MAX_BYTELEN;
2382
2383 if (IS_ZEBRA_DEBUG_VXLAN)
2384 zlog_debug ("%u:Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s from %s",
2385 zvrf_id (zvrf),
2386 prefix_mac2str (&macaddr, buf, sizeof (buf)),
2387 ipaddr2str (&ip, buf1, sizeof (buf1)),
2388 vni, inet_ntoa (vtep_ip),
2389 zebra_route_string (client->proto));
2390
2391 /* Locate VNI hash entry - expected to exist. */
2392 zvni = zvni_lookup (zvrf, vni);
2393 if (!zvni)
2394 {
2395 zlog_err ("Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
2396 zvrf_id (zvrf), vni);
2397 continue;
2398 }
2399 if (!zvni->vxlan_if)
2400 {
2401 zlog_err ("VNI %u hash %p doesn't have intf upon remote MACIP add",
2402 vni, zvni);
2403 continue;
2404 }
2405 /* If the local VxLAN interface is not up (should be a transient
2406 * event), there's nothing more to do.
2407 */
2408 if (!if_is_operative (zvni->vxlan_if))
2409 continue;
2410
2411 /* The remote VTEP specified should normally exist, but it is possible
2412 * that when peering comes up, peer may advertise MACIP routes before
2413 * advertising type-3 routes.
2414 */
2415 zvtep = zvni_vtep_find (zvni, &vtep_ip);
2416 if (!zvtep)
2417 {
2418 if (zvni_vtep_add (zvni, &vtep_ip) == NULL)
2419 {
2420 zlog_err ("Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2421 zvrf_id (zvrf), vni, zvni);
2422 continue;
2423 }
2424
2425 zvni_vtep_install (zvni, &vtep_ip);
2426 }
2427
2428 /* First, check if the remote MAC is unknown or has a change. If so,
2429 * that needs to be updated first. Note that client could install
2430 * MAC and MACIP separately or just install the latter.
2431 */
2432 mac = zvni_mac_lookup (zvni, &macaddr);
2433 if (!mac || !CHECK_FLAG (mac->flags, ZEBRA_MAC_REMOTE) ||
2434 !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
2435 update_mac = 1;
13d60d35 2436
2232a77c 2437 if (update_mac)
13d60d35 2438 {
2232a77c 2439 if (!mac)
2440 {
2441 mac = zvni_mac_add (zvni, &macaddr);
2442 if (!mac)
2443 {
2444 zlog_warn ("%u:Failed to add MAC %s VNI %u Remote VTEP %s",
2445 zvrf_id (zvrf),
2446 prefix_mac2str (&macaddr, buf, sizeof (buf)),
2447 vni, inet_ntoa (vtep_ip));
2448 return -1;
2449 }
2450
2451 /* Is this MAC created for a MACIP? */
2452 if (ipa_len)
2453 SET_FLAG (mac->flags, ZEBRA_MAC_AUTO);
2454 }
2455 else if (CHECK_FLAG (mac->flags, ZEBRA_MAC_LOCAL))
2456 {
2457 /* Moving from local to remote, issue delete. */
2458 zvni_mac_uninstall (zvni, mac, 1);
2459 }
2460
2461 /* Set "auto" and "remote" forwarding info. */
2462 UNSET_FLAG (mac->flags, ZEBRA_MAC_LOCAL);
2463 memset (&mac->fwd_info, 0, sizeof (mac->fwd_info));
2464 SET_FLAG (mac->flags, ZEBRA_MAC_REMOTE);
2465 mac->fwd_info.r_vtep_ip = vtep_ip;
2466
2467 /* Install the entry. */
2468 zvni_mac_install (zvni, mac);
13d60d35 2469 }
2470
2232a77c 2471 /* If there is no IP, continue - after clearing AUTO flag of MAC. */
2472 if (!ipa_len)
13d60d35 2473 {
2232a77c 2474 UNSET_FLAG (mac->flags, ZEBRA_MAC_AUTO);
2475 continue;
13d60d35 2476 }
2477
2232a77c 2478 /* Check if the remote neighbor itself is unknown or has a change.
2479 * If so, create or update and then install the entry.
2480 */
2481 n = zvni_neigh_lookup (zvni, &ip);
2482 if (!n || !CHECK_FLAG (n->flags, ZEBRA_NEIGH_REMOTE) ||
2483 (memcmp(&n->emac, &macaddr, sizeof (macaddr)) != 0) ||
2484 !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
2485 update_neigh = 1;
13d60d35 2486
2232a77c 2487 if (update_neigh)
2488 {
2489 if (!n)
2490 {
2491 n = zvni_neigh_add (zvni, &ip);
2492 if (!n)
2493 {
2494 zlog_warn ("%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
2495 zvrf_id (zvrf), ipaddr2str (&ip, buf1, sizeof (buf1)),
2496 prefix_mac2str (&macaddr, buf, sizeof (buf)),
2497 vni, inet_ntoa (vtep_ip));
2498 return -1;
2499 }
2500
2501 /* New neighbor referring to this MAC. */
2502 mac->neigh_refcnt++;
2503 }
2504 else if (memcmp(&n->emac, &macaddr, sizeof (macaddr)) != 0)
2505 {
2506 /* MAC change, update ref counts for old and new MAC. */
2507 old_mac = zvni_mac_lookup (zvni, &n->emac);
2508 if (old_mac)
2509 zvni_deref_ip2mac (zvni, old_mac, 1);
2510 mac->neigh_refcnt++;
2511 }
2512
2513 /* Set "remote" forwarding info. */
2514 UNSET_FLAG (n->flags, ZEBRA_NEIGH_LOCAL);
2515 /* TODO: Handle MAC change. */
2516 memcpy (&n->emac, &macaddr, ETHER_ADDR_LEN);
2517 n->r_vtep_ip = vtep_ip;
2518 SET_FLAG (n->flags, ZEBRA_NEIGH_REMOTE);
2519
2520 /* Install the entry. */
2521 zvni_neigh_install (zvni, n);
2522 }
13d60d35 2523 }
13d60d35 2524
2232a77c 2525 return 0;
13d60d35 2526}
2527
2528/*
2232a77c 2529 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
2530 * us, this must involve a multihoming scenario. Treat this as implicit delete
2531 * of any prior local MAC.
13d60d35 2532 */
2232a77c 2533int
2534zebra_vxlan_check_del_local_mac (struct interface *ifp,
2535 struct interface *br_if,
2536 struct ethaddr *macaddr,
2537 vlanid_t vid)
13d60d35 2538{
2232a77c 2539 struct zebra_if *zif;
2540 struct zebra_vrf *zvrf;
2541 struct zebra_l2info_vxlan *vxl;
2542 vni_t vni;
2543 zebra_vni_t *zvni;
2544 zebra_mac_t *mac;
2545 char buf[ETHER_ADDR_STRLEN];
13d60d35 2546
2232a77c 2547 zif = ifp->info;
2548 assert(zif);
2549 vxl = &zif->l2info.vxl;
2550 vni = vxl->vni;
13d60d35 2551
2232a77c 2552 /* Locate VRF corresponding to interface. */
2553 zvrf = vrf_info_lookup(ifp->vrf_id);
2554 assert(zvrf);
13d60d35 2555
2232a77c 2556 /* If EVPN is not enabled, nothing to do. */
2557 if (!EVPN_ENABLED(zvrf))
2558 return 0;
13d60d35 2559
2232a77c 2560 /* Locate hash entry; it is expected to exist. */
2561 zvni = zvni_lookup (zvrf, vni);
2562 if (!zvni)
2563 return 0;
13d60d35 2564
2232a77c 2565 /* If entry doesn't exist, nothing to do. */
2566 mac = zvni_mac_lookup (zvni, macaddr);
2567 if (!mac)
2568 return 0;
13d60d35 2569
2232a77c 2570 /* Is it a local entry? */
2571 if (!CHECK_FLAG (mac->flags, ZEBRA_MAC_LOCAL))
2572 return 0;
13d60d35 2573
2232a77c 2574 if (IS_ZEBRA_DEBUG_VXLAN)
2575 zlog_debug ("%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
2576 ifp->vrf_id, prefix_mac2str (macaddr, buf, sizeof (buf)),
2577 ifp->name, ifp->ifindex, vni);
13d60d35 2578
2232a77c 2579 /* Remove MAC from BGP. */
2580 zvni_mac_send_del_to_client (zvrf, zvni->vni, macaddr);
13d60d35 2581
2232a77c 2582 /* Delete this MAC entry. */
2583 zvni_mac_del (zvni, mac);
13d60d35 2584
2585 return 0;
2586}
2587
2588/*
2232a77c 2589 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
2590 * This can happen because the remote MAC entries are also added as "dynamic",
2591 * so the kernel can ageout the entry.
13d60d35 2592 */
2232a77c 2593int
2594zebra_vxlan_check_readd_remote_mac (struct interface *ifp,
2595 struct interface *br_if,
2596 struct ethaddr *macaddr,
2597 vlanid_t vid)
13d60d35 2598{
2232a77c 2599 struct zebra_if *zif;
2600 struct zebra_vrf *zvrf;
2601 struct zebra_l2info_vxlan *vxl;
2602 vni_t vni;
2603 zebra_vni_t *zvni;
2604 zebra_mac_t *mac;
2605 char buf[ETHER_ADDR_STRLEN];
2606
2607 zif = ifp->info;
2608 assert(zif);
2609 vxl = &zif->l2info.vxl;
2610 vni = vxl->vni;
2611
2612 /* Locate VRF corresponding to interface. */
2613 zvrf = vrf_info_lookup(ifp->vrf_id);
2614 assert(zvrf);
13d60d35 2615
2232a77c 2616 /* If EVPN is not enabled, nothing to do. */
2617 if (!EVPN_ENABLED(zvrf))
2618 return 0;
2619
2620 /* Locate hash entry; it is expected to exist. */
2621 zvni = zvni_lookup (zvrf, vni);
13d60d35 2622 if (!zvni)
2232a77c 2623 return 0;
13d60d35 2624
2232a77c 2625 /* If entry doesn't exist, nothing to do. */
2626 mac = zvni_mac_lookup (zvni, macaddr);
2627 if (!mac)
2628 return 0;
2629
2630 /* Is it a remote entry? */
2631 if (!CHECK_FLAG (mac->flags, ZEBRA_MAC_REMOTE))
2632 return 0;
2633
2634 if (IS_ZEBRA_DEBUG_VXLAN)
2635 zlog_debug ("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
2636 ifp->vrf_id, prefix_mac2str (macaddr, buf, sizeof (buf)),
2637 ifp->name, ifp->ifindex, vni);
13d60d35 2638
2232a77c 2639 zvni_mac_install (zvni, mac);
13d60d35 2640 return 0;
2641}
2642
2643/*
2232a77c 2644 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
13d60d35 2645 */
2232a77c 2646int
2647zebra_vxlan_local_mac_del (struct interface *ifp, struct interface *br_if,
2648 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2649{
2232a77c 2650 zebra_vni_t *zvni;
2651 zebra_mac_t *mac;
2652 struct zebra_vrf *zvrf;
2653 char buf[ETHER_ADDR_STRLEN];
13d60d35 2654
2232a77c 2655 /* We are interested in MACs only on ports or (port, VLAN) that
2656 * map to a VNI.
2657 */
2658 zvni = zvni_map_vlan (ifp, br_if, vid);
2659 if (!zvni)
2660 return 0;
13d60d35 2661 if (!zvni->vxlan_if)
2662 {
2232a77c 2663 zlog_err ("VNI %u hash %p doesn't have intf upon local MAC DEL",
13d60d35 2664 zvni->vni, zvni);
2665 return -1;
2666 }
2667
2232a77c 2668 if (IS_ZEBRA_DEBUG_VXLAN)
2669 zlog_debug ("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
2670 ifp->vrf_id, prefix_mac2str (macaddr, buf, sizeof (buf)),
2671 ifp->name, ifp->ifindex, vid, zvni->vni);
2672
2673 /* If entry doesn't exist, nothing to do. */
2674 mac = zvni_mac_lookup (zvni, macaddr);
2675 if (!mac)
2676 return 0;
2677
2678 /* Is it a local entry? */
2679 if (!CHECK_FLAG (mac->flags, ZEBRA_MAC_LOCAL))
2680 return 0;
2681
2682 /* Locate VRF corresponding to interface. */
2683 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2684 assert(zvrf);
2685
2686 /* Remove MAC from BGP. */
2687 zvni_mac_send_del_to_client (zvrf, zvni->vni, macaddr);
2688
2689 /* Delete this MAC entry. */
2690 zvni_mac_del (zvni, mac);
2691
2692 return 0;
13d60d35 2693}
2694
2695/*
2232a77c 2696 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
13d60d35 2697 */
2232a77c 2698int
2699zebra_vxlan_local_mac_add_update (struct interface *ifp, struct interface *br_if,
2700 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2701{
2702 zebra_vni_t *zvni;
2232a77c 2703 zebra_mac_t *mac;
2704 struct zebra_vrf *zvrf;
2705 char buf[ETHER_ADDR_STRLEN];
2706 int add = 1;
13d60d35 2707
2232a77c 2708 /* We are interested in MACs only on ports or (port, VLAN) that
2709 * map to a VNI.
2710 */
2711 zvni = zvni_map_vlan (ifp, br_if, vid);
13d60d35 2712 if (!zvni)
2232a77c 2713 {
2714 if (IS_ZEBRA_DEBUG_VXLAN)
2715 zlog_debug ("%u:Add/Update MAC %s intf %s(%u) VID %u, could not find VNI",
2716 ifp->vrf_id,
2717 prefix_mac2str (macaddr, buf, sizeof (buf)),
2718 ifp->name, ifp->ifindex, vid);
2719 return 0;
2720 }
13d60d35 2721
2232a77c 2722 if (!zvni->vxlan_if)
2723 {
2724 zlog_err ("VNI %u hash %p doesn't have intf upon local MAC ADD",
2725 zvni->vni, zvni);
2726 return -1;
2727 }
13d60d35 2728
2232a77c 2729 if (IS_ZEBRA_DEBUG_VXLAN)
2730 zlog_debug ("%u:Add/Update MAC %s intf %s(%u) VID %u -> VNI %u",
2731 ifp->vrf_id,
2732 prefix_mac2str (macaddr, buf, sizeof (buf)),
2733 ifp->name, ifp->ifindex, vid, zvni->vni);
2734
2735 /* If same entry already exists, nothing to do. */
2736 mac = zvni_mac_lookup (zvni, macaddr);
2737 if (mac)
2738 {
2739 if (CHECK_FLAG (mac->flags, ZEBRA_MAC_LOCAL))
2740 {
2741 if (mac->fwd_info.local.ifindex == ifp->ifindex &&
2742 mac->fwd_info.local.vid == vid)
2743 {
2744 if (IS_ZEBRA_DEBUG_VXLAN)
2745 zlog_debug ("%u:Add/Update MAC %s intf %s(%u) VID %u -> VNI %u, "
2746 "entry exists and has not changed ",
2747 ifp->vrf_id,
2748 prefix_mac2str (macaddr, buf, sizeof (buf)),
2749 ifp->name, ifp->ifindex, vid, zvni->vni);
2750 return 0;
2751 }
2752
2753 add = 0; /* This is an update of local interface. */
2754 }
2755 }
13d60d35 2756
2232a77c 2757 /* Locate VRF corresponding to interface. */
2758 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2759 assert(zvrf);
13d60d35 2760
2232a77c 2761 if (!mac)
2762 {
2763 mac = zvni_mac_add (zvni, macaddr);
2764 if (!mac)
2765 {
2766 zlog_err ("%u:Failed to add MAC %s intf %s(%u) VID %u",
2767 ifp->vrf_id, prefix_mac2str (macaddr, buf, sizeof (buf)),
2768 ifp->name, ifp->ifindex, vid);
2769 return -1;
2770 }
2771 }
2772
2773 /* Set "local" forwarding info. */
2774 UNSET_FLAG (mac->flags, ZEBRA_MAC_REMOTE);
2775 memset (&mac->fwd_info, 0, sizeof (mac->fwd_info));
2776 SET_FLAG (mac->flags, ZEBRA_MAC_LOCAL);
2777 mac->fwd_info.local.ifindex = ifp->ifindex;
2778 mac->fwd_info.local.vid = vid;
2779
2780 /* Inform BGP if required. */
2781 if (add)
2782 return zvni_mac_send_add_to_client (zvrf, zvni->vni, macaddr);
2783
2784 return 0;
2785}
13d60d35 2786
2787/*
2788 * Handle message from client to delete a remote VTEP for a VNI.
2789 */
2790int zebra_vxlan_remote_vtep_del (struct zserv *client, int sock,
2791 u_short length, struct zebra_vrf *zvrf)
2792{
2793 struct stream *s;
2794 u_short l = 0;
2795 vni_t vni;
2796 struct in_addr vtep_ip;
2797 zebra_vni_t *zvni;
2798 zebra_vtep_t *zvtep;
2799
2800 s = client->ibuf;
2801
2802 while (l < length)
2803 {
2804 /* Obtain each remote VTEP and process. */
2805 vni = (vni_t) stream_getl (s);
2806 l += 4;
2807 vtep_ip.s_addr = stream_get_ipv4 (s);
2808 l += IPV4_MAX_BYTELEN;
2809
2810 if (IS_ZEBRA_DEBUG_VXLAN)
2811 zlog_debug ("%u:Recv VTEP_DEL %s VNI %u from %s",
2812 zvrf_id (zvrf), inet_ntoa (vtep_ip),
2813 vni, zebra_route_string (client->proto));
2814
2815 /* Locate VNI hash entry - expected to exist. */
2816 zvni = zvni_lookup (zvrf, vni);
2817 if (!zvni)
2818 {
2819 if (IS_ZEBRA_DEBUG_VXLAN)
2820 zlog_debug ("Failed to locate VNI hash upon remote VTEP DEL, "
2821 "VRF %d VNI %u", zvrf_id (zvrf), vni);
2822 continue;
2823 }
2824
2825 /* If the remote VTEP does not exist, there's nothing more to do.
2826 * Otherwise, uninstall any remote MACs pointing to this VTEP and
2827 * then, the VTEP entry itself and remove it.
2828 */
2829 zvtep = zvni_vtep_find (zvni, &vtep_ip);
2830 if (!zvtep)
2831 continue;
2832
2232a77c 2833 zvni_neigh_del_from_vtep (zvni, 1, &vtep_ip);
2834 zvni_mac_del_from_vtep (zvni, 1, &vtep_ip);
13d60d35 2835 zvni_vtep_uninstall (zvni, &vtep_ip);
2836 zvni_vtep_del (zvni, zvtep);
2837 }
2838
2839 return 0;
2840}
2841
2842/*
2843 * Handle message from client to add a remote VTEP for a VNI.
2844 */
2845int zebra_vxlan_remote_vtep_add (struct zserv *client, int sock,
2846 u_short length, struct zebra_vrf *zvrf)
2847{
2848 struct stream *s;
2849 u_short l = 0;
2850 vni_t vni;
2851 struct in_addr vtep_ip;
2852 zebra_vni_t *zvni;
2853
2854 assert (EVPN_ENABLED (zvrf));
2855
2856 s = client->ibuf;
2857
2858 while (l < length)
2859 {
2860 /* Obtain each remote VTEP and process. */
2861 vni = (vni_t) stream_getl (s);
2862 l += 4;
2863 vtep_ip.s_addr = stream_get_ipv4 (s);
2864 l += IPV4_MAX_BYTELEN;
2865
2866 if (IS_ZEBRA_DEBUG_VXLAN)
2867 zlog_debug ("%u:Recv VTEP_ADD %s VNI %u from %s",
2868 zvrf_id (zvrf), inet_ntoa (vtep_ip),
2869 vni, zebra_route_string (client->proto));
2870
2871 /* Locate VNI hash entry - expected to exist. */
2872 zvni = zvni_lookup (zvrf, vni);
2873 if (!zvni)
2874 {
2875 zlog_err ("Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
2876 zvrf_id (zvrf), vni);
2877 continue;
2878 }
2879 if (!zvni->vxlan_if)
2880 {
2881 zlog_err ("VNI %u hash %p doesn't have intf upon remote VTEP ADD",
2882 zvni->vni, zvni);
2883 continue;
2884 }
2885
2886
2887 /* If the remote VTEP already exists, or the local VxLAN interface is
2888 * not up (should be a transient event), there's nothing more to do.
2889 * Otherwise, add and install the entry.
2890 */
2891 if (zvni_vtep_find (zvni, &vtep_ip))
2892 continue;
2893
2894 if (!if_is_operative (zvni->vxlan_if))
2895 continue;
2896
2897 if (zvni_vtep_add (zvni, &vtep_ip) == NULL)
2898 {
2899 zlog_err ("Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2900 zvrf_id (zvrf), vni, zvni);
2901 continue;
2902 }
2903
2904 zvni_vtep_install (zvni, &vtep_ip);
2905 }
2906
2907 return 0;
2908}
2909
2232a77c 2910/*
2911 * Handle SVI interface going down. At this point, this is a NOP since
2912 * the kernel deletes the neighbor entries on this SVI (if any).
2913 */
2914int
2915zebra_vxlan_svi_down (struct interface *ifp, struct interface *link_if)
2916{
2917 return 0;
2918}
2919
2920/*
2921 * Handle SVI interface coming up. This may or may not be of interest,
2922 * but if this is a SVI on a VxLAN bridge, we need to install any remote
2923 * neighbor entries (which will be used for EVPN ARP suppression).
2924 */
2925int
2926zebra_vxlan_svi_up (struct interface *ifp, struct interface *link_if)
2927{
2928 zebra_vni_t *zvni;
2929 struct neigh_walk_ctx n_wctx;
2930
2931 zvni = zvni_map_svi (ifp, link_if);
2932 if (!zvni)
2933 return 0;
2934
2935 if (!zvni->vxlan_if)
2936 {
2937 zlog_err ("VNI %u hash %p doesn't have intf upon SVI up",
2938 zvni->vni, zvni);
2939 return -1;
2940 }
2941
2942 if (IS_ZEBRA_DEBUG_VXLAN)
2943 zlog_debug ("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
2944 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
2945
2946 /* Install any remote neighbors for this VNI. */
2947 memset (&n_wctx, 0, sizeof (struct neigh_walk_ctx));
2948 n_wctx.zvni = zvni;
2949 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash, &n_wctx);
2950
2951 return 0;
2952}
2953
13d60d35 2954/*
2955 * Handle VxLAN interface down - update BGP if required, and do
2956 * internal cleanup.
2957 */
2958int
2959zebra_vxlan_if_down (struct interface *ifp)
2960{
2961 struct zebra_if *zif;
2962 struct zebra_vrf *zvrf;
2963 zebra_vni_t *zvni;
2964 struct zebra_l2info_vxlan *vxl;
2965 vni_t vni;
2966
2967 /* Locate VRF corresponding to interface. */
2968 zvrf = vrf_info_lookup(ifp->vrf_id);
2969 assert(zvrf);
2970
2971 /* If EVPN is not enabled, nothing further to be done. */
2972 if (!EVPN_ENABLED(zvrf))
2973 return 0;
2974
2975 zif = ifp->info;
2976 assert(zif);
2977 vxl = &zif->l2info.vxl;
2978 vni = vxl->vni;
2979
2980 if (IS_ZEBRA_DEBUG_VXLAN)
2981 zlog_debug ("%u:Intf %s(%u) VNI %u is DOWN",
2982 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2983
2984 /* Locate hash entry; it is expected to exist. */
2985 zvni = zvni_lookup (zvrf, vni);
2986 if (!zvni)
2987 {
2988 zlog_err ("Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
2989 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2990 return -1;
2991 }
2992
2993 assert (zvni->vxlan_if == ifp);
2994
2995 /* Delete this VNI from BGP. */
2996 zvni_send_del_to_client (zvrf, zvni->vni);
2997
2232a77c 2998 /* Free up all neighbors and MACs, if any. */
2999 zvni_neigh_del_all (zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
3000 zvni_mac_del_all (zvrf, zvni, 1, 0, DEL_ALL_MAC);
3001
13d60d35 3002 /* Free up all remote VTEPs, if any. */
3003 zvni_vtep_del_all (zvni, 1);
3004
3005 return 0;
3006}
3007
3008/*
3009 * Handle VxLAN interface up - update BGP if required.
3010 */
3011int
3012zebra_vxlan_if_up (struct interface *ifp)
3013{
3014 struct zebra_if *zif;
3015 struct zebra_vrf *zvrf;
3016 zebra_vni_t *zvni;
3017 struct zebra_l2info_vxlan *vxl;
3018 vni_t vni;
3019
3020 /* Locate VRF corresponding to interface. */
3021 zvrf = vrf_info_lookup(ifp->vrf_id);
3022 assert(zvrf);
3023
3024 /* If EVPN is not enabled, nothing further to be done. */
3025 if (!EVPN_ENABLED(zvrf))
3026 return 0;
3027
3028 zif = ifp->info;
3029 assert(zif);
3030 vxl = &zif->l2info.vxl;
3031 vni = vxl->vni;
3032
3033 if (IS_ZEBRA_DEBUG_VXLAN)
3034 zlog_debug ("%u:Intf %s(%u) VNI %u is UP",
3035 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3036
3037 /* Locate hash entry; it is expected to exist. */
3038 zvni = zvni_lookup (zvrf, vni);
3039 if (!zvni)
3040 {
3041 zlog_err ("Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
3042 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3043 return -1;
3044 }
3045
3046 assert (zvni->vxlan_if == ifp);
3047
3048 /* If part of a bridge, inform BGP about this VNI. */
2232a77c 3049 /* Also, read and populate local MACs and neighbors. */
13d60d35 3050 if (zif->brslave_info.br_if)
2232a77c 3051 {
3052 zvni_send_add_to_client (zvrf, zvni);
3053 zvni_read_mac_neigh (zvrf, zvni, ifp);
3054 }
13d60d35 3055
3056 return 0;
3057}
3058
3059/*
3060 * Handle VxLAN interface delete. Locate and remove entry in hash table
3061 * and update BGP, if required.
3062 */
3063int
3064zebra_vxlan_if_del (struct interface *ifp)
3065{
3066 struct zebra_if *zif;
3067 struct zebra_vrf *zvrf;
3068 zebra_vni_t *zvni;
3069 struct zebra_l2info_vxlan *vxl;
3070 vni_t vni;
3071
3072 /* Locate VRF corresponding to interface. */
3073 zvrf = vrf_info_lookup(ifp->vrf_id);
3074 assert(zvrf);
3075
3076 /* If EVPN is not enabled, nothing further to be done. */
3077 if (!EVPN_ENABLED(zvrf))
3078 return 0;
3079
3080 zif = ifp->info;
3081 assert(zif);
3082 vxl = &zif->l2info.vxl;
3083 vni = vxl->vni;
3084
3085 if (IS_ZEBRA_DEBUG_VXLAN)
2232a77c 3086 zlog_debug ("%u:Del VNI %u intf %s(%u)",
3087 ifp->vrf_id, vni, ifp->name, ifp->ifindex);
13d60d35 3088
3089 /* Locate hash entry; it is expected to exist. */
3090 zvni = zvni_lookup (zvrf, vni);
3091 if (!zvni)
3092 {
3093 zlog_err ("Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
3094 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3095 return 0;
3096 }
3097
3098 /* Delete VNI from BGP. */
3099 zvni_send_del_to_client (zvrf, zvni->vni);
3100
2232a77c 3101 /* Free up all neighbors and MAC, if any. */
3102 zvni_neigh_del_all (zvrf, zvni, 0, 0, DEL_ALL_NEIGH);
3103 zvni_mac_del_all (zvrf, zvni, 0, 0, DEL_ALL_MAC);
3104
13d60d35 3105 /* Free up all remote VTEPs, if any. */
3106 zvni_vtep_del_all (zvni, 0);
3107
3108 /* Delete the hash entry. */
3109 if (zvni_del (zvrf, zvni))
3110 {
3111 zlog_err ("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
3112 zvni, ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
3113 return -1;
3114 }
3115
3116 return 0;
3117}
3118
3119/*
3120 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
3121 */
3122int
3123zebra_vxlan_if_update (struct interface *ifp, u_int16_t chgflags)
3124{
3125 struct zebra_if *zif;
3126 struct zebra_vrf *zvrf;
3127 zebra_vni_t *zvni;
3128 struct zebra_l2info_vxlan *vxl;
3129 vni_t vni;
3130
3131 /* Locate VRF corresponding to interface. */
3132 zvrf = vrf_info_lookup(ifp->vrf_id);
3133 assert(zvrf);
3134
3135 /* If EVPN is not enabled, nothing further to be done. */
3136 if (!EVPN_ENABLED(zvrf))
3137 return 0;
3138
3139 zif = ifp->info;
3140 assert(zif);
3141 vxl = &zif->l2info.vxl;
3142 vni = vxl->vni;
3143
3144 /* Update VNI hash. */
3145 zvni = zvni_lookup (zvrf, vni);
3146 if (!zvni)
3147 {
3148 zlog_err ("Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
3149 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3150 return -1;
3151 }
3152
3153 if (IS_ZEBRA_DEBUG_VXLAN)
2232a77c 3154 zlog_debug ("%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
13d60d35 3155 "master %u chg 0x%x",
2232a77c 3156 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
3157 vxl->access_vlan, inet_ntoa (vxl->vtep_ip),
13d60d35 3158 zif->brslave_info.bridge_ifindex, chgflags);
3159
3160 /* Removed from bridge? */
3161 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) &&
3162 (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL))
3163 {
3164 /* Delete from client, remove all remote VTEPs */
2232a77c 3165 /* Also, free up all MACs and neighbors. */
13d60d35 3166 zvni_send_del_to_client (zvrf, zvni->vni);
2232a77c 3167 zvni_neigh_del_all (zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
3168 zvni_mac_del_all (zvrf, zvni, 1, 0, DEL_ALL_MAC);
13d60d35 3169 zvni_vtep_del_all (zvni, 1);
3170 }
2232a77c 3171 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE)
3172 {
3173 /* Remove all existing local neighbors and MACs for this VNI
3174 * (including from BGP)
3175 */
3176 zvni_neigh_del_all (zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
3177 zvni_mac_del_all (zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
3178 }
13d60d35 3179
3180 zvni->local_vtep_ip = vxl->vtep_ip;
3181 zvni->vxlan_if = ifp;
3182
3183 /* Take further actions needed. Note that if we are here, there is a
3184 * change of interest.
3185 */
3186 /* If down or not mapped to a bridge, we're done. */
3187 if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
3188 return 0;
3189
2232a77c 3190 /* Inform BGP, if there is a change of interest. */
3191 if (chgflags & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
13d60d35 3192 zvni_send_add_to_client (zvrf, zvni);
3193
2232a77c 3194 /* If there is a valid new master or a VLAN mapping change, read and
3195 * populate local MACs and neighbors. Also, reinstall any remote MACs
3196 * and neighbors for this VNI (based on new VLAN).
3197 */
3198 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
3199 zvni_read_mac_neigh (zvrf, zvni, ifp);
3200 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE)
3201 {
3202 struct mac_walk_ctx m_wctx;
3203 struct neigh_walk_ctx n_wctx;
3204
3205 zvni_read_mac_neigh (zvrf, zvni, ifp);
3206
3207 memset (&m_wctx, 0, sizeof (struct mac_walk_ctx));
3208 m_wctx.zvni = zvni;
3209 hash_iterate(zvni->mac_table, zvni_install_mac_hash, &m_wctx);
3210
3211 memset (&n_wctx, 0, sizeof (struct neigh_walk_ctx));
3212 n_wctx.zvni = zvni;
3213 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash, &n_wctx);
3214 }
3215
13d60d35 3216 return 0;
3217}
3218
3219/*
3220 * Handle VxLAN interface add.
3221 */
3222int
3223zebra_vxlan_if_add (struct interface *ifp)
3224{
3225 struct zebra_if *zif;
3226 struct zebra_vrf *zvrf;
3227 zebra_vni_t *zvni;
3228 struct zebra_l2info_vxlan *vxl;
3229 vni_t vni;
3230
3231 /* Locate VRF corresponding to interface. */
3232 zvrf = vrf_info_lookup(ifp->vrf_id);
3233 assert(zvrf);
3234
3235 /* If EVPN is not enabled, nothing further to be done. */
3236 if (!EVPN_ENABLED(zvrf))
3237 return 0;
3238
3239 zif = ifp->info;
3240 assert(zif);
3241 vxl = &zif->l2info.vxl;
3242 vni = vxl->vni;
3243
3244 if (IS_ZEBRA_DEBUG_VXLAN)
2232a77c 3245 zlog_debug ("%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
3246 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
3247 vxl->access_vlan, inet_ntoa (vxl->vtep_ip),
13d60d35 3248 zif->brslave_info.bridge_ifindex);
3249
3250 /* Create or update VNI hash. */
3251 zvni = zvni_lookup (zvrf, vni);
3252 if (!zvni)
3253 {
3254 zvni = zvni_add (zvrf, vni);
3255 if (!zvni)
3256 {
3257 zlog_err ("Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
3258 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3259 return -1;
3260 }
3261 }
3262
3263 zvni->local_vtep_ip = vxl->vtep_ip;
3264 zvni->vxlan_if = ifp;
3265
3266 /* If down or not mapped to a bridge, we're done. */
3267 if (!if_is_operative (ifp) || !zif->brslave_info.br_if)
3268 return 0;
3269
3270 /* Inform BGP */
3271 zvni_send_add_to_client (zvrf, zvni);
3272
2232a77c 3273 /* Read and populate local MACs and neighbors */
3274 zvni_read_mac_neigh (zvrf, zvni, ifp);
3275
13d60d35 3276 return 0;
3277}
3278
3279/*
3280 * Handle message from client to learn (or stop learning) about VNIs and MACs.
3281 * When enabled, the VNI hash table will be built and MAC FDB table read;
3282 * when disabled, the entries should be deleted and remote VTEPs and MACs
3283 * uninstalled from the kernel.
3284 */
3285int zebra_vxlan_advertise_all_vni (struct zserv *client, int sock,
3286 u_short length, struct zebra_vrf *zvrf)
3287{
3288 struct stream *s;
3289 int advertise;
3290
3291 s = client->ibuf;
3292 advertise = stream_getc (s);
3293
3294 if (IS_ZEBRA_DEBUG_VXLAN)
3295 zlog_debug ("%u:EVPN VNI Adv %s, currently %s",
3296 zvrf_id (zvrf), advertise ? "enabled" : "disabled",
3297 EVPN_ENABLED(zvrf) ? "enabled" : "disabled");
3298
3299 if (zvrf->advertise_all_vni == advertise)
3300 return 0;
3301
3302 zvrf->advertise_all_vni = advertise;
3303 if (EVPN_ENABLED(zvrf))
3304 {
3305 /* Build VNI hash table and inform BGP. */
3306 zvni_build_hash_table (zvrf);
2232a77c 3307
3308 /* Read the MAC FDB */
3309 macfdb_read (zvrf->zns);
3310
3311 /* Read neighbors */
3312 neigh_read (zvrf->zns);
13d60d35 3313 }
3314 else
3315 {
3316 /* Cleanup VTEPs for all VNIs - uninstall from
3317 * kernel and free entries.
3318 */
3319 hash_iterate (zvrf->vni_table, zvni_cleanup_all, zvrf);
3320 }
3321
3322 return 0;
3323}
3324
3325/*
3326 * Allocate VNI hash table for this VRF and do other initialization.
3327 * NOTE: Currently supported only for default VRF.
3328 */
3329void
3330zebra_vxlan_init_tables (struct zebra_vrf *zvrf)
3331{
3332 if (!zvrf)
3333 return;
3334 zvrf->vni_table = hash_create(vni_hash_keymake,
3335 vni_hash_cmp,
3336 "Zebra VRF VNI Table");
3337}
3338
3339/* Close all VNI handling */
3340void
3341zebra_vxlan_close_tables (struct zebra_vrf *zvrf)
3342{
3343 hash_iterate (zvrf->vni_table, zvni_cleanup_all, zvrf);
3344}