]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
Merge pull request #1476 from qlyoung/null0-hack
[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, 0);
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
1215 zvrf = vrf_info_lookup(ifp->vrf_id);
1216 assert(zvrf);
1217
1218 FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
1219 zif = tmp_if->info;
1220 if (!zif)
1221 continue;
1222
1223 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
1224 continue;
1225
1226 if (zif->link == ifp)
1227 return tmp_if;
1228 }
1229
1230 return NULL;
1231 }
1232
1233 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1234 {
1235 struct listnode *cnode = NULL, *cnnode = NULL;
1236 struct connected *c = NULL;
1237 struct ethaddr macaddr;
1238
1239 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1240
1241 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1242 struct ipaddr ip;
1243
1244 memset(&ip, 0, sizeof(struct ipaddr));
1245 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1246 continue;
1247
1248 if (c->address->family == AF_INET) {
1249 ip.ipa_type = IPADDR_V4;
1250 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1251 sizeof(struct in_addr));
1252 } else if (c->address->family == AF_INET6) {
1253 ip.ipa_type = IPADDR_V6;
1254 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1255 sizeof(struct in6_addr));
1256 } else {
1257 continue;
1258 }
1259
1260 zvni_gw_macip_del(ifp, zvni, &ip);
1261 }
1262
1263 return 0;
1264 }
1265
1266 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1267 {
1268 struct listnode *cnode = NULL, *cnnode = NULL;
1269 struct connected *c = NULL;
1270 struct ethaddr macaddr;
1271
1272 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1273
1274 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1275 struct ipaddr ip;
1276
1277 memset(&ip, 0, sizeof(struct ipaddr));
1278 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1279 continue;
1280
1281 if (c->address->family == AF_INET) {
1282 ip.ipa_type = IPADDR_V4;
1283 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1284 sizeof(struct in_addr));
1285 } else if (c->address->family == AF_INET6) {
1286 ip.ipa_type = IPADDR_V6;
1287 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1288 sizeof(struct in6_addr));
1289 } else {
1290 continue;
1291 }
1292
1293 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
1294 }
1295
1296 return 0;
1297 }
1298
1299 /*
1300 * zvni_gw_macip_add_to_client
1301 */
1302 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
1303 struct ethaddr *macaddr, struct ipaddr *ip)
1304 {
1305 struct zebra_if *zif = NULL;
1306 struct zebra_l2info_vxlan *vxl = NULL;
1307 zebra_neigh_t *n = NULL;
1308 zebra_mac_t *mac = NULL;
1309 char buf[ETHER_ADDR_STRLEN];
1310 char buf2[INET6_ADDRSTRLEN];
1311
1312 zif = zvni->vxlan_if->info;
1313 if (!zif)
1314 return -1;
1315
1316 vxl = &zif->l2info.vxl;
1317
1318 mac = zvni_mac_lookup(zvni, macaddr);
1319 if (!mac) {
1320 mac = zvni_mac_add(zvni, macaddr);
1321 if (!mac) {
1322 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1323 prefix_mac2str(macaddr, buf, sizeof(buf)),
1324 ifp->name, ifp->ifindex, vxl->access_vlan);
1325 return -1;
1326 }
1327 }
1328
1329 /* Set "local" forwarding info. */
1330 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
1331 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
1332 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
1333 mac->fwd_info.local.ifindex = ifp->ifindex;
1334 mac->fwd_info.local.vid = vxl->access_vlan;
1335
1336 n = zvni_neigh_lookup(zvni, ip);
1337 if (!n) {
1338 n = zvni_neigh_add(zvni, ip, macaddr);
1339 if (!n) {
1340 zlog_err(
1341 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1342 ipaddr2str(ip, buf2, sizeof(buf2)),
1343 prefix_mac2str(macaddr, buf, sizeof(buf)),
1344 ifp->name, ifp->ifindex, zvni->vni);
1345 return -1;
1346 }
1347 }
1348
1349 /* Set "local" forwarding info. */
1350 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1351 memcpy(&n->emac, macaddr, ETH_ALEN);
1352 n->ifindex = ifp->ifindex;
1353
1354 if (IS_ZEBRA_DEBUG_VXLAN)
1355 zlog_debug(
1356 "SVI %s(%u) VNI %u, sending GW MAC %s IP %s add to BGP",
1357 ifp->name, ifp->ifindex, zvni->vni,
1358 prefix_mac2str(macaddr, buf, sizeof(buf)),
1359 ipaddr2str(ip, buf2, sizeof(buf2)));
1360
1361 zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
1362 ZEBRA_MAC_TYPE_GW);
1363
1364 return 0;
1365 }
1366
1367 /*
1368 * zvni_gw_macip_del_from_client
1369 */
1370 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
1371 struct ipaddr *ip)
1372 {
1373 zebra_neigh_t *n = NULL;
1374 zebra_mac_t *mac = NULL;
1375 char buf1[ETHER_ADDR_STRLEN];
1376 char buf2[INET6_ADDRSTRLEN];
1377
1378 /* If the neigh entry is not present nothing to do*/
1379 n = zvni_neigh_lookup(zvni, ip);
1380 if (!n)
1381 return 0;
1382
1383 /* mac entry should be present */
1384 mac = zvni_mac_lookup(zvni, &n->emac);
1385 if (!mac) {
1386 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1387 prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
1388 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
1389 return -1;
1390 }
1391
1392 /* If the entry is not local nothing to do*/
1393 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
1394 return -1;
1395
1396 if (IS_ZEBRA_DEBUG_VXLAN)
1397 zlog_debug(
1398 "SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
1399 ifp->name, ifp->ifindex, zvni->vni,
1400 prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
1401 ipaddr2str(ip, buf2, sizeof(buf2)));
1402
1403 /* Remove neighbor from BGP. */
1404 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
1405 ZEBRA_MAC_TYPE_GW);
1406
1407 /* Delete this neighbor entry. */
1408 zvni_neigh_del(zvni, n);
1409
1410 /* see if the mac needs to be deleted as well*/
1411 if (mac)
1412 zvni_deref_ip2mac(zvni, mac, 0);
1413
1414 return 0;
1415 }
1416
1417 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
1418 void *ctxt)
1419 {
1420 zebra_vni_t *zvni = NULL;
1421 struct zebra_if *zif = NULL;
1422 struct zebra_l2info_vxlan zl2_info;
1423 struct interface *vlan_if = NULL;
1424 struct interface *vrr_if = NULL;
1425 struct interface *ifp;
1426
1427 /* Add primary SVI MAC*/
1428 zvni = (zebra_vni_t *)backet->data;
1429 if (!zvni)
1430 return;
1431
1432 ifp = zvni->vxlan_if;
1433 if (!ifp)
1434 return;
1435 zif = ifp->info;
1436
1437 /* If down or not mapped to a bridge, we're done. */
1438 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
1439 return;
1440
1441 zl2_info = zif->l2info.vxl;
1442
1443 vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
1444 if (!vlan_if)
1445 return;
1446
1447 /* Del primary MAC-IP */
1448 zvni_del_macip_for_intf(vlan_if, zvni);
1449
1450 /* Del VRR MAC-IP - if any*/
1451 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1452 if (vrr_if)
1453 zvni_del_macip_for_intf(vrr_if, zvni);
1454
1455 return;
1456 }
1457
1458 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
1459 void *ctxt)
1460 {
1461 zebra_vni_t *zvni = NULL;
1462 struct zebra_if *zif = NULL;
1463 struct zebra_l2info_vxlan zl2_info;
1464 struct interface *vlan_if = NULL;
1465 struct interface *vrr_if = NULL;
1466 struct interface *ifp = NULL;
1467
1468 zvni = (zebra_vni_t *)backet->data;
1469 if (!zvni)
1470 return;
1471
1472 if (!advertise_gw_macip_enabled(zvni))
1473 return;
1474
1475 ifp = zvni->vxlan_if;
1476 if (!ifp)
1477 return;
1478 zif = ifp->info;
1479
1480 /* If down or not mapped to a bridge, we're done. */
1481 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
1482 return;
1483 zl2_info = zif->l2info.vxl;
1484
1485 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
1486 zif->brslave_info.br_if);
1487 if (!vlan_if)
1488 return;
1489
1490 /* Add primary SVI MAC-IP */
1491 zvni_add_macip_for_intf(vlan_if, zvni);
1492
1493 /* Add VRR MAC-IP - if any*/
1494 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1495 if (vrr_if)
1496 zvni_add_macip_for_intf(vrr_if, zvni);
1497
1498 return;
1499 }
1500
1501 /*
1502 * Make hash key for MAC.
1503 */
1504 static unsigned int mac_hash_keymake(void *p)
1505 {
1506 zebra_mac_t *pmac = p;
1507 const void *pnt = (void *)pmac->macaddr.octet;
1508
1509 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
1510 }
1511
1512 /*
1513 * Compare two MAC addresses.
1514 */
1515 static int mac_cmp(const void *p1, const void *p2)
1516 {
1517 const zebra_mac_t *pmac1 = p1;
1518 const zebra_mac_t *pmac2 = p2;
1519
1520 if (pmac1 == NULL && pmac2 == NULL)
1521 return 1;
1522
1523 if (pmac1 == NULL || pmac2 == NULL)
1524 return 0;
1525
1526 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet,
1527 ETH_ALEN)
1528 == 0);
1529 }
1530
1531 /*
1532 * Callback to allocate MAC hash entry.
1533 */
1534 static void *zvni_mac_alloc(void *p)
1535 {
1536 const zebra_mac_t *tmp_mac = p;
1537 zebra_mac_t *mac;
1538
1539 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
1540 *mac = *tmp_mac;
1541
1542 return ((void *)mac);
1543 }
1544
1545 /*
1546 * Add MAC entry.
1547 */
1548 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
1549 {
1550 zebra_mac_t tmp_mac;
1551 zebra_mac_t *mac = NULL;
1552
1553 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
1554 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
1555 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
1556 assert(mac);
1557
1558 mac->neigh_list = list_new();
1559 mac->neigh_list->cmp = (int (*)(void *, void *))neigh_cmp;
1560
1561 return mac;
1562 }
1563
1564 /*
1565 * Delete MAC entry.
1566 */
1567 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
1568 {
1569 zebra_mac_t *tmp_mac;
1570
1571 list_delete_and_null(&mac->neigh_list);
1572
1573 /* Free the VNI hash entry and allocated memory. */
1574 tmp_mac = hash_release(zvni->mac_table, mac);
1575 if (tmp_mac)
1576 XFREE(MTYPE_MAC, tmp_mac);
1577
1578 return 0;
1579 }
1580
1581 /*
1582 * Free MAC hash entry (callback)
1583 */
1584 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
1585 {
1586 struct mac_walk_ctx *wctx = arg;
1587 zebra_mac_t *mac = backet->data;
1588 u_char sticky = 0;
1589
1590 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
1591 || ((wctx->flags & DEL_REMOTE_MAC)
1592 && (mac->flags & ZEBRA_MAC_REMOTE))
1593 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
1594 && (mac->flags & ZEBRA_MAC_REMOTE)
1595 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
1596 &wctx->r_vtep_ip))) {
1597 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
1598 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
1599 : 0;
1600 zvni_mac_send_del_to_client(
1601 wctx->zvni->vni, &mac->macaddr,
1602 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
1603 }
1604
1605 if (wctx->uninstall)
1606 zvni_mac_uninstall(wctx->zvni, mac, 0);
1607
1608 return zvni_mac_del(wctx->zvni, mac);
1609 }
1610
1611 return 0;
1612 }
1613
1614 /*
1615 * Delete all MAC entries from specific VTEP for a particular VNI.
1616 */
1617 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
1618 struct in_addr *r_vtep_ip)
1619 {
1620 struct mac_walk_ctx wctx;
1621
1622 if (!zvni->mac_table)
1623 return;
1624
1625 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1626 wctx.zvni = zvni;
1627 wctx.uninstall = uninstall;
1628 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
1629 wctx.r_vtep_ip = *r_vtep_ip;
1630
1631 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
1632 void *))zvni_mac_del_hash_entry,
1633 &wctx);
1634 }
1635
1636 /*
1637 * Delete all MAC entries for this VNI.
1638 */
1639 static void zvni_mac_del_all(zebra_vni_t *zvni,
1640 int uninstall, int upd_client, u_int32_t flags)
1641 {
1642 struct mac_walk_ctx wctx;
1643
1644 if (!zvni->mac_table)
1645 return;
1646
1647 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1648 wctx.zvni = zvni;
1649 wctx.uninstall = uninstall;
1650 wctx.upd_client = upd_client;
1651 wctx.flags = flags;
1652
1653 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
1654 void *))zvni_mac_del_hash_entry,
1655 &wctx);
1656 }
1657
1658 /*
1659 * Look up MAC hash entry.
1660 */
1661 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
1662 {
1663 zebra_mac_t tmp;
1664 zebra_mac_t *pmac;
1665
1666 memset(&tmp, 0, sizeof(tmp));
1667 memcpy(&tmp.macaddr, mac, ETH_ALEN);
1668 pmac = hash_lookup(zvni->mac_table, &tmp);
1669
1670 return pmac;
1671 }
1672
1673 /*
1674 * Inform BGP about local MAC addition.
1675 */
1676 static int zvni_mac_send_add_to_client(vni_t vni,
1677 struct ethaddr *macaddr, u_char flags)
1678 {
1679 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
1680 ZEBRA_MACIP_ADD);
1681 }
1682
1683 /*
1684 * Inform BGP about local MAC deletion.
1685 */
1686 static int zvni_mac_send_del_to_client(vni_t vni,
1687 struct ethaddr *macaddr, u_char flags)
1688 {
1689 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
1690 ZEBRA_MACIP_DEL);
1691 }
1692
1693 /*
1694 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
1695 * notifications, to see if they are of interest.
1696 */
1697 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
1698 struct interface *br_if, vlanid_t vid)
1699 {
1700 struct zebra_ns *zns;
1701 struct route_node *rn;
1702 struct interface *tmp_if = NULL;
1703 struct zebra_if *zif;
1704 struct zebra_l2info_bridge *br;
1705 struct zebra_l2info_vxlan *vxl = NULL;
1706 u_char bridge_vlan_aware;
1707 zebra_vni_t *zvni;
1708 int found = 0;
1709
1710 /* Determine if bridge is VLAN-aware or not */
1711 zif = br_if->info;
1712 assert(zif);
1713 br = &zif->l2info.br;
1714 bridge_vlan_aware = br->vlan_aware;
1715
1716 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1717 /* TODO: Optimize with a hash. */
1718 zns = zebra_ns_lookup(NS_DEFAULT);
1719 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1720 tmp_if = (struct interface *)rn->info;
1721 if (!tmp_if)
1722 continue;
1723 zif = tmp_if->info;
1724 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1725 continue;
1726 if (!if_is_operative(tmp_if))
1727 continue;
1728 vxl = &zif->l2info.vxl;
1729
1730 if (zif->brslave_info.br_if != br_if)
1731 continue;
1732
1733 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
1734 found = 1;
1735 break;
1736 }
1737 }
1738
1739 if (!found)
1740 return NULL;
1741
1742 zvni = zvni_lookup(vxl->vni);
1743 return zvni;
1744 }
1745
1746 /*
1747 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1748 * neighbor notifications, to see if they are of interest.
1749 */
1750 static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
1751 {
1752 struct zebra_ns *zns;
1753 struct route_node *rn;
1754 struct interface *tmp_if = NULL;
1755 struct zebra_if *zif;
1756 struct zebra_l2info_bridge *br;
1757 struct zebra_l2info_vxlan *vxl = NULL;
1758 u_char bridge_vlan_aware;
1759 vlanid_t vid = 0;
1760 zebra_vni_t *zvni;
1761 int found = 0;
1762
1763 if (!br_if)
1764 return NULL;
1765
1766 /* Make sure the linked interface is a bridge. */
1767 if (!IS_ZEBRA_IF_BRIDGE(br_if))
1768 return NULL;
1769
1770 /* Determine if bridge is VLAN-aware or not */
1771 zif = br_if->info;
1772 assert(zif);
1773 br = &zif->l2info.br;
1774 bridge_vlan_aware = br->vlan_aware;
1775 if (bridge_vlan_aware) {
1776 struct zebra_l2info_vlan *vl;
1777
1778 if (!IS_ZEBRA_IF_VLAN(ifp))
1779 return NULL;
1780
1781 zif = ifp->info;
1782 assert(zif);
1783 vl = &zif->l2info.vl;
1784 vid = vl->vid;
1785 }
1786
1787 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1788 /* TODO: Optimize with a hash. */
1789 zns = zebra_ns_lookup(NS_DEFAULT);
1790 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1791 tmp_if = (struct interface *)rn->info;
1792 if (!tmp_if)
1793 continue;
1794 zif = tmp_if->info;
1795 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1796 continue;
1797 if (!if_is_operative(tmp_if))
1798 continue;
1799 vxl = &zif->l2info.vxl;
1800
1801 if (zif->brslave_info.br_if != br_if)
1802 continue;
1803
1804 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
1805 found = 1;
1806 break;
1807 }
1808 }
1809
1810 if (!found)
1811 return NULL;
1812
1813 zvni = zvni_lookup(vxl->vni);
1814 return zvni;
1815 }
1816
1817 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
1818 * of two cases:
1819 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1820 * linked to the bridge
1821 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1822 * itself
1823 */
1824 static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
1825 {
1826 struct zebra_ns *zns;
1827 struct route_node *rn;
1828 struct interface *tmp_if = NULL;
1829 struct zebra_if *zif;
1830 struct zebra_l2info_bridge *br;
1831 struct zebra_l2info_vlan *vl;
1832 u_char bridge_vlan_aware;
1833 int found = 0;
1834
1835 /* Defensive check, caller expected to invoke only with valid bridge. */
1836 if (!br_if)
1837 return NULL;
1838
1839 /* Determine if bridge is VLAN-aware or not */
1840 zif = br_if->info;
1841 assert(zif);
1842 br = &zif->l2info.br;
1843 bridge_vlan_aware = br->vlan_aware;
1844
1845 /* Check oper status of the SVI. */
1846 if (!bridge_vlan_aware)
1847 return if_is_operative(br_if) ? br_if : NULL;
1848
1849 /* Identify corresponding VLAN interface. */
1850 /* TODO: Optimize with a hash. */
1851 zns = zebra_ns_lookup(NS_DEFAULT);
1852 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
1853 tmp_if = (struct interface *)rn->info;
1854 /* Check oper status of the SVI. */
1855 if (!tmp_if || !if_is_operative(tmp_if))
1856 continue;
1857 zif = tmp_if->info;
1858 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
1859 || zif->link != br_if)
1860 continue;
1861 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
1862
1863 if (vl->vid == vid) {
1864 found = 1;
1865 break;
1866 }
1867 }
1868
1869 return found ? tmp_if : NULL;
1870 }
1871
1872 /*
1873 * Install remote MAC into the kernel.
1874 */
1875 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
1876 {
1877 struct zebra_if *zif;
1878 struct zebra_l2info_vxlan *vxl;
1879 u_char sticky;
1880
1881 if (!(mac->flags & ZEBRA_MAC_REMOTE))
1882 return 0;
1883
1884 zif = zvni->vxlan_if->info;
1885 if (!zif)
1886 return -1;
1887 vxl = &zif->l2info.vxl;
1888
1889 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
1890
1891 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
1892 mac->fwd_info.r_vtep_ip, sticky);
1893 }
1894
1895 /*
1896 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1897 * moves to remote, we have to uninstall any existing local entry first.
1898 */
1899 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
1900 {
1901 struct zebra_if *zif;
1902 struct zebra_l2info_vxlan *vxl;
1903 struct in_addr vtep_ip = {.s_addr = 0};
1904 struct zebra_ns *zns;
1905 struct interface *ifp;
1906
1907 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
1908 return 0;
1909
1910 if (!zvni->vxlan_if) {
1911 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1912 zvni->vni, zvni);
1913 return -1;
1914 }
1915
1916 zif = zvni->vxlan_if->info;
1917 if (!zif)
1918 return -1;
1919 vxl = &zif->l2info.vxl;
1920
1921 if (local) {
1922 zns = zebra_ns_lookup(NS_DEFAULT);
1923 ifp = if_lookup_by_index_per_ns(zns,
1924 mac->fwd_info.local.ifindex);
1925 if (!ifp) // unexpected
1926 return -1;
1927 } else {
1928 ifp = zvni->vxlan_if;
1929 vtep_ip = mac->fwd_info.r_vtep_ip;
1930 }
1931
1932 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
1933 local);
1934 }
1935
1936 /*
1937 * Install MAC hash entry - called upon access VLAN change.
1938 */
1939 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
1940 {
1941 zebra_mac_t *mac;
1942 struct mac_walk_ctx *wctx = ctxt;
1943
1944 mac = (zebra_mac_t *)backet->data;
1945 if (!mac)
1946 return;
1947
1948 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
1949 zvni_mac_install(wctx->zvni, mac);
1950 }
1951
1952 /*
1953 * Decrement neighbor refcount of MAC; uninstall and free it if
1954 * appropriate.
1955 */
1956 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
1957 int uninstall)
1958 {
1959 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)
1960 || !list_isempty(mac->neigh_list))
1961 return;
1962
1963 if (uninstall)
1964 zvni_mac_uninstall(zvni, mac, 0);
1965
1966 zvni_mac_del(zvni, mac);
1967 }
1968
1969 /*
1970 * Read and populate local MACs and neighbors corresponding to this VNI.
1971 */
1972 static void zvni_read_mac_neigh(zebra_vni_t *zvni,
1973 struct interface *ifp)
1974 {
1975 struct zebra_ns *zns;
1976 struct zebra_if *zif;
1977 struct interface *vlan_if;
1978 struct zebra_l2info_vxlan *vxl;
1979 struct interface *vrr_if;
1980
1981 zif = ifp->info;
1982 vxl = &zif->l2info.vxl;
1983 zns = zebra_ns_lookup(NS_DEFAULT);
1984
1985 if (IS_ZEBRA_DEBUG_VXLAN)
1986 zlog_debug(
1987 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1988 ifp->name, ifp->ifindex, zvni->vni,
1989 zif->brslave_info.bridge_ifindex);
1990
1991 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
1992 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
1993 if (vlan_if) {
1994
1995 if (advertise_gw_macip_enabled(zvni)) {
1996 /* Add SVI MAC-IP */
1997 zvni_add_macip_for_intf(vlan_if, zvni);
1998
1999 /* Add VRR MAC-IP - if any*/
2000 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2001 if (vrr_if)
2002 zvni_add_macip_for_intf(vrr_if, zvni);
2003 }
2004
2005 neigh_read_for_vlan(zns, vlan_if);
2006 }
2007 }
2008
2009 /*
2010 * Hash function for VNI.
2011 */
2012 static unsigned int vni_hash_keymake(void *p)
2013 {
2014 const zebra_vni_t *zvni = p;
2015
2016 return (jhash_1word(zvni->vni, 0));
2017 }
2018
2019 /*
2020 * Compare 2 VNI hash entries.
2021 */
2022 static int vni_hash_cmp(const void *p1, const void *p2)
2023 {
2024 const zebra_vni_t *zvni1 = p1;
2025 const zebra_vni_t *zvni2 = p2;
2026
2027 return (zvni1->vni == zvni2->vni);
2028 }
2029
2030 /*
2031 * Callback to allocate VNI hash entry.
2032 */
2033 static void *zvni_alloc(void *p)
2034 {
2035 const zebra_vni_t *tmp_vni = p;
2036 zebra_vni_t *zvni;
2037
2038 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
2039 zvni->vni = tmp_vni->vni;
2040 return ((void *)zvni);
2041 }
2042
2043 /*
2044 * Look up VNI hash entry.
2045 */
2046 static zebra_vni_t *zvni_lookup(vni_t vni)
2047 {
2048 struct zebra_vrf *zvrf;
2049 zebra_vni_t tmp_vni;
2050 zebra_vni_t *zvni = NULL;
2051
2052 zvrf = vrf_info_lookup(VRF_DEFAULT);
2053 assert(zvrf);
2054 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
2055 tmp_vni.vni = vni;
2056 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
2057
2058 return zvni;
2059 }
2060
2061 /*
2062 * Add VNI hash entry.
2063 */
2064 static zebra_vni_t *zvni_add(vni_t vni)
2065 {
2066 struct zebra_vrf *zvrf;
2067 zebra_vni_t tmp_zvni;
2068 zebra_vni_t *zvni = NULL;
2069
2070 zvrf = vrf_info_lookup(VRF_DEFAULT);
2071 assert(zvrf);
2072 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
2073 tmp_zvni.vni = vni;
2074 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
2075 assert(zvni);
2076
2077 /* Create hash table for MAC */
2078 zvni->mac_table =
2079 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
2080
2081 /* Create hash table for neighbors */
2082 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
2083 "Zebra VNI Neighbor Table");
2084
2085 return zvni;
2086 }
2087
2088 /*
2089 * Delete VNI hash entry.
2090 */
2091 static int zvni_del(zebra_vni_t *zvni)
2092 {
2093 struct zebra_vrf *zvrf;
2094 zebra_vni_t *tmp_zvni;
2095
2096 zvrf = vrf_info_lookup(VRF_DEFAULT);
2097 assert(zvrf);
2098
2099 zvni->vxlan_if = NULL;
2100
2101 /* Free the neighbor hash table. */
2102 hash_free(zvni->neigh_table);
2103 zvni->neigh_table = NULL;
2104
2105 /* Free the MAC hash table. */
2106 hash_free(zvni->mac_table);
2107 zvni->mac_table = NULL;
2108
2109 /* Free the VNI hash entry and allocated memory. */
2110 tmp_zvni = hash_release(zvrf->vni_table, zvni);
2111 if (tmp_zvni)
2112 XFREE(MTYPE_ZVNI, tmp_zvni);
2113
2114 return 0;
2115 }
2116
2117 /*
2118 * Inform BGP about local VNI addition.
2119 */
2120 static int zvni_send_add_to_client(zebra_vni_t *zvni)
2121 {
2122 struct zserv *client;
2123 struct stream *s;
2124
2125 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
2126 /* BGP may not be running. */
2127 if (!client)
2128 return 0;
2129
2130 s = client->obuf;
2131 stream_reset(s);
2132
2133 zserv_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
2134 stream_putl(s, zvni->vni);
2135 stream_put_in_addr(s, &zvni->local_vtep_ip);
2136
2137 /* Write packet size. */
2138 stream_putw_at(s, 0, stream_get_endp(s));
2139
2140 if (IS_ZEBRA_DEBUG_VXLAN)
2141 zlog_debug("Send VNI_ADD %u %s to %s",
2142 zvni->vni, inet_ntoa(zvni->local_vtep_ip),
2143 zebra_route_string(client->proto));
2144
2145 client->vniadd_cnt++;
2146 return zebra_server_send_message(client);
2147 }
2148
2149 /*
2150 * Inform BGP about local VNI deletion.
2151 */
2152 static int zvni_send_del_to_client(vni_t vni)
2153 {
2154 struct zserv *client;
2155 struct stream *s;
2156
2157 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
2158 /* BGP may not be running. */
2159 if (!client)
2160 return 0;
2161
2162 s = client->obuf;
2163 stream_reset(s);
2164
2165 zserv_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
2166 stream_putl(s, vni);
2167
2168 /* Write packet size. */
2169 stream_putw_at(s, 0, stream_get_endp(s));
2170
2171 if (IS_ZEBRA_DEBUG_VXLAN)
2172 zlog_debug("Send VNI_DEL %u to %s", vni,
2173 zebra_route_string(client->proto));
2174
2175 client->vnidel_cnt++;
2176 return zebra_server_send_message(client);
2177 }
2178
2179 /*
2180 * Build the VNI hash table by going over the VxLAN interfaces. This
2181 * is called when EVPN (advertise-all-vni) is enabled.
2182 */
2183 static void zvni_build_hash_table()
2184 {
2185 struct zebra_ns *zns;
2186 struct route_node *rn;
2187 struct interface *ifp;
2188
2189 /* Walk VxLAN interfaces and create VNI hash. */
2190 zns = zebra_ns_lookup(NS_DEFAULT);
2191 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2192 struct zebra_if *zif;
2193 struct zebra_l2info_vxlan *vxl;
2194 zebra_vni_t *zvni;
2195 vni_t vni;
2196
2197 ifp = (struct interface *)rn->info;
2198 if (!ifp)
2199 continue;
2200 zif = ifp->info;
2201 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2202 continue;
2203 vxl = &zif->l2info.vxl;
2204
2205 vni = vxl->vni;
2206
2207 if (IS_ZEBRA_DEBUG_VXLAN)
2208 zlog_debug(
2209 "Create VNI hash for intf %s(%u) VNI %u local IP %s",
2210 ifp->name, ifp->ifindex, vni,
2211 inet_ntoa(vxl->vtep_ip));
2212
2213 /* VNI hash entry is not expected to exist. */
2214 zvni = zvni_lookup(vni);
2215 if (zvni) {
2216 zlog_err(
2217 "VNI hash already present for IF %s(%u) VNI %u",
2218 ifp->name, ifp->ifindex, vni);
2219 continue;
2220 }
2221
2222 zvni = zvni_add(vni);
2223 if (!zvni) {
2224 zlog_err(
2225 "Failed to add VNI hash, IF %s(%u) VNI %u",
2226 ifp->name, ifp->ifindex, vni);
2227 return;
2228 }
2229
2230 zvni->local_vtep_ip = vxl->vtep_ip;
2231 zvni->vxlan_if = ifp;
2232
2233 /* Inform BGP if interface is up and mapped to bridge. */
2234 if (if_is_operative(ifp) && zif->brslave_info.br_if)
2235 zvni_send_add_to_client(zvni);
2236 }
2237 }
2238
2239 /*
2240 * See if remote VTEP matches with prefix.
2241 */
2242 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
2243 {
2244 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
2245 }
2246
2247 /*
2248 * Locate remote VTEP in VNI hash table.
2249 */
2250 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2251 {
2252 zebra_vtep_t *zvtep;
2253
2254 if (!zvni)
2255 return NULL;
2256
2257 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
2258 if (zvni_vtep_match(vtep_ip, zvtep))
2259 break;
2260 }
2261
2262 return zvtep;
2263 }
2264
2265 /*
2266 * Add remote VTEP to VNI hash table.
2267 */
2268 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2269 {
2270 zebra_vtep_t *zvtep;
2271
2272 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
2273 if (!zvtep) {
2274 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni->vni);
2275 return NULL;
2276 }
2277
2278 zvtep->vtep_ip = *vtep_ip;
2279
2280 if (zvni->vteps)
2281 zvni->vteps->prev = zvtep;
2282 zvtep->next = zvni->vteps;
2283 zvni->vteps = zvtep;
2284
2285 return zvtep;
2286 }
2287
2288 /*
2289 * Remove remote VTEP from VNI hash table.
2290 */
2291 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
2292 {
2293 if (zvtep->next)
2294 zvtep->next->prev = zvtep->prev;
2295 if (zvtep->prev)
2296 zvtep->prev->next = zvtep->next;
2297 else
2298 zvni->vteps = zvtep->next;
2299
2300 zvtep->prev = zvtep->next = NULL;
2301 XFREE(MTYPE_ZVNI_VTEP, zvtep);
2302
2303 return 0;
2304 }
2305
2306 /*
2307 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2308 * uninstall from kernel if asked to.
2309 */
2310 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
2311 {
2312 zebra_vtep_t *zvtep, *zvtep_next;
2313
2314 if (!zvni)
2315 return -1;
2316
2317 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
2318 zvtep_next = zvtep->next;
2319 if (uninstall)
2320 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
2321 zvni_vtep_del(zvni, zvtep);
2322 }
2323
2324 return 0;
2325 }
2326
2327 /*
2328 * Install remote VTEP into the kernel.
2329 */
2330 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2331 {
2332 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2333 }
2334
2335 /*
2336 * Uninstall remote VTEP from the kernel.
2337 */
2338 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2339 {
2340 if (!zvni->vxlan_if) {
2341 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2342 zvni->vni, zvni);
2343 return -1;
2344 }
2345
2346 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2347 }
2348
2349 /*
2350 * Cleanup VNI/VTEP and update kernel
2351 */
2352 static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
2353 {
2354 zebra_vni_t *zvni;
2355
2356 zvni = (zebra_vni_t *)backet->data;
2357 if (!zvni)
2358 return;
2359
2360 /* Free up all neighbors and MACs, if any. */
2361 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
2362 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
2363
2364 /* Free up all remote VTEPs, if any. */
2365 zvni_vtep_del_all(zvni, 1);
2366
2367 /* Delete the hash entry. */
2368 zvni_del(zvni);
2369 }
2370
2371
2372 /* Public functions */
2373
2374 /*
2375 * Display Neighbors for a VNI (VTY command handler).
2376 */
2377 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
2378 vni_t vni, u_char use_json)
2379 {
2380 zebra_vni_t *zvni;
2381 u_int32_t num_neigh;
2382 struct neigh_walk_ctx wctx;
2383 json_object *json = NULL;
2384
2385 if (!is_evpn_enabled())
2386 return;
2387 zvni = zvni_lookup(vni);
2388 if (!zvni) {
2389 if (use_json)
2390 vty_out(vty, "{}\n");
2391 else
2392 vty_out(vty, "%% VNI %u does not exist\n", vni);
2393 return;
2394 }
2395 num_neigh = hashcount(zvni->neigh_table);
2396 if (!num_neigh)
2397 return;
2398
2399 if (use_json)
2400 json = json_object_new_object();
2401
2402 /* Since we have IPv6 addresses to deal with which can vary widely in
2403 * size, we try to be a bit more elegant in display by first computing
2404 * the maximum width.
2405 */
2406 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2407 wctx.zvni = zvni;
2408 wctx.vty = vty;
2409 wctx.addr_width = 15;
2410 wctx.json = json;
2411 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
2412
2413 if (!use_json) {
2414 vty_out(vty,
2415 "Number of ARPs (local and remote) known for this VNI: %u\n",
2416 num_neigh);
2417 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
2418 "Type", "MAC", "Remote VTEP");
2419 } else
2420 json_object_int_add(json, "numArpNd", num_neigh);
2421
2422 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
2423 if (use_json) {
2424 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2425 json, JSON_C_TO_STRING_PRETTY));
2426 json_object_free(json);
2427 }
2428 }
2429
2430 /*
2431 * Display neighbors across all VNIs (VTY command handler).
2432 */
2433 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2434 u_char use_json)
2435 {
2436 json_object *json = NULL;
2437 void *args[2];
2438
2439 if (!is_evpn_enabled())
2440 return;
2441
2442 if (use_json)
2443 json = json_object_new_object();
2444
2445 args[0] = vty;
2446 args[1] = json;
2447 hash_iterate(zvrf->vni_table,
2448 (void (*)(struct hash_backet *,
2449 void *))zvni_print_neigh_hash_all_vni,
2450 args);
2451 if (use_json) {
2452 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2453 json, JSON_C_TO_STRING_PRETTY));
2454 json_object_free(json);
2455 }
2456 }
2457
2458 /*
2459 * Display specific neighbor for a VNI, if present (VTY command handler).
2460 */
2461 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
2462 struct zebra_vrf *zvrf, vni_t vni,
2463 struct ipaddr *ip, u_char use_json)
2464 {
2465 zebra_vni_t *zvni;
2466 zebra_neigh_t *n;
2467 json_object *json = NULL;
2468
2469 if (!is_evpn_enabled())
2470 return;
2471 zvni = zvni_lookup(vni);
2472 if (!zvni) {
2473 if (use_json)
2474 vty_out(vty, "{}\n");
2475 else
2476 vty_out(vty, "%% VNI %u does not exist\n", vni);
2477 return;
2478 }
2479 n = zvni_neigh_lookup(zvni, ip);
2480 if (!n) {
2481 if (!use_json)
2482 vty_out(vty,
2483 "%% Requested neighbor does not exist in VNI %u\n",
2484 vni);
2485 return;
2486 }
2487 if (use_json)
2488 json = json_object_new_object();
2489
2490 zvni_print_neigh(n, vty, json);
2491
2492 if (use_json) {
2493 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2494 json, JSON_C_TO_STRING_PRETTY));
2495 json_object_free(json);
2496 }
2497 }
2498
2499 /*
2500 * Display neighbors for a VNI from specific VTEP (VTY command handler).
2501 * By definition, these are remote neighbors.
2502 */
2503 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
2504 vni_t vni, struct in_addr vtep_ip,
2505 u_char use_json)
2506 {
2507 zebra_vni_t *zvni;
2508 u_int32_t num_neigh;
2509 struct neigh_walk_ctx wctx;
2510 json_object *json = NULL;
2511
2512 if (!is_evpn_enabled())
2513 return;
2514 zvni = zvni_lookup(vni);
2515 if (!zvni) {
2516 if (use_json)
2517 vty_out(vty, "{}\n");
2518 else
2519 vty_out(vty, "%% VNI %u does not exist\n", vni);
2520 return;
2521 }
2522 num_neigh = hashcount(zvni->neigh_table);
2523 if (!num_neigh)
2524 return;
2525
2526 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
2527 wctx.zvni = zvni;
2528 wctx.vty = vty;
2529 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
2530 wctx.r_vtep_ip = vtep_ip;
2531 wctx.json = json;
2532 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
2533
2534 if (use_json) {
2535 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2536 json, JSON_C_TO_STRING_PRETTY));
2537 json_object_free(json);
2538 }
2539 }
2540
2541 /*
2542 * Display MACs for a VNI (VTY command handler).
2543 */
2544 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
2545 vni_t vni, u_char use_json)
2546 {
2547 zebra_vni_t *zvni;
2548 u_int32_t num_macs;
2549 struct mac_walk_ctx wctx;
2550 json_object *json = NULL;
2551 json_object *json_mac = NULL;
2552
2553 if (!is_evpn_enabled())
2554 return;
2555 zvni = zvni_lookup(vni);
2556 if (!zvni) {
2557 if (use_json)
2558 vty_out(vty, "{}\n");
2559 else
2560 vty_out(vty, "%% VNI %u does not exist\n", vni);
2561 return;
2562 }
2563 num_macs = num_valid_macs(zvni);
2564 if (!num_macs)
2565 return;
2566
2567 if (use_json) {
2568 json = json_object_new_object();
2569 json_mac = json_object_new_object();
2570 }
2571
2572 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2573 wctx.zvni = zvni;
2574 wctx.vty = vty;
2575 wctx.json = json_mac;
2576
2577 if (!use_json) {
2578 vty_out(vty,
2579 "Number of MACs (local and remote) known for this VNI: %u\n",
2580 num_macs);
2581 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
2582 "Intf/Remote VTEP", "VLAN");
2583 } else
2584 json_object_int_add(json, "numMacs", num_macs);
2585
2586 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
2587
2588 if (use_json) {
2589 json_object_object_add(json, "macs", json_mac);
2590 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2591 json, JSON_C_TO_STRING_PRETTY));
2592 json_object_free(json);
2593 }
2594 }
2595
2596 /*
2597 * Display MACs for all VNIs (VTY command handler).
2598 */
2599 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
2600 u_char use_json)
2601 {
2602 struct mac_walk_ctx wctx;
2603 json_object *json = NULL;
2604
2605 if (!is_evpn_enabled()) {
2606 if (use_json)
2607 vty_out(vty, "{}\n");
2608 return;
2609 }
2610 if (use_json)
2611 json = json_object_new_object();
2612
2613 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2614 wctx.vty = vty;
2615 wctx.json = json;
2616 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
2617
2618 if (use_json) {
2619 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2620 json, JSON_C_TO_STRING_PRETTY));
2621 json_object_free(json);
2622 }
2623 }
2624
2625 /*
2626 * Display MACs for all VNIs (VTY command handler).
2627 */
2628 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
2629 struct zebra_vrf *zvrf,
2630 struct in_addr vtep_ip,
2631 u_char use_json)
2632 {
2633 struct mac_walk_ctx wctx;
2634 json_object *json = NULL;
2635
2636 if (!is_evpn_enabled())
2637 return;
2638
2639 if (use_json)
2640 json = json_object_new_object();
2641
2642 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2643 wctx.vty = vty;
2644 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
2645 wctx.r_vtep_ip = vtep_ip;
2646 wctx.json = json;
2647 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
2648
2649 if (use_json) {
2650 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2651 json, JSON_C_TO_STRING_PRETTY));
2652 json_object_free(json);
2653 }
2654 }
2655
2656 /*
2657 * Display specific MAC for a VNI, if present (VTY command handler).
2658 */
2659 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
2660 vni_t vni, struct ethaddr *macaddr)
2661 {
2662 zebra_vni_t *zvni;
2663 zebra_mac_t *mac;
2664
2665 if (!is_evpn_enabled())
2666 return;
2667 zvni = zvni_lookup(vni);
2668 if (!zvni) {
2669 vty_out(vty, "%% VNI %u does not exist\n", vni);
2670 return;
2671 }
2672 mac = zvni_mac_lookup(zvni, macaddr);
2673 if (!mac) {
2674 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
2675 vni);
2676 return;
2677 }
2678
2679 zvni_print_mac(mac, vty);
2680 }
2681
2682 /*
2683 * Display MACs for a VNI from specific VTEP (VTY command handler).
2684 */
2685 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
2686 vni_t vni, struct in_addr vtep_ip,
2687 u_char use_json)
2688 {
2689 zebra_vni_t *zvni;
2690 u_int32_t num_macs;
2691 struct mac_walk_ctx wctx;
2692 json_object *json = NULL;
2693 json_object *json_mac = NULL;
2694
2695 if (!is_evpn_enabled())
2696 return;
2697 zvni = zvni_lookup(vni);
2698 if (!zvni) {
2699 if (use_json)
2700 vty_out(vty, "{}\n");
2701 else
2702 vty_out(vty, "%% VNI %u does not exist\n", vni);
2703 return;
2704 }
2705 num_macs = num_valid_macs(zvni);
2706 if (!num_macs)
2707 return;
2708
2709 if (use_json) {
2710 json = json_object_new_object();
2711 json_mac = json_object_new_object();
2712 }
2713
2714 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2715 wctx.zvni = zvni;
2716 wctx.vty = vty;
2717 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
2718 wctx.r_vtep_ip = vtep_ip;
2719 wctx.json = json_mac;
2720 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
2721
2722 if (use_json) {
2723 json_object_int_add(json, "numMacs", wctx.count);
2724 if (wctx.count)
2725 json_object_object_add(json, "macs", json_mac);
2726 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2727 json, JSON_C_TO_STRING_PRETTY));
2728 json_object_free(json);
2729 }
2730 }
2731
2732
2733 /*
2734 * Display VNI information (VTY command handler).
2735 */
2736 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
2737 u_char use_json)
2738 {
2739 zebra_vni_t *zvni;
2740 json_object *json = NULL;
2741 void *args[2];
2742
2743 if (!is_evpn_enabled())
2744 return;
2745 zvni = zvni_lookup(vni);
2746 if (!zvni) {
2747 if (use_json)
2748 vty_out(vty, "{}\n");
2749 else
2750 vty_out(vty, "%% VNI %u does not exist\n", vni);
2751 return;
2752 }
2753 if (use_json)
2754 json = json_object_new_object();
2755 args[0] = vty;
2756 args[1] = json;
2757 zvni_print(zvni, (void *)args);
2758 if (use_json) {
2759 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2760 json, JSON_C_TO_STRING_PRETTY));
2761 json_object_free(json);
2762 }
2763 }
2764
2765 /*
2766 * Display VNI hash table (VTY command handler).
2767 */
2768 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
2769 u_char use_json)
2770 {
2771 u_int32_t num_vnis;
2772 json_object *json = NULL;
2773 void *args[2];
2774
2775 if (!is_evpn_enabled())
2776 return;
2777 num_vnis = hashcount(zvrf->vni_table);
2778 if (!num_vnis) {
2779 if (use_json)
2780 vty_out(vty, "{}\n");
2781 return;
2782 }
2783 if (use_json) {
2784 json = json_object_new_object();
2785 json_object_string_add(json, "advertiseGatewayMacip",
2786 zvrf->advertise_gw_macip ? "Yes" : "No");
2787 json_object_int_add(json, "numVnis", num_vnis);
2788 } else {
2789 vty_out(vty, "Advertise gateway mac-ip: %s\n",
2790 zvrf->advertise_gw_macip ? "Yes" : "No");
2791 vty_out(vty, "Number of VNIs: %u\n", num_vnis);
2792 vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI",
2793 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
2794 "# Remote VTEPs");
2795 }
2796 args[0] = vty;
2797 args[1] = json;
2798
2799 hash_iterate(zvrf->vni_table,
2800 (void (*)(struct hash_backet *, void *))zvni_print_hash,
2801 args);
2802
2803 if (use_json) {
2804 vty_out(vty, "%s\n", json_object_to_json_string_ext(
2805 json, JSON_C_TO_STRING_PRETTY));
2806 json_object_free(json);
2807 }
2808 }
2809
2810 /*
2811 * Handle neighbor delete (on a VLAN device / L3 interface) from the
2812 * kernel. This may result in either the neighbor getting deleted from
2813 * our database or being re-added to the kernel (if it is a valid
2814 * remote neighbor).
2815 */
2816 int zebra_vxlan_local_neigh_del(struct interface *ifp,
2817 struct interface *link_if, struct ipaddr *ip)
2818 {
2819 zebra_vni_t *zvni;
2820 zebra_neigh_t *n;
2821 char buf[INET6_ADDRSTRLEN];
2822 char buf2[ETHER_ADDR_STRLEN];
2823 zebra_mac_t *zmac;
2824
2825 /* We are only interested in neighbors on an SVI that resides on top
2826 * of a VxLAN bridge.
2827 */
2828 zvni = zvni_map_svi(ifp, link_if);
2829 if (!zvni)
2830 return 0;
2831 if (!zvni->vxlan_if) {
2832 zlog_err(
2833 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
2834 zvni->vni, zvni);
2835 return -1;
2836 }
2837
2838 if (IS_ZEBRA_DEBUG_VXLAN)
2839 zlog_debug("Del neighbor %s intf %s(%u) -> VNI %u",
2840 ipaddr2str(ip, buf, sizeof(buf)),
2841 ifp->name, ifp->ifindex, zvni->vni);
2842
2843 /* If entry doesn't exist, nothing to do. */
2844 n = zvni_neigh_lookup(zvni, ip);
2845 if (!n)
2846 return 0;
2847
2848 zmac = zvni_mac_lookup(zvni, &n->emac);
2849 if (!zmac) {
2850 if (IS_ZEBRA_DEBUG_VXLAN)
2851 zlog_err(
2852 "Trying to del a neigh %s without a mac %s on VNI %u",
2853 ipaddr2str(ip, buf, sizeof(buf)),
2854 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
2855 zvni->vni);
2856
2857 return 0;
2858 }
2859
2860 /* If it is a remote entry, the kernel has aged this out or someone has
2861 * deleted it, it needs to be re-installed as Quagga is the owner.
2862 */
2863 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
2864 zvni_neigh_install(zvni, n);
2865 return 0;
2866 }
2867
2868 /* Remove neighbor from BGP. */
2869 if (IS_ZEBRA_NEIGH_ACTIVE(n))
2870 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
2871 0);
2872
2873 /* Delete this neighbor entry. */
2874 zvni_neigh_del(zvni, n);
2875
2876 /* see if the AUTO mac needs to be deleted */
2877 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
2878 && !listcount(zmac->neigh_list))
2879 zvni_mac_del(zvni, zmac);
2880
2881 return 0;
2882 }
2883
2884 /*
2885 * Handle neighbor add or update (on a VLAN device / L3 interface)
2886 * from the kernel.
2887 */
2888 int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
2889 struct interface *link_if,
2890 struct ipaddr *ip,
2891 struct ethaddr *macaddr, u_int16_t state,
2892 u_char ext_learned)
2893 {
2894 zebra_vni_t *zvni;
2895 zebra_neigh_t *n;
2896 zebra_mac_t *zmac, *old_zmac;
2897 char buf[ETHER_ADDR_STRLEN];
2898 char buf2[INET6_ADDRSTRLEN];
2899
2900 /* We are only interested in neighbors on an SVI that resides on top
2901 * of a VxLAN bridge.
2902 */
2903 zvni = zvni_map_svi(ifp, link_if);
2904 if (!zvni)
2905 return 0;
2906
2907 if (IS_ZEBRA_DEBUG_VXLAN)
2908 zlog_debug(
2909 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
2910 "%s-> VNI %u",
2911 ipaddr2str(ip, buf2, sizeof(buf2)),
2912 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2913 ifp->ifindex, state, ext_learned ? "ext-learned " : "",
2914 zvni->vni);
2915
2916 /* create a dummy MAC if the MAC is not already present */
2917 zmac = zvni_mac_lookup(zvni, macaddr);
2918 if (!zmac) {
2919 if (IS_ZEBRA_DEBUG_VXLAN)
2920 zlog_debug(
2921 "AUTO MAC %s created for neigh %s on VNI %u",
2922 prefix_mac2str(macaddr, buf, sizeof(buf)),
2923 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
2924
2925 zmac = zvni_mac_add(zvni, macaddr);
2926 if (!zmac) {
2927 zlog_warn("Failed to add MAC %s VNI %u",
2928 prefix_mac2str(macaddr, buf, sizeof(buf)),
2929 zvni->vni);
2930 return -1;
2931 }
2932
2933 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
2934 memset(&zmac->flags, 0, sizeof(u_int32_t));
2935 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
2936 }
2937
2938 /* If same entry already exists, it might be a change or it might be a
2939 * move from remote to local.
2940 */
2941 n = zvni_neigh_lookup(zvni, ip);
2942 if (n) {
2943 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
2944 if (memcmp(n->emac.octet, macaddr->octet,
2945 ETH_ALEN)
2946 == 0) {
2947 /* Update any params and return - client doesn't
2948 * care about a purely local change.
2949 */
2950 n->ifindex = ifp->ifindex;
2951 return 0;
2952 }
2953
2954 /* If the MAC has changed,
2955 * need to issue a delete first
2956 * as this means a different MACIP route.
2957 * Also, need to do some unlinking/relinking.
2958 */
2959 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
2960 &n->emac, 0);
2961 old_zmac = zvni_mac_lookup(zvni, &n->emac);
2962 if (old_zmac) {
2963 listnode_delete(old_zmac->neigh_list, n);
2964 zvni_deref_ip2mac(zvni, old_zmac, 0);
2965 }
2966
2967 /* Set "local" forwarding info. */
2968 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2969 n->ifindex = ifp->ifindex;
2970 memcpy(&n->emac, macaddr, ETH_ALEN);
2971
2972 /* Link to new MAC */
2973 listnode_add_sort(zmac->neigh_list, n);
2974 } else if (ext_learned)
2975 /* The neighbor is remote and that is the notification we got.
2976 */
2977 {
2978 /* TODO: Evaluate if we need to do anything here. */
2979 return 0;
2980 } else
2981 /* Neighbor has moved from remote to local. */
2982 {
2983 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2984 n->r_vtep_ip.s_addr = 0;
2985 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2986 n->ifindex = ifp->ifindex;
2987 }
2988 } else {
2989 n = zvni_neigh_add(zvni, ip, macaddr);
2990 if (!n) {
2991 zlog_err(
2992 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2993 ipaddr2str(ip, buf2, sizeof(buf2)),
2994 prefix_mac2str(macaddr, buf, sizeof(buf)),
2995 ifp->name, ifp->ifindex, zvni->vni);
2996 return -1;
2997 }
2998 /* Set "local" forwarding info. */
2999 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3000 n->ifindex = ifp->ifindex;
3001 }
3002
3003 /* Before we program this in BGP, we need to check if MAC is locally
3004 * learnt as well */
3005 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
3006 if (IS_ZEBRA_DEBUG_VXLAN)
3007 zlog_debug(
3008 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
3009 ipaddr2str(ip, buf2, sizeof(buf2)),
3010 prefix_mac2str(macaddr, buf, sizeof(buf)),
3011 zvni->vni);
3012
3013 return 0;
3014 }
3015
3016 /* Inform BGP. */
3017 if (IS_ZEBRA_DEBUG_VXLAN)
3018 zlog_debug("neigh %s (MAC %s) is now ACTIVE on VNI %u",
3019 ipaddr2str(ip, buf2, sizeof(buf2)),
3020 prefix_mac2str(macaddr, buf, sizeof(buf)),
3021 zvni->vni);
3022
3023 ZEBRA_NEIGH_SET_ACTIVE(n);
3024 return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
3025 }
3026
3027
3028 /*
3029 * Handle message from client to delete a remote MACIP for a VNI.
3030 */
3031 int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
3032 struct zebra_vrf *zvrf)
3033 {
3034 struct stream *s;
3035 vni_t vni;
3036 struct ethaddr macaddr;
3037 struct ipaddr ip;
3038 struct in_addr vtep_ip;
3039 zebra_vni_t *zvni;
3040 zebra_mac_t *mac;
3041 zebra_neigh_t *n;
3042 u_short l = 0, ipa_len;
3043 char buf[ETHER_ADDR_STRLEN];
3044 char buf1[INET6_ADDRSTRLEN];
3045 struct interface *ifp = NULL;
3046 struct zebra_if *zif = NULL;
3047
3048 s = client->ibuf;
3049
3050 while (l < length) {
3051 /* Obtain each remote MACIP and process. */
3052 /* Message contains VNI, followed by MAC followed by IP (if any)
3053 * followed by remote VTEP IP.
3054 */
3055 mac = NULL;
3056 n = NULL;
3057 memset(&ip, 0, sizeof(ip));
3058 STREAM_GETL(s, vni);
3059 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
3060 STREAM_GETL(s, ipa_len);
3061 if (ipa_len) {
3062 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
3063 : IPADDR_V6;
3064 STREAM_GET(&ip.ip.addr, s, ipa_len);
3065 }
3066 l += 4 + ETH_ALEN + 4 + ipa_len;
3067 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
3068 l += IPV4_MAX_BYTELEN;
3069
3070 if (IS_ZEBRA_DEBUG_VXLAN)
3071 zlog_debug(
3072 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
3073 prefix_mac2str(&macaddr, buf, sizeof(buf)),
3074 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
3075 inet_ntoa(vtep_ip),
3076 zebra_route_string(client->proto));
3077
3078 /* Locate VNI hash entry - expected to exist. */
3079 zvni = zvni_lookup(vni);
3080 if (!zvni) {
3081 if (IS_ZEBRA_DEBUG_VXLAN)
3082 zlog_debug(
3083 "Failed to locate VNI hash upon remote MACIP DEL, "
3084 "VNI %u",
3085 vni);
3086 continue;
3087 }
3088 ifp = zvni->vxlan_if;
3089 if (!ifp) {
3090 zlog_err(
3091 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
3092 vni, zvni);
3093 continue;
3094 }
3095 zif = ifp->info;
3096
3097 /* If down or not mapped to a bridge, we're done. */
3098 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3099 continue;
3100
3101 /* The remote VTEP specified is normally expected to exist, but
3102 * it is
3103 * possible that the peer may delete the VTEP before deleting
3104 * any MACs
3105 * referring to the VTEP, in which case the handler (see
3106 * remote_vtep_del)
3107 * would have already deleted the MACs.
3108 */
3109 if (!zvni_vtep_find(zvni, &vtep_ip))
3110 continue;
3111
3112 mac = zvni_mac_lookup(zvni, &macaddr);
3113 if (ipa_len)
3114 n = zvni_neigh_lookup(zvni, &ip);
3115
3116 if (n && !mac) {
3117 zlog_err(
3118 "Failed to locate MAC %s for neigh %s VNI %u",
3119 prefix_mac2str(&macaddr, buf, sizeof(buf)),
3120 ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
3121 continue;
3122 }
3123
3124 /* If the remote mac or neighbor doesn't exist there is nothing
3125 * more
3126 * to do. Otherwise, uninstall the entry and then remove it.
3127 */
3128 if (!mac && !n)
3129 continue;
3130
3131 /* Uninstall remote neighbor or MAC. */
3132 if (n) {
3133 /* When the MAC changes for an IP, it is possible the
3134 * client may
3135 * update the new MAC before trying to delete the "old"
3136 * neighbor
3137 * (as these are two different MACIP routes). Do the
3138 * delete only
3139 * if the MAC matches.
3140 */
3141 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
3142 && (memcmp(n->emac.octet, macaddr.octet,
3143 ETH_ALEN)
3144 == 0)) {
3145 zvni_neigh_uninstall(zvni, n);
3146 zvni_neigh_del(zvni, n);
3147 zvni_deref_ip2mac(zvni, mac, 1);
3148 }
3149 } else {
3150 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3151 zvni_process_neigh_on_remote_mac_del(zvni,
3152 mac);
3153
3154 if (list_isempty(mac->neigh_list)) {
3155 zvni_mac_uninstall(zvni, mac, 0);
3156 zvni_mac_del(zvni, mac);
3157 } else
3158 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3159 }
3160 }
3161 }
3162
3163 stream_failure:
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, 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 if (!EVPN_ENABLED(zvrf)) {
3193 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
3194 __PRETTY_FUNCTION__);
3195 return -1;
3196 }
3197
3198 s = client->ibuf;
3199
3200 while (l < length) {
3201 /* Obtain each remote MACIP and process. */
3202 /* Message contains VNI, followed by MAC followed by IP (if any)
3203 * followed by remote VTEP IP.
3204 */
3205 update_mac = update_neigh = 0;
3206 mac = NULL;
3207 n = NULL;
3208 memset(&ip, 0, sizeof(ip));
3209 STREAM_GETL(s, vni);
3210 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
3211 STREAM_GETL(s, ipa_len);
3212 if (ipa_len) {
3213 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
3214 : IPADDR_V6;
3215 STREAM_GET(&ip.ip.addr, s, ipa_len);
3216 }
3217 l += 4 + ETH_ALEN + 4 + ipa_len;
3218 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
3219 l += IPV4_MAX_BYTELEN;
3220
3221 /* Get 'sticky' flag. */
3222 STREAM_GETC(s, sticky);
3223 l++;
3224
3225 if (IS_ZEBRA_DEBUG_VXLAN)
3226 zlog_debug(
3227 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
3228 sticky ? "sticky " : "",
3229 prefix_mac2str(&macaddr, buf, sizeof(buf)),
3230 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
3231 inet_ntoa(vtep_ip),
3232 zebra_route_string(client->proto));
3233
3234 /* Locate VNI hash entry - expected to exist. */
3235 zvni = zvni_lookup(vni);
3236 if (!zvni) {
3237 zlog_err(
3238 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
3239 vni);
3240 continue;
3241 }
3242 ifp = zvni->vxlan_if;
3243 if (!ifp) {
3244 zlog_err(
3245 "VNI %u hash %p doesn't have intf upon remote MACIP add",
3246 vni, zvni);
3247 continue;
3248 }
3249 zif = ifp->info;
3250
3251 /* If down or not mapped to a bridge, we're done. */
3252 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3253 continue;
3254
3255 /* The remote VTEP specified should normally exist, but it is
3256 * possible
3257 * that when peering comes up, peer may advertise MACIP routes
3258 * before
3259 * advertising type-3 routes.
3260 */
3261 zvtep = zvni_vtep_find(zvni, &vtep_ip);
3262 if (!zvtep) {
3263 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
3264 zlog_err(
3265 "Failed to add remote VTEP, VNI %u zvni %p",
3266 vni, zvni);
3267 continue;
3268 }
3269
3270 zvni_vtep_install(zvni, &vtep_ip);
3271 }
3272
3273 /* First, check if the remote MAC is unknown or has a change. If
3274 * so,
3275 * that needs to be updated first. Note that client could
3276 * install
3277 * MAC and MACIP separately or just install the latter.
3278 */
3279 mac = zvni_mac_lookup(zvni, &macaddr);
3280 if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
3281 || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
3282 != sticky
3283 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
3284 update_mac = 1;
3285
3286 if (update_mac) {
3287 if (!mac) {
3288 mac = zvni_mac_add(zvni, &macaddr);
3289 if (!mac) {
3290 zlog_warn(
3291 "Failed to add MAC %s VNI %u Remote VTEP %s",
3292 prefix_mac2str(&macaddr, buf,
3293 sizeof(buf)),
3294 vni, inet_ntoa(vtep_ip));
3295 return -1;
3296 }
3297
3298 /* Is this MAC created for a MACIP? */
3299 if (ipa_len)
3300 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3301 }
3302
3303 /* Set "auto" and "remote" forwarding info. */
3304 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3305 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
3306 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
3307 mac->fwd_info.r_vtep_ip = vtep_ip;
3308
3309 if (sticky)
3310 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3311 else
3312 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3313
3314 zvni_process_neigh_on_remote_mac_add(zvni, mac);
3315
3316 /* Install the entry. */
3317 zvni_mac_install(zvni, mac);
3318 }
3319
3320 /* If there is no IP, continue - after clearing AUTO flag of
3321 * MAC. */
3322 if (!ipa_len) {
3323 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3324 continue;
3325 }
3326
3327 /* Check if the remote neighbor itself is unknown or has a
3328 * change.
3329 * If so, create or update and then install the entry.
3330 */
3331 n = zvni_neigh_lookup(zvni, &ip);
3332 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
3333 || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
3334 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
3335 update_neigh = 1;
3336
3337 if (update_neigh) {
3338 if (!n) {
3339 n = zvni_neigh_add(zvni, &ip, &macaddr);
3340 if (!n) {
3341 zlog_warn(
3342 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
3343 ipaddr2str(&ip, buf1,
3344 sizeof(buf1)),
3345 prefix_mac2str(&macaddr, buf,
3346 sizeof(buf)),
3347 vni, inet_ntoa(vtep_ip));
3348 return -1;
3349 }
3350
3351 } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
3352 != 0) {
3353 /* MAC change, update neigh list for old and new
3354 * mac */
3355 old_mac = zvni_mac_lookup(zvni, &n->emac);
3356 if (old_mac) {
3357 listnode_delete(old_mac->neigh_list, n);
3358 zvni_deref_ip2mac(zvni, old_mac, 1);
3359 }
3360 listnode_add_sort(mac->neigh_list, n);
3361 memcpy(&n->emac, &macaddr, ETH_ALEN);
3362 }
3363
3364 /* Set "remote" forwarding info. */
3365 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
3366 /* TODO: Handle MAC change. */
3367 n->r_vtep_ip = vtep_ip;
3368 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3369
3370 /* Install the entry. */
3371 zvni_neigh_install(zvni, n);
3372 }
3373 }
3374
3375 stream_failure:
3376 return 0;
3377 }
3378
3379 /*
3380 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
3381 * us, this must involve a multihoming scenario. Treat this as implicit delete
3382 * of any prior local MAC.
3383 */
3384 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
3385 struct interface *br_if,
3386 struct ethaddr *macaddr, vlanid_t vid)
3387 {
3388 struct zebra_if *zif;
3389 struct zebra_l2info_vxlan *vxl;
3390 vni_t vni;
3391 zebra_vni_t *zvni;
3392 zebra_mac_t *mac;
3393 char buf[ETHER_ADDR_STRLEN];
3394 u_char sticky;
3395
3396 zif = ifp->info;
3397 assert(zif);
3398 vxl = &zif->l2info.vxl;
3399 vni = vxl->vni;
3400
3401 /* Check if EVPN is enabled. */
3402 if (!is_evpn_enabled())
3403 return 0;
3404
3405 /* Locate hash entry; it is expected to exist. */
3406 zvni = zvni_lookup(vni);
3407 if (!zvni)
3408 return 0;
3409
3410 /* If entry doesn't exist, nothing to do. */
3411 mac = zvni_mac_lookup(zvni, macaddr);
3412 if (!mac)
3413 return 0;
3414
3415 /* Is it a local entry? */
3416 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
3417 return 0;
3418
3419 if (IS_ZEBRA_DEBUG_VXLAN)
3420 zlog_debug(
3421 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
3422 prefix_mac2str(macaddr, buf, sizeof(buf)),
3423 ifp->name, ifp->ifindex, vni);
3424
3425 /* Remove MAC from BGP. */
3426 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
3427 zvni_mac_send_del_to_client(zvni->vni, macaddr,
3428 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
3429
3430 /*
3431 * If there are no neigh associated with the mac delete the mac
3432 * else mark it as AUTO for forward reference
3433 */
3434 if (!listcount(mac->neigh_list)) {
3435 zvni_mac_del(zvni, mac);
3436 } else {
3437 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3438 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3439 }
3440
3441 return 0;
3442 }
3443
3444 /*
3445 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
3446 * This can happen because the remote MAC entries are also added as "dynamic",
3447 * so the kernel can ageout the entry.
3448 */
3449 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
3450 struct interface *br_if,
3451 struct ethaddr *macaddr, vlanid_t vid)
3452 {
3453 struct zebra_if *zif;
3454 struct zebra_l2info_vxlan *vxl;
3455 vni_t vni;
3456 zebra_vni_t *zvni;
3457 zebra_mac_t *mac;
3458 char buf[ETHER_ADDR_STRLEN];
3459
3460 zif = ifp->info;
3461 assert(zif);
3462 vxl = &zif->l2info.vxl;
3463 vni = vxl->vni;
3464
3465 /* Check if EVPN is enabled. */
3466 if (!is_evpn_enabled())
3467 return 0;
3468
3469 /* Locate hash entry; it is expected to exist. */
3470 zvni = zvni_lookup(vni);
3471 if (!zvni)
3472 return 0;
3473
3474 /* If entry doesn't exist, nothing to do. */
3475 mac = zvni_mac_lookup(zvni, macaddr);
3476 if (!mac)
3477 return 0;
3478
3479 /* Is it a remote entry? */
3480 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
3481 return 0;
3482
3483 if (IS_ZEBRA_DEBUG_VXLAN)
3484 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
3485 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
3486 ifp->ifindex, vni);
3487
3488 zvni_mac_install(zvni, mac);
3489 return 0;
3490 }
3491
3492 /*
3493 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
3494 */
3495 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
3496 struct ethaddr *macaddr, vlanid_t vid)
3497 {
3498 zebra_vni_t *zvni;
3499 zebra_mac_t *mac;
3500 char buf[ETHER_ADDR_STRLEN];
3501 u_char sticky;
3502
3503 /* We are interested in MACs only on ports or (port, VLAN) that
3504 * map to a VNI.
3505 */
3506 zvni = zvni_map_vlan(ifp, br_if, vid);
3507 if (!zvni)
3508 return 0;
3509 if (!zvni->vxlan_if) {
3510 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
3511 zvni->vni, zvni);
3512 return -1;
3513 }
3514
3515 if (IS_ZEBRA_DEBUG_VXLAN)
3516 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
3517 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
3518 ifp->ifindex, vid, zvni->vni);
3519
3520 /* If entry doesn't exist, nothing to do. */
3521 mac = zvni_mac_lookup(zvni, macaddr);
3522 if (!mac)
3523 return 0;
3524
3525 /* Is it a local entry? */
3526 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
3527 return 0;
3528
3529 /* Remove MAC from BGP. */
3530 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
3531 zvni_mac_send_del_to_client(zvni->vni, macaddr,
3532 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
3533
3534 /* Update all the neigh entries associated with this mac */
3535 zvni_process_neigh_on_local_mac_del(zvni, mac);
3536
3537 /*
3538 * If there are no neigh associated with the mac delete the mac
3539 * else mark it as AUTO for forward reference
3540 */
3541 if (!listcount(mac->neigh_list)) {
3542 zvni_mac_del(zvni, mac);
3543 } else {
3544 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3545 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3546 }
3547
3548 return 0;
3549 }
3550
3551 /*
3552 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
3553 */
3554 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
3555 struct interface *br_if,
3556 struct ethaddr *macaddr, vlanid_t vid,
3557 u_char sticky)
3558 {
3559 zebra_vni_t *zvni;
3560 zebra_mac_t *mac;
3561 char buf[ETHER_ADDR_STRLEN];
3562 int add = 1;
3563 u_char mac_sticky;
3564
3565 /* We are interested in MACs only on ports or (port, VLAN) that
3566 * map to a VNI.
3567 */
3568 zvni = zvni_map_vlan(ifp, br_if, vid);
3569 if (!zvni) {
3570 if (IS_ZEBRA_DEBUG_VXLAN)
3571 zlog_debug(
3572 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
3573 sticky ? "sticky " : "",
3574 prefix_mac2str(macaddr, buf, sizeof(buf)),
3575 ifp->name, ifp->ifindex, vid);
3576 return 0;
3577 }
3578
3579 if (!zvni->vxlan_if) {
3580 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
3581 zvni->vni, zvni);
3582 return -1;
3583 }
3584
3585 if (IS_ZEBRA_DEBUG_VXLAN)
3586 zlog_debug(
3587 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
3588 sticky ? "sticky " : "",
3589 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
3590 ifp->ifindex, vid, zvni->vni);
3591
3592 /* If same entry already exists, nothing to do. */
3593 mac = zvni_mac_lookup(zvni, macaddr);
3594 if (mac) {
3595 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
3596 mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
3597 ? 1
3598 : 0;
3599
3600
3601 /*
3602 * return if nothing has changed.
3603 * inform bgp if sticky flag has changed
3604 * update locally and do not inform bgp if local
3605 * parameters like interface has changed
3606 */
3607 if (mac_sticky == sticky
3608 && mac->fwd_info.local.ifindex == ifp->ifindex
3609 && mac->fwd_info.local.vid == vid) {
3610 if (IS_ZEBRA_DEBUG_VXLAN)
3611 zlog_debug(
3612 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
3613 "entry exists and has not changed ",
3614 sticky ? "sticky " : "",
3615 prefix_mac2str(macaddr, buf,
3616 sizeof(buf)),
3617 ifp->name, ifp->ifindex, vid,
3618 zvni->vni);
3619 return 0;
3620 } else if (mac_sticky != sticky) {
3621 add = 1;
3622 } else {
3623 add = 0; /* This is an update of local
3624 interface. */
3625 }
3626 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
3627 /*
3628 * If we have already learned the MAC as a remote sticky
3629 * MAC,
3630 * this is a operator error and we must log a warning
3631 */
3632 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
3633 zlog_warn(
3634 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
3635 prefix_mac2str(macaddr, buf,
3636 sizeof(buf)),
3637 inet_ntoa(mac->fwd_info.r_vtep_ip),
3638 zvni->vni);
3639 return 0;
3640 }
3641 }
3642 }
3643
3644 if (!mac) {
3645 mac = zvni_mac_add(zvni, macaddr);
3646 if (!mac) {
3647 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
3648 prefix_mac2str(macaddr, buf, sizeof(buf)),
3649 ifp->name, ifp->ifindex, vid);
3650 return -1;
3651 }
3652 }
3653
3654 /* Set "local" forwarding info. */
3655 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
3656 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
3657 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
3658 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
3659 mac->fwd_info.local.ifindex = ifp->ifindex;
3660 mac->fwd_info.local.vid = vid;
3661
3662 if (sticky)
3663 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3664 else
3665 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
3666
3667 /* Inform BGP if required. */
3668 if (add) {
3669 zvni_process_neigh_on_local_mac_add(zvni, mac);
3670 return zvni_mac_send_add_to_client(zvni->vni, macaddr,
3671 sticky);
3672 }
3673
3674 return 0;
3675 }
3676
3677 /*
3678 * Handle message from client to delete a remote VTEP for a VNI.
3679 */
3680 int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
3681 struct zebra_vrf *zvrf)
3682 {
3683 struct stream *s;
3684 u_short l = 0;
3685 vni_t vni;
3686 struct in_addr vtep_ip;
3687 zebra_vni_t *zvni;
3688 zebra_vtep_t *zvtep;
3689 struct interface *ifp;
3690 struct zebra_if *zif;
3691
3692 if (!is_evpn_enabled()) {
3693 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
3694 __PRETTY_FUNCTION__);
3695 return -1;
3696 }
3697
3698 if (zvrf_id(zvrf) != VRF_DEFAULT) {
3699 zlog_err("Recv MACIP DEL for non-default VRF %u",
3700 zvrf_id(zvrf));
3701 return -1;
3702 }
3703
3704 s = client->ibuf;
3705
3706 while (l < length) {
3707 /* Obtain each remote VTEP and process. */
3708 STREAM_GETL(s, vni);
3709 l += 4;
3710 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
3711 l += IPV4_MAX_BYTELEN;
3712
3713 if (IS_ZEBRA_DEBUG_VXLAN)
3714 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
3715 inet_ntoa(vtep_ip), vni,
3716 zebra_route_string(client->proto));
3717
3718 /* Locate VNI hash entry - expected to exist. */
3719 zvni = zvni_lookup(vni);
3720 if (!zvni) {
3721 if (IS_ZEBRA_DEBUG_VXLAN)
3722 zlog_debug(
3723 "Failed to locate VNI hash upon remote VTEP DEL, "
3724 "VNI %u",
3725 vni);
3726 continue;
3727 }
3728
3729 ifp = zvni->vxlan_if;
3730 if (!ifp) {
3731 zlog_err(
3732 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
3733 zvni->vni, zvni);
3734 continue;
3735 }
3736 zif = ifp->info;
3737
3738 /* If down or not mapped to a bridge, we're done. */
3739 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3740 continue;
3741
3742 /* If the remote VTEP does not exist, there's nothing more to
3743 * do.
3744 * Otherwise, uninstall any remote MACs pointing to this VTEP
3745 * and
3746 * then, the VTEP entry itself and remove it.
3747 */
3748 zvtep = zvni_vtep_find(zvni, &vtep_ip);
3749 if (!zvtep)
3750 continue;
3751
3752 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
3753 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
3754 zvni_vtep_uninstall(zvni, &vtep_ip);
3755 zvni_vtep_del(zvni, zvtep);
3756 }
3757
3758 stream_failure:
3759 return 0;
3760 }
3761
3762 /*
3763 * Handle message from client to add a remote VTEP for a VNI.
3764 */
3765 int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
3766 struct zebra_vrf *zvrf)
3767 {
3768 struct stream *s;
3769 u_short l = 0;
3770 vni_t vni;
3771 struct in_addr vtep_ip;
3772 zebra_vni_t *zvni;
3773 struct interface *ifp;
3774 struct zebra_if *zif;
3775
3776 if (!is_evpn_enabled()) {
3777 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
3778 __PRETTY_FUNCTION__);
3779 return -1;
3780 }
3781
3782 if (zvrf_id(zvrf) != VRF_DEFAULT) {
3783 zlog_err("Recv MACIP ADD for non-default VRF %u",
3784 zvrf_id(zvrf));
3785 return -1;
3786 }
3787
3788 s = client->ibuf;
3789
3790 while (l < length) {
3791 /* Obtain each remote VTEP and process. */
3792 STREAM_GETL(s, vni);
3793 l += 4;
3794 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
3795 l += IPV4_MAX_BYTELEN;
3796
3797 if (IS_ZEBRA_DEBUG_VXLAN)
3798 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
3799 inet_ntoa(vtep_ip), vni,
3800 zebra_route_string(client->proto));
3801
3802 /* Locate VNI hash entry - expected to exist. */
3803 zvni = zvni_lookup(vni);
3804 if (!zvni) {
3805 zlog_err(
3806 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
3807 vni);
3808 continue;
3809 }
3810
3811 ifp = zvni->vxlan_if;
3812 if (!ifp) {
3813 zlog_err(
3814 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
3815 zvni->vni, zvni);
3816 continue;
3817 }
3818
3819 zif = ifp->info;
3820
3821 /* If down or not mapped to a bridge, we're done. */
3822 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3823 continue;
3824
3825 /* If the remote VTEP already exists,
3826 there's nothing more to do. */
3827 if (zvni_vtep_find(zvni, &vtep_ip))
3828 continue;
3829
3830 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
3831 zlog_err(
3832 "Failed to add remote VTEP, VNI %u zvni %p",
3833 vni, zvni);
3834 continue;
3835 }
3836
3837 zvni_vtep_install(zvni, &vtep_ip);
3838 }
3839
3840 stream_failure:
3841 return 0;
3842 }
3843
3844 /*
3845 * Add/Del gateway macip to evpn
3846 * g/w can be:
3847 * 1. SVI interface on a vlan aware bridge
3848 * 2. SVI interface on a vlan unaware bridge
3849 * 3. vrr interface (MACVLAN) associated to a SVI
3850 * We advertise macip routes for an interface if it is associated to VxLan vlan
3851 */
3852 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
3853 int add)
3854 {
3855 struct ipaddr ip;
3856 struct ethaddr macaddr;
3857 zebra_vni_t *zvni = NULL;
3858
3859 memset(&ip, 0, sizeof(struct ipaddr));
3860 memset(&macaddr, 0, sizeof(struct ethaddr));
3861
3862 /* Check if EVPN is enabled. */
3863 if (!is_evpn_enabled())
3864 return 0;
3865
3866 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
3867 struct interface *svi_if =
3868 NULL; /* SVI corresponding to the MACVLAN */
3869 struct zebra_if *ifp_zif =
3870 NULL; /* Zebra daemon specific info for MACVLAN */
3871 struct zebra_if *svi_if_zif =
3872 NULL; /* Zebra daemon specific info for SVI*/
3873
3874 ifp_zif = ifp->info;
3875 if (!ifp_zif)
3876 return -1;
3877
3878 /*
3879 * for a MACVLAN interface the link represents the svi_if
3880 */
3881 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
3882 ifp_zif->link_ifindex);
3883 if (!svi_if) {
3884 zlog_err("MACVLAN %s(%u) without link information",
3885 ifp->name, ifp->ifindex);
3886 return -1;
3887 }
3888
3889 if (IS_ZEBRA_IF_VLAN(svi_if)) {
3890 /*
3891 * If it is a vlan aware bridge then the link gives the
3892 * bridge information
3893 */
3894 struct interface *svi_if_link = NULL;
3895
3896 svi_if_zif = svi_if->info;
3897 if (svi_if_zif) {
3898 svi_if_link = if_lookup_by_index_per_ns(
3899 zebra_ns_lookup(NS_DEFAULT),
3900 svi_if_zif->link_ifindex);
3901 zvni = zvni_map_svi(svi_if, svi_if_link);
3902 }
3903 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
3904 /*
3905 * If it is a vlan unaware bridge then svi is the bridge
3906 * itself
3907 */
3908 zvni = zvni_map_svi(svi_if, svi_if);
3909 }
3910 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
3911 struct zebra_if *svi_if_zif =
3912 NULL; /* Zebra daemon specific info for SVI */
3913 struct interface *svi_if_link =
3914 NULL; /* link info for the SVI = bridge info */
3915
3916 svi_if_zif = ifp->info;
3917 svi_if_link = if_lookup_by_index_per_ns(
3918 zebra_ns_lookup(NS_DEFAULT), svi_if_zif->link_ifindex);
3919 if (svi_if_zif && svi_if_link)
3920 zvni = zvni_map_svi(ifp, svi_if_link);
3921 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
3922 zvni = zvni_map_svi(ifp, ifp);
3923 }
3924
3925 if (!zvni)
3926 return 0;
3927
3928 if (!zvni->vxlan_if) {
3929 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
3930 zvni->vni, zvni);
3931 return -1;
3932 }
3933
3934
3935 /* check if we are advertising gw macip routes */
3936 if (!advertise_gw_macip_enabled(zvni))
3937 return 0;
3938
3939 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
3940
3941 if (p->family == AF_INET) {
3942 ip.ipa_type = IPADDR_V4;
3943 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
3944 sizeof(struct in_addr));
3945 } else if (p->family == AF_INET6) {
3946 ip.ipa_type = IPADDR_V6;
3947 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
3948 sizeof(struct in6_addr));
3949 }
3950
3951
3952 if (add)
3953 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
3954 else
3955 zvni_gw_macip_del(ifp, zvni, &ip);
3956
3957 return 0;
3958 }
3959
3960 /*
3961 * Handle SVI interface going down. At this point, this is a NOP since
3962 * the kernel deletes the neighbor entries on this SVI (if any).
3963 */
3964 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
3965 {
3966 return 0;
3967 }
3968
3969 /*
3970 * Handle SVI interface coming up. This may or may not be of interest,
3971 * but if this is a SVI on a VxLAN bridge, we need to install any remote
3972 * neighbor entries (which will be used for EVPN ARP suppression).
3973 */
3974 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
3975 {
3976 zebra_vni_t *zvni;
3977 struct neigh_walk_ctx n_wctx;
3978
3979 zvni = zvni_map_svi(ifp, link_if);
3980 if (!zvni)
3981 return 0;
3982
3983 if (!zvni->vxlan_if) {
3984 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
3985 zvni->vni, zvni);
3986 return -1;
3987 }
3988
3989 if (IS_ZEBRA_DEBUG_VXLAN)
3990 zlog_debug("SVI %s(%u) VNI %u is UP, installing neighbors",
3991 ifp->name, ifp->ifindex, zvni->vni);
3992
3993 /* Install any remote neighbors for this VNI. */
3994 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
3995 n_wctx.zvni = zvni;
3996 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash, &n_wctx);
3997
3998 return 0;
3999 }
4000
4001 /*
4002 * Handle VxLAN interface down - update BGP if required, and do
4003 * internal cleanup.
4004 */
4005 int zebra_vxlan_if_down(struct interface *ifp)
4006 {
4007 struct zebra_if *zif;
4008 zebra_vni_t *zvni;
4009 struct zebra_l2info_vxlan *vxl;
4010 vni_t vni;
4011
4012 /* Check if EVPN is enabled. */
4013 if (!is_evpn_enabled())
4014 return 0;
4015
4016 zif = ifp->info;
4017 assert(zif);
4018 vxl = &zif->l2info.vxl;
4019 vni = vxl->vni;
4020
4021 if (IS_ZEBRA_DEBUG_VXLAN)
4022 zlog_debug("Intf %s(%u) VNI %u is DOWN",
4023 ifp->name, ifp->ifindex, vni);
4024
4025 /* Locate hash entry; it is expected to exist. */
4026 zvni = zvni_lookup(vni);
4027 if (!zvni) {
4028 zlog_err(
4029 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
4030 ifp->name, ifp->ifindex, vni);
4031 return -1;
4032 }
4033
4034 assert(zvni->vxlan_if == ifp);
4035
4036 /* Delete this VNI from BGP. */
4037 zvni_send_del_to_client(zvni->vni);
4038
4039 /* Free up all neighbors and MACs, if any. */
4040 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
4041 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
4042
4043 /* Free up all remote VTEPs, if any. */
4044 zvni_vtep_del_all(zvni, 1);
4045
4046 return 0;
4047 }
4048
4049 /*
4050 * Handle VxLAN interface up - update BGP if required.
4051 */
4052 int zebra_vxlan_if_up(struct interface *ifp)
4053 {
4054 struct zebra_if *zif;
4055 zebra_vni_t *zvni;
4056 struct zebra_l2info_vxlan *vxl;
4057 vni_t vni;
4058
4059 /* Check if EVPN is enabled. */
4060 if (!is_evpn_enabled())
4061 return 0;
4062
4063 zif = ifp->info;
4064 assert(zif);
4065 vxl = &zif->l2info.vxl;
4066 vni = vxl->vni;
4067
4068 if (IS_ZEBRA_DEBUG_VXLAN)
4069 zlog_debug("Intf %s(%u) VNI %u is UP",
4070 ifp->name, ifp->ifindex, vni);
4071
4072 /* Locate hash entry; it is expected to exist. */
4073 zvni = zvni_lookup(vni);
4074 if (!zvni) {
4075 zlog_err(
4076 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
4077 ifp->name, ifp->ifindex, vni);
4078 return -1;
4079 }
4080
4081 assert(zvni->vxlan_if == ifp);
4082
4083 /* If part of a bridge, inform BGP about this VNI. */
4084 /* Also, read and populate local MACs and neighbors. */
4085 if (zif->brslave_info.br_if) {
4086 zvni_send_add_to_client(zvni);
4087 zvni_read_mac_neigh(zvni, ifp);
4088 }
4089
4090 return 0;
4091 }
4092
4093 /*
4094 * Handle VxLAN interface delete. Locate and remove entry in hash table
4095 * and update BGP, if required.
4096 */
4097 int zebra_vxlan_if_del(struct interface *ifp)
4098 {
4099 struct zebra_if *zif;
4100 zebra_vni_t *zvni;
4101 struct zebra_l2info_vxlan *vxl;
4102 vni_t vni;
4103
4104 /* Check if EVPN is enabled. */
4105 if (!is_evpn_enabled())
4106 return 0;
4107
4108 zif = ifp->info;
4109 assert(zif);
4110 vxl = &zif->l2info.vxl;
4111 vni = vxl->vni;
4112
4113 if (IS_ZEBRA_DEBUG_VXLAN)
4114 zlog_debug("Del VNI %u intf %s(%u)",
4115 vni, ifp->name, ifp->ifindex);
4116
4117 /* Locate hash entry; it is expected to exist. */
4118 zvni = zvni_lookup(vni);
4119 if (!zvni) {
4120 zlog_err(
4121 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
4122 ifp->name, ifp->ifindex, vni);
4123 return 0;
4124 }
4125
4126 /* Delete VNI from BGP. */
4127 zvni_send_del_to_client(zvni->vni);
4128
4129 /* Free up all neighbors and MAC, if any. */
4130 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
4131 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
4132
4133 /* Free up all remote VTEPs, if any. */
4134 zvni_vtep_del_all(zvni, 0);
4135
4136 /* Delete the hash entry. */
4137 if (zvni_del(zvni)) {
4138 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
4139 zvni, ifp->name, ifp->ifindex, zvni->vni);
4140 return -1;
4141 }
4142
4143 return 0;
4144 }
4145
4146 /*
4147 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
4148 */
4149 int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
4150 {
4151 struct zebra_if *zif;
4152 zebra_vni_t *zvni;
4153 struct zebra_l2info_vxlan *vxl;
4154 vni_t vni;
4155
4156 /* Check if EVPN is enabled. */
4157 if (!is_evpn_enabled())
4158 return 0;
4159
4160 zif = ifp->info;
4161 assert(zif);
4162 vxl = &zif->l2info.vxl;
4163 vni = vxl->vni;
4164
4165 /* Update VNI hash. */
4166 zvni = zvni_lookup(vni);
4167 if (!zvni) {
4168 zlog_err(
4169 "Failed to find VNI hash on update, IF %s(%u) VNI %u",
4170 ifp->name, ifp->ifindex, vni);
4171 return -1;
4172 }
4173
4174 if (IS_ZEBRA_DEBUG_VXLAN)
4175 zlog_debug(
4176 "Update VNI %u intf %s(%u) VLAN %u local IP %s "
4177 "master %u chg 0x%x",
4178 vni, ifp->name, ifp->ifindex,
4179 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
4180 zif->brslave_info.bridge_ifindex, chgflags);
4181
4182 /* Removed from bridge? Cleanup and return */
4183 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
4184 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
4185 /* Delete from client, remove all remote VTEPs */
4186 /* Also, free up all MACs and neighbors. */
4187 zvni_send_del_to_client(zvni->vni);
4188 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
4189 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
4190 zvni_vtep_del_all(zvni, 1);
4191 return 0;
4192 }
4193
4194 /* Handle other changes. */
4195 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
4196 /* Remove all existing local neighbors and MACs for this VNI
4197 * (including from BGP)
4198 */
4199 zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
4200 zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
4201 }
4202
4203 zvni->local_vtep_ip = vxl->vtep_ip;
4204 zvni->vxlan_if = ifp;
4205
4206 /* Take further actions needed. Note that if we are here, there is a
4207 * change of interest.
4208 */
4209 /* If down or not mapped to a bridge, we're done. */
4210 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4211 return 0;
4212
4213 /* Inform BGP, if there is a change of interest. */
4214 if (chgflags
4215 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
4216 zvni_send_add_to_client(zvni);
4217
4218 /* If there is a valid new master or a VLAN mapping change, read and
4219 * populate local MACs and neighbors. Also, reinstall any remote MACs
4220 * and neighbors for this VNI (based on new VLAN).
4221 */
4222 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
4223 zvni_read_mac_neigh(zvni, ifp);
4224 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
4225 struct mac_walk_ctx m_wctx;
4226 struct neigh_walk_ctx n_wctx;
4227
4228 zvni_read_mac_neigh(zvni, ifp);
4229
4230 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
4231 m_wctx.zvni = zvni;
4232 hash_iterate(zvni->mac_table, zvni_install_mac_hash, &m_wctx);
4233
4234 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
4235 n_wctx.zvni = zvni;
4236 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
4237 &n_wctx);
4238 }
4239
4240 return 0;
4241 }
4242
4243 /*
4244 * Handle VxLAN interface add.
4245 */
4246 int zebra_vxlan_if_add(struct interface *ifp)
4247 {
4248 struct zebra_if *zif;
4249 zebra_vni_t *zvni;
4250 struct zebra_l2info_vxlan *vxl;
4251 vni_t vni;
4252
4253 /* Check if EVPN is enabled. */
4254 if (!is_evpn_enabled())
4255 return 0;
4256
4257 zif = ifp->info;
4258 assert(zif);
4259 vxl = &zif->l2info.vxl;
4260 vni = vxl->vni;
4261
4262 if (IS_ZEBRA_DEBUG_VXLAN)
4263 zlog_debug(
4264 "Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
4265 vni, ifp->name, ifp->ifindex,
4266 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
4267 zif->brslave_info.bridge_ifindex);
4268
4269 /* Create or update VNI hash. */
4270 zvni = zvni_lookup(vni);
4271 if (!zvni) {
4272 zvni = zvni_add(vni);
4273 if (!zvni) {
4274 zlog_err(
4275 "Failed to add VNI hash, IF %s(%u) VNI %u",
4276 ifp->name, ifp->ifindex, vni);
4277 return -1;
4278 }
4279 }
4280
4281 zvni->local_vtep_ip = vxl->vtep_ip;
4282 zvni->vxlan_if = ifp;
4283
4284 /* If down or not mapped to a bridge, we're done. */
4285 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4286 return 0;
4287
4288 /* Inform BGP */
4289 zvni_send_add_to_client(zvni);
4290
4291 /* Read and populate local MACs and neighbors */
4292 zvni_read_mac_neigh(zvni, ifp);
4293
4294 return 0;
4295 }
4296
4297 /*
4298 * Handle message from client to enable/disable advertisement of g/w macip
4299 * routes
4300 */
4301 int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
4302 struct zebra_vrf *zvrf)
4303 {
4304 struct stream *s;
4305 int advertise;
4306 vni_t vni = 0;
4307 zebra_vni_t *zvni = NULL;
4308 struct interface *ifp = NULL;
4309
4310 if (zvrf_id(zvrf) != VRF_DEFAULT) {
4311 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
4312 zvrf_id(zvrf));
4313 return -1;
4314 }
4315
4316 s = client->ibuf;
4317 STREAM_GETC(s, advertise);
4318 STREAM_GET(&vni, s, 3);
4319
4320 if (!vni) {
4321 if (IS_ZEBRA_DEBUG_VXLAN)
4322 zlog_debug("EVPN gateway macip Adv %s, currently %s",
4323 advertise ? "enabled" : "disabled",
4324 advertise_gw_macip_enabled(NULL)
4325 ? "enabled"
4326 : "disabled");
4327
4328 if (zvrf->advertise_gw_macip == advertise)
4329 return 0;
4330
4331 zvrf->advertise_gw_macip = advertise;
4332
4333 if (advertise_gw_macip_enabled(zvni))
4334 hash_iterate(zvrf->vni_table,
4335 zvni_gw_macip_add_for_vni_hash, NULL);
4336 else
4337 hash_iterate(zvrf->vni_table,
4338 zvni_gw_macip_del_for_vni_hash, NULL);
4339
4340 } else {
4341 struct zebra_if *zif = NULL;
4342 struct zebra_l2info_vxlan zl2_info;
4343 struct interface *vlan_if = NULL;
4344 struct interface *vrr_if = NULL;
4345
4346 if (IS_ZEBRA_DEBUG_VXLAN)
4347 zlog_debug(
4348 "EVPN gateway macip Adv %s on VNI %d , currently %s",
4349 advertise ? "enabled" : "disabled", vni,
4350 advertise_gw_macip_enabled(zvni)
4351 ? "enabled"
4352 : "disabled");
4353
4354 zvni = zvni_lookup(vni);
4355 if (!zvni)
4356 return 0;
4357
4358 if (zvni->advertise_gw_macip == advertise)
4359 return 0;
4360
4361 zvni->advertise_gw_macip = advertise;
4362
4363 ifp = zvni->vxlan_if;
4364 if (!ifp)
4365 return 0;
4366
4367 zif = ifp->info;
4368
4369 /* If down or not mapped to a bridge, we're done. */
4370 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4371 return 0;
4372
4373 zl2_info = zif->l2info.vxl;
4374
4375 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
4376 zif->brslave_info.br_if);
4377 if (!vlan_if)
4378 return 0;
4379
4380 if (advertise_gw_macip_enabled(zvni)) {
4381 /* Add primary SVI MAC-IP */
4382 zvni_add_macip_for_intf(vlan_if, zvni);
4383
4384 /* Add VRR MAC-IP - if any*/
4385 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
4386 if (vrr_if)
4387 zvni_add_macip_for_intf(vrr_if, zvni);
4388 } else {
4389 /* Del primary MAC-IP */
4390 zvni_del_macip_for_intf(vlan_if, zvni);
4391
4392 /* Del VRR MAC-IP - if any*/
4393 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
4394 if (vrr_if)
4395 zvni_del_macip_for_intf(vrr_if, zvni);
4396 }
4397 }
4398
4399 stream_failure:
4400 return 0;
4401 }
4402
4403
4404 /*
4405 * Handle message from client to learn (or stop learning) about VNIs and MACs.
4406 * When enabled, the VNI hash table will be built and MAC FDB table read;
4407 * when disabled, the entries should be deleted and remote VTEPs and MACs
4408 * uninstalled from the kernel.
4409 */
4410 int zebra_vxlan_advertise_all_vni(struct zserv *client,
4411 u_short length, struct zebra_vrf *zvrf)
4412 {
4413 struct stream *s;
4414 int advertise;
4415
4416 if (zvrf_id(zvrf) != VRF_DEFAULT) {
4417 zlog_err("EVPN VNI Adv for non-default VRF %u",
4418 zvrf_id(zvrf));
4419 return -1;
4420 }
4421
4422 s = client->ibuf;
4423 STREAM_GETC(s, advertise);
4424
4425 if (IS_ZEBRA_DEBUG_VXLAN)
4426 zlog_debug("EVPN VNI Adv %s, currently %s",
4427 advertise ? "enabled" : "disabled",
4428 is_evpn_enabled() ? "enabled" : "disabled");
4429
4430 if (zvrf->advertise_all_vni == advertise)
4431 return 0;
4432
4433 zvrf->advertise_all_vni = advertise;
4434 if (is_evpn_enabled()) {
4435 /* Build VNI hash table and inform BGP. */
4436 zvni_build_hash_table();
4437
4438 /* Add all SVI (L3 GW) MACs to BGP*/
4439 hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
4440 NULL);
4441
4442 /* Read the MAC FDB */
4443 macfdb_read(zvrf->zns);
4444
4445 /* Read neighbors */
4446 neigh_read(zvrf->zns);
4447 } else {
4448 /* Cleanup VTEPs for all VNIs - uninstall from
4449 * kernel and free entries.
4450 */
4451 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
4452 }
4453
4454 stream_failure:
4455 return 0;
4456 }
4457
4458 /*
4459 * Allocate VNI hash table for this VRF and do other initialization.
4460 * NOTE: Currently supported only for default VRF.
4461 */
4462 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
4463 {
4464 if (!zvrf)
4465 return;
4466 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
4467 "Zebra VRF VNI Table");
4468 }
4469
4470 /* Close all VNI handling */
4471 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
4472 {
4473 if (!zvrf)
4474 return;
4475 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
4476 hash_free(zvrf->vni_table);
4477 }