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