]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
f99c16ae91a8586a9a256fefab5a2a94f328275d
[mirror_frr.git] / zebra / zebra_vxlan.c
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 #include "lib/json.h"
50
51 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
52 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
53 DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
54 DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
55
56 /* definitions */
57
58
59 /* static function declarations */
60 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
61 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
62 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
63 void **args);
64 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt);
65 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
66 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
67 static void zvni_print(zebra_vni_t *zvni, void **ctxt);
68 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
69
70 static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
71 struct ethaddr *macaddr,
72 struct ipaddr *ip, u_char flags,
73 u_int16_t cmd);
74 static unsigned int neigh_hash_keymake(void *p);
75 static int neigh_cmp(const void *p1, const void *p2);
76 static void *zvni_neigh_alloc(void *p);
77 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
78 struct ethaddr *mac);
79 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n);
80 static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg);
81 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
82 struct in_addr *r_vtep_ip);
83 static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
84 int uninstall, int upd_client, u_int32_t flags);
85 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
86 static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
87 struct ipaddr *ip,
88 struct ethaddr *macaddr, u_char flags);
89 static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
90 struct ipaddr *ip,
91 struct ethaddr *macaddr, u_char flags);
92 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
93 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
94 static zebra_vni_t *zvni_map_svi(struct interface *ifp,
95 struct interface *br_if);
96 static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
97 struct interface *br_if);
98
99 static unsigned int mac_hash_keymake(void *p);
100 static int mac_cmp(const void *p1, const void *p2);
101 static void *zvni_mac_alloc(void *p);
102 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr);
103 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
104 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg);
105 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
106 struct in_addr *r_vtep_ip);
107 static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
108 int uninstall, int upd_client, u_int32_t flags);
109 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
110 static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
111 struct ethaddr *macaddr, u_char flags);
112 static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
113 struct ethaddr *macaddr, u_char flags);
114 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
115 struct interface *br_if, vlanid_t vid);
116 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
117 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local);
118 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
119
120 static unsigned int vni_hash_keymake(void *p);
121 static int vni_hash_cmp(const void *p1, const void *p2);
122 static void *zvni_alloc(void *p);
123 static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni);
124 static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni);
125 static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni);
126 static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni);
127 static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni);
128 static void zvni_build_hash_table(struct zebra_vrf *zvrf);
129 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
130 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
131 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
132 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
133 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall);
134 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip);
135 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip);
136 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
137 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
138 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
139 struct ethaddr *macaddr, struct ipaddr *ip);
140 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
141 struct ipaddr *ip);
142 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
143 static int advertise_gw_macip_enabled(struct zebra_vrf *zvrf,
144 zebra_vni_t *zvni);
145 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
146 int uninstall);
147
148 /* Private functions */
149
150 static int advertise_gw_macip_enabled(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
151 {
152 if (zvrf && zvrf->advertise_gw_macip)
153 return 1;
154
155 if (zvni && zvni->advertise_gw_macip)
156 return 1;
157
158 return 0;
159 }
160
161 /*
162 * Helper function to determine maximum width of neighbor IP address for
163 * display - just because we're dealing with IPv6 addresses that can
164 * widely vary.
165 */
166 static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
167 {
168 zebra_neigh_t *n;
169 char buf[INET6_ADDRSTRLEN];
170 struct neigh_walk_ctx *wctx = ctxt;
171 int width;
172
173 n = (zebra_neigh_t *)backet->data;
174 if (!n)
175 return;
176
177 ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
178 if (width > wctx->addr_width)
179 wctx->addr_width = width;
180 }
181
182 /*
183 * Print a specific neighbor entry.
184 */
185 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
186 {
187 struct vty *vty;
188 char buf1[ETHER_ADDR_STRLEN];
189 char buf2[INET6_ADDRSTRLEN];
190
191 ipaddr2str(&n->ip, buf2, sizeof(buf2));
192 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
193 vty = (struct vty *)ctxt;
194 if (json == NULL) {
195 vty_out(vty, "IP: %s\n",
196 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
197 vty_out(vty, " MAC: %s",
198 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
199 } else {
200 json_object_string_add(json, "ip", buf2);
201 json_object_string_add(json, "mac", buf1);
202 }
203 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
204 if (json == NULL) {
205 vty_out(vty, " Remote VTEP: %s",
206 inet_ntoa(n->r_vtep_ip));
207 vty_out(vty, " State: %s", IS_ZEBRA_NEIGH_ACTIVE(n)
208 ? "Active"
209 : "Inactive");
210 } else
211 json_object_string_add(json, "remoteVtep",
212 inet_ntoa(n->r_vtep_ip));
213 }
214 if (json == NULL)
215 vty_out(vty, "\n");
216 }
217
218 /*
219 * Print neighbor hash entry - called for display of all neighbors.
220 */
221 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
222 {
223 struct vty *vty;
224 json_object *json_vni = NULL, *json_row = NULL;
225 zebra_neigh_t *n;
226 char buf1[ETHER_ADDR_STRLEN];
227 char buf2[INET6_ADDRSTRLEN];
228 struct neigh_walk_ctx *wctx = ctxt;
229
230 vty = wctx->vty;
231 json_vni = wctx->json;
232 n = (zebra_neigh_t *)backet->data;
233 if (!n)
234 return;
235
236 if (json_vni)
237 json_row = json_object_new_object();
238
239 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
240 ipaddr2str(&n->ip, buf2, sizeof(buf2));
241 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
242 && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
243 if (json_vni == NULL) {
244 vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width,
245 buf2, "local", buf1);
246 } else {
247 json_object_string_add(json_row, "type", "local");
248 json_object_string_add(json_row, "mac", buf1);
249 }
250 wctx->count++;
251 } else {
252 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
253 if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
254 if (json_vni == NULL) {
255 if (wctx->count == 0)
256 vty_out(vty,
257 "%*s %-6s %-17s %-21s\n",
258 -wctx->addr_width,
259 "Neighbor", "Type",
260 "MAC", "Remote VTEP");
261 vty_out(vty, "%*s %-6s %-17s %-21s\n",
262 -wctx->addr_width, buf2,
263 "remote", buf1,
264 inet_ntoa(n->r_vtep_ip));
265 } else {
266 json_object_string_add(json_row, "type",
267 "remote");
268 json_object_string_add(json_row, "mac",
269 buf1);
270 json_object_string_add(
271 json_row, "remoteVtep",
272 inet_ntoa(n->r_vtep_ip));
273 }
274 wctx->count++;
275 }
276 } else {
277 if (json_vni == NULL) {
278 vty_out(vty, "%*s %-6s %-17s %-21s\n",
279 -wctx->addr_width, buf2, "remote", buf1,
280 inet_ntoa(n->r_vtep_ip));
281 } else {
282 json_object_string_add(json_row, "type",
283 "remote");
284 json_object_string_add(json_row, "mac", buf1);
285 json_object_string_add(json_row, "remoteVtep",
286 inet_ntoa(n->r_vtep_ip));
287 }
288 wctx->count++;
289 }
290 }
291
292 if (json_vni)
293 json_object_object_add(json_vni, buf2, json_row);
294 }
295
296 /*
297 * Print neighbors for all VNI.
298 */
299 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
300 void **args)
301 {
302 struct vty *vty;
303 json_object *json = NULL, *json_vni = NULL;
304 zebra_vni_t *zvni;
305 u_int32_t num_neigh;
306 struct neigh_walk_ctx wctx;
307 char vni_str[VNI_STR_LEN];
308
309 vty = (struct vty *)args[0];
310 json = (json_object *)args[1];
311
312 zvni = (zebra_vni_t *)backet->data;
313 if (!zvni) {
314 if (json)
315 vty_out(vty, "{}\n");
316 return;
317 }
318 num_neigh = hashcount(zvni->neigh_table);
319 if (json == NULL)
320 vty_out(vty,
321 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
322 zvni->vni, num_neigh);
323 else {
324 json_vni = json_object_new_object();
325 json_object_int_add(json_vni, "numArpNd", num_neigh);
326 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
327 }
328 if (!num_neigh) {
329 if (json)
330 json_object_object_add(json, vni_str, json_vni);
331 return;
332 }
333
334 /* Since we have IPv6 addresses to deal with which can vary widely in
335 * size, we try to be a bit more elegant in display by first computing
336 * the maximum width.
337 */
338 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
339 wctx.zvni = zvni;
340 wctx.vty = vty;
341 wctx.addr_width = 15;
342 wctx.json = json_vni;
343 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
344
345 if (json == NULL)
346 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
347 "Type", "MAC", "Remote VTEP");
348 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
349
350 if (json)
351 json_object_object_add(json, vni_str, json_vni);
352 }
353
354 /*
355 * Print a specific MAC entry.
356 */
357 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
358 {
359 struct vty *vty;
360 zebra_neigh_t *n = NULL;
361 struct listnode *node = NULL;
362 char buf1[20];
363 char buf2[INET6_ADDRSTRLEN];
364
365 vty = (struct vty *)ctxt;
366 vty_out(vty, "MAC: %s",
367 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
368 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
369 struct zebra_ns *zns;
370 struct interface *ifp;
371 ifindex_t ifindex;
372
373 ifindex = mac->fwd_info.local.ifindex;
374 zns = zebra_ns_lookup(NS_DEFAULT);
375 ifp = if_lookup_by_index_per_ns(zns, ifindex);
376 if (!ifp) // unexpected
377 return;
378 vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
379 if (mac->fwd_info.local.vid)
380 vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
381 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
382 vty_out(vty, " Remote VTEP: %s",
383 inet_ntoa(mac->fwd_info.r_vtep_ip));
384 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
385 vty_out(vty, " Auto Mac ");
386 }
387 vty_out(vty, " ARP ref: %u\n", mac->neigh_refcnt);
388
389 /* print all the associated neigh */
390 vty_out(vty, " Neighbors:\n");
391 if (!listcount(mac->neigh_list))
392 vty_out(vty, " No Neighbors\n");
393 else {
394 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
395 vty_out(vty, " %s %s\n",
396 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
397 CHECK_FLAG(n->flags, ZEBRA_MAC_LOCAL)
398 ? (IS_ZEBRA_NEIGH_ACTIVE(n)
399 ? "Active"
400 : "Inactive")
401 : "");
402 }
403 }
404
405 vty_out(vty, "\n");
406 }
407
408 /*
409 * Print MAC hash entry - called for display of all MACs.
410 */
411 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
412 {
413 struct vty *vty;
414 json_object *json_mac_hdr = NULL, *json_mac = NULL;
415 zebra_mac_t *mac;
416 char buf1[20];
417 struct mac_walk_ctx *wctx = ctxt;
418
419 vty = wctx->vty;
420 json_mac_hdr = wctx->json;
421 mac = (zebra_mac_t *)backet->data;
422 if (!mac)
423 return;
424
425 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
426
427 if (json_mac_hdr)
428 json_mac = json_object_new_object();
429
430 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
431 && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
432 struct zebra_ns *zns;
433 ifindex_t ifindex;
434 struct interface *ifp;
435 vlanid_t vid;
436
437 zns = zebra_ns_lookup(NS_DEFAULT);
438 ifindex = mac->fwd_info.local.ifindex;
439 ifp = if_lookup_by_index_per_ns(zns, ifindex);
440 if (!ifp) // unexpected
441 return;
442 vid = mac->fwd_info.local.vid;
443 if (json_mac_hdr == NULL)
444 vty_out(vty, "%-17s %-6s %-21s", buf1, "local",
445 ifp->name);
446 else {
447 json_object_string_add(json_mac, "type", "local");
448 json_object_string_add(json_mac, "intf", ifp->name);
449 }
450 if (vid) {
451 if (json_mac_hdr == NULL)
452 vty_out(vty, " %-5u", vid);
453 else
454 json_object_int_add(json_mac, "vlan", vid);
455 }
456 if (json_mac_hdr == NULL)
457 vty_out(vty, "\n");
458 else
459 json_object_object_add(json_mac_hdr, buf1, json_mac);
460 wctx->count++;
461 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
462 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
463 if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
464 &wctx->r_vtep_ip)) {
465 if (wctx->count == 0) {
466 if (json_mac_hdr == NULL) {
467 vty_out(vty, "\nVNI %u\n\n",
468 wctx->zvni->vni);
469 vty_out(vty,
470 "%-17s %-6s %-21s %-5s\n",
471 "MAC", "Type",
472 "Intf/Remote VTEP",
473 "VLAN");
474 }
475 }
476 if (json_mac_hdr == NULL)
477 vty_out(vty, "%-17s %-6s %-21s\n", buf1,
478 "remote",
479 inet_ntoa(mac->fwd_info
480 .r_vtep_ip));
481 else {
482 json_object_string_add(json_mac, "type",
483 "remote");
484 json_object_string_add(
485 json_mac, "remoteVtep",
486 inet_ntoa(mac->fwd_info
487 .r_vtep_ip));
488 json_object_object_add(json_mac_hdr,
489 buf1, json_mac);
490 }
491 wctx->count++;
492 }
493 } else {
494 if (json_mac_hdr == NULL)
495 vty_out(vty, "%-17s %-6s %-21s\n", buf1,
496 "remote",
497 inet_ntoa(mac->fwd_info.r_vtep_ip));
498 else {
499 json_object_string_add(json_mac, "type",
500 "remote");
501 json_object_string_add(
502 json_mac, "remoteVtep",
503 inet_ntoa(mac->fwd_info.r_vtep_ip));
504 json_object_object_add(json_mac_hdr, buf1,
505 json_mac);
506 }
507 wctx->count++;
508 }
509 }
510 }
511
512 /*
513 * Print MACs for all VNI.
514 */
515 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
516 {
517 struct vty *vty;
518 json_object *json = NULL, *json_vni = NULL;
519 json_object *json_mac = NULL;
520 zebra_vni_t *zvni;
521 u_int32_t num_macs;
522 struct mac_walk_ctx *wctx = ctxt;
523 char vni_str[VNI_STR_LEN];
524
525 vty = (struct vty *)wctx->vty;
526 json = (struct json_object *)wctx->json;
527
528 zvni = (zebra_vni_t *)backet->data;
529 if (!zvni) {
530 if (json)
531 vty_out(vty, "{}\n");
532 return;
533 }
534 wctx->zvni = zvni;
535
536 /*We are iterating over a new VNI, set the count to 0*/
537 wctx->count = 0;
538
539 num_macs = hashcount(zvni->mac_table);
540 if (!num_macs)
541 return;
542
543 if (json) {
544 json_vni = json_object_new_object();
545 json_mac = json_object_new_object();
546 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
547 }
548
549 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
550 if (json == NULL) {
551 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
552 zvni->vni, num_macs);
553 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
554 "Intf/Remote VTEP", "VLAN");
555 } else
556 json_object_int_add(json_vni, "numMacs", num_macs);
557 }
558 /* assign per-vni to wctx->json object to fill macs
559 * under the vni. Re-assign primary json object to fill
560 * next vni information.
561 */
562 wctx->json = json_mac;
563 hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
564 wctx->json = json;
565 if (json) {
566 if (wctx->count)
567 json_object_object_add(json_vni, "macs", json_mac);
568 json_object_object_add(json, vni_str, json_vni);
569 }
570 }
571
572 /*
573 * Print a specific VNI entry.
574 */
575 static void zvni_print(zebra_vni_t *zvni, void **ctxt)
576 {
577 struct vty *vty;
578 zebra_vtep_t *zvtep;
579 u_int32_t num_macs;
580 u_int32_t num_neigh;
581 json_object *json = NULL;
582 json_object *json_vtep_list = NULL;
583 json_object *json_ip_str = NULL;
584
585 vty = ctxt[0];
586 json = ctxt[1];
587
588 if (json == NULL)
589 vty_out(vty, "VNI: %u\n", zvni->vni);
590 else
591 json_object_int_add(json, "vni", zvni->vni);
592
593 if (!zvni->vxlan_if) { // unexpected
594 if (json == NULL)
595 vty_out(vty, " VxLAN interface: unknown\n");
596 return;
597 }
598 num_macs = hashcount(zvni->mac_table);
599 num_neigh = hashcount(zvni->neigh_table);
600 if (json == NULL)
601 vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
602 zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
603 inet_ntoa(zvni->local_vtep_ip));
604 else {
605 json_object_string_add(json, "vxlanInterface",
606 zvni->vxlan_if->name);
607 json_object_int_add(json, "ifindex", zvni->vxlan_if->ifindex);
608 json_object_string_add(json, "vtepIp",
609 inet_ntoa(zvni->local_vtep_ip));
610 json_object_string_add(json, "advertiseGatewayMacip",
611 zvni->advertise_gw_macip ? "Yes" : "No");
612 json_object_int_add(json, "numMacs", num_macs);
613 json_object_int_add(json, "numArpNd", num_neigh);
614 }
615 if (!zvni->vteps) {
616 if (json == NULL)
617 vty_out(vty, " No remote VTEPs known for this VNI\n");
618 } else {
619 if (json == NULL)
620 vty_out(vty, " Remote VTEPs for this VNI:\n");
621 else
622 json_vtep_list = json_object_new_array();
623 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
624 if (json == NULL)
625 vty_out(vty, " %s\n",
626 inet_ntoa(zvtep->vtep_ip));
627 else {
628 json_ip_str = json_object_new_string(
629 inet_ntoa(zvtep->vtep_ip));
630 json_object_array_add(json_vtep_list,
631 json_ip_str);
632 }
633 }
634 if (json)
635 json_object_object_add(json, "numRemoteVteps",
636 json_vtep_list);
637 }
638 if (json == NULL) {
639 vty_out(vty,
640 " Number of MACs (local and remote) known for this VNI: %u\n",
641 num_macs);
642 vty_out(vty,
643 " Number of ARPs (IPv4 and IPv6, local and remote) "
644 "known for this VNI: %u\n",
645 num_neigh);
646 vty_out(vty, " Advertise-gw-macip: %s\n",
647 zvni->advertise_gw_macip ? "Yes" : "No");
648 }
649 }
650
651 /*
652 * Print a VNI hash entry - called for display of all VNIs.
653 */
654 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
655 {
656 struct vty *vty;
657 zebra_vni_t *zvni;
658 zebra_vtep_t *zvtep;
659 u_int32_t num_vteps = 0;
660 u_int32_t num_macs = 0;
661 u_int32_t num_neigh = 0;
662 json_object *json = NULL;
663 json_object *json_vni = NULL;
664 json_object *json_ip_str = NULL;
665 json_object *json_vtep_list = NULL;
666
667 vty = ctxt[0];
668 json = ctxt[1];
669
670 zvni = (zebra_vni_t *)backet->data;
671 if (!zvni)
672 return;
673
674 zvtep = zvni->vteps;
675 while (zvtep) {
676 num_vteps++;
677 zvtep = zvtep->next;
678 }
679
680 num_macs = hashcount(zvni->mac_table);
681 num_neigh = hashcount(zvni->neigh_table);
682 if (json == NULL)
683 vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni->vni,
684 zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
685 inet_ntoa(zvni->local_vtep_ip), num_macs, num_neigh,
686 num_vteps);
687 else {
688 char vni_str[VNI_STR_LEN];
689 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
690 json_vni = json_object_new_object();
691 json_object_string_add(json_vni, "vxlanIf",
692 zvni->vxlan_if ? zvni->vxlan_if->name
693 : "unknown");
694 json_object_string_add(json_vni, "vtepIp",
695 inet_ntoa(zvni->local_vtep_ip));
696 json_object_int_add(json_vni, "numMacs", num_macs);
697 json_object_int_add(json_vni, "numArpNd", num_neigh);
698 json_object_int_add(json_vni, "numRemoteVteps", num_vteps);
699 if (num_vteps) {
700 json_vtep_list = json_object_new_array();
701 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
702 json_ip_str = json_object_new_string(
703 inet_ntoa(zvtep->vtep_ip));
704 json_object_array_add(json_vtep_list,
705 json_ip_str);
706 }
707 json_object_object_add(json_vni, "remoteVteps",
708 json_vtep_list);
709 }
710 json_object_object_add(json, vni_str, json_vni);
711 }
712 }
713
714 /*
715 * Inform BGP about local MACIP.
716 */
717 static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
718 struct ethaddr *macaddr,
719 struct ipaddr *ip, u_char flags,
720 u_int16_t cmd)
721 {
722 struct zserv *client;
723 struct stream *s;
724 int ipa_len;
725 char buf[ETHER_ADDR_STRLEN];
726 char buf2[INET6_ADDRSTRLEN];
727
728 client = zebra_find_client(ZEBRA_ROUTE_BGP);
729 /* BGP may not be running. */
730 if (!client)
731 return 0;
732
733 s = client->obuf;
734 stream_reset(s);
735
736 zserv_create_header(s, cmd, zvrf_id(zvrf));
737 stream_putl(s, vni);
738 stream_put(s, macaddr->octet, ETH_ALEN);
739 if (ip) {
740 ipa_len = 0;
741 if (IS_IPADDR_V4(ip))
742 ipa_len = IPV4_MAX_BYTELEN;
743 else if (IS_IPADDR_V6(ip))
744 ipa_len = IPV6_MAX_BYTELEN;
745
746 stream_putl(s, ipa_len); /* IP address length */
747 if (ipa_len)
748 stream_put(s, &ip->ip.addr, ipa_len); /* IP address */
749 } else
750 stream_putl(s, 0); /* Just MAC. */
751
752 stream_putc(s, flags); /* sticky mac/gateway mac */
753
754 /* Write packet size. */
755 stream_putw_at(s, 0, stream_get_endp(s));
756
757 if (IS_ZEBRA_DEBUG_VXLAN)
758 zlog_debug(
759 "%u:Send MACIP %s flags 0x%x MAC %s IP %s VNI %u to %s",
760 zvrf_id(zvrf), (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
761 flags, prefix_mac2str(macaddr, buf, sizeof(buf)),
762 ipaddr2str(ip, buf2, sizeof(buf2)), vni,
763 zebra_route_string(client->proto));
764
765 if (cmd == ZEBRA_MACIP_ADD)
766 client->macipadd_cnt++;
767 else
768 client->macipdel_cnt++;
769
770 return zebra_server_send_message(client);
771 }
772
773 /*
774 * Make hash key for neighbors.
775 */
776 static unsigned int neigh_hash_keymake(void *p)
777 {
778 zebra_neigh_t *n = p;
779 struct ipaddr *ip = &n->ip;
780
781 if (IS_IPADDR_V4(ip))
782 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
783
784 return jhash2(ip->ipaddr_v6.s6_addr32,
785 ZEBRA_NUM_OF(ip->ipaddr_v6.s6_addr32), 0);
786 }
787
788 /*
789 * Compare two neighbor hash structures.
790 */
791 static int neigh_cmp(const void *p1, const void *p2)
792 {
793 const zebra_neigh_t *n1 = p1;
794 const zebra_neigh_t *n2 = p2;
795
796 if (n1 == NULL && n2 == NULL)
797 return 1;
798
799 if (n1 == NULL || n2 == NULL)
800 return 0;
801
802 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
803 }
804
805 /*
806 * Callback to allocate neighbor hash entry.
807 */
808 static void *zvni_neigh_alloc(void *p)
809 {
810 const zebra_neigh_t *tmp_n = p;
811 zebra_neigh_t *n;
812
813 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
814 *n = *tmp_n;
815
816 return ((void *)n);
817 }
818
819 /*
820 * Add neighbor entry.
821 */
822 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
823 struct ethaddr *mac)
824 {
825 zebra_neigh_t tmp_n;
826 zebra_neigh_t *n = NULL;
827 zebra_mac_t *zmac = NULL;
828
829 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
830 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
831 n = hash_get(zvni->neigh_table, &tmp_n, zvni_neigh_alloc);
832 assert(n);
833
834 memcpy(&n->emac, mac, ETH_ALEN);
835 n->state = ZEBRA_NEIGH_INACTIVE;
836
837 /* Associate the neigh to mac */
838 zmac = zvni_mac_lookup(zvni, mac);
839 if (zmac)
840 listnode_add_sort(zmac->neigh_list, n);
841
842 return n;
843 }
844
845 /*
846 * Delete neighbor entry.
847 */
848 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
849 {
850 zebra_neigh_t *tmp_n;
851 zebra_mac_t *zmac = NULL;
852
853 zmac = zvni_mac_lookup(zvni, &n->emac);
854 if (zmac)
855 listnode_delete(zmac->neigh_list, n);
856
857 /* Free the VNI hash entry and allocated memory. */
858 tmp_n = hash_release(zvni->neigh_table, n);
859 if (tmp_n)
860 XFREE(MTYPE_NEIGH, tmp_n);
861
862 return 0;
863 }
864
865 /*
866 * Free neighbor hash entry (callback)
867 */
868 static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
869 {
870 struct neigh_walk_ctx *wctx = arg;
871 zebra_neigh_t *n = backet->data;
872
873 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
874 || ((wctx->flags & DEL_REMOTE_NEIGH)
875 && (n->flags & ZEBRA_NEIGH_REMOTE))
876 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
877 && (n->flags & ZEBRA_NEIGH_REMOTE)
878 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
879 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
880 zvni_neigh_send_del_to_client(wctx->zvrf,
881 wctx->zvni->vni, &n->ip,
882 &n->emac, 0);
883
884 if (wctx->uninstall)
885 zvni_neigh_uninstall(wctx->zvni, n);
886
887 return zvni_neigh_del(wctx->zvni, n);
888 }
889
890 return 0;
891 }
892
893 /*
894 * Delete all neighbor entries from specific VTEP for a particular VNI.
895 */
896 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
897 struct in_addr *r_vtep_ip)
898 {
899 struct neigh_walk_ctx wctx;
900
901 if (!zvni->neigh_table)
902 return;
903
904 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
905 wctx.zvni = zvni;
906 wctx.uninstall = uninstall;
907 wctx.flags = DEL_REMOTE_NEIGH_FROM_VTEP;
908 wctx.r_vtep_ip = *r_vtep_ip;
909
910 hash_iterate(zvni->neigh_table,
911 (void (*)(struct hash_backet *,
912 void *))zvni_neigh_del_hash_entry,
913 &wctx);
914 }
915
916 /*
917 * Delete all neighbor entries for this VNI.
918 */
919 static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
920 int uninstall, int upd_client, u_int32_t flags)
921 {
922 struct neigh_walk_ctx wctx;
923
924 if (!zvni->neigh_table)
925 return;
926
927 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
928 wctx.zvni = zvni;
929 wctx.zvrf = zvrf;
930 wctx.uninstall = uninstall;
931 wctx.upd_client = upd_client;
932 wctx.flags = flags;
933
934 hash_iterate(zvni->neigh_table,
935 (void (*)(struct hash_backet *,
936 void *))zvni_neigh_del_hash_entry,
937 &wctx);
938 }
939
940 /*
941 * Look up neighbor hash entry.
942 */
943 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
944 {
945 zebra_neigh_t tmp;
946 zebra_neigh_t *n;
947
948 memset(&tmp, 0, sizeof(tmp));
949 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
950 n = hash_lookup(zvni->neigh_table, &tmp);
951
952 return n;
953 }
954
955 /* Process all neigh associated to a mac upon local mac add event */
956 static void zvni_process_neigh_on_local_mac_add(struct zebra_vrf *zvrf,
957 zebra_vni_t *zvni,
958 zebra_mac_t *zmac)
959 {
960 zebra_neigh_t *n = NULL;
961 struct listnode *node = NULL;
962 char buf[ETHER_ADDR_STRLEN];
963 char buf2[INET6_ADDRSTRLEN];
964
965 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
966 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
967 /* MAC is learnt locally, program all inactive neigh
968 * pointing to this mac */
969 if (IS_ZEBRA_NEIGH_INACTIVE(n)) {
970 if (IS_ZEBRA_DEBUG_VXLAN)
971 zlog_debug(
972 "%u: neigh %s (MAC %s) on VNI %u is now ACTIVE",
973 zvrf_id(zvrf),
974 ipaddr2str(&n->ip, buf2,
975 sizeof(buf2)),
976 prefix_mac2str(&n->emac, buf,
977 sizeof(buf)),
978 zvni->vni);
979
980 ZEBRA_NEIGH_SET_ACTIVE(n);
981 zvni_neigh_send_add_to_client(
982 zvrf, zvni->vni, &n->ip, &n->emac, 0);
983 } else {
984 if (IS_ZEBRA_DEBUG_VXLAN)
985 zlog_debug(
986 "%u: neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
987 zvrf_id(zvrf),
988 ipaddr2str(&n->ip, buf2,
989 sizeof(buf2)),
990 prefix_mac2str(&n->emac, buf,
991 sizeof(buf)),
992 zvni->vni);
993 }
994 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
995 /* TODO: assume the neigh has moved too ?? */
996 }
997 }
998 }
999
1000 /* Process all neigh associated to a mac upon local mac del event */
1001 static void zvni_process_neigh_on_local_mac_del(struct zebra_vrf *zvrf,
1002 zebra_vni_t *zvni,
1003 zebra_mac_t *zmac)
1004 {
1005 zebra_neigh_t *n = NULL;
1006 struct listnode *node = NULL;
1007 char buf[ETHER_ADDR_STRLEN];
1008 char buf2[INET6_ADDRSTRLEN];
1009
1010 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1011 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1012 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1013 if (IS_ZEBRA_DEBUG_VXLAN)
1014 zlog_debug(
1015 "%u: neigh %s (MAC %s) on VNI %u is now INACTIVE",
1016 zvrf_id(zvrf),
1017 ipaddr2str(&n->ip, buf2,
1018 sizeof(buf2)),
1019 prefix_mac2str(&n->emac, buf,
1020 sizeof(buf)),
1021 zvni->vni);
1022
1023 ZEBRA_NEIGH_SET_INACTIVE(n);
1024 zvni_neigh_send_del_to_client(
1025 zvrf, zvni->vni, &n->ip, &n->emac, 0);
1026 }
1027 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1028 if (IS_ZEBRA_DEBUG_VXLAN)
1029 zlog_err(
1030 "%u: local MAC %s getting deleted on VNI %u has remote neigh %s",
1031 zvrf_id(zvrf),
1032 prefix_mac2str(&n->emac, buf,
1033 sizeof(buf)),
1034 zvni->vni,
1035 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1036 }
1037 }
1038 }
1039
1040 /* process all neigh associated to a mac entry upon remote mac add */
1041 static void zvni_process_neigh_on_remote_mac_add(struct zebra_vrf *zvrf,
1042 zebra_vni_t *zvni,
1043 zebra_mac_t *zmac)
1044 {
1045 zebra_neigh_t *n = NULL;
1046 struct listnode *node = NULL;
1047 char buf[ETHER_ADDR_STRLEN];
1048 char buf2[INET6_ADDRSTRLEN];
1049
1050 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1051 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1052 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1053 if (IS_ZEBRA_DEBUG_VXLAN)
1054 zlog_debug(
1055 "%u: neigh %s (MAC %s) on VNI %u INACTIVE",
1056 zvrf_id(zvrf),
1057 ipaddr2str(&n->ip, buf2,
1058 sizeof(buf2)),
1059 prefix_mac2str(&n->emac, buf,
1060 sizeof(buf)),
1061 zvni->vni);
1062
1063 ZEBRA_NEIGH_SET_INACTIVE(n);
1064 zvni_neigh_send_del_to_client(
1065 zvrf, zvni->vni, &n->ip, &n->emac, 0);
1066 }
1067 }
1068 }
1069 }
1070
1071 /* process all neigh associated to mac entry upon remote mac del */
1072 static void zvni_process_neigh_on_remote_mac_del(struct zebra_vrf *zvrf,
1073 zebra_vni_t *zvni,
1074 zebra_mac_t *zmac)
1075 {
1076 zebra_neigh_t *n = NULL;
1077 struct listnode *node = NULL;
1078 char buf[ETHER_ADDR_STRLEN];
1079 char buf2[INET6_ADDRSTRLEN];
1080
1081 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1082 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1083 if (IS_ZEBRA_DEBUG_VXLAN)
1084 zlog_err(
1085 "%u: remote MAC %s getting deleted on VNI %u has local neigh %s",
1086 zvrf_id(zvrf),
1087 prefix_mac2str(&n->emac, buf,
1088 sizeof(buf)),
1089 zvni->vni,
1090 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1091 }
1092 }
1093 }
1094
1095 /*
1096 * Inform BGP about local neighbor addition.
1097 */
1098 static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
1099 struct ipaddr *ip,
1100 struct ethaddr *macaddr, u_char flags)
1101 {
1102 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, flags,
1103 ZEBRA_MACIP_ADD);
1104 }
1105
1106 /*
1107 * Inform BGP about local neighbor deletion.
1108 */
1109 static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
1110 struct ipaddr *ip,
1111 struct ethaddr *macaddr, u_char flags)
1112 {
1113 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, flags,
1114 ZEBRA_MACIP_DEL);
1115 }
1116
1117 /*
1118 * Install remote neighbor into the kernel.
1119 */
1120 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
1121 {
1122 struct zebra_vrf *zvrf;
1123 struct zebra_if *zif;
1124 struct zebra_l2info_vxlan *vxl;
1125 struct interface *vlan_if;
1126
1127 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
1128 return 0;
1129
1130 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1131 assert(zvrf);
1132 zif = zvni->vxlan_if->info;
1133 if (!zif)
1134 return -1;
1135 vxl = &zif->l2info.vxl;
1136
1137 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
1138 zif->brslave_info.br_if);
1139 if (!vlan_if)
1140 return -1;
1141
1142 return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
1143 }
1144
1145 /*
1146 * Uninstall remote neighbor from the kernel.
1147 */
1148 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
1149 {
1150 struct zebra_vrf *zvrf;
1151 struct zebra_if *zif;
1152 struct zebra_l2info_vxlan *vxl;
1153 struct interface *vlan_if;
1154
1155 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
1156 return 0;
1157
1158 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1159 assert(zvrf);
1160 if (!zvni->vxlan_if) {
1161 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1162 zvni->vni, zvni);
1163 return -1;
1164 }
1165
1166 zif = zvni->vxlan_if->info;
1167 if (!zif)
1168 return -1;
1169 vxl = &zif->l2info.vxl;
1170 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
1171 zif->brslave_info.br_if);
1172 if (!vlan_if)
1173 return -1;
1174
1175 return kernel_del_neigh(vlan_if, &n->ip);
1176 }
1177
1178 /*
1179 * Install neighbor hash entry - called upon access VLAN change.
1180 */
1181 static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt)
1182 {
1183 zebra_neigh_t *n;
1184 struct neigh_walk_ctx *wctx = ctxt;
1185
1186 n = (zebra_neigh_t *)backet->data;
1187 if (!n)
1188 return;
1189
1190 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
1191 zvni_neigh_install(wctx->zvni, n);
1192 }
1193
1194 /* Get the VRR interface for SVI if any */
1195 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
1196 {
1197 struct zebra_vrf *zvrf = NULL;
1198 struct interface *tmp_if = NULL;
1199 struct zebra_if *zif = NULL;
1200 struct listnode *node;
1201
1202 zvrf = vrf_info_lookup(ifp->vrf_id);
1203 assert(zvrf);
1204
1205 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1206 zif = tmp_if->info;
1207 if (!zif)
1208 continue;
1209
1210 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
1211 continue;
1212
1213 if (zif->link == ifp)
1214 return tmp_if;
1215 }
1216
1217 return NULL;
1218 }
1219
1220 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1221 {
1222 struct zebra_vrf *zvrf = NULL;
1223 struct listnode *cnode = NULL, *cnnode = NULL;
1224 struct connected *c = NULL;
1225 struct ethaddr macaddr;
1226
1227 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1228 if (!zvrf)
1229 return -1;
1230
1231 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1232
1233 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1234 struct ipaddr ip;
1235
1236 memset(&ip, 0, sizeof(struct ipaddr));
1237 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1238 continue;
1239
1240 if (c->address->family == AF_INET) {
1241 ip.ipa_type = IPADDR_V4;
1242 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1243 sizeof(struct in_addr));
1244 } else if (c->address->family == AF_INET6) {
1245 ip.ipa_type = IPADDR_V6;
1246 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1247 sizeof(struct in6_addr));
1248 } else {
1249 continue;
1250 }
1251
1252 zvni_gw_macip_del(ifp, zvni, &ip);
1253 }
1254
1255 return 0;
1256 }
1257
1258 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1259 {
1260 struct zebra_vrf *zvrf = NULL;
1261 struct listnode *cnode = NULL, *cnnode = NULL;
1262 struct connected *c = NULL;
1263 struct ethaddr macaddr;
1264
1265 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1266 if (!zvrf)
1267 return -1;
1268
1269 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1270
1271 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1272 struct ipaddr ip;
1273
1274 memset(&ip, 0, sizeof(struct ipaddr));
1275 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1276 continue;
1277
1278 if (c->address->family == AF_INET) {
1279 ip.ipa_type = IPADDR_V4;
1280 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1281 sizeof(struct in_addr));
1282 } else if (c->address->family == AF_INET6) {
1283 ip.ipa_type = IPADDR_V6;
1284 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1285 sizeof(struct in6_addr));
1286 } else {
1287 continue;
1288 }
1289
1290 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
1291 }
1292
1293 return 0;
1294 }
1295
1296 /*
1297 * zvni_gw_macip_add_to_client
1298 */
1299 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
1300 struct ethaddr *macaddr, struct ipaddr *ip)
1301 {
1302 struct zebra_vrf *zvrf = NULL;
1303 struct zebra_if *zif = NULL;
1304 struct zebra_l2info_vxlan *vxl = NULL;
1305 zebra_neigh_t *n = NULL;
1306 zebra_mac_t *mac = NULL;
1307 char buf[ETHER_ADDR_STRLEN];
1308 char buf2[INET6_ADDRSTRLEN];
1309
1310 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1311 if (!zvrf)
1312 return -1;
1313
1314 zif = zvni->vxlan_if->info;
1315 if (!zif)
1316 return -1;
1317
1318 vxl = &zif->l2info.vxl;
1319
1320 mac = zvni_mac_lookup(zvni, macaddr);
1321 if (!mac) {
1322 mac = zvni_mac_add(zvni, macaddr);
1323 if (!mac) {
1324 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
1325 ifp->vrf_id,
1326 prefix_mac2str(macaddr, buf, sizeof(buf)),
1327 ifp->name, ifp->ifindex, vxl->access_vlan);
1328 return -1;
1329 }
1330 }
1331
1332 /* Set "local" forwarding info. */
1333 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
1334 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
1335 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
1336 mac->fwd_info.local.ifindex = ifp->ifindex;
1337 mac->fwd_info.local.vid = vxl->access_vlan;
1338
1339 n = zvni_neigh_lookup(zvni, ip);
1340 if (!n) {
1341 n = zvni_neigh_add(zvni, ip, macaddr);
1342 if (!n) {
1343 zlog_err(
1344 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1345 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
1346 prefix_mac2str(macaddr, NULL,
1347 ETHER_ADDR_STRLEN),
1348 ifp->name, ifp->ifindex, zvni->vni);
1349 return -1;
1350 }
1351 }
1352
1353 /* Set "local" forwarding info. */
1354 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1355 memcpy(&n->emac, macaddr, ETH_ALEN);
1356 n->ifindex = ifp->ifindex;
1357
1358 /* We have a neigh associated to mac increment the refcnt*/
1359 mac->neigh_refcnt++;
1360
1361 if (IS_ZEBRA_DEBUG_VXLAN)
1362 zlog_debug(
1363 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP",
1364 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
1365 prefix_mac2str(macaddr, NULL, ETHER_ADDR_STRLEN),
1366 ipaddr2str(ip, buf2, sizeof(buf2)));
1367
1368 zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip, macaddr,
1369 ZEBRA_MAC_TYPE_GW);
1370
1371 return 0;
1372 }
1373
1374 /*
1375 * zvni_gw_macip_del_from_client
1376 */
1377 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
1378 struct ipaddr *ip)
1379 {
1380 struct zebra_vrf *zvrf = NULL;
1381 zebra_neigh_t *n = NULL;
1382 zebra_mac_t *mac = NULL;
1383 char buf2[INET6_ADDRSTRLEN];
1384
1385 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1386 if (!zvrf)
1387 return -1;
1388
1389 /* If the neigh entry is not present nothing to do*/
1390 n = zvni_neigh_lookup(zvni, ip);
1391 if (!n)
1392 return 0;
1393
1394 /* mac entry should be present */
1395 mac = zvni_mac_lookup(zvni, &n->emac);
1396 if (!mac)
1397 zlog_err("%u: MAC %s doesnt exsists for neigh %s on VNI %u",
1398 ifp->vrf_id,
1399 prefix_mac2str(&n->emac, NULL, ETHER_ADDR_STRLEN),
1400 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
1401
1402 /* If the entry is not local nothing to do*/
1403 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
1404 return -1;
1405
1406 if (IS_ZEBRA_DEBUG_VXLAN)
1407 zlog_debug(
1408 "%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1409 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
1410 prefix_mac2str(&(n->emac), NULL, ETHER_ADDR_STRLEN),
1411 ipaddr2str(ip, buf2, sizeof(buf2)));
1412
1413 /* Remove neighbor from BGP. */
1414 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
1415 ZEBRA_MAC_TYPE_GW);
1416
1417 /* Delete this neighbor entry. */
1418 zvni_neigh_del(zvni, n);
1419
1420 /* see if the mac needs to be deleted as well*/
1421 zvni_deref_ip2mac(zvni, mac, 0);
1422
1423 return 0;
1424 }
1425
1426 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
1427 void *zvrf)
1428 {
1429 zebra_vni_t *zvni = NULL;
1430 struct zebra_if *zif = NULL;
1431 struct zebra_l2info_vxlan zl2_info;
1432 struct interface *vlan_if = NULL;
1433 struct interface *vrr_if = NULL;
1434
1435 /* Add primary SVI MAC*/
1436 zvni = (zebra_vni_t *)backet->data;
1437 if (!zvni)
1438 return;
1439
1440 zif = zvni->vxlan_if->info;
1441 zl2_info = zif->l2info.vxl;
1442
1443 vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan,
1444 zif->brslave_info.br_if);
1445 if (!vlan_if)
1446 return;
1447
1448 /* Del primary MAC-IP */
1449 zvni_del_macip_for_intf(vlan_if, zvni);
1450
1451 /* Del VRR MAC-IP - if any*/
1452 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1453 if (vrr_if)
1454 zvni_del_macip_for_intf(vrr_if, zvni);
1455
1456 return;
1457 }
1458
1459 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
1460 void *zvrf)
1461 {
1462 zebra_vni_t *zvni = NULL;
1463 struct zebra_if *zif = NULL;
1464 struct zebra_l2info_vxlan zl2_info;
1465 struct interface *vlan_if = NULL;
1466 struct interface *vrr_if = NULL;
1467
1468 zvni = (zebra_vni_t *)backet->data;
1469 if (!zvni)
1470 return;
1471
1472 if (!advertise_gw_macip_enabled(zvrf, zvni))
1473 return;
1474
1475 zif = zvni->vxlan_if->info;
1476 zl2_info = zif->l2info.vxl;
1477
1478 vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan,
1479 zif->brslave_info.br_if);
1480 if (!vlan_if)
1481 return;
1482
1483 if (!advertise_gw_macip_enabled(zvrf, zvni))
1484 return;
1485
1486 /* Add primary SVI MAC-IP */
1487 zvni_add_macip_for_intf(vlan_if, zvni);
1488
1489 /* Add VRR MAC-IP - if any*/
1490 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1491 if (vrr_if)
1492 zvni_add_macip_for_intf(vrr_if, zvni);
1493
1494 return;
1495 }
1496
1497 /*
1498 * Make hash key for MAC.
1499 */
1500 static unsigned int mac_hash_keymake(void *p)
1501 {
1502 zebra_mac_t *pmac = p;
1503 const void *pnt = (void *)pmac->macaddr.octet;
1504
1505 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
1506 }
1507
1508 /*
1509 * Compare two MAC addresses.
1510 */
1511 static int mac_cmp(const void *p1, const void *p2)
1512 {
1513 const zebra_mac_t *pmac1 = p1;
1514 const zebra_mac_t *pmac2 = p2;
1515
1516 if (pmac1 == NULL && pmac2 == NULL)
1517 return 1;
1518
1519 if (pmac1 == NULL || pmac2 == NULL)
1520 return 0;
1521
1522 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet,
1523 ETH_ALEN)
1524 == 0);
1525 }
1526
1527 /*
1528 * Callback to allocate MAC hash entry.
1529 */
1530 static void *zvni_mac_alloc(void *p)
1531 {
1532 const zebra_mac_t *tmp_mac = p;
1533 zebra_mac_t *mac;
1534
1535 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
1536 *mac = *tmp_mac;
1537
1538 return ((void *)mac);
1539 }
1540
1541 /*
1542 * Add MAC entry.
1543 */
1544 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
1545 {
1546 zebra_mac_t tmp_mac;
1547 zebra_mac_t *mac = NULL;
1548
1549 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
1550 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
1551 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
1552 assert(mac);
1553
1554 mac->neigh_list = list_new();
1555 mac->neigh_list->cmp = (int (*)(void *, void *))neigh_cmp;
1556
1557 return mac;
1558 }
1559
1560 /*
1561 * Delete MAC entry.
1562 */
1563 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
1564 {
1565 zebra_mac_t *tmp_mac;
1566
1567 list_delete(mac->neigh_list);
1568
1569 /* Free the VNI hash entry and allocated memory. */
1570 tmp_mac = hash_release(zvni->mac_table, mac);
1571 if (tmp_mac)
1572 XFREE(MTYPE_MAC, tmp_mac);
1573
1574 return 0;
1575 }
1576
1577 /*
1578 * Free MAC hash entry (callback)
1579 */
1580 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
1581 {
1582 struct mac_walk_ctx *wctx = arg;
1583 zebra_mac_t *mac = backet->data;
1584 u_char sticky = 0;
1585
1586 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
1587 || ((wctx->flags & DEL_REMOTE_MAC)
1588 && (mac->flags & ZEBRA_MAC_REMOTE))
1589 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
1590 && (mac->flags & ZEBRA_MAC_REMOTE)
1591 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
1592 &wctx->r_vtep_ip))) {
1593 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
1594 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
1595 : 0;
1596 zvni_mac_send_del_to_client(
1597 wctx->zvrf, wctx->zvni->vni, &mac->macaddr,
1598 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
1599 }
1600
1601 if (wctx->uninstall)
1602 zvni_mac_uninstall(wctx->zvni, mac, 0);
1603
1604 return zvni_mac_del(wctx->zvni, mac);
1605 }
1606
1607 return 0;
1608 }
1609
1610 /*
1611 * Delete all MAC entries from specific VTEP for a particular VNI.
1612 */
1613 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
1614 struct in_addr *r_vtep_ip)
1615 {
1616 struct mac_walk_ctx wctx;
1617
1618 if (!zvni->mac_table)
1619 return;
1620
1621 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1622 wctx.zvni = zvni;
1623 wctx.uninstall = uninstall;
1624 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
1625 wctx.r_vtep_ip = *r_vtep_ip;
1626
1627 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
1628 void *))zvni_mac_del_hash_entry,
1629 &wctx);
1630 }
1631
1632 /*
1633 * Delete all MAC entries for this VNI.
1634 */
1635 static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
1636 int uninstall, int upd_client, u_int32_t flags)
1637 {
1638 struct mac_walk_ctx wctx;
1639
1640 if (!zvni->mac_table)
1641 return;
1642
1643 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1644 wctx.zvni = zvni;
1645 wctx.zvrf = zvrf;
1646 wctx.uninstall = uninstall;
1647 wctx.upd_client = upd_client;
1648 wctx.flags = flags;
1649
1650 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
1651 void *))zvni_mac_del_hash_entry,
1652 &wctx);
1653 }
1654
1655 /*
1656 * Look up MAC hash entry.
1657 */
1658 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
1659 {
1660 zebra_mac_t tmp;
1661 zebra_mac_t *pmac;
1662
1663 memset(&tmp, 0, sizeof(tmp));
1664 memcpy(&tmp.macaddr, mac, ETH_ALEN);
1665 pmac = hash_lookup(zvni->mac_table, &tmp);
1666
1667 return pmac;
1668 }
1669
1670 /*
1671 * Inform BGP about local MAC addition.
1672 */
1673 static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
1674 struct ethaddr *macaddr, u_char flags)
1675 {
1676 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, flags,
1677 ZEBRA_MACIP_ADD);
1678 }
1679
1680 /*
1681 * Inform BGP about local MAC deletion.
1682 */
1683 static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
1684 struct ethaddr *macaddr, u_char flags)
1685 {
1686 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, flags,
1687 ZEBRA_MACIP_DEL);
1688 }
1689
1690 /*
1691 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
1692 * notifications, to see if there are of interest.
1693 * TODO: Need to make this as a hash table.
1694 */
1695 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
1696 struct interface *br_if, vlanid_t vid)
1697 {
1698 struct zebra_vrf *zvrf;
1699 struct listnode *node;
1700 struct interface *tmp_if;
1701 struct zebra_if *zif;
1702 struct zebra_l2info_bridge *br;
1703 struct zebra_l2info_vxlan *vxl;
1704 u_char bridge_vlan_aware;
1705 zebra_vni_t *zvni;
1706
1707 /* Locate VRF corresponding to interface. */
1708 zvrf = vrf_info_lookup(ifp->vrf_id);
1709 assert(zvrf);
1710
1711 /* Determine if bridge is VLAN-aware or not */
1712 zif = br_if->info;
1713 assert(zif);
1714 br = &zif->l2info.br;
1715 bridge_vlan_aware = br->vlan_aware;
1716
1717 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1718 /* TODO: Optimize with a hash. */
1719 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1720 zif = tmp_if->info;
1721 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1722 continue;
1723 if (!if_is_operative(tmp_if))
1724 continue;
1725 vxl = &zif->l2info.vxl;
1726
1727 if (zif->brslave_info.br_if != br_if)
1728 continue;
1729
1730 if (!bridge_vlan_aware)
1731 break;
1732
1733 if (vxl->access_vlan == vid)
1734 break;
1735 }
1736
1737 if (!tmp_if)
1738 return NULL;
1739
1740 zvni = zvni_lookup(zvrf, vxl->vni);
1741 return zvni;
1742 }
1743
1744 /*
1745 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1746 * neighbor notifications, to see if they are of interest.
1747 * TODO: Need to make this as a hash table.
1748 */
1749 static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
1750 {
1751 struct zebra_vrf *zvrf;
1752 struct listnode *node;
1753 struct interface *tmp_if;
1754 struct zebra_if *zif;
1755 struct zebra_l2info_bridge *br;
1756 struct zebra_l2info_vxlan *vxl;
1757 u_char bridge_vlan_aware;
1758 vlanid_t vid = 0;
1759 zebra_vni_t *zvni;
1760
1761 /* Make sure the linked interface is a bridge. */
1762 if (!IS_ZEBRA_IF_BRIDGE(br_if))
1763 return NULL;
1764
1765 /* Locate VRF corresponding to interface. */
1766 zvrf = vrf_info_lookup(ifp->vrf_id);
1767 assert(zvrf);
1768
1769 /* Determine if bridge is VLAN-aware or not */
1770 zif = br_if->info;
1771 assert(zif);
1772 br = &zif->l2info.br;
1773 bridge_vlan_aware = br->vlan_aware;
1774 if (bridge_vlan_aware) {
1775 struct zebra_l2info_vlan *vl;
1776
1777 if (!IS_ZEBRA_IF_VLAN(ifp))
1778 return NULL;
1779
1780 zif = ifp->info;
1781 assert(zif);
1782 vl = &zif->l2info.vl;
1783 vid = vl->vid;
1784 }
1785
1786 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1787 /* TODO: Optimize with a hash. */
1788 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1789 zif = tmp_if->info;
1790 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1791 continue;
1792 if (!if_is_operative(tmp_if))
1793 continue;
1794 vxl = &zif->l2info.vxl;
1795
1796 if (zif->brslave_info.br_if != br_if)
1797 continue;
1798
1799 if (!bridge_vlan_aware)
1800 break;
1801
1802 if (vxl->access_vlan == vid)
1803 break;
1804 }
1805
1806 if (!tmp_if)
1807 return NULL;
1808
1809 zvni = zvni_lookup(zvrf, vxl->vni);
1810 return zvni;
1811 }
1812
1813 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
1814 * of two cases:
1815 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1816 * linked to the bridge
1817 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1818 * itself
1819 */
1820 static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
1821 struct interface *br_if)
1822 {
1823 struct listnode *node;
1824 struct interface *tmp_if;
1825 struct zebra_if *zif;
1826 struct zebra_l2info_bridge *br;
1827 struct zebra_l2info_vlan *vl;
1828 u_char bridge_vlan_aware;
1829
1830 /* Determine if bridge is VLAN-aware or not */
1831 zif = br_if->info;
1832 assert(zif);
1833 br = &zif->l2info.br;
1834 bridge_vlan_aware = br->vlan_aware;
1835
1836 /* Check oper status of the SVI. */
1837 if (!bridge_vlan_aware)
1838 return if_is_operative(br_if) ? br_if : NULL;
1839
1840 /* Identify corresponding VLAN interface. */
1841 /* TODO: Optimize with a hash. */
1842 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1843 /* Check oper status of the SVI. */
1844 if (!if_is_operative(tmp_if))
1845 continue;
1846 zif = tmp_if->info;
1847 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
1848 || zif->link != br_if)
1849 continue;
1850 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
1851
1852 if (vl->vid == vid)
1853 break;
1854 }
1855
1856 return tmp_if;
1857 }
1858
1859 /*
1860 * Install remote MAC into the kernel.
1861 */
1862 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
1863 {
1864 struct zebra_if *zif;
1865 struct zebra_l2info_vxlan *vxl;
1866 u_char sticky;
1867
1868 if (!(mac->flags & ZEBRA_MAC_REMOTE))
1869 return 0;
1870
1871 zif = zvni->vxlan_if->info;
1872 if (!zif)
1873 return -1;
1874 vxl = &zif->l2info.vxl;
1875
1876 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
1877
1878 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
1879 mac->fwd_info.r_vtep_ip, sticky);
1880 }
1881
1882 /*
1883 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1884 * moves to remote, we have to uninstall any existing local entry first.
1885 */
1886 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
1887 {
1888 struct zebra_if *zif;
1889 struct zebra_l2info_vxlan *vxl;
1890 struct in_addr vtep_ip = {.s_addr = 0};
1891 struct zebra_ns *zns;
1892 struct interface *ifp;
1893
1894 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
1895 return 0;
1896
1897 if (!zvni->vxlan_if) {
1898 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1899 zvni->vni, zvni);
1900 return -1;
1901 }
1902
1903 zif = zvni->vxlan_if->info;
1904 if (!zif)
1905 return -1;
1906 vxl = &zif->l2info.vxl;
1907
1908 if (local) {
1909 zns = zebra_ns_lookup(NS_DEFAULT);
1910 ifp = if_lookup_by_index_per_ns(zns,
1911 mac->fwd_info.local.ifindex);
1912 if (!ifp) // unexpected
1913 return -1;
1914 } else {
1915 ifp = zvni->vxlan_if;
1916 vtep_ip = mac->fwd_info.r_vtep_ip;
1917 }
1918
1919 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
1920 local);
1921 }
1922
1923 /*
1924 * Install MAC hash entry - called upon access VLAN change.
1925 */
1926 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
1927 {
1928 zebra_mac_t *mac;
1929 struct mac_walk_ctx *wctx = ctxt;
1930
1931 mac = (zebra_mac_t *)backet->data;
1932 if (!mac)
1933 return;
1934
1935 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
1936 zvni_mac_install(wctx->zvni, mac);
1937 }
1938
1939 /*
1940 * Decrement neighbor refcount of MAC; uninstall and free it if
1941 * appropriate.
1942 */
1943 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
1944 int uninstall)
1945 {
1946 if (mac->neigh_refcnt)
1947 mac->neigh_refcnt--;
1948
1949 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) || mac->neigh_refcnt > 0)
1950 return;
1951
1952 if (uninstall)
1953 zvni_mac_uninstall(zvni, mac, 0);
1954
1955 zvni_mac_del(zvni, mac);
1956 }
1957
1958 /*
1959 * Read and populate local MACs and neighbors corresponding to this VNI.
1960 */
1961 static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
1962 struct interface *ifp)
1963 {
1964 struct zebra_if *zif;
1965 struct interface *vlan_if;
1966 struct zebra_l2info_vxlan *vxl;
1967 struct interface *vrr_if;
1968
1969 zif = ifp->info;
1970 vxl = &zif->l2info.vxl;
1971
1972 if (IS_ZEBRA_DEBUG_VXLAN)
1973 zlog_debug(
1974 "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1975 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
1976 zif->brslave_info.bridge_ifindex);
1977
1978 macfdb_read_for_bridge(zvrf->zns, ifp, zif->brslave_info.br_if);
1979 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
1980 zif->brslave_info.br_if);
1981 if (vlan_if) {
1982
1983 if (advertise_gw_macip_enabled(zvrf, zvni)) {
1984 /* Add SVI MAC-IP */
1985 zvni_add_macip_for_intf(vlan_if, zvni);
1986
1987 /* Add VRR MAC-IP - if any*/
1988 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1989 if (vrr_if)
1990 zvni_add_macip_for_intf(vrr_if, zvni);
1991 }
1992
1993 neigh_read_for_vlan(zvrf->zns, vlan_if);
1994 }
1995 }
1996
1997 /*
1998 * Hash function for VNI.
1999 */
2000 static unsigned int vni_hash_keymake(void *p)
2001 {
2002 const zebra_vni_t *zvni = p;
2003
2004 return (jhash_1word(zvni->vni, 0));
2005 }
2006
2007 /*
2008 * Compare 2 VNI hash entries.
2009 */
2010 static int vni_hash_cmp(const void *p1, const void *p2)
2011 {
2012 const zebra_vni_t *zvni1 = p1;
2013 const zebra_vni_t *zvni2 = p2;
2014
2015 return (zvni1->vni == zvni2->vni);
2016 }
2017
2018 /*
2019 * Callback to allocate VNI hash entry.
2020 */
2021 static void *zvni_alloc(void *p)
2022 {
2023 const zebra_vni_t *tmp_vni = p;
2024 zebra_vni_t *zvni;
2025
2026 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
2027 zvni->vni = tmp_vni->vni;
2028 return ((void *)zvni);
2029 }
2030
2031 /*
2032 * Look up VNI hash entry.
2033 */
2034 static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni)
2035 {
2036 zebra_vni_t tmp_vni;
2037 zebra_vni_t *zvni = NULL;
2038
2039 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
2040 tmp_vni.vni = vni;
2041 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
2042
2043 return zvni;
2044 }
2045
2046 /*
2047 * Add VNI hash entry.
2048 */
2049 static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni)
2050 {
2051 zebra_vni_t tmp_zvni;
2052 zebra_vni_t *zvni = NULL;
2053
2054 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
2055 tmp_zvni.vni = vni;
2056 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
2057 assert(zvni);
2058
2059 /* Create hash table for MAC */
2060 zvni->mac_table =
2061 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
2062
2063 /* Create hash table for neighbors */
2064 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
2065 "Zebra VNI Neighbor Table");
2066
2067 return zvni;
2068 }
2069
2070 /*
2071 * Delete VNI hash entry.
2072 */
2073 static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
2074 {
2075 zebra_vni_t *tmp_zvni;
2076
2077 zvni->vxlan_if = NULL;
2078
2079 /* Free the neighbor hash table. */
2080 hash_free(zvni->neigh_table);
2081 zvni->neigh_table = NULL;
2082
2083 /* Free the MAC hash table. */
2084 hash_free(zvni->mac_table);
2085 zvni->mac_table = NULL;
2086
2087 /* Free the VNI hash entry and allocated memory. */
2088 tmp_zvni = hash_release(zvrf->vni_table, zvni);
2089 if (tmp_zvni)
2090 XFREE(MTYPE_ZVNI, tmp_zvni);
2091
2092 return 0;
2093 }
2094
2095 /*
2096 * Inform BGP about local VNI addition.
2097 */
2098 static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
2099 {
2100 struct zserv *client;
2101 struct stream *s;
2102
2103 client = zebra_find_client(ZEBRA_ROUTE_BGP);
2104 /* BGP may not be running. */
2105 if (!client)
2106 return 0;
2107
2108 s = client->obuf;
2109 stream_reset(s);
2110
2111 zserv_create_header(s, ZEBRA_VNI_ADD, zvrf_id(zvrf));
2112 stream_putl(s, zvni->vni);
2113 stream_put_in_addr(s, &zvni->local_vtep_ip);
2114
2115 /* Write packet size. */
2116 stream_putw_at(s, 0, stream_get_endp(s));
2117
2118 if (IS_ZEBRA_DEBUG_VXLAN)
2119 zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf),
2120 zvni->vni, inet_ntoa(zvni->local_vtep_ip),
2121 zebra_route_string(client->proto));
2122
2123 client->vniadd_cnt++;
2124 return zebra_server_send_message(client);
2125 }
2126
2127 /*
2128 * Inform BGP about local VNI deletion.
2129 */
2130 static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni)
2131 {
2132 struct zserv *client;
2133 struct stream *s;
2134
2135 client = zebra_find_client(ZEBRA_ROUTE_BGP);
2136 /* BGP may not be running. */
2137 if (!client)
2138 return 0;
2139
2140 s = client->obuf;
2141 stream_reset(s);
2142
2143 zserv_create_header(s, ZEBRA_VNI_DEL, zvrf_id(zvrf));
2144 stream_putl(s, vni);
2145
2146 /* Write packet size. */
2147 stream_putw_at(s, 0, stream_get_endp(s));
2148
2149 if (IS_ZEBRA_DEBUG_VXLAN)
2150 zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf), vni,
2151 zebra_route_string(client->proto));
2152
2153 client->vnidel_cnt++;
2154 return zebra_server_send_message(client);
2155 }
2156
2157 /*
2158 * Build the VNI hash table by going over the VxLAN interfaces. This
2159 * is called when EVPN (advertise-all-vni) is enabled.
2160 */
2161 static void zvni_build_hash_table(struct zebra_vrf *zvrf)
2162 {
2163 struct listnode *node;
2164 struct interface *ifp;
2165
2166 /* Walk VxLAN interfaces and create VNI hash. */
2167 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, ifp)) {
2168 struct zebra_if *zif;
2169 struct zebra_l2info_vxlan *vxl;
2170 zebra_vni_t *zvni;
2171 vni_t vni;
2172
2173 zif = ifp->info;
2174 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2175 continue;
2176 vxl = &zif->l2info.vxl;
2177
2178 vni = vxl->vni;
2179
2180 if (IS_ZEBRA_DEBUG_VXLAN)
2181 zlog_debug(
2182 "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
2183 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni,
2184 inet_ntoa(vxl->vtep_ip));
2185
2186 /* VNI hash entry is not expected to exist. */
2187 zvni = zvni_lookup(zvrf, vni);
2188 if (zvni) {
2189 zlog_err(
2190 "VNI hash already present for VRF %d IF %s(%u) VNI %u",
2191 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
2192 continue;
2193 }
2194
2195 zvni = zvni_add(zvrf, vni);
2196 if (!zvni) {
2197 zlog_err(
2198 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
2199 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
2200 return;
2201 }
2202
2203 zvni->local_vtep_ip = vxl->vtep_ip;
2204 zvni->vxlan_if = ifp;
2205
2206 /* Inform BGP if interface is up and mapped to bridge. */
2207 if (if_is_operative(ifp) && zif->brslave_info.br_if)
2208 zvni_send_add_to_client(zvrf, zvni);
2209 }
2210 }
2211
2212 /*
2213 * See if remote VTEP matches with prefix.
2214 */
2215 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
2216 {
2217 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
2218 }
2219
2220 /*
2221 * Locate remote VTEP in VNI hash table.
2222 */
2223 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2224 {
2225 zebra_vtep_t *zvtep;
2226
2227 if (!zvni)
2228 return NULL;
2229
2230 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
2231 if (zvni_vtep_match(vtep_ip, zvtep))
2232 break;
2233 }
2234
2235 return zvtep;
2236 }
2237
2238 /*
2239 * Add remote VTEP to VNI hash table.
2240 */
2241 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2242 {
2243 zebra_vtep_t *zvtep;
2244
2245 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
2246 if (!zvtep) {
2247 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni->vni);
2248 return NULL;
2249 }
2250
2251 zvtep->vtep_ip = *vtep_ip;
2252
2253 if (zvni->vteps)
2254 zvni->vteps->prev = zvtep;
2255 zvtep->next = zvni->vteps;
2256 zvni->vteps = zvtep;
2257
2258 return zvtep;
2259 }
2260
2261 /*
2262 * Remove remote VTEP from VNI hash table.
2263 */
2264 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
2265 {
2266 if (zvtep->next)
2267 zvtep->next->prev = zvtep->prev;
2268 if (zvtep->prev)
2269 zvtep->prev->next = zvtep->next;
2270 else
2271 zvni->vteps = zvtep->next;
2272
2273 zvtep->prev = zvtep->next = NULL;
2274 XFREE(MTYPE_ZVNI_VTEP, zvtep);
2275
2276 return 0;
2277 }
2278
2279 /*
2280 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2281 * uninstall from kernel if asked to.
2282 */
2283 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
2284 {
2285 zebra_vtep_t *zvtep, *zvtep_next;
2286
2287 if (!zvni)
2288 return -1;
2289
2290 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
2291 zvtep_next = zvtep->next;
2292 if (uninstall)
2293 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
2294 zvni_vtep_del(zvni, zvtep);
2295 }
2296
2297 return 0;
2298 }
2299
2300 /*
2301 * Install remote VTEP into the kernel.
2302 */
2303 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2304 {
2305 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2306 }
2307
2308 /*
2309 * Uninstall remote VTEP from the kernel.
2310 */
2311 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2312 {
2313 if (!zvni->vxlan_if) {
2314 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2315 zvni->vni, zvni);
2316 return -1;
2317 }
2318
2319 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2320 }
2321
2322 /*
2323 * Cleanup VNI/VTEP and update kernel
2324 */
2325 static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
2326 {
2327 zebra_vni_t *zvni;
2328
2329 zvni = (zebra_vni_t *)backet->data;
2330 if (!zvni)
2331 return;
2332
2333 /* Free up all neighbors and MACs, if any. */
2334 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
2335 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
2336
2337 /* Free up all remote VTEPs, if any. */
2338 zvni_vtep_del_all(zvni, 1);
2339
2340 /* Delete the hash entry. */
2341 zvni_del(zvrf, zvni);
2342 }
2343
2344
2345 /* Public functions */
2346
2347 /*
2348 * Display Neighbors for a VNI (VTY command handler).
2349 */
2350 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
2351 vni_t vni, u_char use_json)
2352 {
2353 zebra_vni_t *zvni;
2354 u_int32_t num_neigh;
2355 struct neigh_walk_ctx wctx;
2356 json_object *json = NULL;
2357
2358 if (!EVPN_ENABLED(zvrf))
2359 return;
2360 zvni = zvni_lookup(zvrf, vni);
2361 if (!zvni) {
2362 if (use_json)
2363 vty_out(vty, "{}\n");
2364 else
2365 vty_out(vty, "%% VNI %u does not exist\n", vni);
2366 return;
2367 }
2368 num_neigh = hashcount(zvni->neigh_table);
2369 if (!num_neigh)
2370 return;
2371
2372 if (use_json)
2373 json = json_object_new_object();
2374
2375 /* Since we have IPv6 addresses to deal with which can vary widely in
2376 * size, we try to be a bit more elegant in display by first computing
2377 * the maximum width.
2378 */
2379 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2380 wctx.zvni = zvni;
2381 wctx.vty = vty;
2382 wctx.addr_width = 15;
2383 wctx.json = json;
2384 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
2385
2386 if (!use_json) {
2387 vty_out(vty,
2388 "Number of ARPs (local and remote) known for this VNI: %u\n",
2389 num_neigh);
2390 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
2391 "Type", "MAC", "Remote VTEP");
2392 } else
2393 json_object_int_add(json, "numArpNd", num_neigh);
2394
2395 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
2396 if (use_json) {
2397 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2398 json, JSON_C_TO_STRING_PRETTY));
2399 json_object_free(json);
2400 }
2401 }
2402
2403 /*
2404 * Display neighbors across all VNIs (VTY command handler).
2405 */
2406 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2407 u_char use_json)
2408 {
2409 json_object *json = NULL;
2410 void *args[2];
2411
2412 if (!EVPN_ENABLED(zvrf))
2413 return;
2414
2415 if (use_json)
2416 json = json_object_new_object();
2417
2418 args[0] = vty;
2419 args[1] = json;
2420 hash_iterate(zvrf->vni_table,
2421 (void (*)(struct hash_backet *,
2422 void *))zvni_print_neigh_hash_all_vni,
2423 args);
2424 if (use_json) {
2425 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2426 json, JSON_C_TO_STRING_PRETTY));
2427 json_object_free(json);
2428 }
2429 }
2430
2431 /*
2432 * Display specific neighbor for a VNI, if present (VTY command handler).
2433 */
2434 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
2435 struct zebra_vrf *zvrf, vni_t vni,
2436 struct ipaddr *ip, u_char use_json)
2437 {
2438 zebra_vni_t *zvni;
2439 zebra_neigh_t *n;
2440 json_object *json = NULL;
2441
2442 if (!EVPN_ENABLED(zvrf))
2443 return;
2444 zvni = zvni_lookup(zvrf, vni);
2445 if (!zvni) {
2446 if (use_json)
2447 vty_out(vty, "{}\n");
2448 else
2449 vty_out(vty, "%% VNI %u does not exist\n", vni);
2450 return;
2451 }
2452 n = zvni_neigh_lookup(zvni, ip);
2453 if (!n) {
2454 if (!use_json)
2455 vty_out(vty,
2456 "%% Requested neighbor does not exist in VNI %u\n",
2457 vni);
2458 return;
2459 }
2460 if (use_json)
2461 json = json_object_new_object();
2462
2463 zvni_print_neigh(n, vty, json);
2464
2465 if (use_json) {
2466 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2467 json, JSON_C_TO_STRING_PRETTY));
2468 json_object_free(json);
2469 }
2470 }
2471
2472 /*
2473 * Display neighbors for a VNI from specific VTEP (VTY command handler).
2474 * By definition, these are remote neighbors.
2475 */
2476 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
2477 vni_t vni, struct in_addr vtep_ip,
2478 u_char use_json)
2479 {
2480 zebra_vni_t *zvni;
2481 u_int32_t num_neigh;
2482 struct neigh_walk_ctx wctx;
2483 json_object *json = NULL;
2484
2485 if (!EVPN_ENABLED(zvrf))
2486 return;
2487 zvni = zvni_lookup(zvrf, vni);
2488 if (!zvni) {
2489 if (use_json)
2490 vty_out(vty, "{}\n");
2491 else
2492 vty_out(vty, "%% VNI %u does not exist\n", vni);
2493 return;
2494 }
2495 num_neigh = hashcount(zvni->neigh_table);
2496 if (!num_neigh)
2497 return;
2498
2499 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2500 wctx.zvni = zvni;
2501 wctx.vty = vty;
2502 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
2503 wctx.r_vtep_ip = vtep_ip;
2504 wctx.json = json;
2505 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
2506
2507 if (use_json) {
2508 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2509 json, JSON_C_TO_STRING_PRETTY));
2510 json_object_free(json);
2511 }
2512 }
2513
2514 /*
2515 * Display MACs for a VNI (VTY command handler).
2516 */
2517 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
2518 vni_t vni, u_char use_json)
2519 {
2520 zebra_vni_t *zvni;
2521 u_int32_t num_macs;
2522 struct mac_walk_ctx wctx;
2523 json_object *json = NULL;
2524 json_object *json_mac = NULL;
2525
2526 if (!EVPN_ENABLED(zvrf))
2527 return;
2528 zvni = zvni_lookup(zvrf, vni);
2529 if (!zvni) {
2530 if (use_json)
2531 vty_out(vty, "{}\n");
2532 else
2533 vty_out(vty, "%% VNI %u does not exist\n", vni);
2534 return;
2535 }
2536 num_macs = hashcount(zvni->mac_table);
2537 if (!num_macs)
2538 return;
2539
2540 if (use_json) {
2541 json = json_object_new_object();
2542 json_mac = json_object_new_object();
2543 }
2544
2545 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2546 wctx.zvni = zvni;
2547 wctx.vty = vty;
2548 wctx.json = json_mac;
2549
2550 if (!use_json) {
2551 vty_out(vty,
2552 "Number of MACs (local and remote) known for this VNI: %u\n",
2553 num_macs);
2554 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
2555 "Intf/Remote VTEP", "VLAN");
2556 } else
2557 json_object_int_add(json, "numMacs", num_macs);
2558
2559 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
2560
2561 if (use_json) {
2562 json_object_object_add(json, "macs", json_mac);
2563 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2564 json, JSON_C_TO_STRING_PRETTY));
2565 json_object_free(json);
2566 }
2567 }
2568
2569 /*
2570 * Display MACs for all VNIs (VTY command handler).
2571 */
2572 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2573 u_char use_json)
2574 {
2575 struct mac_walk_ctx wctx;
2576 json_object *json = NULL;
2577
2578 if (!EVPN_ENABLED(zvrf)) {
2579 if (use_json)
2580 vty_out(vty, "{}\n");
2581 return;
2582 }
2583 if (use_json)
2584 json = json_object_new_object();
2585
2586 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2587 wctx.vty = vty;
2588 wctx.json = json;
2589 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
2590
2591 if (use_json) {
2592 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2593 json, JSON_C_TO_STRING_PRETTY));
2594 json_object_free(json);
2595 }
2596 }
2597
2598 /*
2599 * Display MACs for all VNIs (VTY command handler).
2600 */
2601 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
2602 struct zebra_vrf *zvrf,
2603 struct in_addr vtep_ip,
2604 u_char use_json)
2605 {
2606 struct mac_walk_ctx wctx;
2607 json_object *json = NULL;
2608
2609 if (!EVPN_ENABLED(zvrf))
2610 return;
2611
2612 if (use_json)
2613 json = json_object_new_object();
2614
2615 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2616 wctx.vty = vty;
2617 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
2618 wctx.r_vtep_ip = vtep_ip;
2619 wctx.json = json;
2620 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
2621
2622 if (use_json) {
2623 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2624 json, JSON_C_TO_STRING_PRETTY));
2625 json_object_free(json);
2626 }
2627 }
2628
2629 /*
2630 * Display specific MAC for a VNI, if present (VTY command handler).
2631 */
2632 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
2633 vni_t vni, struct ethaddr *macaddr)
2634 {
2635 zebra_vni_t *zvni;
2636 zebra_mac_t *mac;
2637
2638 if (!EVPN_ENABLED(zvrf))
2639 return;
2640 zvni = zvni_lookup(zvrf, vni);
2641 if (!zvni) {
2642 vty_out(vty, "%% VNI %u does not exist\n", vni);
2643 return;
2644 }
2645 mac = zvni_mac_lookup(zvni, macaddr);
2646 if (!mac) {
2647 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
2648 vni);
2649 return;
2650 }
2651
2652 zvni_print_mac(mac, vty);
2653 }
2654
2655 /*
2656 * Display MACs for a VNI from specific VTEP (VTY command handler).
2657 */
2658 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
2659 vni_t vni, struct in_addr vtep_ip,
2660 u_char use_json)
2661 {
2662 zebra_vni_t *zvni;
2663 u_int32_t num_macs;
2664 struct mac_walk_ctx wctx;
2665 json_object *json = NULL;
2666 json_object *json_mac = NULL;
2667
2668 if (!EVPN_ENABLED(zvrf))
2669 return;
2670 zvni = zvni_lookup(zvrf, vni);
2671 if (!zvni) {
2672 if (use_json)
2673 vty_out(vty, "{}\n");
2674 else
2675 vty_out(vty, "%% VNI %u does not exist\n", vni);
2676 return;
2677 }
2678 num_macs = hashcount(zvni->mac_table);
2679 if (!num_macs)
2680 return;
2681
2682 if (use_json) {
2683 json = json_object_new_object();
2684 json_mac = json_object_new_object();
2685 }
2686
2687 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2688 wctx.zvni = zvni;
2689 wctx.vty = vty;
2690 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
2691 wctx.r_vtep_ip = vtep_ip;
2692 wctx.json = json_mac;
2693 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
2694
2695 if (use_json) {
2696 json_object_int_add(json, "numMacs", wctx.count);
2697 if (wctx.count)
2698 json_object_object_add(json, "macs", json_mac);
2699 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2700 json, JSON_C_TO_STRING_PRETTY));
2701 json_object_free(json);
2702 }
2703 }
2704
2705
2706 /*
2707 * Display VNI information (VTY command handler).
2708 */
2709 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
2710 u_char use_json)
2711 {
2712 zebra_vni_t *zvni;
2713 json_object *json = NULL;
2714 void *args[2];
2715
2716 if (!EVPN_ENABLED(zvrf))
2717 return;
2718 zvni = zvni_lookup(zvrf, vni);
2719 if (!zvni) {
2720 if (use_json)
2721 vty_out(vty, "{}\n");
2722 else
2723 vty_out(vty, "%% VNI %u does not exist\n", vni);
2724 return;
2725 }
2726 if (use_json)
2727 json = json_object_new_object();
2728 args[0] = vty;
2729 args[1] = json;
2730 zvni_print(zvni, (void *)args);
2731 if (use_json) {
2732 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2733 json, JSON_C_TO_STRING_PRETTY));
2734 json_object_free(json);
2735 }
2736 }
2737
2738 /*
2739 * Display VNI hash table (VTY command handler).
2740 */
2741 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
2742 u_char use_json)
2743 {
2744 u_int32_t num_vnis;
2745 json_object *json = NULL;
2746 void *args[2];
2747
2748 if (!EVPN_ENABLED(zvrf))
2749 return;
2750 num_vnis = hashcount(zvrf->vni_table);
2751 if (!num_vnis) {
2752 if (use_json)
2753 vty_out(vty, "{}\n");
2754 return;
2755 }
2756 if (use_json) {
2757 json = json_object_new_object();
2758 json_object_string_add(json, "advertiseGatewayMacip",
2759 zvrf->advertise_gw_macip ? "Yes" : "No");
2760 json_object_int_add(json, "numVnis", num_vnis);
2761 } else {
2762 vty_out(vty, "Advertise gateway mac-ip: %s\n",
2763 zvrf->advertise_gw_macip ? "Yes" : "No");
2764 vty_out(vty, "Number of VNIs: %u\n", num_vnis);
2765 vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI",
2766 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
2767 "# Remote VTEPs");
2768 }
2769 args[0] = vty;
2770 args[1] = json;
2771
2772 hash_iterate(zvrf->vni_table,
2773 (void (*)(struct hash_backet *, void *))zvni_print_hash,
2774 args);
2775
2776 if (use_json) {
2777 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2778 json, JSON_C_TO_STRING_PRETTY));
2779 json_object_free(json);
2780 }
2781 }
2782
2783 /*
2784 * Handle neighbor delete (on a VLAN device / L3 interface) from the
2785 * kernel. This may result in either the neighbor getting deleted from
2786 * our database or being re-added to the kernel (if it is a valid
2787 * remote neighbor).
2788 */
2789 int zebra_vxlan_local_neigh_del(struct interface *ifp,
2790 struct interface *link_if, struct ipaddr *ip)
2791 {
2792 zebra_vni_t *zvni;
2793 zebra_neigh_t *n;
2794 struct zebra_vrf *zvrf;
2795 char buf[INET6_ADDRSTRLEN];
2796 char buf2[ETHER_ADDR_STRLEN];
2797 zebra_mac_t *zmac;
2798
2799 /* We are only interested in neighbors on an SVI that resides on top
2800 * of a VxLAN bridge.
2801 */
2802 zvni = zvni_map_svi(ifp, link_if);
2803 if (!zvni)
2804 return 0;
2805 if (!zvni->vxlan_if) {
2806 zlog_err(
2807 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
2808 zvni->vni, zvni);
2809 return -1;
2810 }
2811
2812 if (IS_ZEBRA_DEBUG_VXLAN)
2813 zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u",
2814 ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)),
2815 ifp->name, ifp->ifindex, zvni->vni);
2816
2817 /* If entry doesn't exist, nothing to do. */
2818 n = zvni_neigh_lookup(zvni, ip);
2819 if (!n)
2820 return 0;
2821
2822 zmac = zvni_mac_lookup(zvni, &n->emac);
2823 if (!zmac) {
2824 if (IS_ZEBRA_DEBUG_VXLAN)
2825 zlog_err(
2826 "%u: trying to del a neigh %s without a mac %s on VNI %u",
2827 ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)),
2828 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
2829 zvni->vni);
2830
2831 return 0;
2832 }
2833
2834 /* If it is a remote entry, the kernel has aged this out or someone has
2835 * deleted it, it needs to be re-installed as Quagga is the owner.
2836 */
2837 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2838 zvni_neigh_install(zvni, n);
2839 return 0;
2840 }
2841
2842 /* Locate VRF corresponding to interface. */
2843 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2844 assert(zvrf);
2845
2846 /* Remove neighbor from BGP. */
2847 if (IS_ZEBRA_NEIGH_ACTIVE(n))
2848 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
2849 0);
2850
2851 /* Delete this neighbor entry. */
2852 zvni_neigh_del(zvni, n);
2853
2854 /* see if the AUTO mac needs to be deleted */
2855 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
2856 || !listcount(zmac->neigh_list))
2857 zvni_mac_del(zvni, zmac);
2858
2859 return 0;
2860 }
2861
2862 /*
2863 * Handle neighbor add or update (on a VLAN device / L3 interface)
2864 * from the kernel.
2865 */
2866 int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
2867 struct interface *link_if,
2868 struct ipaddr *ip,
2869 struct ethaddr *macaddr, u_int16_t state,
2870 u_char ext_learned)
2871 {
2872 zebra_vni_t *zvni;
2873 zebra_neigh_t *n;
2874 struct zebra_vrf *zvrf;
2875 zebra_mac_t *zmac;
2876 char buf[ETHER_ADDR_STRLEN];
2877 char buf2[INET6_ADDRSTRLEN];
2878 int send_upd = 1, send_del = 0;
2879
2880 /* We are only interested in neighbors on an SVI that resides on top
2881 * of a VxLAN bridge.
2882 */
2883 zvni = zvni_map_svi(ifp, link_if);
2884 if (!zvni)
2885 return 0;
2886
2887 /* Locate VRF corresponding to interface. */
2888 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2889 assert(zvrf);
2890
2891 if (IS_ZEBRA_DEBUG_VXLAN)
2892 zlog_debug(
2893 "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
2894 "%s-> VNI %u",
2895 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
2896 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2897 ifp->ifindex, state, ext_learned ? "ext-learned " : "",
2898 zvni->vni);
2899
2900 /* create a dummy MAC if the MAC is not already present */
2901 zmac = zvni_mac_lookup(zvni, macaddr);
2902 if (!zmac) {
2903 if (IS_ZEBRA_DEBUG_VXLAN)
2904 zlog_debug(
2905 "%u: AUTO MAC %s created for neigh %s on VNI %u",
2906 ifp->vrf_id,
2907 prefix_mac2str(macaddr, buf, sizeof(buf)),
2908 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
2909
2910 zmac = zvni_mac_add(zvni, macaddr);
2911 if (!zmac) {
2912 zlog_warn("%u:Failed to add MAC %s VNI %u",
2913 zvrf_id(zvrf),
2914 prefix_mac2str(macaddr, buf, sizeof(buf)),
2915 zvni->vni);
2916 return -1;
2917 }
2918
2919 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
2920 memset(&zmac->flags, 0, sizeof(u_int32_t));
2921 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
2922 }
2923
2924 /* If same entry already exists, it might be a change or it might be a
2925 * move from remote to local.
2926 */
2927 n = zvni_neigh_lookup(zvni, ip);
2928 if (n) {
2929 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2930 if (memcmp(n->emac.octet, macaddr->octet,
2931 ETH_ALEN)
2932 == 0) {
2933 if (n->ifindex == ifp->ifindex)
2934 /* we're not interested in whatever has
2935 * changed. */
2936 return 0;
2937 /* client doesn't care about a purely local
2938 * change. */
2939 send_upd = 0;
2940 } else
2941 /* If the MAC has changed, issue a delete first
2942 * as this means a
2943 * different MACIP route.
2944 */
2945 send_del = 1;
2946 } else if (ext_learned)
2947 /* The neighbor is remote and that is the notification we got.
2948 */
2949 {
2950 /* TODO: Evaluate if we need to do anything here. */
2951 return 0;
2952 } else
2953 /* Neighbor has moved from remote to local. */
2954 {
2955 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2956 n->r_vtep_ip.s_addr = 0;
2957 }
2958 } else {
2959 n = zvni_neigh_add(zvni, ip, macaddr);
2960 if (!n) {
2961 zlog_err(
2962 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2963 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
2964 prefix_mac2str(macaddr, buf, sizeof(buf)),
2965 ifp->name, ifp->ifindex, zvni->vni);
2966 return -1;
2967 }
2968 }
2969
2970 /* Issue delete for older info, if needed. */
2971 if (send_del)
2972 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac,
2973 0);
2974
2975 /* Set "local" forwarding info. */
2976 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2977 n->ifindex = ifp->ifindex;
2978
2979 /* Before we program this in BGP, we need to check if MAC is locally
2980 * learnt as well */
2981 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
2982 if (IS_ZEBRA_DEBUG_VXLAN)
2983 zlog_debug(
2984 "%u: Skipping neigh %s add to client as MAC %s is not local on VNI %u",
2985 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
2986 prefix_mac2str(macaddr, buf, sizeof(buf)),
2987 zvni->vni);
2988
2989 return 0;
2990 }
2991
2992 /* Inform BGP if required. */
2993 if (send_upd) {
2994 if (IS_ZEBRA_DEBUG_VXLAN)
2995 zlog_debug(
2996 "%u: neigh %s (MAC %s) is now ACTIVE on VNI %u",
2997 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
2998 prefix_mac2str(macaddr, buf, sizeof(buf)),
2999 zvni->vni);
3000
3001 ZEBRA_NEIGH_SET_ACTIVE(n);
3002 return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip,
3003 macaddr, 0);
3004 }
3005
3006 return 0;
3007 }
3008
3009 /*
3010 * Handle message from client to delete a remote MACIP for a VNI.
3011 */
3012 int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
3013 struct zebra_vrf *zvrf)
3014 {
3015 struct stream *s;
3016 vni_t vni;
3017 struct ethaddr macaddr;
3018 struct ipaddr ip;
3019 struct in_addr vtep_ip;
3020 zebra_vni_t *zvni;
3021 zebra_mac_t *mac;
3022 zebra_neigh_t *n;
3023 u_short l = 0, ipa_len;
3024 char buf[ETHER_ADDR_STRLEN];
3025 char buf1[INET6_ADDRSTRLEN];
3026
3027 s = client->ibuf;
3028
3029 while (l < length) {
3030 /* Obtain each remote MACIP and process. */
3031 /* Message contains VNI, followed by MAC followed by IP (if any)
3032 * followed by remote VTEP IP.
3033 */
3034 mac = NULL;
3035 n = NULL;
3036 memset(&ip, 0, sizeof(ip));
3037 vni = (vni_t)stream_getl(s);
3038 stream_get(&macaddr.octet, s, ETH_ALEN);
3039 ipa_len = stream_getl(s);
3040 if (ipa_len) {
3041 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
3042 : IPADDR_V6;
3043 stream_get(&ip.ip.addr, s, ipa_len);
3044 }
3045 l += 4 + ETH_ALEN + 4 + ipa_len;
3046 vtep_ip.s_addr = stream_get_ipv4(s);
3047 l += IPV4_MAX_BYTELEN;
3048
3049 if (IS_ZEBRA_DEBUG_VXLAN)
3050 zlog_debug(
3051 "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
3052 zvrf_id(zvrf),
3053 prefix_mac2str(&macaddr, buf, sizeof(buf)),
3054 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
3055 inet_ntoa(vtep_ip),
3056 zebra_route_string(client->proto));
3057
3058 /* Locate VNI hash entry - expected to exist. */
3059 zvni = zvni_lookup(zvrf, vni);
3060 if (!zvni) {
3061 if (IS_ZEBRA_DEBUG_VXLAN)
3062 zlog_debug(
3063 "Failed to locate VNI hash upon remote MACIP DEL, "
3064 "VRF %d VNI %u",
3065 zvrf_id(zvrf), vni);
3066 continue;
3067 }
3068 if (!zvni->vxlan_if) {
3069 zlog_err(
3070 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
3071 vni, zvni);
3072 continue;
3073 }
3074
3075 /* The remote VTEP specified is normally expected to exist, but
3076 * it is
3077 * possible that the peer may delete the VTEP before deleting
3078 * any MACs
3079 * referring to the VTEP, in which case the handler (see
3080 * remote_vtep_del)
3081 * would have already deleted the MACs.
3082 */
3083 if (!zvni_vtep_find(zvni, &vtep_ip))
3084 continue;
3085
3086 /* If the local VxLAN interface is not up (should be a transient
3087 * event), there's nothing more to do.
3088 */
3089 if (!if_is_operative(zvni->vxlan_if))
3090 continue;
3091
3092 mac = zvni_mac_lookup(zvni, &macaddr);
3093 if (ipa_len)
3094 n = zvni_neigh_lookup(zvni, &ip);
3095
3096 if (n && !mac) {
3097 zlog_err(
3098 "failed to locate MAC %s for neigh %s in VRF %u VNI %u",
3099 prefix_mac2str(&macaddr, buf, sizeof(buf)),
3100 ipaddr2str(&ip, buf1, sizeof(buf1)),
3101 zvrf_id(zvrf), vni);
3102 continue;
3103 }
3104
3105 /* If the remote mac or neighbor doesn't exist there is nothing
3106 * more
3107 * to do. Otherwise, uninstall the entry and then remove it.
3108 */
3109 if (!mac && !n)
3110 continue;
3111
3112 /* Uninstall remote neighbor or MAC. */
3113 if (n) {
3114 /* When the MAC changes for an IP, it is possible the
3115 * client may
3116 * update the new MAC before trying to delete the "old"
3117 * neighbor
3118 * (as these are two different MACIP routes). Do the
3119 * delete only
3120 * if the MAC matches.
3121 */
3122 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
3123 && (memcmp(n->emac.octet, macaddr.octet,
3124 ETH_ALEN)
3125 == 0)) {
3126 zvni_neigh_uninstall(zvni, n);
3127 zvni_neigh_del(zvni, n);
3128 zvni_deref_ip2mac(zvni, mac, 1);
3129 }
3130 } else {
3131 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3132 zvni_process_neigh_on_remote_mac_del(zvrf, zvni,
3133 mac);
3134
3135 if (!mac->neigh_refcnt) {
3136 zvni_mac_uninstall(zvni, mac, 0);
3137 zvni_mac_del(zvni, mac);
3138 } else
3139 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3140 }
3141 }
3142 }
3143
3144 return 0;
3145 }
3146
3147 /*
3148 * Handle message from client to add a remote MACIP for a VNI. This
3149 * could be just the add of a MAC address or the add of a neighbor
3150 * (IP+MAC).
3151 */
3152 int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
3153 struct zebra_vrf *zvrf)
3154 {
3155 struct stream *s;
3156 vni_t vni;
3157 struct ethaddr macaddr;
3158 struct ipaddr ip;
3159 struct in_addr vtep_ip;
3160 zebra_vni_t *zvni;
3161 zebra_vtep_t *zvtep;
3162 zebra_mac_t *mac, *old_mac;
3163 zebra_neigh_t *n;
3164 u_short l = 0, ipa_len;
3165 int update_mac = 0, update_neigh = 0;
3166 char buf[ETHER_ADDR_STRLEN];
3167 char buf1[INET6_ADDRSTRLEN];
3168 u_char sticky;
3169
3170 assert(EVPN_ENABLED(zvrf));
3171
3172 s = client->ibuf;
3173
3174 while (l < length) {
3175 /* Obtain each remote MACIP and process. */
3176 /* Message contains VNI, followed by MAC followed by IP (if any)
3177 * followed by remote VTEP IP.
3178 */
3179 update_mac = update_neigh = 0;
3180 mac = NULL;
3181 n = NULL;
3182 memset(&ip, 0, sizeof(ip));
3183 vni = (vni_t)stream_getl(s);
3184 stream_get(&macaddr.octet, s, ETH_ALEN);
3185 ipa_len = stream_getl(s);
3186 if (ipa_len) {
3187 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
3188 : IPADDR_V6;
3189 stream_get(&ip.ip.addr, s, ipa_len);
3190 }
3191 l += 4 + ETH_ALEN + 4 + ipa_len;
3192 vtep_ip.s_addr = stream_get_ipv4(s);
3193 l += IPV4_MAX_BYTELEN;
3194
3195 /* Get 'sticky' flag. */
3196 sticky = stream_getc(s);
3197 l++;
3198
3199 if (IS_ZEBRA_DEBUG_VXLAN)
3200 zlog_debug(
3201 "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
3202 zvrf_id(zvrf), sticky ? "sticky " : "",
3203 prefix_mac2str(&macaddr, buf, sizeof(buf)),
3204 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
3205 inet_ntoa(vtep_ip),
3206 zebra_route_string(client->proto));
3207
3208 /* Locate VNI hash entry - expected to exist. */
3209 zvni = zvni_lookup(zvrf, vni);
3210 if (!zvni) {
3211 zlog_err(
3212 "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
3213 zvrf_id(zvrf), vni);
3214 continue;
3215 }
3216 if (!zvni->vxlan_if) {
3217 zlog_err(
3218 "VNI %u hash %p doesn't have intf upon remote MACIP add",
3219 vni, zvni);
3220 continue;
3221 }
3222 /* If the local VxLAN interface is not up (should be a transient
3223 * event), there's nothing more to do.
3224 */
3225 if (!if_is_operative(zvni->vxlan_if))
3226 continue;
3227
3228 /* The remote VTEP specified should normally exist, but it is
3229 * possible
3230 * that when peering comes up, peer may advertise MACIP routes
3231 * before
3232 * advertising type-3 routes.
3233 */
3234 zvtep = zvni_vtep_find(zvni, &vtep_ip);
3235 if (!zvtep) {
3236 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
3237 zlog_err(
3238 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
3239 zvrf_id(zvrf), vni, zvni);
3240 continue;
3241 }
3242
3243 zvni_vtep_install(zvni, &vtep_ip);
3244 }
3245
3246 /* First, check if the remote MAC is unknown or has a change. If
3247 * so,
3248 * that needs to be updated first. Note that client could
3249 * install
3250 * MAC and MACIP separately or just install the latter.
3251 */
3252 mac = zvni_mac_lookup(zvni, &macaddr);
3253 if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
3254 || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
3255 != sticky
3256 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
3257 update_mac = 1;
3258
3259 if (update_mac) {
3260 if (!mac) {
3261 mac = zvni_mac_add(zvni, &macaddr);
3262 if (!mac) {
3263 zlog_warn(
3264 "%u:Failed to add MAC %s VNI %u Remote VTEP %s",
3265 zvrf_id(zvrf),
3266 prefix_mac2str(&macaddr, buf,
3267 sizeof(buf)),
3268 vni, inet_ntoa(vtep_ip));
3269 return -1;
3270 }
3271
3272 /* Is this MAC created for a MACIP? */
3273 if (ipa_len)
3274 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3275 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3276 /* Moving from local to remote, issue delete. */
3277 zvni_mac_uninstall(zvni, mac, 1);
3278 }
3279
3280 /* Set "auto" and "remote" forwarding info. */
3281 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3282 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
3283 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
3284 mac->fwd_info.r_vtep_ip = vtep_ip;
3285
3286 if (sticky)
3287 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3288 else
3289 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3290
3291 zvni_process_neigh_on_remote_mac_add(zvrf, zvni, mac);
3292
3293 /* Install the entry. */
3294 zvni_mac_install(zvni, mac);
3295 }
3296
3297 /* If there is no IP, continue - after clearing AUTO flag of
3298 * MAC. */
3299 if (!ipa_len) {
3300 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3301 continue;
3302 }
3303
3304 /* Check if the remote neighbor itself is unknown or has a
3305 * change.
3306 * If so, create or update and then install the entry.
3307 */
3308 n = zvni_neigh_lookup(zvni, &ip);
3309 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
3310 || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
3311 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
3312 update_neigh = 1;
3313
3314 if (update_neigh) {
3315 if (!n) {
3316 n = zvni_neigh_add(zvni, &ip, &macaddr);
3317 if (!n) {
3318 zlog_warn(
3319 "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
3320 zvrf_id(zvrf),
3321 ipaddr2str(&ip, buf1,
3322 sizeof(buf1)),
3323 prefix_mac2str(&macaddr, buf,
3324 sizeof(buf)),
3325 vni, inet_ntoa(vtep_ip));
3326 return -1;
3327 }
3328
3329 /* New neighbor referring to this MAC. */
3330 mac->neigh_refcnt++;
3331 } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
3332 != 0) {
3333 /* MAC change, update ref counts for old and new
3334 * MAC. */
3335 old_mac = zvni_mac_lookup(zvni, &n->emac);
3336 if (old_mac)
3337 zvni_deref_ip2mac(zvni, old_mac, 1);
3338 mac->neigh_refcnt++;
3339 memcpy(&n->emac, &macaddr, ETH_ALEN);
3340 }
3341
3342 /* Set "remote" forwarding info. */
3343 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3344 /* TODO: Handle MAC change. */
3345 n->r_vtep_ip = vtep_ip;
3346 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3347
3348 /* Install the entry. */
3349 zvni_neigh_install(zvni, n);
3350 }
3351 }
3352
3353 return 0;
3354 }
3355
3356 /*
3357 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
3358 * us, this must involve a multihoming scenario. Treat this as implicit delete
3359 * of any prior local MAC.
3360 */
3361 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
3362 struct interface *br_if,
3363 struct ethaddr *macaddr, vlanid_t vid)
3364 {
3365 struct zebra_if *zif;
3366 struct zebra_vrf *zvrf;
3367 struct zebra_l2info_vxlan *vxl;
3368 vni_t vni;
3369 zebra_vni_t *zvni;
3370 zebra_mac_t *mac;
3371 char buf[ETHER_ADDR_STRLEN];
3372 u_char sticky;
3373
3374 zif = ifp->info;
3375 assert(zif);
3376 vxl = &zif->l2info.vxl;
3377 vni = vxl->vni;
3378
3379 /* Locate VRF corresponding to interface. */
3380 zvrf = vrf_info_lookup(ifp->vrf_id);
3381 assert(zvrf);
3382
3383 /* If EVPN is not enabled, nothing to do. */
3384 if (!EVPN_ENABLED(zvrf))
3385 return 0;
3386
3387 /* Locate hash entry; it is expected to exist. */
3388 zvni = zvni_lookup(zvrf, vni);
3389 if (!zvni)
3390 return 0;
3391
3392 /* If entry doesn't exist, nothing to do. */
3393 mac = zvni_mac_lookup(zvni, macaddr);
3394 if (!mac)
3395 return 0;
3396
3397 /* Is it a local entry? */
3398 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
3399 return 0;
3400
3401 if (IS_ZEBRA_DEBUG_VXLAN)
3402 zlog_debug(
3403 "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
3404 ifp->vrf_id, prefix_mac2str(macaddr, buf, sizeof(buf)),
3405 ifp->name, ifp->ifindex, vni);
3406
3407 /* Remove MAC from BGP. */
3408 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
3409 zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr,
3410 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
3411
3412 /*
3413 * If there are no neigh associated with the mac delete the mac
3414 * else mark it as AUTO for forward reference
3415 */
3416 if (!listcount(mac->neigh_list)) {
3417 zvni_mac_del(zvni, mac);
3418 } else {
3419 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3420 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3421 }
3422
3423 return 0;
3424 }
3425
3426 /*
3427 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
3428 * This can happen because the remote MAC entries are also added as "dynamic",
3429 * so the kernel can ageout the entry.
3430 */
3431 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
3432 struct interface *br_if,
3433 struct ethaddr *macaddr, vlanid_t vid)
3434 {
3435 struct zebra_if *zif;
3436 struct zebra_vrf *zvrf;
3437 struct zebra_l2info_vxlan *vxl;
3438 vni_t vni;
3439 zebra_vni_t *zvni;
3440 zebra_mac_t *mac;
3441 char buf[ETHER_ADDR_STRLEN];
3442
3443 zif = ifp->info;
3444 assert(zif);
3445 vxl = &zif->l2info.vxl;
3446 vni = vxl->vni;
3447
3448 /* Locate VRF corresponding to interface. */
3449 zvrf = vrf_info_lookup(ifp->vrf_id);
3450 assert(zvrf);
3451
3452 /* If EVPN is not enabled, nothing to do. */
3453 if (!EVPN_ENABLED(zvrf))
3454 return 0;
3455
3456 /* Locate hash entry; it is expected to exist. */
3457 zvni = zvni_lookup(zvrf, vni);
3458 if (!zvni)
3459 return 0;
3460
3461 /* If entry doesn't exist, nothing to do. */
3462 mac = zvni_mac_lookup(zvni, macaddr);
3463 if (!mac)
3464 return 0;
3465
3466 /* Is it a remote entry? */
3467 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
3468 return 0;
3469
3470 if (IS_ZEBRA_DEBUG_VXLAN)
3471 zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
3472 ifp->vrf_id,
3473 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
3474 ifp->ifindex, vni);
3475
3476 zvni_mac_install(zvni, mac);
3477 return 0;
3478 }
3479
3480 /*
3481 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
3482 */
3483 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
3484 struct ethaddr *macaddr, vlanid_t vid)
3485 {
3486 zebra_vni_t *zvni;
3487 zebra_mac_t *mac;
3488 struct zebra_vrf *zvrf;
3489 char buf[ETHER_ADDR_STRLEN];
3490 u_char sticky;
3491
3492 /* We are interested in MACs only on ports or (port, VLAN) that
3493 * map to a VNI.
3494 */
3495 zvni = zvni_map_vlan(ifp, br_if, vid);
3496 if (!zvni)
3497 return 0;
3498 if (!zvni->vxlan_if) {
3499 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
3500 zvni->vni, zvni);
3501 return -1;
3502 }
3503
3504 if (IS_ZEBRA_DEBUG_VXLAN)
3505 zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
3506 ifp->vrf_id,
3507 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
3508 ifp->ifindex, vid, zvni->vni);
3509
3510 /* If entry doesn't exist, nothing to do. */
3511 mac = zvni_mac_lookup(zvni, macaddr);
3512 if (!mac)
3513 return 0;
3514
3515 /* Is it a local entry? */
3516 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
3517 return 0;
3518
3519 /* Locate VRF corresponding to interface. */
3520 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
3521 assert(zvrf);
3522
3523 /* Remove MAC from BGP. */
3524 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
3525 zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr,
3526 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
3527
3528 /* Update all the neigh entries associated with this mac */
3529 zvni_process_neigh_on_local_mac_del(zvrf, zvni, mac);
3530
3531 /*
3532 * If there are no neigh associated with the mac delete the mac
3533 * else mark it as AUTO for forward reference
3534 */
3535 if (!listcount(mac->neigh_list)) {
3536 zvni_mac_del(zvni, mac);
3537 } else {
3538 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3539 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3540 }
3541
3542 return 0;
3543 }
3544
3545 /*
3546 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
3547 */
3548 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
3549 struct interface *br_if,
3550 struct ethaddr *macaddr, vlanid_t vid,
3551 u_char sticky)
3552 {
3553 zebra_vni_t *zvni;
3554 zebra_mac_t *mac;
3555 struct zebra_vrf *zvrf;
3556 char buf[ETHER_ADDR_STRLEN];
3557 int add = 1;
3558 u_char mac_sticky;
3559
3560 /* We are interested in MACs only on ports or (port, VLAN) that
3561 * map to a VNI.
3562 */
3563 zvni = zvni_map_vlan(ifp, br_if, vid);
3564 if (!zvni) {
3565 if (IS_ZEBRA_DEBUG_VXLAN)
3566 zlog_debug(
3567 "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
3568 ifp->vrf_id, sticky ? "sticky " : "",
3569 prefix_mac2str(macaddr, buf, sizeof(buf)),
3570 ifp->name, ifp->ifindex, vid);
3571 return 0;
3572 }
3573
3574 if (!zvni->vxlan_if) {
3575 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
3576 zvni->vni, zvni);
3577 return -1;
3578 }
3579
3580 if (IS_ZEBRA_DEBUG_VXLAN)
3581 zlog_debug(
3582 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
3583 ifp->vrf_id, sticky ? "sticky " : "",
3584 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
3585 ifp->ifindex, vid, zvni->vni);
3586
3587 /* If same entry already exists, nothing to do. */
3588 mac = zvni_mac_lookup(zvni, macaddr);
3589 if (mac) {
3590 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3591 mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
3592 ? 1
3593 : 0;
3594
3595
3596 /*
3597 * return if nothing has changed.
3598 * inform bgp if sticky flag has changed
3599 * update locally and do not inform bgp if local
3600 * parameters like interface has changed
3601 */
3602 if (mac_sticky == sticky
3603 && mac->fwd_info.local.ifindex == ifp->ifindex
3604 && mac->fwd_info.local.vid == vid) {
3605 if (IS_ZEBRA_DEBUG_VXLAN)
3606 zlog_debug(
3607 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
3608 "entry exists and has not changed ",
3609 ifp->vrf_id,
3610 sticky ? "sticky " : "",
3611 prefix_mac2str(macaddr, buf,
3612 sizeof(buf)),
3613 ifp->name, ifp->ifindex, vid,
3614 zvni->vni);
3615 return 0;
3616 } else if (mac_sticky != sticky) {
3617 add = 1;
3618 } else {
3619 add = 0; /* This is an update of local
3620 interface. */
3621 }
3622 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3623 /*
3624 * If we have already learned the MAC as a remote sticky
3625 * MAC,
3626 * this is a operator error and we must log a warning
3627 */
3628 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
3629 zlog_warn(
3630 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
3631 prefix_mac2str(macaddr, buf,
3632 sizeof(buf)),
3633 inet_ntoa(mac->fwd_info.r_vtep_ip),
3634 zvni->vni);
3635 return 0;
3636 }
3637 }
3638 }
3639
3640 /* Locate VRF corresponding to interface. */
3641 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
3642 assert(zvrf);
3643
3644 if (!mac) {
3645 mac = zvni_mac_add(zvni, macaddr);
3646 if (!mac) {
3647 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
3648 ifp->vrf_id,
3649 prefix_mac2str(macaddr, buf, sizeof(buf)),
3650 ifp->name, ifp->ifindex, vid);
3651 return -1;
3652 }
3653 }
3654
3655 /* Set "local" forwarding info. */
3656 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
3657 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3658 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3659 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
3660 mac->fwd_info.local.ifindex = ifp->ifindex;
3661 mac->fwd_info.local.vid = vid;
3662
3663 if (sticky)
3664 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3665 else
3666 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3667
3668 /* Inform BGP if required. */
3669 if (add) {
3670 zvni_process_neigh_on_local_mac_add(zvrf, zvni, mac);
3671 return zvni_mac_send_add_to_client(zvrf, zvni->vni, macaddr,
3672 sticky);
3673 }
3674
3675 return 0;
3676 }
3677
3678 /*
3679 * Handle message from client to delete a remote VTEP for a VNI.
3680 */
3681 int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
3682 struct zebra_vrf *zvrf)
3683 {
3684 struct stream *s;
3685 u_short l = 0;
3686 vni_t vni;
3687 struct in_addr vtep_ip;
3688 zebra_vni_t *zvni;
3689 zebra_vtep_t *zvtep;
3690
3691 s = client->ibuf;
3692
3693 while (l < length) {
3694 /* Obtain each remote VTEP and process. */
3695 vni = (vni_t)stream_getl(s);
3696 l += 4;
3697 vtep_ip.s_addr = stream_get_ipv4(s);
3698 l += IPV4_MAX_BYTELEN;
3699
3700 if (IS_ZEBRA_DEBUG_VXLAN)
3701 zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s",
3702 zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
3703 zebra_route_string(client->proto));
3704
3705 /* Locate VNI hash entry - expected to exist. */
3706 zvni = zvni_lookup(zvrf, vni);
3707 if (!zvni) {
3708 if (IS_ZEBRA_DEBUG_VXLAN)
3709 zlog_debug(
3710 "Failed to locate VNI hash upon remote VTEP DEL, "
3711 "VRF %d VNI %u",
3712 zvrf_id(zvrf), vni);
3713 continue;
3714 }
3715
3716 /* If the remote VTEP does not exist, there's nothing more to
3717 * do.
3718 * Otherwise, uninstall any remote MACs pointing to this VTEP
3719 * and
3720 * then, the VTEP entry itself and remove it.
3721 */
3722 zvtep = zvni_vtep_find(zvni, &vtep_ip);
3723 if (!zvtep)
3724 continue;
3725
3726 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
3727 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
3728 zvni_vtep_uninstall(zvni, &vtep_ip);
3729 zvni_vtep_del(zvni, zvtep);
3730 }
3731
3732 return 0;
3733 }
3734
3735 /*
3736 * Handle message from client to add a remote VTEP for a VNI.
3737 */
3738 int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
3739 struct zebra_vrf *zvrf)
3740 {
3741 struct stream *s;
3742 u_short l = 0;
3743 vni_t vni;
3744 struct in_addr vtep_ip;
3745 zebra_vni_t *zvni;
3746
3747 assert(EVPN_ENABLED(zvrf));
3748
3749 s = client->ibuf;
3750
3751 while (l < length) {
3752 /* Obtain each remote VTEP and process. */
3753 vni = (vni_t)stream_getl(s);
3754 l += 4;
3755 vtep_ip.s_addr = stream_get_ipv4(s);
3756 l += IPV4_MAX_BYTELEN;
3757
3758 if (IS_ZEBRA_DEBUG_VXLAN)
3759 zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s",
3760 zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
3761 zebra_route_string(client->proto));
3762
3763 /* Locate VNI hash entry - expected to exist. */
3764 zvni = zvni_lookup(zvrf, vni);
3765 if (!zvni) {
3766 zlog_err(
3767 "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
3768 zvrf_id(zvrf), vni);
3769 continue;
3770 }
3771 if (!zvni->vxlan_if) {
3772 zlog_err(
3773 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
3774 zvni->vni, zvni);
3775 continue;
3776 }
3777
3778
3779 /* If the remote VTEP already exists, or the local VxLAN
3780 * interface is
3781 * not up (should be a transient event), there's nothing more
3782 * to do.
3783 * Otherwise, add and install the entry.
3784 */
3785 if (zvni_vtep_find(zvni, &vtep_ip))
3786 continue;
3787
3788 if (!if_is_operative(zvni->vxlan_if))
3789 continue;
3790
3791 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
3792 zlog_err(
3793 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
3794 zvrf_id(zvrf), vni, zvni);
3795 continue;
3796 }
3797
3798 zvni_vtep_install(zvni, &vtep_ip);
3799 }
3800
3801 return 0;
3802 }
3803
3804 /*
3805 * Add/Del gateway macip to evpn
3806 * g/w can be:
3807 * 1. SVI interface on a vlan aware bridge
3808 * 2. SVI interface on a vlan unaware bridge
3809 * 3. vrr interface (MACVLAN) associated to a SVI
3810 * We advertise macip routes for an interface if it is associated to VxLan vlan
3811 */
3812 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
3813 int add)
3814 {
3815 struct ipaddr ip;
3816 struct ethaddr macaddr;
3817 zebra_vni_t *zvni = NULL;
3818 struct zebra_vrf *zvrf = NULL;
3819
3820 memset(&ip, 0, sizeof(struct ipaddr));
3821 memset(&macaddr, 0, sizeof(struct ethaddr));
3822
3823 zvrf = vrf_info_lookup(ifp->vrf_id);
3824 if (!zvrf)
3825 return -1;
3826
3827 if (!EVPN_ENABLED(zvrf))
3828 return 0;
3829
3830 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
3831 struct interface *svi_if =
3832 NULL; /* SVI corresponding to the MACVLAN */
3833 struct zebra_if *ifp_zif =
3834 NULL; /* Zebra daemon specific info for MACVLAN */
3835 struct zebra_if *svi_if_zif =
3836 NULL; /* Zebra daemon specific info for SVI*/
3837
3838 ifp_zif = ifp->info;
3839 if (!ifp_zif)
3840 return -1;
3841
3842 svi_if = ifp_zif->link;
3843 if (!svi_if) {
3844 zlog_err("%u:MACVLAN %s(%u) without link information",
3845 ifp->vrf_id, ifp->name, ifp->ifindex);
3846 return -1;
3847 }
3848
3849 if (IS_ZEBRA_IF_VLAN(svi_if)) {
3850 svi_if_zif = svi_if->info;
3851 if (svi_if_zif)
3852 zvni = zvni_map_svi(svi_if, svi_if_zif->link);
3853 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
3854 zvni = zvni_map_svi(svi_if, svi_if);
3855 }
3856 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
3857 struct zebra_if *svi_if_zif =
3858 NULL; /* Zebra daemon specific info for SVI*/
3859
3860 svi_if_zif = ifp->info;
3861 if (svi_if_zif)
3862 zvni = zvni_map_svi(ifp, svi_if_zif->link);
3863 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
3864 zvni = zvni_map_svi(ifp, ifp);
3865 }
3866
3867 if (!zvni)
3868 return 0;
3869
3870 if (!zvni->vxlan_if) {
3871 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
3872 zvni->vni, zvni);
3873 return -1;
3874 }
3875
3876
3877 /* check if we are advertising gw macip routes */
3878 if (!advertise_gw_macip_enabled(zvrf, zvni))
3879 return 0;
3880
3881 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
3882
3883 if (p->family == AF_INET) {
3884 ip.ipa_type = IPADDR_V4;
3885 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
3886 sizeof(struct in_addr));
3887 } else if (p->family == AF_INET6) {
3888 ip.ipa_type = IPADDR_V6;
3889 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
3890 sizeof(struct in6_addr));
3891 }
3892
3893
3894 if (add)
3895 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
3896 else
3897 zvni_gw_macip_del(ifp, zvni, &ip);
3898
3899 return 0;
3900 }
3901
3902 /*
3903 * Handle SVI interface going down. At this point, this is a NOP since
3904 * the kernel deletes the neighbor entries on this SVI (if any).
3905 */
3906 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
3907 {
3908 return 0;
3909 }
3910
3911 /*
3912 * Handle SVI interface coming up. This may or may not be of interest,
3913 * but if this is a SVI on a VxLAN bridge, we need to install any remote
3914 * neighbor entries (which will be used for EVPN ARP suppression).
3915 */
3916 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
3917 {
3918 zebra_vni_t *zvni;
3919 struct neigh_walk_ctx n_wctx;
3920
3921 zvni = zvni_map_svi(ifp, link_if);
3922 if (!zvni)
3923 return 0;
3924
3925 if (!zvni->vxlan_if) {
3926 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
3927 zvni->vni, zvni);
3928 return -1;
3929 }
3930
3931 if (IS_ZEBRA_DEBUG_VXLAN)
3932 zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
3933 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
3934
3935 /* Install any remote neighbors for this VNI. */
3936 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
3937 n_wctx.zvni = zvni;
3938 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash, &n_wctx);
3939
3940 return 0;
3941 }
3942
3943 /*
3944 * Handle VxLAN interface down - update BGP if required, and do
3945 * internal cleanup.
3946 */
3947 int zebra_vxlan_if_down(struct interface *ifp)
3948 {
3949 struct zebra_if *zif;
3950 struct zebra_vrf *zvrf;
3951 zebra_vni_t *zvni;
3952 struct zebra_l2info_vxlan *vxl;
3953 vni_t vni;
3954
3955 /* Locate VRF corresponding to interface. */
3956 zvrf = vrf_info_lookup(ifp->vrf_id);
3957 assert(zvrf);
3958
3959 /* If EVPN is not enabled, nothing further to be done. */
3960 if (!EVPN_ENABLED(zvrf))
3961 return 0;
3962
3963 zif = ifp->info;
3964 assert(zif);
3965 vxl = &zif->l2info.vxl;
3966 vni = vxl->vni;
3967
3968 if (IS_ZEBRA_DEBUG_VXLAN)
3969 zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp->vrf_id,
3970 ifp->name, ifp->ifindex, vni);
3971
3972 /* Locate hash entry; it is expected to exist. */
3973 zvni = zvni_lookup(zvrf, vni);
3974 if (!zvni) {
3975 zlog_err(
3976 "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
3977 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3978 return -1;
3979 }
3980
3981 assert(zvni->vxlan_if == ifp);
3982
3983 /* Delete this VNI from BGP. */
3984 zvni_send_del_to_client(zvrf, zvni->vni);
3985
3986 /* Free up all neighbors and MACs, if any. */
3987 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
3988 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
3989
3990 /* Free up all remote VTEPs, if any. */
3991 zvni_vtep_del_all(zvni, 1);
3992
3993 return 0;
3994 }
3995
3996 /*
3997 * Handle VxLAN interface up - update BGP if required.
3998 */
3999 int zebra_vxlan_if_up(struct interface *ifp)
4000 {
4001 struct zebra_if *zif;
4002 struct zebra_vrf *zvrf;
4003 zebra_vni_t *zvni;
4004 struct zebra_l2info_vxlan *vxl;
4005 vni_t vni;
4006
4007 /* Locate VRF corresponding to interface. */
4008 zvrf = vrf_info_lookup(ifp->vrf_id);
4009 assert(zvrf);
4010
4011 /* If EVPN is not enabled, nothing further to be done. */
4012 if (!EVPN_ENABLED(zvrf))
4013 return 0;
4014
4015 zif = ifp->info;
4016 assert(zif);
4017 vxl = &zif->l2info.vxl;
4018 vni = vxl->vni;
4019
4020 if (IS_ZEBRA_DEBUG_VXLAN)
4021 zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp->vrf_id,
4022 ifp->name, ifp->ifindex, vni);
4023
4024 /* Locate hash entry; it is expected to exist. */
4025 zvni = zvni_lookup(zvrf, vni);
4026 if (!zvni) {
4027 zlog_err(
4028 "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
4029 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
4030 return -1;
4031 }
4032
4033 assert(zvni->vxlan_if == ifp);
4034
4035 /* If part of a bridge, inform BGP about this VNI. */
4036 /* Also, read and populate local MACs and neighbors. */
4037 if (zif->brslave_info.br_if) {
4038 zvni_send_add_to_client(zvrf, zvni);
4039 zvni_read_mac_neigh(zvrf, zvni, ifp);
4040 }
4041
4042 return 0;
4043 }
4044
4045 /*
4046 * Handle VxLAN interface delete. Locate and remove entry in hash table
4047 * and update BGP, if required.
4048 */
4049 int zebra_vxlan_if_del(struct interface *ifp)
4050 {
4051 struct zebra_if *zif;
4052 struct zebra_vrf *zvrf;
4053 zebra_vni_t *zvni;
4054 struct zebra_l2info_vxlan *vxl;
4055 vni_t vni;
4056
4057 /* Locate VRF corresponding to interface. */
4058 zvrf = vrf_info_lookup(ifp->vrf_id);
4059 assert(zvrf);
4060
4061 /* If EVPN is not enabled, nothing further to be done. */
4062 if (!EVPN_ENABLED(zvrf))
4063 return 0;
4064
4065 zif = ifp->info;
4066 assert(zif);
4067 vxl = &zif->l2info.vxl;
4068 vni = vxl->vni;
4069
4070 if (IS_ZEBRA_DEBUG_VXLAN)
4071 zlog_debug("%u:Del VNI %u intf %s(%u)", ifp->vrf_id, vni,
4072 ifp->name, ifp->ifindex);
4073
4074 /* Locate hash entry; it is expected to exist. */
4075 zvni = zvni_lookup(zvrf, vni);
4076 if (!zvni) {
4077 zlog_err(
4078 "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
4079 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
4080 return 0;
4081 }
4082
4083 /* Delete VNI from BGP. */
4084 zvni_send_del_to_client(zvrf, zvni->vni);
4085
4086 /* Free up all neighbors and MAC, if any. */
4087 zvni_neigh_del_all(zvrf, zvni, 0, 0, DEL_ALL_NEIGH);
4088 zvni_mac_del_all(zvrf, zvni, 0, 0, DEL_ALL_MAC);
4089
4090 /* Free up all remote VTEPs, if any. */
4091 zvni_vtep_del_all(zvni, 0);
4092
4093 /* Delete the hash entry. */
4094 if (zvni_del(zvrf, zvni)) {
4095 zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
4096 zvni, ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
4097 return -1;
4098 }
4099
4100 return 0;
4101 }
4102
4103 /*
4104 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
4105 */
4106 int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
4107 {
4108 struct zebra_if *zif;
4109 struct zebra_vrf *zvrf;
4110 zebra_vni_t *zvni;
4111 struct zebra_l2info_vxlan *vxl;
4112 vni_t vni;
4113
4114 /* Locate VRF corresponding to interface. */
4115 zvrf = vrf_info_lookup(ifp->vrf_id);
4116 assert(zvrf);
4117
4118 /* If EVPN is not enabled, nothing further to be done. */
4119 if (!EVPN_ENABLED(zvrf))
4120 return 0;
4121
4122 zif = ifp->info;
4123 assert(zif);
4124 vxl = &zif->l2info.vxl;
4125 vni = vxl->vni;
4126
4127 /* Update VNI hash. */
4128 zvni = zvni_lookup(zvrf, vni);
4129 if (!zvni) {
4130 zlog_err(
4131 "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
4132 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
4133 return -1;
4134 }
4135
4136 if (IS_ZEBRA_DEBUG_VXLAN)
4137 zlog_debug(
4138 "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
4139 "master %u chg 0x%x",
4140 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
4141 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
4142 zif->brslave_info.bridge_ifindex, chgflags);
4143
4144 /* Removed from bridge? */
4145 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
4146 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
4147 /* Delete from client, remove all remote VTEPs */
4148 /* Also, free up all MACs and neighbors. */
4149 zvni_send_del_to_client(zvrf, zvni->vni);
4150 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
4151 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
4152 zvni_vtep_del_all(zvni, 1);
4153 } else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
4154 /* Remove all existing local neighbors and MACs for this VNI
4155 * (including from BGP)
4156 */
4157 zvni_neigh_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
4158 zvni_mac_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
4159 }
4160
4161 zvni->local_vtep_ip = vxl->vtep_ip;
4162 zvni->vxlan_if = ifp;
4163
4164 /* Take further actions needed. Note that if we are here, there is a
4165 * change of interest.
4166 */
4167 /* If down or not mapped to a bridge, we're done. */
4168 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4169 return 0;
4170
4171 /* Inform BGP, if there is a change of interest. */
4172 if (chgflags
4173 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
4174 zvni_send_add_to_client(zvrf, zvni);
4175
4176 /* If there is a valid new master or a VLAN mapping change, read and
4177 * populate local MACs and neighbors. Also, reinstall any remote MACs
4178 * and neighbors for this VNI (based on new VLAN).
4179 */
4180 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
4181 zvni_read_mac_neigh(zvrf, zvni, ifp);
4182 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
4183 struct mac_walk_ctx m_wctx;
4184 struct neigh_walk_ctx n_wctx;
4185
4186 zvni_read_mac_neigh(zvrf, zvni, ifp);
4187
4188 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
4189 m_wctx.zvni = zvni;
4190 hash_iterate(zvni->mac_table, zvni_install_mac_hash, &m_wctx);
4191
4192 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
4193 n_wctx.zvni = zvni;
4194 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
4195 &n_wctx);
4196 }
4197
4198 return 0;
4199 }
4200
4201 /*
4202 * Handle VxLAN interface add.
4203 */
4204 int zebra_vxlan_if_add(struct interface *ifp)
4205 {
4206 struct zebra_if *zif;
4207 struct zebra_vrf *zvrf;
4208 zebra_vni_t *zvni;
4209 struct zebra_l2info_vxlan *vxl;
4210 vni_t vni;
4211
4212 /* Locate VRF corresponding to interface. */
4213 zvrf = vrf_info_lookup(ifp->vrf_id);
4214 assert(zvrf);
4215
4216 /* If EVPN is not enabled, nothing further to be done. */
4217 if (!EVPN_ENABLED(zvrf))
4218 return 0;
4219
4220 zif = ifp->info;
4221 assert(zif);
4222 vxl = &zif->l2info.vxl;
4223 vni = vxl->vni;
4224
4225 if (IS_ZEBRA_DEBUG_VXLAN)
4226 zlog_debug(
4227 "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
4228 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
4229 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
4230 zif->brslave_info.bridge_ifindex);
4231
4232 /* Create or update VNI hash. */
4233 zvni = zvni_lookup(zvrf, vni);
4234 if (!zvni) {
4235 zvni = zvni_add(zvrf, vni);
4236 if (!zvni) {
4237 zlog_err(
4238 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
4239 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
4240 return -1;
4241 }
4242 }
4243
4244 zvni->local_vtep_ip = vxl->vtep_ip;
4245 zvni->vxlan_if = ifp;
4246
4247 /* If down or not mapped to a bridge, we're done. */
4248 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4249 return 0;
4250
4251 /* Inform BGP */
4252 zvni_send_add_to_client(zvrf, zvni);
4253
4254 /* Read and populate local MACs and neighbors */
4255 zvni_read_mac_neigh(zvrf, zvni, ifp);
4256
4257 return 0;
4258 }
4259
4260 /*
4261 * Handle message from client to enable/disable advertisement of g/w macip
4262 * routes
4263 */
4264 int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
4265 u_short length, struct zebra_vrf *zvrf)
4266 {
4267 struct stream *s;
4268 int advertise;
4269 vni_t vni = 0;
4270 zebra_vni_t *zvni = NULL;
4271
4272 s = client->ibuf;
4273 advertise = stream_getc(s);
4274 vni = stream_get3(s);
4275
4276 if (!vni) {
4277 if (IS_ZEBRA_DEBUG_VXLAN)
4278 zlog_debug("%u:EVPN gateway macip Adv %s, currently %s",
4279 zvrf_id(zvrf),
4280 advertise ? "enabled" : "disabled",
4281 advertise_gw_macip_enabled(zvrf, NULL)
4282 ? "enabled"
4283 : "disabled");
4284
4285 if (zvrf->advertise_gw_macip == advertise)
4286 return 0;
4287
4288 zvrf->advertise_gw_macip = advertise;
4289
4290 if (advertise_gw_macip_enabled(zvrf, zvni))
4291 hash_iterate(zvrf->vni_table,
4292 zvni_gw_macip_add_for_vni_hash, zvrf);
4293 else
4294 hash_iterate(zvrf->vni_table,
4295 zvni_gw_macip_del_for_vni_hash, zvrf);
4296
4297 } else {
4298 struct zebra_if *zif = NULL;
4299 struct zebra_l2info_vxlan zl2_info;
4300 struct interface *vlan_if = NULL;
4301 struct interface *vrr_if = NULL;
4302
4303 if (IS_ZEBRA_DEBUG_VXLAN)
4304 zlog_debug(
4305 "%u:EVPN gateway macip Adv %s on VNI %d , currently %s",
4306 zvrf_id(zvrf),
4307 advertise ? "enabled" : "disabled", vni,
4308 advertise_gw_macip_enabled(zvrf, zvni)
4309 ? "enabled"
4310 : "disabled");
4311
4312 zvni = zvni_lookup(zvrf, vni);
4313 if (!zvni)
4314 return 0;
4315
4316 if (zvni->advertise_gw_macip == advertise)
4317 return 0;
4318
4319 zvni->advertise_gw_macip = advertise;
4320
4321 zif = zvni->vxlan_if->info;
4322 zl2_info = zif->l2info.vxl;
4323
4324 vlan_if = zvni_map_to_svi(zvrf, zl2_info.access_vlan,
4325 zif->brslave_info.br_if);
4326 if (!vlan_if)
4327 return 0;
4328
4329 if (advertise_gw_macip_enabled(zvrf, zvni)) {
4330 /* Add primary SVI MAC-IP */
4331 zvni_add_macip_for_intf(vlan_if, zvni);
4332
4333 /* Add VRR MAC-IP - if any*/
4334 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
4335 if (vrr_if)
4336 zvni_add_macip_for_intf(vrr_if, zvni);
4337 } else {
4338 /* Del primary MAC-IP */
4339 zvni_del_macip_for_intf(vlan_if, zvni);
4340
4341 /* Del VRR MAC-IP - if any*/
4342 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
4343 if (vrr_if)
4344 zvni_del_macip_for_intf(vrr_if, zvni);
4345 }
4346 }
4347
4348 return 0;
4349 }
4350
4351
4352 /*
4353 * Handle message from client to learn (or stop learning) about VNIs and MACs.
4354 * When enabled, the VNI hash table will be built and MAC FDB table read;
4355 * when disabled, the entries should be deleted and remote VTEPs and MACs
4356 * uninstalled from the kernel.
4357 */
4358 int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
4359 u_short length, struct zebra_vrf *zvrf)
4360 {
4361 struct stream *s;
4362 int advertise;
4363
4364 s = client->ibuf;
4365 advertise = stream_getc(s);
4366
4367 if (IS_ZEBRA_DEBUG_VXLAN)
4368 zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf),
4369 advertise ? "enabled" : "disabled",
4370 EVPN_ENABLED(zvrf) ? "enabled" : "disabled");
4371
4372 if (zvrf->advertise_all_vni == advertise)
4373 return 0;
4374
4375 zvrf->advertise_all_vni = advertise;
4376 if (EVPN_ENABLED(zvrf)) {
4377 /* Build VNI hash table and inform BGP. */
4378 zvni_build_hash_table(zvrf);
4379
4380 /* Add all SVI (L3 GW) MACs to BGP*/
4381 hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
4382 zvrf);
4383
4384 /* Read the MAC FDB */
4385 macfdb_read(zvrf->zns);
4386
4387 /* Read neighbors */
4388 neigh_read(zvrf->zns);
4389 } else {
4390 /* Cleanup VTEPs for all VNIs - uninstall from
4391 * kernel and free entries.
4392 */
4393 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
4394 }
4395
4396 return 0;
4397 }
4398
4399 /*
4400 * Allocate VNI hash table for this VRF and do other initialization.
4401 * NOTE: Currently supported only for default VRF.
4402 */
4403 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
4404 {
4405 if (!zvrf)
4406 return;
4407 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
4408 "Zebra VRF VNI Table");
4409 }
4410
4411 /* Close all VNI handling */
4412 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
4413 {
4414 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
4415 hash_free(zvrf->vni_table);
4416 }