]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_vxlan.c
redhat: Add option to build with RPKI
[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, HOST_PREFIX, "host prefix");
52 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
53 DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash");
54 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
55 DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
56 DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
57
58 /* definitions */
59
60
61 /* static function declarations */
62 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
63 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
64 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
65 void **args);
66 static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
67 json_object *json);
68 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
69 json_object *json);
70 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt);
71 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
72 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
73 static void zvni_print(zebra_vni_t *zvni, void **ctxt);
74 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
75
76 static int zvni_macip_send_msg_to_client(vni_t vni,
77 struct ethaddr *macaddr,
78 struct ipaddr *ip, u_char flags,
79 u_int16_t cmd);
80 static unsigned int neigh_hash_keymake(void *p);
81 static int neigh_cmp(const void *p1, const void *p2);
82 static void *zvni_neigh_alloc(void *p);
83 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
84 struct ethaddr *mac);
85 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n);
86 static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg);
87 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
88 struct in_addr *r_vtep_ip);
89 static void zvni_neigh_del_all(zebra_vni_t *zvni,
90 int uninstall, int upd_client, u_int32_t flags);
91 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
92 static int zvni_neigh_send_add_to_client(vni_t vni,
93 struct ipaddr *ip,
94 struct ethaddr *macaddr, u_char flags);
95 static int zvni_neigh_send_del_to_client(vni_t vni,
96 struct ipaddr *ip,
97 struct ethaddr *macaddr, u_char flags);
98 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
99 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
100 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
101 struct interface *br_if);
102 static struct interface *zvni_map_to_svi(vlanid_t vid,
103 struct interface *br_if);
104
105 /* l3-vni next-hop neigh related APIs */
106 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
107 struct ipaddr *ip);
108 static void *zl3vni_nh_alloc(void *p);
109 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
110 struct ipaddr *vtep_ip,
111 struct ethaddr *rmac);
112 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
113 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
114 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni, zebra_neigh_t *n);
115
116 /* l3-vni rmac related APIs */
117 static void zl3vni_print_rmac_hash(struct hash_backet *, void *);
118 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
119 struct ethaddr *rmac);
120 static void *zl3vni_rmac_alloc(void *p);
121 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
122 struct ethaddr *rmac);
123 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
124 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac);
125 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
126 zebra_mac_t *zrmac);
127
128 /* l3-vni related APIs*/
129 static int is_vni_l3(vni_t);
130 static zebra_l3vni_t *zl3vni_lookup(vni_t vni);
131 static void *zl3vni_alloc(void *p);
132 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
133 static int zl3vni_del(zebra_l3vni_t *zl3vni);
134 static zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t);
135 static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni);
136 static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni);
137 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni);
138 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni);
139
140 static unsigned int mac_hash_keymake(void *p);
141 static int mac_cmp(const void *p1, const void *p2);
142 static void *zvni_mac_alloc(void *p);
143 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr);
144 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
145 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg);
146 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
147 struct in_addr *r_vtep_ip);
148 static void zvni_mac_del_all(zebra_vni_t *zvni,
149 int uninstall, int upd_client, u_int32_t flags);
150 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
151 static int zvni_mac_send_add_to_client(vni_t vni,
152 struct ethaddr *macaddr, u_char flags);
153 static int zvni_mac_send_del_to_client(vni_t vni,
154 struct ethaddr *macaddr, u_char flags);
155 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
156 struct interface *br_if, vlanid_t vid);
157 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
158 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local);
159 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
160
161 static unsigned int vni_hash_keymake(void *p);
162 static int vni_hash_cmp(const void *p1, const void *p2);
163 static void *zvni_alloc(void *p);
164 static zebra_vni_t *zvni_lookup(vni_t vni);
165 static zebra_vni_t *zvni_add(vni_t vni);
166 static int zvni_del(zebra_vni_t *zvni);
167 static int zvni_send_add_to_client(zebra_vni_t *zvni);
168 static int zvni_send_del_to_client(vni_t vni);
169 static void zvni_build_hash_table();
170 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
171 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
172 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
173 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
174 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall);
175 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip);
176 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip);
177 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
178 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni);
179 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
180 struct ethaddr *macaddr, struct ipaddr *ip);
181 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
182 struct ipaddr *ip);
183 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp);
184 static int advertise_gw_macip_enabled(zebra_vni_t *zvni);
185 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
186 int uninstall);
187
188 /* Private functions */
189
190 /*
191 * Return number of valid MACs in a VNI's MAC hash table - all
192 * remote MACs and non-internal (auto) local MACs count.
193 */
194 static u_int32_t num_valid_macs(zebra_vni_t *zvni)
195 {
196 unsigned int i;
197 u_int32_t num_macs = 0;
198 struct hash *hash;
199 struct hash_backet *hb;
200 zebra_mac_t *mac;
201
202 hash = zvni->mac_table;
203 if (!hash)
204 return num_macs;
205 for (i = 0; i < hash->size; i++) {
206 for (hb = hash->index[i]; hb; hb = hb->next) {
207 mac = (zebra_mac_t *)hb->data;
208 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
209 || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
210 num_macs++;
211 }
212 }
213
214 return num_macs;
215 }
216
217 static int advertise_gw_macip_enabled(zebra_vni_t *zvni)
218 {
219 struct zebra_vrf *zvrf;
220
221 zvrf = vrf_info_lookup(VRF_DEFAULT);
222 if (zvrf && zvrf->advertise_gw_macip)
223 return 1;
224
225 if (zvni && zvni->advertise_gw_macip)
226 return 1;
227
228 return 0;
229 }
230
231 /*
232 * Helper function to determine maximum width of neighbor IP address for
233 * display - just because we're dealing with IPv6 addresses that can
234 * widely vary.
235 */
236 static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
237 {
238 zebra_neigh_t *n;
239 char buf[INET6_ADDRSTRLEN];
240 struct neigh_walk_ctx *wctx = ctxt;
241 int width;
242
243 n = (zebra_neigh_t *)backet->data;
244 if (!n)
245 return;
246
247 ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
248 if (width > wctx->addr_width)
249 wctx->addr_width = width;
250 }
251
252 /*
253 * Print a specific neighbor entry.
254 */
255 static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
256 {
257 struct vty *vty;
258 char buf1[ETHER_ADDR_STRLEN];
259 char buf2[INET6_ADDRSTRLEN];
260
261 ipaddr2str(&n->ip, buf2, sizeof(buf2));
262 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
263 vty = (struct vty *)ctxt;
264 if (json == NULL) {
265 vty_out(vty, "IP: %s\n",
266 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
267 vty_out(vty, " MAC: %s",
268 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
269 } else {
270 json_object_string_add(json, "ip", buf2);
271 json_object_string_add(json, "mac", buf1);
272 }
273 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
274 if (json == NULL) {
275 vty_out(vty, " Remote VTEP: %s",
276 inet_ntoa(n->r_vtep_ip));
277 } else
278 json_object_string_add(json, "remoteVtep",
279 inet_ntoa(n->r_vtep_ip));
280 }
281 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
282 if (!json) {
283 vty_out(vty, "\n");
284 vty_out(vty, " State: %s",
285 IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active"
286 : "Inactive");
287 }
288 }
289 if (json == NULL)
290 vty_out(vty, "\n");
291 }
292
293 /*
294 * Print neighbor hash entry - called for display of all neighbors.
295 */
296 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
297 {
298 struct vty *vty;
299 json_object *json_vni = NULL, *json_row = NULL;
300 zebra_neigh_t *n;
301 char buf1[ETHER_ADDR_STRLEN];
302 char buf2[INET6_ADDRSTRLEN];
303 struct neigh_walk_ctx *wctx = ctxt;
304
305 vty = wctx->vty;
306 json_vni = wctx->json;
307 n = (zebra_neigh_t *)backet->data;
308 if (!n)
309 return;
310
311 if (json_vni)
312 json_row = json_object_new_object();
313
314 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
315 ipaddr2str(&n->ip, buf2, sizeof(buf2));
316 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
317 && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
318 if (json_vni == NULL) {
319 vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width,
320 buf2, "local", buf1);
321 } else {
322 json_object_string_add(json_row, "type", "local");
323 json_object_string_add(json_row, "mac", buf1);
324 }
325 wctx->count++;
326 } else {
327 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
328 if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
329 if (json_vni == NULL) {
330 if (wctx->count == 0)
331 vty_out(vty,
332 "%*s %-6s %-17s %-21s\n",
333 -wctx->addr_width,
334 "Neighbor", "Type",
335 "MAC", "Remote VTEP");
336 vty_out(vty, "%*s %-6s %-17s %-21s\n",
337 -wctx->addr_width, buf2,
338 "remote", buf1,
339 inet_ntoa(n->r_vtep_ip));
340 } else {
341 json_object_string_add(json_row, "type",
342 "remote");
343 json_object_string_add(json_row, "mac",
344 buf1);
345 json_object_string_add(
346 json_row, "remoteVtep",
347 inet_ntoa(n->r_vtep_ip));
348 }
349 wctx->count++;
350 }
351 } else {
352 if (json_vni == NULL) {
353 vty_out(vty, "%*s %-6s %-17s %-21s\n",
354 -wctx->addr_width, buf2, "remote", buf1,
355 inet_ntoa(n->r_vtep_ip));
356 } else {
357 json_object_string_add(json_row, "type",
358 "remote");
359 json_object_string_add(json_row, "mac", buf1);
360 json_object_string_add(json_row, "remoteVtep",
361 inet_ntoa(n->r_vtep_ip));
362 }
363 wctx->count++;
364 }
365 }
366
367 if (json_vni)
368 json_object_object_add(json_vni, buf2, json_row);
369 }
370
371 /*
372 * Print neighbors for all VNI.
373 */
374 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
375 void **args)
376 {
377 struct vty *vty;
378 json_object *json = NULL, *json_vni = NULL;
379 zebra_vni_t *zvni;
380 u_int32_t num_neigh;
381 struct neigh_walk_ctx wctx;
382 char vni_str[VNI_STR_LEN];
383
384 vty = (struct vty *)args[0];
385 json = (json_object *)args[1];
386
387 zvni = (zebra_vni_t *)backet->data;
388 if (!zvni) {
389 if (json)
390 vty_out(vty, "{}\n");
391 return;
392 }
393 num_neigh = hashcount(zvni->neigh_table);
394 if (json == NULL)
395 vty_out(vty,
396 "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
397 zvni->vni, num_neigh);
398 else {
399 json_vni = json_object_new_object();
400 json_object_int_add(json_vni, "numArpNd", num_neigh);
401 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
402 }
403 if (!num_neigh) {
404 if (json)
405 json_object_object_add(json, vni_str, json_vni);
406 return;
407 }
408
409 /* Since we have IPv6 addresses to deal with which can vary widely in
410 * size, we try to be a bit more elegant in display by first computing
411 * the maximum width.
412 */
413 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
414 wctx.zvni = zvni;
415 wctx.vty = vty;
416 wctx.addr_width = 15;
417 wctx.json = json_vni;
418 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
419
420 if (json == NULL)
421 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
422 "Type", "MAC", "Remote VTEP");
423 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
424
425 if (json)
426 json_object_object_add(json, vni_str, json_vni);
427 }
428
429 /* print a specific next hop for an l3vni */
430 static void zl3vni_print_nh(zebra_neigh_t *n,
431 struct vty *vty,
432 json_object *json)
433 {
434 char buf1[ETHER_ADDR_STRLEN];
435 char buf2[INET6_ADDRSTRLEN];
436 struct listnode *node = NULL;
437 struct prefix *p = NULL;
438 json_object *json_hosts = NULL;
439
440 if (!json) {
441 vty_out(vty, "Ip: %s\n",
442 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
443 vty_out(vty, " RMAC: %s\n",
444 prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
445 vty_out(vty, " Host-List:\n");
446 for (ALL_LIST_ELEMENTS_RO(n->host_list, node, p))
447 vty_out(vty, " %s\n",
448 prefix2str(p, buf2, sizeof(buf2)));
449 } else {
450 json_hosts = json_object_new_array();
451 json_object_string_add(json, "ip",
452 ipaddr2str(&(n->ip), buf2,
453 sizeof(buf2)));
454 json_object_string_add(json, "rmac",
455 prefix_mac2str(&n->emac, buf2,
456 sizeof(buf2)));
457 for (ALL_LIST_ELEMENTS_RO(n->host_list, node, p))
458 json_object_array_add(json_hosts,
459 json_object_new_string(
460 prefix2str(p, buf2,
461 sizeof(buf2))));
462 json_object_object_add(json, "hosts", json_hosts);
463 }
464 }
465
466 /* Print a specific RMAC entry */
467 static void zl3vni_print_rmac(zebra_mac_t *zrmac,
468 struct vty *vty,
469 json_object *json)
470 {
471 char buf1[ETHER_ADDR_STRLEN];
472 char buf2[PREFIX_STRLEN];
473 struct listnode *node = NULL;
474 struct prefix *p = NULL;
475 json_object *json_hosts = NULL;
476
477 if (!json) {
478 vty_out(vty, "MAC: %s\n",
479 prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
480 vty_out(vty, " Remote VTEP: %s\n",
481 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
482 vty_out(vty, " Host-List:\n");
483 for (ALL_LIST_ELEMENTS_RO(zrmac->host_list, node, p))
484 vty_out(vty, " %s\n",
485 prefix2str(p, buf2, sizeof(buf2)));
486 } else {
487 json_hosts = json_object_new_array();
488 json_object_string_add(json, "Rmac",
489 prefix_mac2str(&zrmac->macaddr,
490 buf1,
491 sizeof(buf1)));
492 json_object_string_add(json, "vtep-ip",
493 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
494 for (ALL_LIST_ELEMENTS_RO(zrmac->host_list, node, p))
495 json_object_array_add(json_hosts,
496 json_object_new_string(
497 prefix2str(p, buf2,
498 sizeof(buf2))));
499 json_object_object_add(json, "hosts", json_hosts);
500 }
501 }
502
503 /*
504 * Print a specific MAC entry.
505 */
506 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
507 {
508 struct vty *vty;
509 zebra_neigh_t *n = NULL;
510 struct listnode *node = NULL;
511 char buf1[20];
512 char buf2[INET6_ADDRSTRLEN];
513
514 vty = (struct vty *)ctxt;
515 vty_out(vty, "MAC: %s",
516 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
517 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
518 struct zebra_ns *zns;
519 struct interface *ifp;
520 ifindex_t ifindex;
521
522 ifindex = mac->fwd_info.local.ifindex;
523 zns = zebra_ns_lookup(NS_DEFAULT);
524 ifp = if_lookup_by_index_per_ns(zns, ifindex);
525 if (!ifp) // unexpected
526 return;
527 vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
528 if (mac->fwd_info.local.vid)
529 vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
530 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
531 vty_out(vty, " Remote VTEP: %s",
532 inet_ntoa(mac->fwd_info.r_vtep_ip));
533 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
534 vty_out(vty, " Auto Mac ");
535 }
536
537 vty_out(vty, "\n");
538 /* print all the associated neigh */
539 vty_out(vty, " Neighbors:\n");
540 if (!listcount(mac->neigh_list))
541 vty_out(vty, " No Neighbors\n");
542 else {
543 for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
544 vty_out(vty, " %s %s\n",
545 ipaddr2str(&n->ip, buf2, sizeof(buf2)),
546 CHECK_FLAG(n->flags, ZEBRA_MAC_LOCAL)
547 ? (IS_ZEBRA_NEIGH_ACTIVE(n)
548 ? "Active"
549 : "Inactive")
550 : "");
551 }
552 }
553
554 vty_out(vty, "\n");
555 }
556
557 /*
558 * Print MAC hash entry - called for display of all MACs.
559 */
560 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
561 {
562 struct vty *vty;
563 json_object *json_mac_hdr = NULL, *json_mac = NULL;
564 zebra_mac_t *mac;
565 char buf1[20];
566 struct mac_walk_ctx *wctx = ctxt;
567
568 vty = wctx->vty;
569 json_mac_hdr = wctx->json;
570 mac = (zebra_mac_t *)backet->data;
571 if (!mac)
572 return;
573
574 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
575
576 if (json_mac_hdr)
577 json_mac = json_object_new_object();
578
579 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
580 && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
581 struct zebra_ns *zns;
582 ifindex_t ifindex;
583 struct interface *ifp;
584 vlanid_t vid;
585
586 zns = zebra_ns_lookup(NS_DEFAULT);
587 ifindex = mac->fwd_info.local.ifindex;
588 ifp = if_lookup_by_index_per_ns(zns, ifindex);
589 if (!ifp) // unexpected
590 return;
591 vid = mac->fwd_info.local.vid;
592 if (json_mac_hdr == NULL)
593 vty_out(vty, "%-17s %-6s %-21s", buf1, "local",
594 ifp->name);
595 else {
596 json_object_string_add(json_mac, "type", "local");
597 json_object_string_add(json_mac, "intf", ifp->name);
598 }
599 if (vid) {
600 if (json_mac_hdr == NULL)
601 vty_out(vty, " %-5u", vid);
602 else
603 json_object_int_add(json_mac, "vlan", vid);
604 }
605 if (json_mac_hdr == NULL)
606 vty_out(vty, "\n");
607 else
608 json_object_object_add(json_mac_hdr, buf1, json_mac);
609 wctx->count++;
610 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
611 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
612 if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
613 &wctx->r_vtep_ip)) {
614 if (wctx->count == 0) {
615 if (json_mac_hdr == NULL) {
616 vty_out(vty, "\nVNI %u\n\n",
617 wctx->zvni->vni);
618 vty_out(vty,
619 "%-17s %-6s %-21s %-5s\n",
620 "MAC", "Type",
621 "Intf/Remote VTEP",
622 "VLAN");
623 }
624 }
625 if (json_mac_hdr == NULL)
626 vty_out(vty, "%-17s %-6s %-21s\n", buf1,
627 "remote",
628 inet_ntoa(mac->fwd_info
629 .r_vtep_ip));
630 else {
631 json_object_string_add(json_mac, "type",
632 "remote");
633 json_object_string_add(
634 json_mac, "remoteVtep",
635 inet_ntoa(mac->fwd_info
636 .r_vtep_ip));
637 json_object_object_add(json_mac_hdr,
638 buf1, json_mac);
639 }
640 wctx->count++;
641 }
642 } else {
643 if (json_mac_hdr == NULL)
644 vty_out(vty, "%-17s %-6s %-21s\n", buf1,
645 "remote",
646 inet_ntoa(mac->fwd_info.r_vtep_ip));
647 else {
648 json_object_string_add(json_mac, "type",
649 "remote");
650 json_object_string_add(
651 json_mac, "remoteVtep",
652 inet_ntoa(mac->fwd_info.r_vtep_ip));
653 json_object_object_add(json_mac_hdr, buf1,
654 json_mac);
655 }
656 wctx->count++;
657 }
658 }
659 }
660
661 /*
662 * Print MACs for all VNI.
663 */
664 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
665 {
666 struct vty *vty;
667 json_object *json = NULL, *json_vni = NULL;
668 json_object *json_mac = NULL;
669 zebra_vni_t *zvni;
670 u_int32_t num_macs;
671 struct mac_walk_ctx *wctx = ctxt;
672 char vni_str[VNI_STR_LEN];
673
674 vty = (struct vty *)wctx->vty;
675 json = (struct json_object *)wctx->json;
676
677 zvni = (zebra_vni_t *)backet->data;
678 if (!zvni) {
679 if (json)
680 vty_out(vty, "{}\n");
681 return;
682 }
683 wctx->zvni = zvni;
684
685 /*We are iterating over a new VNI, set the count to 0*/
686 wctx->count = 0;
687
688 num_macs = num_valid_macs(zvni);
689 if (!num_macs)
690 return;
691
692 if (json) {
693 json_vni = json_object_new_object();
694 json_mac = json_object_new_object();
695 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
696 }
697
698 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
699 if (json == NULL) {
700 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
701 zvni->vni, num_macs);
702 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
703 "Intf/Remote VTEP", "VLAN");
704 } else
705 json_object_int_add(json_vni, "numMacs", num_macs);
706 }
707 /* assign per-vni to wctx->json object to fill macs
708 * under the vni. Re-assign primary json object to fill
709 * next vni information.
710 */
711 wctx->json = json_mac;
712 hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
713 wctx->json = json;
714 if (json) {
715 if (wctx->count)
716 json_object_object_add(json_vni, "macs", json_mac);
717 json_object_object_add(json, vni_str, json_vni);
718 }
719 }
720
721 static void zl3vni_print_nh_hash(struct hash_backet *backet,
722 void *ctx)
723 {
724 struct nh_walk_ctx *wctx = NULL;
725 struct vty *vty = NULL;
726 struct json_object *json_vni = NULL;
727 struct json_object *json_nh = NULL;
728 zebra_neigh_t *n = NULL;
729 char buf1[ETHER_ADDR_STRLEN];
730 char buf2[INET6_ADDRSTRLEN];
731
732 wctx = (struct nh_walk_ctx *)ctx;
733 vty = wctx->vty;
734 json_vni = wctx->json;
735 if (json_vni)
736 json_nh = json_object_new_object();
737 n = (zebra_neigh_t *)backet->data;
738 if (!n)
739 return;
740
741 if (!json_vni) {
742 vty_out(vty, "%-15s %-17s %6d\n",
743 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
744 prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
745 listcount(n->host_list));
746 } else {
747 json_object_string_add(json_nh, "nexthop-ip",
748 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
749 json_object_string_add(json_nh, "rmac",
750 prefix_mac2str(&n->emac, buf1,
751 sizeof(buf1)));
752 json_object_int_add(json_nh, "refCnt", listcount(n->host_list));
753 json_object_object_add(json_vni,
754 ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
755 json_nh);
756 }
757 }
758
759 static void zl3vni_print_nh_hash_all_vni(struct hash_backet *backet,
760 void **args)
761 {
762 struct vty *vty = NULL;
763 json_object *json = NULL;
764 json_object *json_vni = NULL;
765 zebra_l3vni_t *zl3vni = NULL;
766 uint32_t num_nh = 0;
767 struct nh_walk_ctx wctx;
768 char vni_str[VNI_STR_LEN];
769
770 vty = (struct vty *)args[0];
771 json = (struct json_object *)args[1];
772
773 zl3vni = (zebra_l3vni_t *)backet->data;
774 if (!zl3vni) {
775 if (json)
776 vty_out(vty, "{}\n");
777 return;
778 }
779
780 num_nh = hashcount(zl3vni->nh_table);
781 if (!num_nh)
782 return;
783
784 if (json) {
785 json_vni = json_object_new_object();
786 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
787 }
788
789 if (json == NULL) {
790 vty_out(vty, "\nVNI %u #Next-Hops %u\n\n",
791 zl3vni->vni, num_nh);
792 vty_out(vty, "%-15s %-17s %6s\n", "IP",
793 "RMAC", "Refcnt");
794 } else
795 json_object_int_add(json_vni, "numNh", num_nh);
796
797 memset(&wctx, 0, sizeof(struct nh_walk_ctx));
798 wctx.vty = vty;
799 wctx.json = json_vni;
800 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
801 if (json)
802 json_object_object_add(json, vni_str, json_vni);
803 }
804
805 static void zl3vni_print_rmac_hash_all_vni(struct hash_backet *backet,
806 void **args)
807 {
808 struct vty *vty = NULL;
809 json_object *json = NULL;
810 json_object *json_vni = NULL;
811 zebra_l3vni_t *zl3vni = NULL;
812 u_int32_t num_rmacs;
813 struct rmac_walk_ctx wctx;
814 char vni_str[VNI_STR_LEN];
815
816 vty = (struct vty *)args[0];
817 json = (struct json_object *)args[1];
818
819 zl3vni = (zebra_l3vni_t *)backet->data;
820 if (!zl3vni) {
821 if (json)
822 vty_out(vty, "{}\n");
823 return;
824 }
825
826 num_rmacs = hashcount(zl3vni->rmac_table);
827 if (!num_rmacs)
828 return;
829
830 if (json) {
831 json_vni = json_object_new_object();
832 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
833 }
834
835 if (json == NULL) {
836 vty_out(vty, "\nVNI %u #MACs %u\n\n",
837 zl3vni->vni, num_rmacs);
838 vty_out(vty, "%-17s %-21s %-6s\n", "MAC",
839 "Remote VTEP", "Refcnt");
840 } else
841 json_object_int_add(json_vni, "numRmacs", num_rmacs);
842
843 /* assign per-vni to wctx->json object to fill macs
844 * under the vni. Re-assign primary json object to fill
845 * next vni information.
846 */
847 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
848 wctx.vty = vty;
849 wctx.json = json_vni;
850 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
851 if (json)
852 json_object_object_add(json, vni_str, json_vni);
853 }
854
855 static void zl3vni_print_rmac_hash(struct hash_backet *backet,
856 void *ctx)
857 {
858 zebra_mac_t *zrmac = NULL;
859 struct rmac_walk_ctx *wctx = NULL;
860 struct vty *vty = NULL;
861 struct json_object *json = NULL;
862 struct json_object *json_rmac = NULL;
863 char buf[ETHER_ADDR_STRLEN];
864
865 wctx = (struct rmac_walk_ctx *)ctx;
866 vty = wctx->vty;
867 json = wctx->json;
868 if (json)
869 json_rmac = json_object_new_object();
870 zrmac = (zebra_mac_t *)backet->data;
871 if (!zrmac)
872 return;
873
874 if (!json) {
875 vty_out(vty, "%-17s %-21s %-6d\n",
876 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
877 inet_ntoa(zrmac->fwd_info.r_vtep_ip),
878 listcount(zrmac->host_list));
879 } else {
880 json_object_string_add(json_rmac, "rmac",
881 prefix_mac2str(&zrmac->macaddr, buf,
882 sizeof(buf)));
883 json_object_string_add(json_rmac, "vtep-ip",
884 inet_ntoa(zrmac->fwd_info.r_vtep_ip));
885 json_object_int_add(json_rmac, "refcnt",
886 listcount(zrmac->host_list));
887 json_object_object_add(json,
888 prefix_mac2str(&zrmac->macaddr, buf,
889 sizeof(buf)),
890 json_rmac);
891 }
892 }
893
894 /* print a specific L3 VNI entry */
895 static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
896 {
897 char buf[ETHER_ADDR_STRLEN];
898 struct vty *vty = NULL;
899 json_object *json = NULL;
900 zebra_vni_t *zvni = NULL;
901 json_object *json_vni_list = NULL;
902 struct listnode *node = NULL, *nnode = NULL;
903
904 vty = ctx[0];
905 json = ctx[1];
906
907 if (!json) {
908 vty_out(vty, "VNI: %u\n", zl3vni->vni);
909 vty_out(vty, " Local Vtep Ip: %s",
910 inet_ntoa(zl3vni->local_vtep_ip));
911 vty_out(vty, " Vxlan-Intf: %s\n",
912 zl3vni_vxlan_if_name(zl3vni));
913 vty_out(vty, " SVI-If: %s\n",
914 zl3vni_svi_if_name(zl3vni));
915 vty_out(vty, " State: %s\n",
916 zl3vni_state2str(zl3vni));
917 vty_out(vty, " Vrf: %s\n",
918 zl3vni_vrf_name(zl3vni));
919 vty_out(vty, " Rmac: %s\n",
920 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
921 vty_out(vty, " L2-VNIs: ");
922 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni))
923 vty_out(vty, "%u ", zvni->vni);
924 vty_out(vty, "\n");
925 } else {
926 json_vni_list = json_object_new_array();
927 json_object_int_add(json, "vni", zl3vni->vni);
928 json_object_string_add(json, "local-vtep-ip",
929 inet_ntoa(zl3vni->local_vtep_ip));
930 json_object_string_add(json, "vxlan-intf",
931 zl3vni_vxlan_if_name(zl3vni));
932 json_object_string_add(json, "svi-if",
933 zl3vni_svi_if_name(zl3vni));
934 json_object_string_add(json, "state",
935 zl3vni_state2str(zl3vni));
936 json_object_string_add(json, "vrf",
937 zl3vni_vrf_name(zl3vni));
938 json_object_string_add(json, "rmac",
939 zl3vni_rmac2str(zl3vni, buf,
940 sizeof(buf)));
941 for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni)) {
942 json_object_array_add(json_vni_list,
943 json_object_new_int(zvni->vni));
944 }
945 json_object_object_add(json, "l2-vnis", json_vni_list);
946 }
947 }
948
949 /*
950 * Print a specific VNI entry.
951 */
952 static void zvni_print(zebra_vni_t *zvni, void **ctxt)
953 {
954 struct vty *vty;
955 zebra_vtep_t *zvtep;
956 u_int32_t num_macs;
957 u_int32_t num_neigh;
958 json_object *json = NULL;
959 json_object *json_vtep_list = NULL;
960 json_object *json_ip_str = NULL;
961
962 vty = ctxt[0];
963 json = ctxt[1];
964
965 if (json == NULL) {
966 vty_out(vty, "VNI: %u\n", zvni->vni);
967 vty_out(vty, " VRF: %s\n", vrf_id_to_name(zvni->vrf_id));
968 } else {
969 json_object_int_add(json, "vni", zvni->vni);
970 json_object_string_add(json, "vrf",
971 vrf_id_to_name(zvni->vrf_id));
972 }
973
974 if (!zvni->vxlan_if) { // unexpected
975 if (json == NULL)
976 vty_out(vty, " VxLAN interface: unknown\n");
977 return;
978 }
979 num_macs = num_valid_macs(zvni);
980 num_neigh = hashcount(zvni->neigh_table);
981 if (json == NULL)
982 vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
983 zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
984 inet_ntoa(zvni->local_vtep_ip));
985 else {
986 json_object_string_add(json, "vxlanInterface",
987 zvni->vxlan_if->name);
988 json_object_int_add(json, "ifindex", zvni->vxlan_if->ifindex);
989 json_object_string_add(json, "vtepIp",
990 inet_ntoa(zvni->local_vtep_ip));
991 json_object_string_add(json, "advertiseGatewayMacip",
992 zvni->advertise_gw_macip ? "Yes" : "No");
993 json_object_int_add(json, "numMacs", num_macs);
994 json_object_int_add(json, "numArpNd", num_neigh);
995 }
996 if (!zvni->vteps) {
997 if (json == NULL)
998 vty_out(vty, " No remote VTEPs known for this VNI\n");
999 } else {
1000 if (json == NULL)
1001 vty_out(vty, " Remote VTEPs for this VNI:\n");
1002 else
1003 json_vtep_list = json_object_new_array();
1004 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1005 if (json == NULL)
1006 vty_out(vty, " %s\n",
1007 inet_ntoa(zvtep->vtep_ip));
1008 else {
1009 json_ip_str = json_object_new_string(
1010 inet_ntoa(zvtep->vtep_ip));
1011 json_object_array_add(json_vtep_list,
1012 json_ip_str);
1013 }
1014 }
1015 if (json)
1016 json_object_object_add(json, "numRemoteVteps",
1017 json_vtep_list);
1018 }
1019 if (json == NULL) {
1020 vty_out(vty,
1021 " Number of MACs (local and remote) known for this VNI: %u\n",
1022 num_macs);
1023 vty_out(vty,
1024 " Number of ARPs (IPv4 and IPv6, local and remote) "
1025 "known for this VNI: %u\n",
1026 num_neigh);
1027 vty_out(vty, " Advertise-gw-macip: %s\n",
1028 zvni->advertise_gw_macip ? "Yes" : "No");
1029 }
1030 }
1031
1032 /* print a L3 VNI hash entry */
1033 static void zl3vni_print_hash(struct hash_backet *backet,
1034 void *ctx[])
1035 {
1036 char buf[ETHER_ADDR_STRLEN];
1037 struct vty *vty = NULL;
1038 json_object *json = NULL;
1039 json_object *json_vni = NULL;
1040 zebra_l3vni_t *zl3vni = NULL;
1041
1042 vty = (struct vty *)ctx[0];
1043 json = (json_object *)ctx[1];
1044
1045 zl3vni = (zebra_l3vni_t *)backet->data;
1046 if (!zl3vni)
1047 return;
1048
1049 if (!json) {
1050 vty_out(vty, "%-10u %-15s %-20s %-20s %-5s %-37s %-18s\n",
1051 zl3vni->vni,
1052 inet_ntoa(zl3vni->local_vtep_ip),
1053 zl3vni_vxlan_if_name(zl3vni),
1054 zl3vni_svi_if_name(zl3vni),
1055 zl3vni_state2str(zl3vni),
1056 zl3vni_vrf_name(zl3vni),
1057 zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
1058 } else {
1059 char vni_str[VNI_STR_LEN];
1060
1061 snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
1062 json_vni = json_object_new_object();
1063 json_object_int_add(json_vni, "vni", zl3vni->vni);
1064 json_object_string_add(json_vni, "local-ip",
1065 inet_ntoa(zl3vni->local_vtep_ip));
1066 json_object_string_add(json_vni, "vxlan-if",
1067 zl3vni_vxlan_if_name(zl3vni));
1068 json_object_string_add(json_vni, "svi-if",
1069 zl3vni_svi_if_name(zl3vni));
1070 json_object_string_add(json_vni, "state",
1071 zl3vni_state2str(zl3vni));
1072 json_object_string_add(json_vni, "vrf",
1073 zl3vni_vrf_name(zl3vni));
1074 json_object_string_add(json_vni, "rmac",
1075 zl3vni_rmac2str(zl3vni, buf,
1076 sizeof(buf)));
1077 json_object_object_add(json, vni_str, json_vni);
1078 }
1079
1080 }
1081
1082 /*
1083 * Print a VNI hash entry - called for display of all VNIs.
1084 */
1085 static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
1086 {
1087 struct vty *vty;
1088 zebra_vni_t *zvni;
1089 zebra_vtep_t *zvtep;
1090 u_int32_t num_vteps = 0;
1091 u_int32_t num_macs = 0;
1092 u_int32_t num_neigh = 0;
1093 json_object *json = NULL;
1094 json_object *json_vni = NULL;
1095 json_object *json_ip_str = NULL;
1096 json_object *json_vtep_list = NULL;
1097
1098 vty = ctxt[0];
1099 json = ctxt[1];
1100
1101 zvni = (zebra_vni_t *)backet->data;
1102 if (!zvni)
1103 return;
1104
1105 zvtep = zvni->vteps;
1106 while (zvtep) {
1107 num_vteps++;
1108 zvtep = zvtep->next;
1109 }
1110
1111 num_macs = num_valid_macs(zvni);
1112 num_neigh = hashcount(zvni->neigh_table);
1113 if (json == NULL)
1114 vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u %-37s\n",
1115 zvni->vni,
1116 zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
1117 inet_ntoa(zvni->local_vtep_ip), num_macs, num_neigh,
1118 num_vteps,
1119 vrf_id_to_name(zvni->vrf_id));
1120 else {
1121 char vni_str[VNI_STR_LEN];
1122 snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
1123 json_vni = json_object_new_object();
1124 json_object_string_add(json_vni, "vxlanIf",
1125 zvni->vxlan_if ? zvni->vxlan_if->name
1126 : "unknown");
1127 json_object_string_add(json_vni, "vtepIp",
1128 inet_ntoa(zvni->local_vtep_ip));
1129 json_object_int_add(json_vni, "numMacs", num_macs);
1130 json_object_int_add(json_vni, "numArpNd", num_neigh);
1131 json_object_int_add(json_vni, "numRemoteVteps", num_vteps);
1132 if (num_vteps) {
1133 json_vtep_list = json_object_new_array();
1134 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1135 json_ip_str = json_object_new_string(
1136 inet_ntoa(zvtep->vtep_ip));
1137 json_object_array_add(json_vtep_list,
1138 json_ip_str);
1139 }
1140 json_object_object_add(json_vni, "remoteVteps",
1141 json_vtep_list);
1142 }
1143 json_object_object_add(json, vni_str, json_vni);
1144 }
1145 }
1146
1147 /*
1148 * Inform BGP about local MACIP.
1149 */
1150 static int zvni_macip_send_msg_to_client(vni_t vni,
1151 struct ethaddr *macaddr,
1152 struct ipaddr *ip, u_char flags,
1153 u_int16_t cmd)
1154 {
1155 char buf[ETHER_ADDR_STRLEN];
1156 char buf2[INET6_ADDRSTRLEN];
1157 int ipa_len;
1158 struct zserv *client = NULL;
1159 struct stream *s = NULL;
1160
1161 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
1162 /* BGP may not be running. */
1163 if (!client)
1164 return 0;
1165
1166 s = client->obuf;
1167 stream_reset(s);
1168
1169 zclient_create_header(s, cmd, VRF_DEFAULT);
1170 stream_putl(s, vni);
1171 stream_put(s, macaddr->octet, ETH_ALEN);
1172 if (ip) {
1173 ipa_len = 0;
1174 if (IS_IPADDR_V4(ip))
1175 ipa_len = IPV4_MAX_BYTELEN;
1176 else if (IS_IPADDR_V6(ip))
1177 ipa_len = IPV6_MAX_BYTELEN;
1178
1179 stream_putl(s, ipa_len); /* IP address length */
1180 if (ipa_len)
1181 stream_put(s, &ip->ip.addr, ipa_len); /* IP address */
1182 } else
1183 stream_putl(s, 0); /* Just MAC. */
1184
1185 stream_putc(s, flags); /* sticky mac/gateway mac */
1186
1187
1188 /* Write packet size. */
1189 stream_putw_at(s, 0, stream_get_endp(s));
1190
1191 if (IS_ZEBRA_DEBUG_VXLAN)
1192 zlog_debug(
1193 "Send MACIP %s flags 0x%x MAC %s IP %s L2-VNI %u to %s",
1194 (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
1195 flags, prefix_mac2str(macaddr, buf, sizeof(buf)),
1196 ipaddr2str(ip, buf2, sizeof(buf2)), vni,
1197 zebra_route_string(client->proto));
1198
1199 if (cmd == ZEBRA_MACIP_ADD)
1200 client->macipadd_cnt++;
1201 else
1202 client->macipdel_cnt++;
1203
1204 return zebra_server_send_message(client);
1205 }
1206
1207 /*
1208 * Make hash key for neighbors.
1209 */
1210 static unsigned int neigh_hash_keymake(void *p)
1211 {
1212 zebra_neigh_t *n = p;
1213 struct ipaddr *ip = &n->ip;
1214
1215 if (IS_IPADDR_V4(ip))
1216 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
1217
1218 return jhash2(ip->ipaddr_v6.s6_addr32,
1219 ZEBRA_NUM_OF(ip->ipaddr_v6.s6_addr32), 0);
1220 }
1221
1222 /*
1223 * Compare two neighbor hash structures.
1224 */
1225 static int neigh_cmp(const void *p1, const void *p2)
1226 {
1227 const zebra_neigh_t *n1 = p1;
1228 const zebra_neigh_t *n2 = p2;
1229
1230 if (n1 == NULL && n2 == NULL)
1231 return 1;
1232
1233 if (n1 == NULL || n2 == NULL)
1234 return 0;
1235
1236 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
1237 }
1238
1239 /*
1240 * Callback to allocate neighbor hash entry.
1241 */
1242 static void *zvni_neigh_alloc(void *p)
1243 {
1244 const zebra_neigh_t *tmp_n = p;
1245 zebra_neigh_t *n;
1246
1247 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
1248 *n = *tmp_n;
1249
1250 return ((void *)n);
1251 }
1252
1253 /*
1254 * Add neighbor entry.
1255 */
1256 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
1257 struct ethaddr *mac)
1258 {
1259 zebra_neigh_t tmp_n;
1260 zebra_neigh_t *n = NULL;
1261 zebra_mac_t *zmac = NULL;
1262
1263 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
1264 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
1265 n = hash_get(zvni->neigh_table, &tmp_n, zvni_neigh_alloc);
1266 assert(n);
1267
1268 memcpy(&n->emac, mac, ETH_ALEN);
1269 n->state = ZEBRA_NEIGH_INACTIVE;
1270
1271 /* Associate the neigh to mac */
1272 zmac = zvni_mac_lookup(zvni, mac);
1273 if (zmac)
1274 listnode_add_sort(zmac->neigh_list, n);
1275
1276 return n;
1277 }
1278
1279 /*
1280 * Delete neighbor entry.
1281 */
1282 static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
1283 {
1284 zebra_neigh_t *tmp_n;
1285 zebra_mac_t *zmac = NULL;
1286
1287 zmac = zvni_mac_lookup(zvni, &n->emac);
1288 if (zmac)
1289 listnode_delete(zmac->neigh_list, n);
1290
1291 /* Free the VNI hash entry and allocated memory. */
1292 tmp_n = hash_release(zvni->neigh_table, n);
1293 if (tmp_n)
1294 XFREE(MTYPE_NEIGH, tmp_n);
1295
1296 return 0;
1297 }
1298
1299 /*
1300 * Free neighbor hash entry (callback)
1301 */
1302 static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
1303 {
1304 struct neigh_walk_ctx *wctx = arg;
1305 zebra_neigh_t *n = backet->data;
1306
1307 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
1308 || ((wctx->flags & DEL_REMOTE_NEIGH)
1309 && (n->flags & ZEBRA_NEIGH_REMOTE))
1310 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
1311 && (n->flags & ZEBRA_NEIGH_REMOTE)
1312 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
1313 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
1314 zvni_neigh_send_del_to_client(wctx->zvni->vni, &n->ip,
1315 &n->emac, 0);
1316
1317 if (wctx->uninstall)
1318 zvni_neigh_uninstall(wctx->zvni, n);
1319
1320 return zvni_neigh_del(wctx->zvni, n);
1321 }
1322
1323 return 0;
1324 }
1325
1326 /*
1327 * Delete all neighbor entries from specific VTEP for a particular VNI.
1328 */
1329 static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
1330 struct in_addr *r_vtep_ip)
1331 {
1332 struct neigh_walk_ctx wctx;
1333
1334 if (!zvni->neigh_table)
1335 return;
1336
1337 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1338 wctx.zvni = zvni;
1339 wctx.uninstall = uninstall;
1340 wctx.flags = DEL_REMOTE_NEIGH_FROM_VTEP;
1341 wctx.r_vtep_ip = *r_vtep_ip;
1342
1343 hash_iterate(zvni->neigh_table,
1344 (void (*)(struct hash_backet *,
1345 void *))zvni_neigh_del_hash_entry,
1346 &wctx);
1347 }
1348
1349 /*
1350 * Delete all neighbor entries for this VNI.
1351 */
1352 static void zvni_neigh_del_all(zebra_vni_t *zvni,
1353 int uninstall, int upd_client, u_int32_t flags)
1354 {
1355 struct neigh_walk_ctx wctx;
1356
1357 if (!zvni->neigh_table)
1358 return;
1359
1360 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1361 wctx.zvni = zvni;
1362 wctx.uninstall = uninstall;
1363 wctx.upd_client = upd_client;
1364 wctx.flags = flags;
1365
1366 hash_iterate(zvni->neigh_table,
1367 (void (*)(struct hash_backet *,
1368 void *))zvni_neigh_del_hash_entry,
1369 &wctx);
1370 }
1371
1372 /*
1373 * Look up neighbor hash entry.
1374 */
1375 static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
1376 {
1377 zebra_neigh_t tmp;
1378 zebra_neigh_t *n;
1379
1380 memset(&tmp, 0, sizeof(tmp));
1381 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
1382 n = hash_lookup(zvni->neigh_table, &tmp);
1383
1384 return n;
1385 }
1386
1387 /* Process all neigh associated to a mac upon local mac add event */
1388 static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni,
1389 zebra_mac_t *zmac)
1390 {
1391 zebra_neigh_t *n = NULL;
1392 struct listnode *node = NULL;
1393 char buf[ETHER_ADDR_STRLEN];
1394 char buf2[INET6_ADDRSTRLEN];
1395
1396 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1397 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1398 /* MAC is learnt locally, program all inactive neigh
1399 * pointing to this mac */
1400 if (IS_ZEBRA_NEIGH_INACTIVE(n)) {
1401 if (IS_ZEBRA_DEBUG_VXLAN)
1402 zlog_debug(
1403 "neigh %s (MAC %s) on L2-VNI %u is now ACTIVE",
1404 ipaddr2str(&n->ip, buf2,
1405 sizeof(buf2)),
1406 prefix_mac2str(&n->emac, buf,
1407 sizeof(buf)),
1408 zvni->vni);
1409
1410 ZEBRA_NEIGH_SET_ACTIVE(n);
1411 zvni_neigh_send_add_to_client(
1412 zvni->vni, &n->ip, &n->emac, 0);
1413 } else {
1414 if (IS_ZEBRA_DEBUG_VXLAN)
1415 zlog_debug(
1416 "neigh %s (MAC %s) on VNI %u should NOT be ACTIVE",
1417 ipaddr2str(&n->ip, buf2,
1418 sizeof(buf2)),
1419 prefix_mac2str(&n->emac, buf,
1420 sizeof(buf)),
1421 zvni->vni);
1422 }
1423 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1424 /* TODO: assume the neigh has moved too ?? */
1425 }
1426 }
1427 }
1428
1429 /* Process all neigh associated to a mac upon local mac del event */
1430 static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni,
1431 zebra_mac_t *zmac)
1432 {
1433 zebra_neigh_t *n = NULL;
1434 struct listnode *node = NULL;
1435 char buf[ETHER_ADDR_STRLEN];
1436 char buf2[INET6_ADDRSTRLEN];
1437
1438 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1439 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1440 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1441 if (IS_ZEBRA_DEBUG_VXLAN)
1442 zlog_debug(
1443 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1444 ipaddr2str(&n->ip, buf2,
1445 sizeof(buf2)),
1446 prefix_mac2str(&n->emac, buf,
1447 sizeof(buf)),
1448 zvni->vni);
1449
1450 ZEBRA_NEIGH_SET_INACTIVE(n);
1451 zvni_neigh_send_del_to_client(
1452 zvni->vni, &n->ip, &n->emac, 0);
1453 }
1454 } else if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1455 if (IS_ZEBRA_DEBUG_VXLAN)
1456 zlog_err(
1457 "local MAC %s getting deleted on VNI %u has remote neigh %s",
1458 prefix_mac2str(&n->emac, buf,
1459 sizeof(buf)),
1460 zvni->vni,
1461 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1462 }
1463 }
1464 }
1465
1466 /* process all neigh associated to a mac entry upon remote mac add */
1467 static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
1468 zebra_mac_t *zmac)
1469 {
1470 zebra_neigh_t *n = NULL;
1471 struct listnode *node = NULL;
1472 char buf[ETHER_ADDR_STRLEN];
1473 char buf2[INET6_ADDRSTRLEN];
1474
1475 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1476 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1477 if (IS_ZEBRA_NEIGH_ACTIVE(n)) {
1478 if (IS_ZEBRA_DEBUG_VXLAN)
1479 zlog_debug(
1480 "neigh %s (MAC %s) on L2-VNI %u is now INACTIVE",
1481 ipaddr2str(&n->ip, buf2,
1482 sizeof(buf2)),
1483 prefix_mac2str(&n->emac, buf,
1484 sizeof(buf)),
1485 zvni->vni);
1486
1487 ZEBRA_NEIGH_SET_INACTIVE(n);
1488 zvni_neigh_send_del_to_client(
1489 zvni->vni, &n->ip, &n->emac, 0);
1490 }
1491 }
1492 }
1493 }
1494
1495 /* process all neigh associated to mac entry upon remote mac del */
1496 static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
1497 zebra_mac_t *zmac)
1498 {
1499 zebra_neigh_t *n = NULL;
1500 struct listnode *node = NULL;
1501 char buf[ETHER_ADDR_STRLEN];
1502 char buf2[INET6_ADDRSTRLEN];
1503
1504 for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, n)) {
1505 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1506 if (IS_ZEBRA_DEBUG_VXLAN)
1507 zlog_err(
1508 "remote MAC %s getting deleted on VNI %u has local neigh %s",
1509 prefix_mac2str(&n->emac, buf,
1510 sizeof(buf)),
1511 zvni->vni,
1512 ipaddr2str(&n->ip, buf2, sizeof(buf2)));
1513 }
1514 }
1515 }
1516
1517 /*
1518 * Inform BGP about local neighbor addition.
1519 */
1520 static int zvni_neigh_send_add_to_client(vni_t vni,
1521 struct ipaddr *ip,
1522 struct ethaddr *macaddr, u_char flags)
1523 {
1524 return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
1525 ZEBRA_MACIP_ADD);
1526 }
1527
1528 /*
1529 * Inform BGP about local neighbor deletion.
1530 */
1531 static int zvni_neigh_send_del_to_client(vni_t vni,
1532 struct ipaddr *ip,
1533 struct ethaddr *macaddr, u_char flags)
1534 {
1535 return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
1536 ZEBRA_MACIP_DEL);
1537 }
1538
1539 /*
1540 * Install remote neighbor into the kernel.
1541 */
1542 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
1543 {
1544 struct zebra_if *zif;
1545 struct zebra_l2info_vxlan *vxl;
1546 struct interface *vlan_if;
1547
1548 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
1549 return 0;
1550
1551 zif = zvni->vxlan_if->info;
1552 if (!zif)
1553 return -1;
1554 vxl = &zif->l2info.vxl;
1555
1556 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
1557 if (!vlan_if)
1558 return -1;
1559
1560 return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
1561 }
1562
1563 /*
1564 * Uninstall remote neighbor from the kernel.
1565 */
1566 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
1567 {
1568 struct zebra_if *zif;
1569 struct zebra_l2info_vxlan *vxl;
1570 struct interface *vlan_if;
1571
1572 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
1573 return 0;
1574
1575 if (!zvni->vxlan_if) {
1576 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1577 zvni->vni, zvni);
1578 return -1;
1579 }
1580
1581 zif = zvni->vxlan_if->info;
1582 if (!zif)
1583 return -1;
1584 vxl = &zif->l2info.vxl;
1585 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
1586 if (!vlan_if)
1587 return -1;
1588
1589 return kernel_del_neigh(vlan_if, &n->ip);
1590 }
1591
1592 /*
1593 * Install neighbor hash entry - called upon access VLAN change.
1594 */
1595 static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt)
1596 {
1597 zebra_neigh_t *n;
1598 struct neigh_walk_ctx *wctx = ctxt;
1599
1600 n = (zebra_neigh_t *)backet->data;
1601 if (!n)
1602 return;
1603
1604 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
1605 zvni_neigh_install(wctx->zvni, n);
1606 }
1607
1608 /* Get the VRR interface for SVI if any */
1609 struct interface *zebra_get_vrr_intf_for_svi(struct interface *ifp)
1610 {
1611 struct zebra_vrf *zvrf = NULL;
1612 struct interface *tmp_if = NULL;
1613 struct zebra_if *zif = NULL;
1614
1615 zvrf = vrf_info_lookup(ifp->vrf_id);
1616 assert(zvrf);
1617
1618 FOR_ALL_INTERFACES (zvrf->vrf, tmp_if) {
1619 zif = tmp_if->info;
1620 if (!zif)
1621 continue;
1622
1623 if (!IS_ZEBRA_IF_MACVLAN(tmp_if))
1624 continue;
1625
1626 if (zif->link == ifp)
1627 return tmp_if;
1628 }
1629
1630 return NULL;
1631 }
1632
1633 static int zvni_del_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1634 {
1635 struct listnode *cnode = NULL, *cnnode = NULL;
1636 struct connected *c = NULL;
1637 struct ethaddr macaddr;
1638
1639 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1640
1641 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1642 struct ipaddr ip;
1643
1644 memset(&ip, 0, sizeof(struct ipaddr));
1645 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1646 continue;
1647
1648 if (c->address->family == AF_INET) {
1649 ip.ipa_type = IPADDR_V4;
1650 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1651 sizeof(struct in_addr));
1652 } else if (c->address->family == AF_INET6) {
1653 ip.ipa_type = IPADDR_V6;
1654 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1655 sizeof(struct in6_addr));
1656 } else {
1657 continue;
1658 }
1659
1660 zvni_gw_macip_del(ifp, zvni, &ip);
1661 }
1662
1663 return 0;
1664 }
1665
1666 static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
1667 {
1668 struct listnode *cnode = NULL, *cnnode = NULL;
1669 struct connected *c = NULL;
1670 struct ethaddr macaddr;
1671
1672 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
1673
1674 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
1675 struct ipaddr ip;
1676
1677 memset(&ip, 0, sizeof(struct ipaddr));
1678 if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
1679 continue;
1680
1681 if (c->address->family == AF_INET) {
1682 ip.ipa_type = IPADDR_V4;
1683 memcpy(&(ip.ipaddr_v4), &(c->address->u.prefix4),
1684 sizeof(struct in_addr));
1685 } else if (c->address->family == AF_INET6) {
1686 ip.ipa_type = IPADDR_V6;
1687 memcpy(&(ip.ipaddr_v6), &(c->address->u.prefix6),
1688 sizeof(struct in6_addr));
1689 } else {
1690 continue;
1691 }
1692
1693 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
1694 }
1695
1696 return 0;
1697 }
1698
1699 /*
1700 * zvni_gw_macip_add_to_client
1701 */
1702 static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
1703 struct ethaddr *macaddr, struct ipaddr *ip)
1704 {
1705 char buf[ETHER_ADDR_STRLEN];
1706 char buf2[INET6_ADDRSTRLEN];
1707 zebra_neigh_t *n = NULL;
1708 zebra_mac_t *mac = NULL;
1709 struct zebra_if *zif = NULL;
1710 struct zebra_l2info_vxlan *vxl = NULL;
1711
1712 zif = zvni->vxlan_if->info;
1713 if (!zif)
1714 return -1;
1715
1716 vxl = &zif->l2info.vxl;
1717
1718 mac = zvni_mac_lookup(zvni, macaddr);
1719 if (!mac) {
1720 mac = zvni_mac_add(zvni, macaddr);
1721 if (!mac) {
1722 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
1723 prefix_mac2str(macaddr, buf, sizeof(buf)),
1724 ifp->name, ifp->ifindex, vxl->access_vlan);
1725 return -1;
1726 }
1727 }
1728
1729 /* Set "local" forwarding info. */
1730 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
1731 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
1732 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
1733 mac->fwd_info.local.ifindex = ifp->ifindex;
1734 mac->fwd_info.local.vid = vxl->access_vlan;
1735
1736 n = zvni_neigh_lookup(zvni, ip);
1737 if (!n) {
1738 n = zvni_neigh_add(zvni, ip, macaddr);
1739 if (!n) {
1740 zlog_err(
1741 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
1742 ipaddr2str(ip, buf2, sizeof(buf2)),
1743 prefix_mac2str(macaddr, buf, sizeof(buf)),
1744 ifp->name, ifp->ifindex, zvni->vni);
1745 return -1;
1746 }
1747 }
1748
1749 /* Set "local" forwarding info. */
1750 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
1751 memcpy(&n->emac, macaddr, ETH_ALEN);
1752 n->ifindex = ifp->ifindex;
1753
1754 if (IS_ZEBRA_DEBUG_VXLAN)
1755 zlog_debug(
1756 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
1757 ifp->name, ifp->ifindex, zvni->vni,
1758 prefix_mac2str(macaddr, buf, sizeof(buf)),
1759 ipaddr2str(ip, buf2, sizeof(buf2)));
1760
1761 zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
1762 ZEBRA_MAC_TYPE_GW);
1763
1764 return 0;
1765 }
1766
1767 /*
1768 * zvni_gw_macip_del_from_client
1769 */
1770 static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
1771 struct ipaddr *ip)
1772 {
1773 char buf1[ETHER_ADDR_STRLEN];
1774 char buf2[INET6_ADDRSTRLEN];
1775 zebra_neigh_t *n = NULL;
1776 zebra_mac_t *mac = NULL;
1777
1778 /* If the neigh entry is not present nothing to do*/
1779 n = zvni_neigh_lookup(zvni, ip);
1780 if (!n)
1781 return 0;
1782
1783 /* mac entry should be present */
1784 mac = zvni_mac_lookup(zvni, &n->emac);
1785 if (!mac) {
1786 zlog_err("MAC %s doesnt exists for neigh %s on VNI %u",
1787 prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
1788 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
1789 return -1;
1790 }
1791
1792 /* If the entry is not local nothing to do*/
1793 if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
1794 return -1;
1795
1796 if (IS_ZEBRA_DEBUG_VXLAN)
1797 zlog_debug(
1798 "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s del to BGP",
1799 ifp->name, ifp->ifindex, zvni->vni,
1800 prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
1801 ipaddr2str(ip, buf2, sizeof(buf2)));
1802
1803 /* Remove neighbor from BGP. */
1804 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
1805 ZEBRA_MAC_TYPE_GW);
1806
1807 /* Delete this neighbor entry. */
1808 zvni_neigh_del(zvni, n);
1809
1810 /* see if the mac needs to be deleted as well*/
1811 if (mac)
1812 zvni_deref_ip2mac(zvni, mac, 0);
1813
1814 return 0;
1815 }
1816
1817 static void zvni_gw_macip_del_for_vni_hash(struct hash_backet *backet,
1818 void *ctxt)
1819 {
1820 zebra_vni_t *zvni = NULL;
1821 struct zebra_if *zif = NULL;
1822 struct zebra_l2info_vxlan zl2_info;
1823 struct interface *vlan_if = NULL;
1824 struct interface *vrr_if = NULL;
1825 struct interface *ifp;
1826
1827 /* Add primary SVI MAC*/
1828 zvni = (zebra_vni_t *)backet->data;
1829 if (!zvni)
1830 return;
1831
1832 ifp = zvni->vxlan_if;
1833 if (!ifp)
1834 return;
1835 zif = ifp->info;
1836
1837 /* If down or not mapped to a bridge, we're done. */
1838 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
1839 return;
1840
1841 zl2_info = zif->l2info.vxl;
1842
1843 vlan_if = zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
1844 if (!vlan_if)
1845 return;
1846
1847 /* Del primary MAC-IP */
1848 zvni_del_macip_for_intf(vlan_if, zvni);
1849
1850 /* Del VRR MAC-IP - if any*/
1851 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1852 if (vrr_if)
1853 zvni_del_macip_for_intf(vrr_if, zvni);
1854
1855 return;
1856 }
1857
1858 static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
1859 void *ctxt)
1860 {
1861 zebra_vni_t *zvni = NULL;
1862 struct zebra_if *zif = NULL;
1863 struct zebra_l2info_vxlan zl2_info;
1864 struct interface *vlan_if = NULL;
1865 struct interface *vrr_if = NULL;
1866 struct interface *ifp = NULL;
1867
1868 zvni = (zebra_vni_t *)backet->data;
1869 if (!zvni)
1870 return;
1871
1872 if (!advertise_gw_macip_enabled(zvni))
1873 return;
1874
1875 ifp = zvni->vxlan_if;
1876 if (!ifp)
1877 return;
1878 zif = ifp->info;
1879
1880 /* If down or not mapped to a bridge, we're done. */
1881 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
1882 return;
1883 zl2_info = zif->l2info.vxl;
1884
1885 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
1886 zif->brslave_info.br_if);
1887 if (!vlan_if)
1888 return;
1889
1890 /* Add primary SVI MAC-IP */
1891 zvni_add_macip_for_intf(vlan_if, zvni);
1892
1893 /* Add VRR MAC-IP - if any*/
1894 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
1895 if (vrr_if)
1896 zvni_add_macip_for_intf(vrr_if, zvni);
1897
1898 return;
1899 }
1900
1901 /*
1902 * Make hash key for MAC.
1903 */
1904 static unsigned int mac_hash_keymake(void *p)
1905 {
1906 zebra_mac_t *pmac = p;
1907 const void *pnt = (void *)pmac->macaddr.octet;
1908
1909 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
1910 }
1911
1912 /*
1913 * Compare two MAC addresses.
1914 */
1915 static int mac_cmp(const void *p1, const void *p2)
1916 {
1917 const zebra_mac_t *pmac1 = p1;
1918 const zebra_mac_t *pmac2 = p2;
1919
1920 if (pmac1 == NULL && pmac2 == NULL)
1921 return 1;
1922
1923 if (pmac1 == NULL || pmac2 == NULL)
1924 return 0;
1925
1926 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet,
1927 ETH_ALEN)
1928 == 0);
1929 }
1930
1931 /*
1932 * Callback to allocate MAC hash entry.
1933 */
1934 static void *zvni_mac_alloc(void *p)
1935 {
1936 const zebra_mac_t *tmp_mac = p;
1937 zebra_mac_t *mac;
1938
1939 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
1940 *mac = *tmp_mac;
1941
1942 return ((void *)mac);
1943 }
1944
1945 /*
1946 * Add MAC entry.
1947 */
1948 static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
1949 {
1950 zebra_mac_t tmp_mac;
1951 zebra_mac_t *mac = NULL;
1952
1953 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
1954 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
1955 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
1956 assert(mac);
1957
1958 mac->neigh_list = list_new();
1959 mac->neigh_list->cmp = (int (*)(void *, void *))neigh_cmp;
1960
1961 return mac;
1962 }
1963
1964 /*
1965 * Delete MAC entry.
1966 */
1967 static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
1968 {
1969 zebra_mac_t *tmp_mac;
1970
1971 list_delete_and_null(&mac->neigh_list);
1972
1973 /* Free the VNI hash entry and allocated memory. */
1974 tmp_mac = hash_release(zvni->mac_table, mac);
1975 if (tmp_mac)
1976 XFREE(MTYPE_MAC, tmp_mac);
1977
1978 return 0;
1979 }
1980
1981 /*
1982 * Free MAC hash entry (callback)
1983 */
1984 static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
1985 {
1986 struct mac_walk_ctx *wctx = arg;
1987 zebra_mac_t *mac = backet->data;
1988 u_char sticky = 0;
1989
1990 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
1991 || ((wctx->flags & DEL_REMOTE_MAC)
1992 && (mac->flags & ZEBRA_MAC_REMOTE))
1993 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
1994 && (mac->flags & ZEBRA_MAC_REMOTE)
1995 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
1996 &wctx->r_vtep_ip))) {
1997 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
1998 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
1999 : 0;
2000 zvni_mac_send_del_to_client(
2001 wctx->zvni->vni, &mac->macaddr,
2002 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
2003 }
2004
2005 if (wctx->uninstall)
2006 zvni_mac_uninstall(wctx->zvni, mac, 0);
2007
2008 return zvni_mac_del(wctx->zvni, mac);
2009 }
2010
2011 return 0;
2012 }
2013
2014 /*
2015 * Delete all MAC entries from specific VTEP for a particular VNI.
2016 */
2017 static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
2018 struct in_addr *r_vtep_ip)
2019 {
2020 struct mac_walk_ctx wctx;
2021
2022 if (!zvni->mac_table)
2023 return;
2024
2025 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2026 wctx.zvni = zvni;
2027 wctx.uninstall = uninstall;
2028 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
2029 wctx.r_vtep_ip = *r_vtep_ip;
2030
2031 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
2032 void *))zvni_mac_del_hash_entry,
2033 &wctx);
2034 }
2035
2036 /*
2037 * Delete all MAC entries for this VNI.
2038 */
2039 static void zvni_mac_del_all(zebra_vni_t *zvni,
2040 int uninstall, int upd_client, u_int32_t flags)
2041 {
2042 struct mac_walk_ctx wctx;
2043
2044 if (!zvni->mac_table)
2045 return;
2046
2047 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
2048 wctx.zvni = zvni;
2049 wctx.uninstall = uninstall;
2050 wctx.upd_client = upd_client;
2051 wctx.flags = flags;
2052
2053 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
2054 void *))zvni_mac_del_hash_entry,
2055 &wctx);
2056 }
2057
2058 /*
2059 * Look up MAC hash entry.
2060 */
2061 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
2062 {
2063 zebra_mac_t tmp;
2064 zebra_mac_t *pmac;
2065
2066 memset(&tmp, 0, sizeof(tmp));
2067 memcpy(&tmp.macaddr, mac, ETH_ALEN);
2068 pmac = hash_lookup(zvni->mac_table, &tmp);
2069
2070 return pmac;
2071 }
2072
2073 /*
2074 * Inform BGP about local MAC addition.
2075 */
2076 static int zvni_mac_send_add_to_client(vni_t vni,
2077 struct ethaddr *macaddr, u_char flags)
2078 {
2079 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
2080 ZEBRA_MACIP_ADD);
2081 }
2082
2083 /*
2084 * Inform BGP about local MAC deletion.
2085 */
2086 static int zvni_mac_send_del_to_client(vni_t vni,
2087 struct ethaddr *macaddr, u_char flags)
2088 {
2089 return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
2090 ZEBRA_MACIP_DEL);
2091 }
2092
2093 /*
2094 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
2095 * notifications, to see if they are of interest.
2096 */
2097 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
2098 struct interface *br_if, vlanid_t vid)
2099 {
2100 struct zebra_ns *zns;
2101 struct route_node *rn;
2102 struct interface *tmp_if = NULL;
2103 struct zebra_if *zif;
2104 struct zebra_l2info_bridge *br;
2105 struct zebra_l2info_vxlan *vxl = NULL;
2106 u_char bridge_vlan_aware;
2107 zebra_vni_t *zvni;
2108 int found = 0;
2109
2110 /* Determine if bridge is VLAN-aware or not */
2111 zif = br_if->info;
2112 assert(zif);
2113 br = &zif->l2info.br;
2114 bridge_vlan_aware = br->vlan_aware;
2115
2116 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2117 /* TODO: Optimize with a hash. */
2118 zns = zebra_ns_lookup(NS_DEFAULT);
2119 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2120 tmp_if = (struct interface *)rn->info;
2121 if (!tmp_if)
2122 continue;
2123 zif = tmp_if->info;
2124 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2125 continue;
2126 if (!if_is_operative(tmp_if))
2127 continue;
2128 vxl = &zif->l2info.vxl;
2129
2130 if (zif->brslave_info.br_if != br_if)
2131 continue;
2132
2133 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
2134 found = 1;
2135 break;
2136 }
2137 }
2138
2139 if (!found)
2140 return NULL;
2141
2142 zvni = zvni_lookup(vxl->vni);
2143 return zvni;
2144 }
2145
2146 /*
2147 * Map SVI and associated bridge to a VNI. This is invoked upon getting
2148 * neighbor notifications, to see if they are of interest.
2149 */
2150 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
2151 struct interface *br_if)
2152 {
2153 struct zebra_ns *zns;
2154 struct route_node *rn;
2155 struct interface *tmp_if = NULL;
2156 struct zebra_if *zif;
2157 struct zebra_l2info_bridge *br;
2158 struct zebra_l2info_vxlan *vxl = NULL;
2159 u_char bridge_vlan_aware;
2160 vlanid_t vid = 0;
2161 zebra_vni_t *zvni;
2162 int found = 0;
2163
2164 if (!br_if)
2165 return NULL;
2166
2167 /* Make sure the linked interface is a bridge. */
2168 if (!IS_ZEBRA_IF_BRIDGE(br_if))
2169 return NULL;
2170
2171 /* Determine if bridge is VLAN-aware or not */
2172 zif = br_if->info;
2173 assert(zif);
2174 br = &zif->l2info.br;
2175 bridge_vlan_aware = br->vlan_aware;
2176 if (bridge_vlan_aware) {
2177 struct zebra_l2info_vlan *vl;
2178
2179 if (!IS_ZEBRA_IF_VLAN(ifp))
2180 return NULL;
2181
2182 zif = ifp->info;
2183 assert(zif);
2184 vl = &zif->l2info.vl;
2185 vid = vl->vid;
2186 }
2187
2188 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
2189 /* TODO: Optimize with a hash. */
2190 zns = zebra_ns_lookup(NS_DEFAULT);
2191 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2192 tmp_if = (struct interface *)rn->info;
2193 if (!tmp_if)
2194 continue;
2195 zif = tmp_if->info;
2196 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2197 continue;
2198 if (!if_is_operative(tmp_if))
2199 continue;
2200 vxl = &zif->l2info.vxl;
2201
2202 if (zif->brslave_info.br_if != br_if)
2203 continue;
2204
2205 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
2206 found = 1;
2207 break;
2208 }
2209 }
2210
2211 if (!found)
2212 return NULL;
2213
2214 zvni = zvni_lookup(vxl->vni);
2215 return zvni;
2216 }
2217
2218 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
2219 * of two cases:
2220 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
2221 * linked to the bridge
2222 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
2223 * itself
2224 */
2225 static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
2226 {
2227 struct zebra_ns *zns;
2228 struct route_node *rn;
2229 struct interface *tmp_if = NULL;
2230 struct zebra_if *zif;
2231 struct zebra_l2info_bridge *br;
2232 struct zebra_l2info_vlan *vl;
2233 u_char bridge_vlan_aware;
2234 int found = 0;
2235
2236 /* Defensive check, caller expected to invoke only with valid bridge. */
2237 if (!br_if)
2238 return NULL;
2239
2240 /* Determine if bridge is VLAN-aware or not */
2241 zif = br_if->info;
2242 assert(zif);
2243 br = &zif->l2info.br;
2244 bridge_vlan_aware = br->vlan_aware;
2245
2246 /* Check oper status of the SVI. */
2247 if (!bridge_vlan_aware)
2248 return if_is_operative(br_if) ? br_if : NULL;
2249
2250 /* Identify corresponding VLAN interface. */
2251 /* TODO: Optimize with a hash. */
2252 zns = zebra_ns_lookup(NS_DEFAULT);
2253 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2254 tmp_if = (struct interface *)rn->info;
2255 /* Check oper status of the SVI. */
2256 if (!tmp_if || !if_is_operative(tmp_if))
2257 continue;
2258 zif = tmp_if->info;
2259 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
2260 || zif->link != br_if)
2261 continue;
2262 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
2263
2264 if (vl->vid == vid) {
2265 found = 1;
2266 break;
2267 }
2268 }
2269
2270 return found ? tmp_if : NULL;
2271 }
2272
2273 /*
2274 * Install remote MAC into the kernel.
2275 */
2276 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
2277 {
2278 struct zebra_if *zif;
2279 struct zebra_l2info_vxlan *vxl;
2280 u_char sticky;
2281
2282 if (!(mac->flags & ZEBRA_MAC_REMOTE))
2283 return 0;
2284
2285 zif = zvni->vxlan_if->info;
2286 if (!zif)
2287 return -1;
2288 vxl = &zif->l2info.vxl;
2289
2290 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
2291
2292 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
2293 mac->fwd_info.r_vtep_ip, sticky);
2294 }
2295
2296 /*
2297 * Uninstall remote MAC from the kernel. In the scenario where the MAC
2298 * moves to remote, we have to uninstall any existing local entry first.
2299 */
2300 static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
2301 {
2302 struct zebra_if *zif;
2303 struct zebra_l2info_vxlan *vxl;
2304 struct in_addr vtep_ip = {.s_addr = 0};
2305 struct zebra_ns *zns;
2306 struct interface *ifp;
2307
2308 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
2309 return 0;
2310
2311 if (!zvni->vxlan_if) {
2312 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2313 zvni->vni, zvni);
2314 return -1;
2315 }
2316
2317 zif = zvni->vxlan_if->info;
2318 if (!zif)
2319 return -1;
2320 vxl = &zif->l2info.vxl;
2321
2322 if (local) {
2323 zns = zebra_ns_lookup(NS_DEFAULT);
2324 ifp = if_lookup_by_index_per_ns(zns,
2325 mac->fwd_info.local.ifindex);
2326 if (!ifp) // unexpected
2327 return -1;
2328 } else {
2329 ifp = zvni->vxlan_if;
2330 vtep_ip = mac->fwd_info.r_vtep_ip;
2331 }
2332
2333 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
2334 local);
2335 }
2336
2337 /*
2338 * Install MAC hash entry - called upon access VLAN change.
2339 */
2340 static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
2341 {
2342 zebra_mac_t *mac;
2343 struct mac_walk_ctx *wctx = ctxt;
2344
2345 mac = (zebra_mac_t *)backet->data;
2346 if (!mac)
2347 return;
2348
2349 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
2350 zvni_mac_install(wctx->zvni, mac);
2351 }
2352
2353 /*
2354 * Decrement neighbor refcount of MAC; uninstall and free it if
2355 * appropriate.
2356 */
2357 static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
2358 int uninstall)
2359 {
2360 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)
2361 || !list_isempty(mac->neigh_list))
2362 return;
2363
2364 if (uninstall)
2365 zvni_mac_uninstall(zvni, mac, 0);
2366
2367 zvni_mac_del(zvni, mac);
2368 }
2369
2370 /*
2371 * Read and populate local MACs and neighbors corresponding to this VNI.
2372 */
2373 static void zvni_read_mac_neigh(zebra_vni_t *zvni,
2374 struct interface *ifp)
2375 {
2376 struct zebra_ns *zns;
2377 struct zebra_if *zif;
2378 struct interface *vlan_if;
2379 struct zebra_l2info_vxlan *vxl;
2380 struct interface *vrr_if;
2381
2382 zif = ifp->info;
2383 vxl = &zif->l2info.vxl;
2384 zns = zebra_ns_lookup(NS_DEFAULT);
2385
2386 if (IS_ZEBRA_DEBUG_VXLAN)
2387 zlog_debug(
2388 "Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
2389 ifp->name, ifp->ifindex, zvni->vni,
2390 zif->brslave_info.bridge_ifindex);
2391
2392 macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
2393 vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
2394 if (vlan_if) {
2395
2396 if (advertise_gw_macip_enabled(zvni)) {
2397 /* Add SVI MAC-IP */
2398 zvni_add_macip_for_intf(vlan_if, zvni);
2399
2400 /* Add VRR MAC-IP - if any*/
2401 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
2402 if (vrr_if)
2403 zvni_add_macip_for_intf(vrr_if, zvni);
2404 }
2405
2406 neigh_read_for_vlan(zns, vlan_if);
2407 }
2408 }
2409
2410 /*
2411 * Hash function for VNI.
2412 */
2413 static unsigned int vni_hash_keymake(void *p)
2414 {
2415 const zebra_vni_t *zvni = p;
2416
2417 return (jhash_1word(zvni->vni, 0));
2418 }
2419
2420 /*
2421 * Compare 2 VNI hash entries.
2422 */
2423 static int vni_hash_cmp(const void *p1, const void *p2)
2424 {
2425 const zebra_vni_t *zvni1 = p1;
2426 const zebra_vni_t *zvni2 = p2;
2427
2428 return (zvni1->vni == zvni2->vni);
2429 }
2430
2431 /*
2432 * Callback to allocate VNI hash entry.
2433 */
2434 static void *zvni_alloc(void *p)
2435 {
2436 const zebra_vni_t *tmp_vni = p;
2437 zebra_vni_t *zvni;
2438
2439 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
2440 zvni->vni = tmp_vni->vni;
2441 return ((void *)zvni);
2442 }
2443
2444 /*
2445 * Look up VNI hash entry.
2446 */
2447 static zebra_vni_t *zvni_lookup(vni_t vni)
2448 {
2449 struct zebra_vrf *zvrf;
2450 zebra_vni_t tmp_vni;
2451 zebra_vni_t *zvni = NULL;
2452
2453 zvrf = vrf_info_lookup(VRF_DEFAULT);
2454 assert(zvrf);
2455 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
2456 tmp_vni.vni = vni;
2457 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
2458
2459 return zvni;
2460 }
2461
2462 /*
2463 * Add VNI hash entry.
2464 */
2465 static zebra_vni_t *zvni_add(vni_t vni)
2466 {
2467 struct zebra_vrf *zvrf;
2468 zebra_vni_t tmp_zvni;
2469 zebra_vni_t *zvni = NULL;
2470
2471 zvrf = vrf_info_lookup(VRF_DEFAULT);
2472 assert(zvrf);
2473 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
2474 tmp_zvni.vni = vni;
2475 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
2476 assert(zvni);
2477
2478 /* Create hash table for MAC */
2479 zvni->mac_table =
2480 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
2481
2482 /* Create hash table for neighbors */
2483 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
2484 "Zebra VNI Neighbor Table");
2485
2486 return zvni;
2487 }
2488
2489 /*
2490 * Delete VNI hash entry.
2491 */
2492 static int zvni_del(zebra_vni_t *zvni)
2493 {
2494 struct zebra_vrf *zvrf;
2495 zebra_vni_t *tmp_zvni;
2496
2497 zvrf = vrf_info_lookup(VRF_DEFAULT);
2498 assert(zvrf);
2499
2500 zvni->vxlan_if = NULL;
2501
2502 /* Free the neighbor hash table. */
2503 hash_free(zvni->neigh_table);
2504 zvni->neigh_table = NULL;
2505
2506 /* Free the MAC hash table. */
2507 hash_free(zvni->mac_table);
2508 zvni->mac_table = NULL;
2509
2510 /* Free the VNI hash entry and allocated memory. */
2511 tmp_zvni = hash_release(zvrf->vni_table, zvni);
2512 if (tmp_zvni)
2513 XFREE(MTYPE_ZVNI, tmp_zvni);
2514
2515 return 0;
2516 }
2517
2518 /*
2519 * Inform BGP about local VNI addition.
2520 */
2521 static int zvni_send_add_to_client(zebra_vni_t *zvni)
2522 {
2523 struct zserv *client;
2524 struct stream *s;
2525
2526 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
2527 /* BGP may not be running. */
2528 if (!client)
2529 return 0;
2530
2531 s = client->obuf;
2532 stream_reset(s);
2533
2534 zclient_create_header(s, ZEBRA_VNI_ADD, VRF_DEFAULT);
2535 stream_putl(s, zvni->vni);
2536 stream_put_in_addr(s, &zvni->local_vtep_ip);
2537 stream_put(s, &zvni->vrf_id, sizeof(vrf_id_t)); /* tenant vrf */
2538
2539 /* Write packet size. */
2540 stream_putw_at(s, 0, stream_get_endp(s));
2541
2542 if (IS_ZEBRA_DEBUG_VXLAN)
2543 zlog_debug("Send VNI_ADD %u %s tenant vrf %s to %s",
2544 zvni->vni, inet_ntoa(zvni->local_vtep_ip),
2545 vrf_id_to_name(zvni->vrf_id),
2546 zebra_route_string(client->proto));
2547
2548 client->vniadd_cnt++;
2549 return zebra_server_send_message(client);
2550 }
2551
2552 /*
2553 * Inform BGP about local VNI deletion.
2554 */
2555 static int zvni_send_del_to_client(vni_t vni)
2556 {
2557 struct zserv *client;
2558 struct stream *s;
2559
2560 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
2561 /* BGP may not be running. */
2562 if (!client)
2563 return 0;
2564
2565 s = client->obuf;
2566 stream_reset(s);
2567
2568 zclient_create_header(s, ZEBRA_VNI_DEL, VRF_DEFAULT);
2569 stream_putl(s, vni);
2570
2571 /* Write packet size. */
2572 stream_putw_at(s, 0, stream_get_endp(s));
2573
2574 if (IS_ZEBRA_DEBUG_VXLAN)
2575 zlog_debug("Send VNI_DEL %u to %s", vni,
2576 zebra_route_string(client->proto));
2577
2578 client->vnidel_cnt++;
2579 return zebra_server_send_message(client);
2580 }
2581
2582 /*
2583 * Build the VNI hash table by going over the VxLAN interfaces. This
2584 * is called when EVPN (advertise-all-vni) is enabled.
2585 */
2586 static void zvni_build_hash_table()
2587 {
2588 struct zebra_ns *zns;
2589 struct route_node *rn;
2590 struct interface *ifp;
2591
2592 /* Walk VxLAN interfaces and create VNI hash. */
2593 zns = zebra_ns_lookup(NS_DEFAULT);
2594 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
2595 vni_t vni;
2596 struct zebra_if *zif;
2597 struct zebra_l2info_vxlan *vxl;
2598
2599 ifp = (struct interface *)rn->info;
2600 if (!ifp)
2601 continue;
2602 zif = ifp->info;
2603 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
2604 continue;
2605
2606 vxl = &zif->l2info.vxl;
2607 vni = vxl->vni;
2608
2609 if (is_vni_l3(vni)) {
2610 zebra_l3vni_t *zl3vni = NULL;
2611
2612 if (IS_ZEBRA_DEBUG_VXLAN)
2613 zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
2614 ifp->name, ifp->ifindex, vni);
2615
2616 zl3vni = zl3vni_lookup(vni);
2617 if (!zl3vni) {
2618 zlog_err(
2619 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
2620 ifp->name, ifp->ifindex, vni);
2621 return;
2622 }
2623
2624 /* associate with vxlan_if */
2625 zl3vni->local_vtep_ip = vxl->vtep_ip;
2626 zl3vni->vxlan_if = ifp;
2627
2628 /*
2629 * we need to associate with SVI.
2630 * we can associate with svi-if only after association
2631 * with vxlan-intf is complete
2632 */
2633 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
2634
2635 if (is_l3vni_oper_up(zl3vni))
2636 zebra_vxlan_process_l3vni_oper_up(zl3vni);
2637
2638 } else {
2639 zebra_vni_t *zvni = NULL;
2640 zebra_l3vni_t *zl3vni = NULL;
2641 struct interface *vlan_if = NULL;
2642
2643 if (IS_ZEBRA_DEBUG_VXLAN)
2644 zlog_debug(
2645 "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
2646 ifp->name, ifp->ifindex, vni,
2647 inet_ntoa(vxl->vtep_ip));
2648
2649 /* VNI hash entry is not expected to exist. */
2650 zvni = zvni_lookup(vni);
2651 if (zvni) {
2652 zlog_err(
2653 "VNI hash already present for IF %s(%u) L2-VNI %u",
2654 ifp->name, ifp->ifindex, vni);
2655 continue;
2656 }
2657
2658 zvni = zvni_add(vni);
2659 if (!zvni) {
2660 zlog_err(
2661 "Failed to add VNI hash, IF %s(%u) L2-VNI %u",
2662 ifp->name, ifp->ifindex, vni);
2663 return;
2664 }
2665
2666 zvni->local_vtep_ip = vxl->vtep_ip;
2667 zvni->vxlan_if = ifp;
2668 vlan_if = zvni_map_to_svi(vxl->access_vlan,
2669 zif->brslave_info.br_if);
2670 if (vlan_if) {
2671 zvni->vrf_id = vlan_if->vrf_id;
2672 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
2673 if (zl3vni)
2674 listnode_add_sort(zl3vni->l2vnis, zvni);
2675 }
2676
2677
2678 /* Inform BGP if intf is up and mapped to bridge. */
2679 if (if_is_operative(ifp) && zif->brslave_info.br_if)
2680 zvni_send_add_to_client(zvni);
2681 }
2682 }
2683 }
2684
2685 /*
2686 * See if remote VTEP matches with prefix.
2687 */
2688 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
2689 {
2690 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
2691 }
2692
2693 /*
2694 * Locate remote VTEP in VNI hash table.
2695 */
2696 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2697 {
2698 zebra_vtep_t *zvtep;
2699
2700 if (!zvni)
2701 return NULL;
2702
2703 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
2704 if (zvni_vtep_match(vtep_ip, zvtep))
2705 break;
2706 }
2707
2708 return zvtep;
2709 }
2710
2711 /*
2712 * Add remote VTEP to VNI hash table.
2713 */
2714 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2715 {
2716 zebra_vtep_t *zvtep;
2717
2718 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
2719 if (!zvtep) {
2720 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni->vni);
2721 return NULL;
2722 }
2723
2724 zvtep->vtep_ip = *vtep_ip;
2725
2726 if (zvni->vteps)
2727 zvni->vteps->prev = zvtep;
2728 zvtep->next = zvni->vteps;
2729 zvni->vteps = zvtep;
2730
2731 return zvtep;
2732 }
2733
2734 /*
2735 * Remove remote VTEP from VNI hash table.
2736 */
2737 static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
2738 {
2739 if (zvtep->next)
2740 zvtep->next->prev = zvtep->prev;
2741 if (zvtep->prev)
2742 zvtep->prev->next = zvtep->next;
2743 else
2744 zvni->vteps = zvtep->next;
2745
2746 zvtep->prev = zvtep->next = NULL;
2747 XFREE(MTYPE_ZVNI_VTEP, zvtep);
2748
2749 return 0;
2750 }
2751
2752 /*
2753 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
2754 * uninstall from kernel if asked to.
2755 */
2756 static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
2757 {
2758 zebra_vtep_t *zvtep, *zvtep_next;
2759
2760 if (!zvni)
2761 return -1;
2762
2763 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
2764 zvtep_next = zvtep->next;
2765 if (uninstall)
2766 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
2767 zvni_vtep_del(zvni, zvtep);
2768 }
2769
2770 return 0;
2771 }
2772
2773 /*
2774 * Install remote VTEP into the kernel.
2775 */
2776 static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2777 {
2778 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2779 }
2780
2781 /*
2782 * Uninstall remote VTEP from the kernel.
2783 */
2784 static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2785 {
2786 if (!zvni->vxlan_if) {
2787 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
2788 zvni->vni, zvni);
2789 return -1;
2790 }
2791
2792 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2793 }
2794
2795 /*
2796 * Cleanup VNI/VTEP and update kernel
2797 */
2798 static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
2799 {
2800 zebra_vni_t *zvni = NULL;
2801 zebra_l3vni_t *zl3vni = NULL;
2802
2803 zvni = (zebra_vni_t *)backet->data;
2804 if (!zvni)
2805 return;
2806
2807 /* remove from l3-vni list */
2808 zl3vni = zl3vni_from_vrf(zvni->vrf_id);
2809 if (zl3vni)
2810 listnode_delete(zl3vni->l2vnis, zvni);
2811
2812 /* Free up all neighbors and MACs, if any. */
2813 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
2814 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
2815
2816 /* Free up all remote VTEPs, if any. */
2817 zvni_vtep_del_all(zvni, 1);
2818
2819 /* Delete the hash entry. */
2820 zvni_del(zvni);
2821 }
2822
2823 /* cleanup L3VNI */
2824 static void zl3vni_cleanup_all(struct hash_backet *backet,
2825 void *args)
2826 {
2827 zebra_l3vni_t *zl3vni = NULL;
2828
2829 zl3vni = (zebra_l3vni_t *)backet->data;
2830 if (!zl3vni)
2831 return;
2832
2833 zebra_vxlan_process_l3vni_oper_down(zl3vni);
2834 }
2835
2836 static int is_host_present_in_host_list(struct list *list,
2837 struct prefix *host)
2838 {
2839 struct listnode *node = NULL;
2840 struct prefix *p = NULL;
2841
2842 for (ALL_LIST_ELEMENTS_RO(list, node, p)) {
2843 if (prefix_same(p, host))
2844 return 1;
2845 }
2846 return 0;
2847 }
2848
2849 static void host_list_add_host(struct list *list,
2850 struct prefix *host)
2851 {
2852 struct prefix *p = NULL;
2853
2854 p = XCALLOC(MTYPE_HOST_PREFIX, sizeof(struct prefix));
2855 memcpy(p, host, sizeof(struct prefix));
2856
2857 listnode_add_sort(list, p);
2858 }
2859
2860 static void host_list_delete_host(struct list *list,
2861 struct prefix *host)
2862 {
2863 struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
2864 struct prefix *p = NULL;
2865
2866 for (ALL_LIST_ELEMENTS(list, node, nnode, p)) {
2867 if (prefix_same(p, host)) {
2868 XFREE(MTYPE_HOST_PREFIX, p);
2869 node_to_del = node;
2870 }
2871 }
2872
2873 if (node_to_del)
2874 list_delete_node(list, node_to_del);
2875 }
2876
2877 /*
2878 * Look up MAC hash entry.
2879 */
2880 static zebra_mac_t *zl3vni_rmac_lookup(zebra_l3vni_t *zl3vni,
2881 struct ethaddr *rmac)
2882 {
2883 zebra_mac_t tmp;
2884 zebra_mac_t *pmac;
2885
2886 memset(&tmp, 0, sizeof(tmp));
2887 memcpy(&tmp.macaddr, rmac, ETH_ALEN);
2888 pmac = hash_lookup(zl3vni->rmac_table, &tmp);
2889
2890 return pmac;
2891 }
2892
2893 /*
2894 * Callback to allocate RMAC hash entry.
2895 */
2896 static void *zl3vni_rmac_alloc(void *p)
2897 {
2898 const zebra_mac_t *tmp_rmac = p;
2899 zebra_mac_t *zrmac;
2900
2901 zrmac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
2902 *zrmac = *tmp_rmac;
2903
2904 return ((void *)zrmac);
2905 }
2906
2907 /*
2908 * Add RMAC entry to l3-vni
2909 */
2910 static zebra_mac_t *zl3vni_rmac_add(zebra_l3vni_t *zl3vni,
2911 struct ethaddr *rmac)
2912 {
2913 zebra_mac_t tmp_rmac;
2914 zebra_mac_t *zrmac = NULL;
2915
2916 memset(&tmp_rmac, 0, sizeof(zebra_mac_t));
2917 memcpy(&tmp_rmac.macaddr, rmac, ETH_ALEN);
2918 zrmac = hash_get(zl3vni->rmac_table, &tmp_rmac, zl3vni_rmac_alloc);
2919 assert(zrmac);
2920
2921 zrmac->host_list = list_new();
2922 zrmac->host_list->cmp = (int (*)(void *, void *))prefix_cmp;
2923
2924 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE);
2925 SET_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC);
2926
2927 return zrmac;
2928 }
2929
2930 /*
2931 * Delete MAC entry.
2932 */
2933 static int zl3vni_rmac_del(zebra_l3vni_t *zl3vni,
2934 zebra_mac_t *zrmac)
2935 {
2936 zebra_mac_t *tmp_rmac;
2937
2938 if (zrmac->host_list)
2939 list_delete_and_null(&zrmac->host_list);
2940 zrmac->host_list = NULL;
2941
2942 tmp_rmac = hash_release(zl3vni->rmac_table, zrmac);
2943 if (tmp_rmac)
2944 XFREE(MTYPE_MAC, tmp_rmac);
2945
2946 return 0;
2947 }
2948
2949 /*
2950 * Install remote RMAC into the kernel.
2951 */
2952 static int zl3vni_rmac_install(zebra_l3vni_t *zl3vni,
2953 zebra_mac_t *zrmac)
2954 {
2955 struct zebra_if *zif = NULL;
2956 struct zebra_l2info_vxlan *vxl = NULL;
2957
2958 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) ||
2959 !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
2960 return 0;
2961
2962 zif = zl3vni->vxlan_if->info;
2963 if (!zif)
2964 return -1;
2965
2966 vxl = &zif->l2info.vxl;
2967
2968 return kernel_add_mac(zl3vni->vxlan_if, vxl->access_vlan,
2969 &zrmac->macaddr,
2970 zrmac->fwd_info.r_vtep_ip, 0);
2971 }
2972
2973 /*
2974 * Uninstall remote RMAC from the kernel.
2975 */
2976 static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
2977 zebra_mac_t *zrmac)
2978 {
2979 char buf[ETHER_ADDR_STRLEN];
2980 struct zebra_if *zif = NULL;
2981 struct zebra_l2info_vxlan *vxl = NULL;
2982
2983 if (!(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE)) ||
2984 !(CHECK_FLAG(zrmac->flags, ZEBRA_MAC_REMOTE_RMAC)))
2985 return 0;
2986
2987 if (!zl3vni->vxlan_if) {
2988 zlog_err(
2989 "RMAC %s on L3-VNI %u hash %p couldn't be uninstalled - no vxlan_if",
2990 prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
2991 zl3vni->vni, zl3vni);
2992 return -1;
2993 }
2994
2995 zif = zl3vni->vxlan_if->info;
2996 if (!zif)
2997 return -1;
2998
2999 vxl = &zif->l2info.vxl;
3000
3001 return kernel_del_mac(zl3vni->vxlan_if, vxl->access_vlan,
3002 &zrmac->macaddr, zrmac->fwd_info.r_vtep_ip, 0);
3003 }
3004
3005 /* handle rmac add */
3006 static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni,
3007 struct ethaddr *rmac,
3008 struct ipaddr *vtep_ip,
3009 struct prefix *host_prefix)
3010 {
3011 char buf[ETHER_ADDR_STRLEN];
3012 char buf1[INET6_ADDRSTRLEN];
3013 zebra_mac_t *zrmac = NULL;
3014
3015 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3016 if (!zrmac) {
3017
3018 zrmac = zl3vni_rmac_add(zl3vni, rmac);
3019 if (!zrmac) {
3020 zlog_warn(
3021 "Failed to add RMAC %s L3VNI %u Remote VTEP %s",
3022 prefix_mac2str(rmac, buf,
3023 sizeof(buf)),
3024 zl3vni->vni, ipaddr2str(vtep_ip, buf1,
3025 sizeof(buf1)));
3026 return -1;
3027 }
3028 memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
3029 zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
3030
3031 /* install rmac in kernel */
3032 zl3vni_rmac_install(zl3vni, zrmac);
3033 }
3034
3035 if (!is_host_present_in_host_list(zrmac->host_list, host_prefix))
3036 host_list_add_host(zrmac->host_list, host_prefix);
3037 return 0;
3038 }
3039
3040
3041 /* handle rmac delete */
3042 static int zl3vni_remote_rmac_del(zebra_l3vni_t *zl3vni,
3043 struct ethaddr *rmac,
3044 struct prefix *host_prefix)
3045 {
3046 zebra_mac_t *zrmac = NULL;
3047
3048 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3049 if (!zrmac)
3050 return -1;
3051
3052 host_list_delete_host(zrmac->host_list, host_prefix);
3053 if (list_isempty(zrmac->host_list)) {
3054
3055 /* uninstall from kernel */
3056 zl3vni_rmac_uninstall(zl3vni, zrmac);
3057
3058 /* del the rmac entry */
3059 zl3vni_rmac_del(zl3vni, zrmac);
3060 }
3061 return 0;
3062 }
3063
3064 /*
3065 * Look up nh hash entry on a l3-vni.
3066 */
3067 static zebra_neigh_t *zl3vni_nh_lookup(zebra_l3vni_t *zl3vni,
3068 struct ipaddr *ip)
3069 {
3070 zebra_neigh_t tmp;
3071 zebra_neigh_t *n;
3072
3073 memset(&tmp, 0, sizeof(tmp));
3074 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
3075 n = hash_lookup(zl3vni->nh_table, &tmp);
3076
3077 return n;
3078 }
3079
3080
3081 /*
3082 * Callback to allocate NH hash entry on L3-VNI.
3083 */
3084 static void *zl3vni_nh_alloc(void *p)
3085 {
3086 const zebra_neigh_t *tmp_n = p;
3087 zebra_neigh_t *n;
3088
3089 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
3090 *n = *tmp_n;
3091
3092 return ((void *)n);
3093 }
3094
3095 /*
3096 * Add neighbor entry.
3097 */
3098 static zebra_neigh_t *zl3vni_nh_add(zebra_l3vni_t *zl3vni,
3099 struct ipaddr *ip,
3100 struct ethaddr *mac)
3101 {
3102 zebra_neigh_t tmp_n;
3103 zebra_neigh_t *n = NULL;
3104
3105 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
3106 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
3107 n = hash_get(zl3vni->nh_table, &tmp_n, zl3vni_nh_alloc);
3108 assert(n);
3109
3110 n->host_list = list_new();
3111 n->host_list->cmp = (int (*)(void *, void *))prefix_cmp;
3112
3113 memcpy(&n->emac, mac, ETH_ALEN);
3114 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
3115 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE_NH);
3116
3117 return n;
3118 }
3119
3120 /*
3121 * Delete neighbor entry.
3122 */
3123 static int zl3vni_nh_del(zebra_l3vni_t *zl3vni,
3124 zebra_neigh_t *n)
3125 {
3126 zebra_neigh_t *tmp_n;
3127
3128 if (n->host_list)
3129 list_delete_and_null(&n->host_list);
3130 n->host_list = NULL;
3131
3132 tmp_n = hash_release(zl3vni->nh_table, n);
3133 if (tmp_n)
3134 XFREE(MTYPE_NEIGH, tmp_n);
3135
3136 return 0;
3137 }
3138
3139 /*
3140 * Install remote nh as neigh into the kernel.
3141 */
3142 static int zl3vni_nh_install(zebra_l3vni_t *zl3vni,
3143 zebra_neigh_t *n)
3144 {
3145 if (!is_l3vni_oper_up(zl3vni))
3146 return -1;
3147
3148 if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
3149 !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
3150 return 0;
3151
3152 return kernel_add_neigh(zl3vni->svi_if, &n->ip, &n->emac);
3153 }
3154
3155 /*
3156 * Uninstall remote nh from the kernel.
3157 */
3158 static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni,
3159 zebra_neigh_t *n)
3160 {
3161 if (!is_l3vni_oper_up(zl3vni))
3162 return -1;
3163
3164 if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
3165 !(n->flags & ZEBRA_NEIGH_REMOTE_NH))
3166 return 0;
3167
3168 return kernel_del_neigh(zl3vni->svi_if, &n->ip);
3169 }
3170
3171 /* add remote vtep as a neigh entry */
3172 static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni,
3173 struct ipaddr *vtep_ip,
3174 struct ethaddr *rmac,
3175 struct prefix *host_prefix)
3176 {
3177 char buf[ETHER_ADDR_STRLEN];
3178 char buf1[INET6_ADDRSTRLEN];
3179 zebra_neigh_t *nh = NULL;
3180
3181 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
3182 if (!nh) {
3183 nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
3184 if (!nh) {
3185
3186 zlog_warn(
3187 "Failed to add NH as Neigh (IP %s MAC %s L3-VNI %u)",
3188 ipaddr2str(vtep_ip, buf1,
3189 sizeof(buf1)),
3190 prefix_mac2str(rmac, buf,
3191 sizeof(buf)),
3192 zl3vni->vni);
3193 return -1;
3194 }
3195
3196 /* install the nh neigh in kernel */
3197 zl3vni_nh_install(zl3vni, nh);
3198 }
3199
3200 if (!is_host_present_in_host_list(nh->host_list, host_prefix))
3201 host_list_add_host(nh->host_list, host_prefix);
3202
3203 return 0;
3204 }
3205
3206 /* handle nh neigh delete */
3207 static int zl3vni_remote_nh_del(zebra_l3vni_t *zl3vni,
3208 struct ipaddr *vtep_ip,
3209 struct prefix *host_prefix)
3210 {
3211 zebra_neigh_t *nh = NULL;
3212
3213 nh = zl3vni_nh_lookup(zl3vni, vtep_ip);
3214 if (!nh)
3215 return -1;
3216
3217 host_list_delete_host(nh->host_list, host_prefix);
3218 if (list_isempty(nh->host_list)) {
3219
3220 /* uninstall from kernel */
3221 zl3vni_nh_uninstall(zl3vni, nh);
3222
3223 /* delete the nh entry */
3224 zl3vni_nh_del(zl3vni, nh);
3225 }
3226
3227 return 0;
3228 }
3229
3230 /* handle neigh update from kernel - the only thing of interest is to
3231 * readd stale entries.
3232 */
3233 static int zl3vni_local_nh_add_update(zebra_l3vni_t *zl3vni,
3234 struct ipaddr *ip, u_int16_t state)
3235 {
3236 #ifdef GNU_LINUX
3237 zebra_neigh_t *n = NULL;
3238
3239 n = zl3vni_nh_lookup(zl3vni, ip);
3240 if (!n)
3241 return 0;
3242
3243 /* all next hop neigh are remote and installed by frr.
3244 * If the kernel has aged this entry, re-install.
3245 */
3246 if (state & NUD_STALE)
3247 zl3vni_nh_install(zl3vni, n);
3248 #endif
3249 return 0;
3250 }
3251
3252 /* handle neigh delete from kernel */
3253 static int zl3vni_local_nh_del(zebra_l3vni_t *zl3vni,
3254 struct ipaddr *ip)
3255 {
3256 zebra_neigh_t *n = NULL;
3257
3258 n = zl3vni_nh_lookup(zl3vni, ip);
3259 if (!n)
3260 return 0;
3261
3262 /* all next hop neigh are remote and installed by frr.
3263 * If we get an age out notification for these neigh entries, we have to
3264 * install it back
3265 */
3266 zl3vni_nh_install(zl3vni, n);
3267
3268 return 0;
3269 }
3270
3271 /*
3272 * Hash function for L3 VNI.
3273 */
3274 static unsigned int l3vni_hash_keymake(void *p)
3275 {
3276 const zebra_l3vni_t *zl3vni = p;
3277
3278 return jhash_1word(zl3vni->vni, 0);
3279 }
3280
3281 /*
3282 * Compare 2 L3 VNI hash entries.
3283 */
3284 static int l3vni_hash_cmp(const void *p1, const void *p2)
3285 {
3286 const zebra_l3vni_t *zl3vni1 = p1;
3287 const zebra_l3vni_t *zl3vni2 = p2;
3288
3289 return (zl3vni1->vni == zl3vni2->vni);
3290 }
3291
3292 /*
3293 * Callback to allocate L3 VNI hash entry.
3294 */
3295 static void *zl3vni_alloc(void *p)
3296 {
3297 zebra_l3vni_t *zl3vni = NULL;
3298 const zebra_l3vni_t *tmp_l3vni = p;
3299
3300 zl3vni = XCALLOC(MTYPE_ZL3VNI, sizeof(zebra_l3vni_t));
3301 zl3vni->vni = tmp_l3vni->vni;
3302 return ((void *)zl3vni);
3303 }
3304
3305 /*
3306 * Look up L3 VNI hash entry.
3307 */
3308 static zebra_l3vni_t *zl3vni_lookup(vni_t vni)
3309 {
3310 struct zebra_ns *zns;
3311 zebra_l3vni_t tmp_l3vni;
3312 zebra_l3vni_t *zl3vni = NULL;
3313
3314 zns = zebra_ns_lookup(NS_DEFAULT);
3315 assert(zns);
3316 memset(&tmp_l3vni, 0, sizeof(zebra_l3vni_t));
3317 tmp_l3vni.vni = vni;
3318 zl3vni = hash_lookup(zns->l3vni_table, &tmp_l3vni);
3319
3320 return zl3vni;
3321 }
3322
3323 /*
3324 * Add L3 VNI hash entry.
3325 */
3326 static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id)
3327 {
3328 zebra_l3vni_t tmp_zl3vni;
3329 struct zebra_ns *zns = NULL;
3330 zebra_l3vni_t *zl3vni = NULL;
3331
3332 zns = zebra_ns_lookup(NS_DEFAULT);
3333 assert(zns);
3334
3335 memset(&tmp_zl3vni, 0, sizeof(zebra_l3vni_t));
3336 tmp_zl3vni.vni = vni;
3337
3338 zl3vni = hash_get(zns->l3vni_table, &tmp_zl3vni, zl3vni_alloc);
3339 assert(zl3vni);
3340
3341 zl3vni->vrf_id = vrf_id;
3342 zl3vni->svi_if = NULL;
3343 zl3vni->vxlan_if = NULL;
3344 zl3vni->l2vnis = list_new();
3345 zl3vni->l2vnis->cmp = (int (*)(void *, void *))vni_hash_cmp;
3346
3347 /* Create hash table for remote RMAC */
3348 zl3vni->rmac_table =
3349 hash_create(mac_hash_keymake, mac_cmp,
3350 "Zebra L3-VNI RMAC-Table");
3351
3352 /* Create hash table for neighbors */
3353 zl3vni->nh_table = hash_create(neigh_hash_keymake, neigh_cmp,
3354 "Zebra L3-VNI next-hop table");
3355
3356 return zl3vni;
3357 }
3358
3359 /*
3360 * Delete L3 VNI hash entry.
3361 */
3362 static int zl3vni_del(zebra_l3vni_t *zl3vni)
3363 {
3364 struct zebra_ns *zns;
3365 zebra_l3vni_t *tmp_zl3vni;
3366
3367 zns = zebra_ns_lookup(NS_DEFAULT);
3368 assert(zns);
3369
3370 /* free the list of l2vnis */
3371 list_delete_and_null(&zl3vni->l2vnis);
3372 zl3vni->l2vnis = NULL;
3373
3374 /* Free the rmac table */
3375 hash_free(zl3vni->rmac_table);
3376 zl3vni->rmac_table = NULL;
3377
3378 /* Free the nh table */
3379 hash_free(zl3vni->nh_table);
3380 zl3vni->nh_table = NULL;
3381
3382 /* Free the VNI hash entry and allocated memory. */
3383 tmp_zl3vni = hash_release(zns->l3vni_table, zl3vni);
3384 if (tmp_zl3vni)
3385 XFREE(MTYPE_ZL3VNI, tmp_zl3vni);
3386
3387 return 0;
3388 }
3389
3390 static int is_vni_l3(vni_t vni)
3391 {
3392 zebra_l3vni_t *zl3vni = NULL;
3393
3394 zl3vni = zl3vni_lookup(vni);
3395 if (zl3vni)
3396 return 1;
3397 return 0;
3398 }
3399
3400 static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
3401 {
3402 struct zebra_ns *zns = NULL;
3403 struct route_node *rn = NULL;
3404 struct interface *ifp = NULL;
3405
3406 /* loop through all vxlan-interface */
3407 zns = zebra_ns_lookup(NS_DEFAULT);
3408 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3409
3410 struct zebra_if *zif = NULL;
3411 struct zebra_l2info_vxlan *vxl = NULL;
3412
3413 ifp = (struct interface *)rn->info;
3414 if (!ifp)
3415 continue;
3416
3417 zif = ifp->info;
3418 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3419 continue;
3420
3421 vxl = &zif->l2info.vxl;
3422 if (vxl->vni == zl3vni->vni) {
3423 zl3vni->local_vtep_ip = vxl->vtep_ip;
3424 return ifp;
3425 }
3426 }
3427
3428 return NULL;
3429 }
3430
3431 static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)
3432 {
3433 struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
3434 struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
3435
3436 if (!zl3vni->vxlan_if)
3437 return NULL;
3438
3439 zif = zl3vni->vxlan_if->info;
3440 if (!zif)
3441 return NULL;
3442
3443 vxl = &zif->l2info.vxl;
3444
3445 return zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
3446 }
3447
3448 static zebra_l3vni_t *zl3vni_from_vrf(vrf_id_t vrf_id)
3449 {
3450 struct zebra_vrf *zvrf = NULL;
3451
3452 zvrf = zebra_vrf_lookup_by_id(vrf_id);
3453 if (!zvrf)
3454 return NULL;
3455
3456 return zl3vni_lookup(zvrf->l3vni);
3457 }
3458
3459 /*
3460 * Map SVI and associated bridge to a VNI. This is invoked upon getting
3461 * neighbor notifications, to see if they are of interest.
3462 */
3463 static zebra_l3vni_t *zl3vni_from_svi(struct interface *ifp,
3464 struct interface *br_if)
3465 {
3466 int found = 0;
3467 vlanid_t vid = 0;
3468 u_char bridge_vlan_aware = 0;
3469 zebra_l3vni_t *zl3vni = NULL;
3470 struct zebra_ns *zns = NULL;
3471 struct route_node *rn = NULL;
3472 struct zebra_if *zif = NULL;
3473 struct interface *tmp_if = NULL;
3474 struct zebra_l2info_bridge *br = NULL;
3475 struct zebra_l2info_vxlan *vxl = NULL;
3476
3477 if (!br_if)
3478 return NULL;
3479
3480 /* Make sure the linked interface is a bridge. */
3481 if (!IS_ZEBRA_IF_BRIDGE(br_if))
3482 return NULL;
3483
3484 /* Determine if bridge is VLAN-aware or not */
3485 zif = br_if->info;
3486 assert(zif);
3487 br = &zif->l2info.br;
3488 bridge_vlan_aware = br->vlan_aware;
3489 if (bridge_vlan_aware) {
3490 struct zebra_l2info_vlan *vl;
3491
3492 if (!IS_ZEBRA_IF_VLAN(ifp))
3493 return NULL;
3494
3495 zif = ifp->info;
3496 assert(zif);
3497 vl = &zif->l2info.vl;
3498 vid = vl->vid;
3499 }
3500
3501 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
3502 /* TODO: Optimize with a hash. */
3503 zns = zebra_ns_lookup(NS_DEFAULT);
3504 for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
3505 tmp_if = (struct interface *)rn->info;
3506 if (!tmp_if)
3507 continue;
3508 zif = tmp_if->info;
3509 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
3510 continue;
3511 if (!if_is_operative(tmp_if))
3512 continue;
3513 vxl = &zif->l2info.vxl;
3514
3515 if (zif->brslave_info.br_if != br_if)
3516 continue;
3517
3518 if (!bridge_vlan_aware || vxl->access_vlan == vid) {
3519 found = 1;
3520 break;
3521 }
3522 }
3523
3524 if (!found)
3525 return NULL;
3526
3527 zl3vni = zl3vni_lookup(vxl->vni);
3528 return zl3vni;
3529 }
3530
3531 /*
3532 * Inform BGP about l3-vni.
3533 */
3534 static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
3535 {
3536 struct stream *s = NULL;
3537 struct zserv *client = NULL;
3538 struct ethaddr rmac;
3539 char buf[ETHER_ADDR_STRLEN];
3540
3541 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
3542 /* BGP may not be running. */
3543 if (!client)
3544 return 0;
3545
3546 /* get the rmac */
3547 memset(&rmac, 0, sizeof(struct ethaddr));
3548 zl3vni_get_rmac(zl3vni, &rmac);
3549
3550 s = client->obuf;
3551 stream_reset(s);
3552
3553 zclient_create_header(s, ZEBRA_L3VNI_ADD,
3554 zl3vni_vrf_id(zl3vni));
3555 stream_putl(s, zl3vni->vni);
3556 stream_put(s, &rmac, sizeof(struct ethaddr));
3557 stream_put_in_addr(s, &zl3vni->local_vtep_ip);
3558
3559 /* Write packet size. */
3560 stream_putw_at(s, 0, stream_get_endp(s));
3561
3562 if (IS_ZEBRA_DEBUG_VXLAN)
3563 zlog_debug("Send L3_VNI_ADD %u VRF %s RMAC %s local-ip %s to %s",
3564 zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
3565 prefix_mac2str(&rmac, buf, sizeof(buf)),
3566 inet_ntoa(zl3vni->local_vtep_ip),
3567 zebra_route_string(client->proto));
3568
3569 client->l3vniadd_cnt++;
3570 return zebra_server_send_message(client);
3571 }
3572
3573 /*
3574 * Inform BGP about local l3-VNI deletion.
3575 */
3576 static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
3577 {
3578 struct stream *s = NULL;
3579 struct zserv *client = NULL;
3580
3581 client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
3582 /* BGP may not be running. */
3583 if (!client)
3584 return 0;
3585
3586 s = client->obuf;
3587 stream_reset(s);
3588
3589 zclient_create_header(s, ZEBRA_L3VNI_DEL,
3590 zl3vni_vrf_id(zl3vni));
3591 stream_putl(s, zl3vni->vni);
3592
3593 /* Write packet size. */
3594 stream_putw_at(s, 0, stream_get_endp(s));
3595
3596 if (IS_ZEBRA_DEBUG_VXLAN)
3597 zlog_debug("Send L3_VNI_DEL %u VRF %s to %s",
3598 zl3vni->vni,
3599 vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
3600 zebra_route_string(client->proto));
3601
3602 client->l3vnidel_cnt++;
3603 return zebra_server_send_message(client);
3604 }
3605
3606 static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
3607 {
3608 if (IS_ZEBRA_DEBUG_VXLAN)
3609 zlog_debug("L3-VNI %u is UP - send add to BGP",
3610 zl3vni->vni);
3611
3612 /* send l3vni add to BGP */
3613 zl3vni_send_add_to_client(zl3vni);
3614 }
3615
3616 static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
3617 {
3618 if (IS_ZEBRA_DEBUG_VXLAN)
3619 zlog_debug("L3-VNI %u is Down - Send del to BGP",
3620 zl3vni->vni);
3621
3622 /* send l3-vni del to BGP*/
3623 zl3vni_send_del_to_client(zl3vni);
3624 }
3625
3626 static void zvni_add_to_l3vni_list(struct hash_backet *backet,
3627 void *ctxt)
3628 {
3629 zebra_vni_t *zvni = (zebra_vni_t *) backet->data;
3630 zebra_l3vni_t *zl3vni = (zebra_l3vni_t *) ctxt;
3631
3632 if (zvni->vrf_id == zl3vni_vrf_id(zl3vni))
3633 listnode_add_sort(zl3vni->l2vnis, zvni);
3634 }
3635
3636 /*
3637 * handle transition of vni from l2 to l3 and vice versa
3638 */
3639 static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf,
3640 vni_t vni, int add)
3641 {
3642 zebra_vni_t *zvni = NULL;
3643
3644 /* There is a possibility that VNI notification was already received
3645 * from kernel and we programmed it as L2-VNI
3646 * In such a case we need to delete this L2-VNI first, so
3647 * that it can be reprogrammed as L3-VNI in the system. It is also
3648 * possible that the vrf-vni mapping is removed from FRR while the vxlan
3649 * interface is still present in kernel. In this case to keep it
3650 * symmetric, we will delete the l3-vni and reprogram it as l2-vni
3651 */
3652 if (add) {
3653 /* Locate hash entry */
3654 zvni = zvni_lookup(vni);
3655 if (!zvni)
3656 return 0;
3657
3658 if (IS_ZEBRA_DEBUG_VXLAN)
3659 zlog_debug("Del L2-VNI %u - transition to L3-VNI",
3660 vni);
3661
3662 /* Delete VNI from BGP. */
3663 zvni_send_del_to_client(zvni->vni);
3664
3665 /* Free up all neighbors and MAC, if any. */
3666 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
3667 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
3668
3669 /* Free up all remote VTEPs, if any. */
3670 zvni_vtep_del_all(zvni, 0);
3671
3672 /* Delete the hash entry. */
3673 if (zvni_del(zvni)) {
3674 zlog_err("Failed to del VNI hash %p, VNI %u",
3675 zvni, zvni->vni);
3676 return -1;
3677 }
3678 } else {
3679 /* TODO_MITESH: This needs to be thought through. We don't have
3680 * enough information at this point to reprogram the vni as
3681 * l2-vni. One way is to store the required info in l3-vni and
3682 * used it solely for this purpose
3683 */
3684 }
3685
3686 return 0;
3687 }
3688
3689 /* delete and uninstall rmac hash entry */
3690 static void zl3vni_del_rmac_hash_entry(struct hash_backet *backet,
3691 void *ctx)
3692 {
3693 zebra_mac_t *zrmac = NULL;
3694 zebra_l3vni_t *zl3vni = NULL;
3695
3696 zrmac = (zebra_mac_t *)backet->data;
3697 zl3vni = (zebra_l3vni_t *)ctx;
3698 zl3vni_rmac_uninstall(zl3vni, zrmac);
3699 zl3vni_rmac_del(zl3vni, zrmac);
3700 }
3701
3702 /* delete and uninstall nh hash entry */
3703 static void zl3vni_del_nh_hash_entry(struct hash_backet *backet,
3704 void *ctx)
3705 {
3706 zebra_neigh_t *n = NULL;
3707 zebra_l3vni_t *zl3vni = NULL;
3708
3709 n = (zebra_neigh_t *)backet->data;
3710 zl3vni = (zebra_l3vni_t *)ctx;
3711 zl3vni_nh_uninstall(zl3vni, n);
3712 zl3vni_nh_del(zl3vni, n);
3713 }
3714
3715 /* Public functions */
3716
3717 /* handle evpn route in vrf table */
3718 void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id,
3719 struct ethaddr *rmac,
3720 struct ipaddr *vtep_ip,
3721 struct prefix *host_prefix)
3722 {
3723 zebra_l3vni_t *zl3vni = NULL;
3724
3725 zl3vni = zl3vni_from_vrf(vrf_id);
3726 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
3727 return;
3728
3729 /* add the next hop neighbor */
3730 zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
3731
3732 /* add the rmac */
3733 zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip, host_prefix);
3734 }
3735
3736 /* handle evpn vrf route delete */
3737 void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
3738 struct ethaddr *rmac,
3739 struct ipaddr *vtep_ip,
3740 struct prefix *host_prefix)
3741 {
3742 zebra_l3vni_t *zl3vni = NULL;
3743
3744 zl3vni = zl3vni_from_vrf(vrf_id);
3745 if (!zl3vni)
3746 return;
3747
3748 /* delete the next hop entry */
3749 zl3vni_remote_nh_del(zl3vni, vtep_ip, host_prefix);
3750
3751 /* delete the rmac entry */
3752 zl3vni_remote_rmac_del(zl3vni, rmac, host_prefix);
3753 }
3754
3755 void zebra_vxlan_print_specific_rmac_l3vni(struct vty *vty,
3756 vni_t l3vni,
3757 struct ethaddr *rmac,
3758 u_char use_json)
3759 {
3760 zebra_l3vni_t *zl3vni = NULL;
3761 zebra_mac_t *zrmac = NULL;
3762 json_object *json = NULL;
3763
3764 if (!is_evpn_enabled()) {
3765 if (use_json)
3766 vty_out(vty, "{}\n");
3767 return;
3768 }
3769
3770 if (use_json)
3771 json = json_object_new_object();
3772
3773 zl3vni = zl3vni_lookup(l3vni);
3774 if (!zl3vni) {
3775 if (use_json)
3776 vty_out(vty, "{}\n");
3777 else
3778 vty_out(vty, "%% L3-VNI %u doesnt exist\n",
3779 l3vni);
3780 return;
3781 }
3782
3783 zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
3784 if (!zrmac) {
3785 if (use_json)
3786 vty_out(vty, "{}\n");
3787 else
3788 vty_out(vty,
3789 "%% Requested RMAC doesnt exist in L3-VNI %u",
3790 l3vni);
3791 return;
3792 }
3793
3794 zl3vni_print_rmac(zrmac, vty, json);
3795
3796 if (use_json) {
3797 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3798 json, JSON_C_TO_STRING_PRETTY));
3799 json_object_free(json);
3800 }
3801 }
3802
3803 void zebra_vxlan_print_rmacs_l3vni(struct vty *vty,
3804 vni_t l3vni,
3805 u_char use_json)
3806 {
3807 zebra_l3vni_t *zl3vni;
3808 u_int32_t num_rmacs;
3809 struct rmac_walk_ctx wctx;
3810 json_object *json = NULL;
3811
3812 if (!is_evpn_enabled())
3813 return;
3814
3815 zl3vni = zl3vni_lookup(l3vni);
3816 if (!zl3vni) {
3817 if (use_json)
3818 vty_out(vty, "{}\n");
3819 else
3820 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
3821 return;
3822 }
3823 num_rmacs = hashcount(zl3vni->rmac_table);
3824 if (!num_rmacs)
3825 return;
3826
3827 if (use_json)
3828 json = json_object_new_object();
3829
3830 memset(&wctx, 0, sizeof(struct rmac_walk_ctx));
3831 wctx.vty = vty;
3832 wctx.json = json;
3833 if (!use_json) {
3834 vty_out(vty,
3835 "Number of Remote RMACs known for this VNI: %u\n",
3836 num_rmacs);
3837 vty_out(vty, "%-17s %-21s %-6s\n", "MAC",
3838 "Remote VTEP", "Refcnt");
3839 } else
3840 json_object_int_add(json, "numRmacs", num_rmacs);
3841
3842 hash_iterate(zl3vni->rmac_table, zl3vni_print_rmac_hash, &wctx);
3843
3844 if (use_json) {
3845 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3846 json, JSON_C_TO_STRING_PRETTY));
3847 json_object_free(json);
3848 }
3849 }
3850
3851 void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty,
3852 u_char use_json)
3853 {
3854 struct zebra_ns *zns = NULL;
3855 json_object *json = NULL;
3856 void *args[2];
3857
3858 if (!is_evpn_enabled()) {
3859 if (use_json)
3860 vty_out(vty, "{}\n");
3861 return;
3862 }
3863
3864 zns = zebra_ns_lookup(NS_DEFAULT);
3865 if (!zns) {
3866 if (use_json)
3867 vty_out(vty, "{}\n");
3868 return;
3869 }
3870
3871 if (use_json)
3872 json = json_object_new_object();
3873
3874 args[0] = vty;
3875 args[1] = json;
3876 hash_iterate(zns->l3vni_table,
3877 (void (*)(struct hash_backet *,
3878 void *))zl3vni_print_rmac_hash_all_vni,
3879 args);
3880
3881 if (use_json) {
3882 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3883 json, JSON_C_TO_STRING_PRETTY));
3884 json_object_free(json);
3885 }
3886 }
3887
3888 void zebra_vxlan_print_specific_nh_l3vni(struct vty *vty,
3889 vni_t l3vni,
3890 struct ipaddr *ip,
3891 u_char use_json)
3892 {
3893 zebra_l3vni_t *zl3vni = NULL;
3894 zebra_neigh_t *n = NULL;
3895 json_object *json = NULL;
3896
3897 if (!is_evpn_enabled()) {
3898 if (use_json)
3899 vty_out(vty, "{}\n");
3900 return;
3901 }
3902
3903 if (use_json)
3904 json = json_object_new_object();
3905
3906 zl3vni = zl3vni_lookup(l3vni);
3907 if (!zl3vni) {
3908 if (use_json)
3909 vty_out(vty, "{}\n");
3910 else
3911 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
3912 return;
3913 }
3914
3915 n = zl3vni_nh_lookup(zl3vni, ip);
3916 if (!n) {
3917 if (use_json)
3918 vty_out(vty, "{}\n");
3919 else
3920 vty_out(vty,
3921 "%% Requested next-hop not present for L3-VNI %u",
3922 l3vni);
3923 return;
3924 }
3925
3926 zl3vni_print_nh(n, vty, json);
3927
3928 if (use_json) {
3929 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3930 json, JSON_C_TO_STRING_PRETTY));
3931 json_object_free(json);
3932 }
3933 }
3934
3935 void zebra_vxlan_print_nh_l3vni(struct vty *vty,
3936 vni_t l3vni,
3937 u_char use_json)
3938 {
3939 u_int32_t num_nh;
3940 struct nh_walk_ctx wctx;
3941 json_object *json = NULL;
3942 zebra_l3vni_t *zl3vni = NULL;
3943
3944 if (!is_evpn_enabled())
3945 return;
3946
3947 zl3vni = zl3vni_lookup(l3vni);
3948 if (!zl3vni) {
3949 if (use_json)
3950 vty_out(vty, "{}\n");
3951 else
3952 vty_out(vty, "%% L3-VNI %u does not exist\n", l3vni);
3953 return;
3954 }
3955
3956 num_nh = hashcount(zl3vni->nh_table);
3957 if (!num_nh)
3958 return;
3959
3960 if (use_json)
3961 json = json_object_new_object();
3962
3963 wctx.vty = vty;
3964 wctx.json = json;
3965 if (!use_json) {
3966 vty_out(vty,
3967 "Number of NH Neighbors known for this VNI: %u\n",
3968 num_nh);
3969 vty_out(vty, "%-15s %-17s %6s\n", "IP",
3970 "RMAC", "Refcnt");
3971 } else
3972 json_object_int_add(json, "numNh", num_nh);
3973
3974 hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
3975
3976 if (use_json) {
3977 vty_out(vty, "%s\n", json_object_to_json_string_ext(
3978 json, JSON_C_TO_STRING_PRETTY));
3979 json_object_free(json);
3980 }
3981 }
3982
3983 void zebra_vxlan_print_nh_all_l3vni(struct vty *vty,
3984 u_char use_json)
3985 {
3986 struct zebra_ns *zns = NULL;
3987 json_object *json = NULL;
3988 void *args[2];
3989
3990 if (!is_evpn_enabled()) {
3991 if (use_json)
3992 vty_out(vty, "{}\n");
3993 return;
3994 }
3995
3996 zns = zebra_ns_lookup(NS_DEFAULT);
3997 if (!zns)
3998 return;
3999
4000 if (use_json)
4001 json = json_object_new_object();
4002
4003 args[0] = vty;
4004 args[1] = json;
4005 hash_iterate(zns->l3vni_table,
4006 (void (*)(struct hash_backet *,
4007 void *))zl3vni_print_nh_hash_all_vni,
4008 args);
4009
4010 if (use_json) {
4011 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4012 json, JSON_C_TO_STRING_PRETTY));
4013 json_object_free(json);
4014 }
4015 return;
4016 }
4017
4018 /*
4019 * Display L3 VNI information (VTY command handler).
4020 */
4021 void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, u_char use_json)
4022 {
4023 void *args[2];
4024 json_object *json = NULL;
4025 zebra_l3vni_t *zl3vni = NULL;
4026
4027 if (!is_evpn_enabled()) {
4028 if (use_json)
4029 vty_out(vty, "{}\n");
4030 return;
4031 }
4032
4033 zl3vni = zl3vni_lookup(vni);
4034 if (!zl3vni) {
4035 if (use_json)
4036 vty_out(vty, "{}\n");
4037 else
4038 vty_out(vty, "%% VNI %u does not exist\n", vni);
4039 return;
4040 }
4041
4042 if (use_json)
4043 json = json_object_new_object();
4044
4045 args[0] = vty;
4046 args[1] = json;
4047 zl3vni_print(zl3vni, (void *)args);
4048
4049 if (use_json) {
4050 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4051 json, JSON_C_TO_STRING_PRETTY));
4052 json_object_free(json);
4053 }
4054 }
4055
4056 /*
4057 * Display L3 VNI hash table (VTY command handler).
4058 */
4059 void zebra_vxlan_print_l3vnis(struct vty *vty, u_char use_json)
4060 {
4061 u_int32_t num_vnis;
4062 void *args[2];
4063 json_object *json = NULL;
4064 struct zebra_ns *zns = NULL;
4065
4066 if (!is_evpn_enabled()) {
4067 if (use_json)
4068 vty_out(vty, "{}\n");
4069 return;
4070 }
4071
4072 zns = zebra_ns_lookup(NS_DEFAULT);
4073 assert(zns);
4074
4075 num_vnis = hashcount(zns->l3vni_table);
4076 if (!num_vnis) {
4077 if (use_json)
4078 vty_out(vty, "{}\n");
4079 return;
4080 }
4081
4082 if (use_json) {
4083 json = json_object_new_object();
4084 json_object_int_add(json, "numVnis", num_vnis);
4085 } else {
4086 vty_out(vty, "Number of L3 VNIs: %u\n", num_vnis);
4087 vty_out(vty, "%-10s %-15s %-20s %-20s %-5s %-37s %-18s\n",
4088 "VNI", "Local-ip", "Vx-intf", "L3-SVI", "State",
4089 "VRF", "Rmac");
4090 }
4091
4092 args[0] = vty;
4093 args[1] = json;
4094 hash_iterate(zns->l3vni_table,
4095 (void (*)(struct hash_backet *, void *))zl3vni_print_hash,
4096 args);
4097
4098 if (use_json) {
4099 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4100 json, JSON_C_TO_STRING_PRETTY));
4101 json_object_free(json);
4102 }
4103 }
4104
4105 /*
4106 * Display Neighbors for a VNI (VTY command handler).
4107 */
4108 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
4109 vni_t vni, u_char use_json)
4110 {
4111 zebra_vni_t *zvni;
4112 u_int32_t num_neigh;
4113 struct neigh_walk_ctx wctx;
4114 json_object *json = NULL;
4115
4116 if (!is_evpn_enabled())
4117 return;
4118 zvni = zvni_lookup(vni);
4119 if (!zvni) {
4120 if (use_json)
4121 vty_out(vty, "{}\n");
4122 else
4123 vty_out(vty, "%% VNI %u does not exist\n", vni);
4124 return;
4125 }
4126 num_neigh = hashcount(zvni->neigh_table);
4127 if (!num_neigh)
4128 return;
4129
4130 if (use_json)
4131 json = json_object_new_object();
4132
4133 /* Since we have IPv6 addresses to deal with which can vary widely in
4134 * size, we try to be a bit more elegant in display by first computing
4135 * the maximum width.
4136 */
4137 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
4138 wctx.zvni = zvni;
4139 wctx.vty = vty;
4140 wctx.addr_width = 15;
4141 wctx.json = json;
4142 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
4143
4144 if (!use_json) {
4145 vty_out(vty,
4146 "Number of ARPs (local and remote) known for this VNI: %u\n",
4147 num_neigh);
4148 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
4149 "Type", "MAC", "Remote VTEP");
4150 } else
4151 json_object_int_add(json, "numArpNd", num_neigh);
4152
4153 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
4154 if (use_json) {
4155 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4156 json, JSON_C_TO_STRING_PRETTY));
4157 json_object_free(json);
4158 }
4159 }
4160
4161 /*
4162 * Display neighbors across all VNIs (VTY command handler).
4163 */
4164 void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
4165 u_char use_json)
4166 {
4167 json_object *json = NULL;
4168 void *args[2];
4169
4170 if (!is_evpn_enabled())
4171 return;
4172
4173 if (use_json)
4174 json = json_object_new_object();
4175
4176 args[0] = vty;
4177 args[1] = json;
4178 hash_iterate(zvrf->vni_table,
4179 (void (*)(struct hash_backet *,
4180 void *))zvni_print_neigh_hash_all_vni,
4181 args);
4182 if (use_json) {
4183 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4184 json, JSON_C_TO_STRING_PRETTY));
4185 json_object_free(json);
4186 }
4187 }
4188
4189 /*
4190 * Display specific neighbor for a VNI, if present (VTY command handler).
4191 */
4192 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
4193 struct zebra_vrf *zvrf, vni_t vni,
4194 struct ipaddr *ip, u_char use_json)
4195 {
4196 zebra_vni_t *zvni;
4197 zebra_neigh_t *n;
4198 json_object *json = NULL;
4199
4200 if (!is_evpn_enabled())
4201 return;
4202 zvni = zvni_lookup(vni);
4203 if (!zvni) {
4204 if (use_json)
4205 vty_out(vty, "{}\n");
4206 else
4207 vty_out(vty, "%% VNI %u does not exist\n", vni);
4208 return;
4209 }
4210 n = zvni_neigh_lookup(zvni, ip);
4211 if (!n) {
4212 if (!use_json)
4213 vty_out(vty,
4214 "%% Requested neighbor does not exist in VNI %u\n",
4215 vni);
4216 return;
4217 }
4218 if (use_json)
4219 json = json_object_new_object();
4220
4221 zvni_print_neigh(n, vty, json);
4222
4223 if (use_json) {
4224 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4225 json, JSON_C_TO_STRING_PRETTY));
4226 json_object_free(json);
4227 }
4228 }
4229
4230 /*
4231 * Display neighbors for a VNI from specific VTEP (VTY command handler).
4232 * By definition, these are remote neighbors.
4233 */
4234 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
4235 vni_t vni, struct in_addr vtep_ip,
4236 u_char use_json)
4237 {
4238 zebra_vni_t *zvni;
4239 u_int32_t num_neigh;
4240 struct neigh_walk_ctx wctx;
4241 json_object *json = NULL;
4242
4243 if (!is_evpn_enabled())
4244 return;
4245 zvni = zvni_lookup(vni);
4246 if (!zvni) {
4247 if (use_json)
4248 vty_out(vty, "{}\n");
4249 else
4250 vty_out(vty, "%% VNI %u does not exist\n", vni);
4251 return;
4252 }
4253 num_neigh = hashcount(zvni->neigh_table);
4254 if (!num_neigh)
4255 return;
4256
4257 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
4258 wctx.zvni = zvni;
4259 wctx.vty = vty;
4260 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
4261 wctx.r_vtep_ip = vtep_ip;
4262 wctx.json = json;
4263 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
4264
4265 if (use_json) {
4266 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4267 json, JSON_C_TO_STRING_PRETTY));
4268 json_object_free(json);
4269 }
4270 }
4271
4272 /*
4273 * Display MACs for a VNI (VTY command handler).
4274 */
4275 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
4276 vni_t vni, u_char use_json)
4277 {
4278 zebra_vni_t *zvni;
4279 u_int32_t num_macs;
4280 struct mac_walk_ctx wctx;
4281 json_object *json = NULL;
4282 json_object *json_mac = NULL;
4283
4284 if (!is_evpn_enabled())
4285 return;
4286 zvni = zvni_lookup(vni);
4287 if (!zvni) {
4288 if (use_json)
4289 vty_out(vty, "{}\n");
4290 else
4291 vty_out(vty, "%% VNI %u does not exist\n", vni);
4292 return;
4293 }
4294 num_macs = num_valid_macs(zvni);
4295 if (!num_macs)
4296 return;
4297
4298 if (use_json) {
4299 json = json_object_new_object();
4300 json_mac = json_object_new_object();
4301 }
4302
4303 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4304 wctx.zvni = zvni;
4305 wctx.vty = vty;
4306 wctx.json = json_mac;
4307
4308 if (!use_json) {
4309 vty_out(vty,
4310 "Number of MACs (local and remote) known for this VNI: %u\n",
4311 num_macs);
4312 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
4313 "Intf/Remote VTEP", "VLAN");
4314 } else
4315 json_object_int_add(json, "numMacs", num_macs);
4316
4317 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
4318
4319 if (use_json) {
4320 json_object_object_add(json, "macs", json_mac);
4321 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4322 json, JSON_C_TO_STRING_PRETTY));
4323 json_object_free(json);
4324 }
4325 }
4326
4327 /*
4328 * Display MACs for all VNIs (VTY command handler).
4329 */
4330 void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
4331 u_char use_json)
4332 {
4333 struct mac_walk_ctx wctx;
4334 json_object *json = NULL;
4335
4336 if (!is_evpn_enabled()) {
4337 if (use_json)
4338 vty_out(vty, "{}\n");
4339 return;
4340 }
4341 if (use_json)
4342 json = json_object_new_object();
4343
4344 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4345 wctx.vty = vty;
4346 wctx.json = json;
4347 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
4348
4349 if (use_json) {
4350 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4351 json, JSON_C_TO_STRING_PRETTY));
4352 json_object_free(json);
4353 }
4354 }
4355
4356 /*
4357 * Display MACs for all VNIs (VTY command handler).
4358 */
4359 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
4360 struct zebra_vrf *zvrf,
4361 struct in_addr vtep_ip,
4362 u_char use_json)
4363 {
4364 struct mac_walk_ctx wctx;
4365 json_object *json = NULL;
4366
4367 if (!is_evpn_enabled())
4368 return;
4369
4370 if (use_json)
4371 json = json_object_new_object();
4372
4373 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4374 wctx.vty = vty;
4375 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
4376 wctx.r_vtep_ip = vtep_ip;
4377 wctx.json = json;
4378 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
4379
4380 if (use_json) {
4381 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4382 json, JSON_C_TO_STRING_PRETTY));
4383 json_object_free(json);
4384 }
4385 }
4386
4387 /*
4388 * Display specific MAC for a VNI, if present (VTY command handler).
4389 */
4390 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
4391 vni_t vni, struct ethaddr *macaddr)
4392 {
4393 zebra_vni_t *zvni;
4394 zebra_mac_t *mac;
4395
4396 if (!is_evpn_enabled())
4397 return;
4398 zvni = zvni_lookup(vni);
4399 if (!zvni) {
4400 vty_out(vty, "%% VNI %u does not exist\n", vni);
4401 return;
4402 }
4403 mac = zvni_mac_lookup(zvni, macaddr);
4404 if (!mac) {
4405 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
4406 vni);
4407 return;
4408 }
4409
4410 zvni_print_mac(mac, vty);
4411 }
4412
4413 /*
4414 * Display MACs for a VNI from specific VTEP (VTY command handler).
4415 */
4416 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
4417 vni_t vni, struct in_addr vtep_ip,
4418 u_char use_json)
4419 {
4420 zebra_vni_t *zvni;
4421 u_int32_t num_macs;
4422 struct mac_walk_ctx wctx;
4423 json_object *json = NULL;
4424 json_object *json_mac = NULL;
4425
4426 if (!is_evpn_enabled())
4427 return;
4428 zvni = zvni_lookup(vni);
4429 if (!zvni) {
4430 if (use_json)
4431 vty_out(vty, "{}\n");
4432 else
4433 vty_out(vty, "%% VNI %u does not exist\n", vni);
4434 return;
4435 }
4436 num_macs = num_valid_macs(zvni);
4437 if (!num_macs)
4438 return;
4439
4440 if (use_json) {
4441 json = json_object_new_object();
4442 json_mac = json_object_new_object();
4443 }
4444
4445 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
4446 wctx.zvni = zvni;
4447 wctx.vty = vty;
4448 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
4449 wctx.r_vtep_ip = vtep_ip;
4450 wctx.json = json_mac;
4451 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
4452
4453 if (use_json) {
4454 json_object_int_add(json, "numMacs", wctx.count);
4455 if (wctx.count)
4456 json_object_object_add(json, "macs", json_mac);
4457 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4458 json, JSON_C_TO_STRING_PRETTY));
4459 json_object_free(json);
4460 }
4461 }
4462
4463
4464 /*
4465 * Display VNI information (VTY command handler).
4466 */
4467 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
4468 u_char use_json)
4469 {
4470 zebra_vni_t *zvni;
4471 json_object *json = NULL;
4472 void *args[2];
4473
4474 if (!is_evpn_enabled())
4475 return;
4476 zvni = zvni_lookup(vni);
4477 if (!zvni) {
4478 if (use_json)
4479 vty_out(vty, "{}\n");
4480 else
4481 vty_out(vty, "%% VNI %u does not exist\n", vni);
4482 return;
4483 }
4484 if (use_json)
4485 json = json_object_new_object();
4486 args[0] = vty;
4487 args[1] = json;
4488 zvni_print(zvni, (void *)args);
4489 if (use_json) {
4490 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4491 json, JSON_C_TO_STRING_PRETTY));
4492 json_object_free(json);
4493 }
4494 }
4495
4496 /*
4497 * Display VNI hash table (VTY command handler).
4498 */
4499 void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
4500 u_char use_json)
4501 {
4502 u_int32_t num_vnis;
4503 json_object *json = NULL;
4504 void *args[2];
4505
4506 if (!is_evpn_enabled())
4507 return;
4508 num_vnis = hashcount(zvrf->vni_table);
4509 if (!num_vnis) {
4510 if (use_json)
4511 vty_out(vty, "{}\n");
4512 return;
4513 }
4514 if (use_json) {
4515 json = json_object_new_object();
4516 json_object_string_add(json, "advertiseGatewayMacip",
4517 zvrf->advertise_gw_macip ? "Yes" : "No");
4518 json_object_int_add(json, "numVnis", num_vnis);
4519 } else {
4520 vty_out(vty, "Advertise gateway mac-ip: %s\n",
4521 zvrf->advertise_gw_macip ? "Yes" : "No");
4522 vty_out(vty, "Number of VNIs: %u\n", num_vnis);
4523 vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s %-37s\n", "VNI",
4524 "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
4525 "# Remote VTEPs", "VRF");
4526 }
4527 args[0] = vty;
4528 args[1] = json;
4529
4530 hash_iterate(zvrf->vni_table,
4531 (void (*)(struct hash_backet *, void *))zvni_print_hash,
4532 args);
4533
4534 if (use_json) {
4535 vty_out(vty, "%s\n", json_object_to_json_string_ext(
4536 json, JSON_C_TO_STRING_PRETTY));
4537 json_object_free(json);
4538 }
4539 }
4540
4541 /*
4542 * Handle neighbor delete (on a VLAN device / L3 interface) from the
4543 * kernel. This may result in either the neighbor getting deleted from
4544 * our database or being re-added to the kernel (if it is a valid
4545 * remote neighbor).
4546 */
4547 int zebra_vxlan_local_neigh_del(struct interface *ifp,
4548 struct interface *link_if, struct ipaddr *ip)
4549 {
4550 char buf[INET6_ADDRSTRLEN];
4551 char buf2[ETHER_ADDR_STRLEN];
4552 zebra_neigh_t *n = NULL;
4553 zebra_vni_t *zvni = NULL;
4554 zebra_mac_t *zmac = NULL;
4555 zebra_l3vni_t *zl3vni = NULL;
4556
4557 /* check if this is a remote neigh entry corresponding to remote
4558 * next-hop
4559 */
4560 zl3vni = zl3vni_from_svi(ifp, link_if);
4561 if (zl3vni)
4562 return zl3vni_local_nh_del(zl3vni, ip);
4563
4564 /* We are only interested in neighbors on an SVI that resides on top
4565 * of a VxLAN bridge.
4566 */
4567 zvni = zvni_from_svi(ifp, link_if);
4568 if (!zvni)
4569 return 0;
4570
4571 if (!zvni->vxlan_if) {
4572 zlog_err(
4573 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
4574 zvni->vni, zvni);
4575 return -1;
4576 }
4577
4578 if (IS_ZEBRA_DEBUG_VXLAN)
4579 zlog_debug("Del neighbor %s intf %s(%u) -> L2-VNI %u",
4580 ipaddr2str(ip, buf, sizeof(buf)),
4581 ifp->name, ifp->ifindex, zvni->vni);
4582
4583 /* If entry doesn't exist, nothing to do. */
4584 n = zvni_neigh_lookup(zvni, ip);
4585 if (!n)
4586 return 0;
4587
4588 zmac = zvni_mac_lookup(zvni, &n->emac);
4589 if (!zmac) {
4590 if (IS_ZEBRA_DEBUG_VXLAN)
4591 zlog_err(
4592 "Trying to del a neigh %s without a mac %s on VNI %u",
4593 ipaddr2str(ip, buf, sizeof(buf)),
4594 prefix_mac2str(&n->emac, buf2, sizeof(buf2)),
4595 zvni->vni);
4596
4597 return 0;
4598 }
4599
4600 /* If it is a remote entry, the kernel has aged this out or someone has
4601 * deleted it, it needs to be re-installed as Quagga is the owner.
4602 */
4603 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
4604 zvni_neigh_install(zvni, n);
4605 return 0;
4606 }
4607
4608 /* Remove neighbor from BGP. */
4609 if (IS_ZEBRA_NEIGH_ACTIVE(n))
4610 zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
4611 0);
4612
4613 /* Delete this neighbor entry. */
4614 zvni_neigh_del(zvni, n);
4615
4616 /* see if the AUTO mac needs to be deleted */
4617 if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_AUTO)
4618 && !listcount(zmac->neigh_list))
4619 zvni_mac_del(zvni, zmac);
4620
4621 return 0;
4622 }
4623
4624 /*
4625 * Handle neighbor add or update (on a VLAN device / L3 interface)
4626 * from the kernel.
4627 */
4628 int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
4629 struct interface *link_if,
4630 struct ipaddr *ip,
4631 struct ethaddr *macaddr, u_int16_t state,
4632 u_char ext_learned)
4633 {
4634 char buf[ETHER_ADDR_STRLEN];
4635 char buf2[INET6_ADDRSTRLEN];
4636 zebra_vni_t *zvni = NULL;
4637 zebra_neigh_t *n = NULL;
4638 zebra_mac_t *zmac = NULL, *old_zmac = NULL;
4639 zebra_l3vni_t *zl3vni = NULL;
4640
4641 /* check if this is a remote neigh entry corresponding to remote
4642 * next-hop
4643 */
4644 zl3vni = zl3vni_from_svi(ifp, link_if);
4645 if (zl3vni)
4646 return zl3vni_local_nh_add_update(zl3vni, ip, state);
4647
4648 /* We are only interested in neighbors on an SVI that resides on top
4649 * of a VxLAN bridge.
4650 */
4651 zvni = zvni_from_svi(ifp, link_if);
4652 if (!zvni)
4653 return 0;
4654
4655 if (IS_ZEBRA_DEBUG_VXLAN)
4656 zlog_debug(
4657 "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s-> L2-VNI %u",
4658 ipaddr2str(ip, buf2, sizeof(buf2)),
4659 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
4660 ifp->ifindex, state, ext_learned ? "ext-learned " : "",
4661 zvni->vni);
4662
4663 /* create a dummy MAC if the MAC is not already present */
4664 zmac = zvni_mac_lookup(zvni, macaddr);
4665 if (!zmac) {
4666 if (IS_ZEBRA_DEBUG_VXLAN)
4667 zlog_debug(
4668 "AUTO MAC %s created for neigh %s on VNI %u",
4669 prefix_mac2str(macaddr, buf, sizeof(buf)),
4670 ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
4671
4672 zmac = zvni_mac_add(zvni, macaddr);
4673 if (!zmac) {
4674 zlog_warn("Failed to add MAC %s VNI %u",
4675 prefix_mac2str(macaddr, buf, sizeof(buf)),
4676 zvni->vni);
4677 return -1;
4678 }
4679
4680 memset(&zmac->fwd_info, 0, sizeof(zmac->fwd_info));
4681 memset(&zmac->flags, 0, sizeof(u_int32_t));
4682 SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
4683 }
4684
4685 /* If same entry already exists, it might be a change or it might be a
4686 * move from remote to local.
4687 */
4688 n = zvni_neigh_lookup(zvni, ip);
4689 if (n) {
4690 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
4691 if (memcmp(n->emac.octet, macaddr->octet,
4692 ETH_ALEN)
4693 == 0) {
4694 /* Update any params and return - client doesn't
4695 * care about a purely local change.
4696 */
4697 n->ifindex = ifp->ifindex;
4698 return 0;
4699 }
4700
4701 /* If the MAC has changed,
4702 * need to issue a delete first
4703 * as this means a different MACIP route.
4704 * Also, need to do some unlinking/relinking.
4705 */
4706 zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
4707 &n->emac, 0);
4708 old_zmac = zvni_mac_lookup(zvni, &n->emac);
4709 if (old_zmac) {
4710 listnode_delete(old_zmac->neigh_list, n);
4711 zvni_deref_ip2mac(zvni, old_zmac, 0);
4712 }
4713
4714 /* Set "local" forwarding info. */
4715 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
4716 n->ifindex = ifp->ifindex;
4717 memcpy(&n->emac, macaddr, ETH_ALEN);
4718
4719 /* Link to new MAC */
4720 listnode_add_sort(zmac->neigh_list, n);
4721 } else if (ext_learned)
4722 /* The neighbor is remote and that is the notification we got.
4723 */
4724 {
4725 /* TODO: Evaluate if we need to do anything here. */
4726 return 0;
4727 } else
4728 /* Neighbor has moved from remote to local. */
4729 {
4730 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
4731 n->r_vtep_ip.s_addr = 0;
4732 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
4733 n->ifindex = ifp->ifindex;
4734 }
4735 } else {
4736 n = zvni_neigh_add(zvni, ip, macaddr);
4737 if (!n) {
4738 zlog_err(
4739 "Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
4740 ipaddr2str(ip, buf2, sizeof(buf2)),
4741 prefix_mac2str(macaddr, buf, sizeof(buf)),
4742 ifp->name, ifp->ifindex, zvni->vni);
4743 return -1;
4744 }
4745 /* Set "local" forwarding info. */
4746 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
4747 n->ifindex = ifp->ifindex;
4748 }
4749
4750 /* Before we program this in BGP, we need to check if MAC is locally
4751 * learnt as well */
4752 if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) {
4753 if (IS_ZEBRA_DEBUG_VXLAN)
4754 zlog_debug(
4755 "Skipping neigh %s add to client as MAC %s is not local on VNI %u",
4756 ipaddr2str(ip, buf2, sizeof(buf2)),
4757 prefix_mac2str(macaddr, buf, sizeof(buf)),
4758 zvni->vni);
4759
4760 return 0;
4761 }
4762
4763 /* Inform BGP. */
4764 if (IS_ZEBRA_DEBUG_VXLAN)
4765 zlog_debug("neigh %s (MAC %s) is now ACTIVE on L2-VNI %u",
4766 ipaddr2str(ip, buf2, sizeof(buf2)),
4767 prefix_mac2str(macaddr, buf, sizeof(buf)),
4768 zvni->vni);
4769 ZEBRA_NEIGH_SET_ACTIVE(n);
4770
4771 return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
4772 }
4773
4774
4775 /*
4776 * Handle message from client to delete a remote MACIP for a VNI.
4777 */
4778 int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
4779 struct zebra_vrf *zvrf)
4780 {
4781 struct stream *s;
4782 vni_t vni;
4783 struct ethaddr macaddr;
4784 struct ipaddr ip;
4785 struct in_addr vtep_ip;
4786 zebra_vni_t *zvni;
4787 zebra_mac_t *mac;
4788 zebra_neigh_t *n;
4789 u_short l = 0, ipa_len;
4790 char buf[ETHER_ADDR_STRLEN];
4791 char buf1[INET6_ADDRSTRLEN];
4792 struct interface *ifp = NULL;
4793 struct zebra_if *zif = NULL;
4794
4795 memset(&macaddr, 0, sizeof(struct ethaddr));
4796 memset(&ip, 0, sizeof(struct ipaddr));
4797 memset(&vtep_ip, 0, sizeof(struct in_addr));
4798
4799 s = client->ibuf;
4800
4801 while (l < length) {
4802 /* Obtain each remote MACIP and process. */
4803 /* Message contains VNI, followed by MAC followed by IP (if any)
4804 * followed by remote VTEP IP.
4805 */
4806 mac = NULL;
4807 n = NULL;
4808 memset(&ip, 0, sizeof(ip));
4809 STREAM_GETL(s, vni);
4810 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
4811 STREAM_GETL(s, ipa_len);
4812 if (ipa_len) {
4813 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
4814 : IPADDR_V6;
4815 STREAM_GET(&ip.ip.addr, s, ipa_len);
4816 }
4817 l += 4 + ETH_ALEN + 4 + ipa_len;
4818 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4819 l += IPV4_MAX_BYTELEN;
4820
4821 if (IS_ZEBRA_DEBUG_VXLAN)
4822 zlog_debug(
4823 "Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
4824 prefix_mac2str(&macaddr, buf, sizeof(buf)),
4825 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
4826 inet_ntoa(vtep_ip),
4827 zebra_route_string(client->proto));
4828
4829 /* Locate VNI hash entry - expected to exist. */
4830 zvni = zvni_lookup(vni);
4831 if (!zvni) {
4832 if (IS_ZEBRA_DEBUG_VXLAN)
4833 zlog_debug(
4834 "Failed to locate VNI hash upon remote MACIP DEL, "
4835 "VNI %u",
4836 vni);
4837 continue;
4838 }
4839 ifp = zvni->vxlan_if;
4840 if (!ifp) {
4841 zlog_err(
4842 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
4843 vni, zvni);
4844 continue;
4845 }
4846 zif = ifp->info;
4847
4848 /* If down or not mapped to a bridge, we're done. */
4849 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
4850 continue;
4851
4852 /* The remote VTEP specified is normally expected to exist, but
4853 * it is
4854 * possible that the peer may delete the VTEP before deleting
4855 * any MACs
4856 * referring to the VTEP, in which case the handler (see
4857 * remote_vtep_del)
4858 * would have already deleted the MACs.
4859 */
4860 if (!zvni_vtep_find(zvni, &vtep_ip))
4861 continue;
4862
4863 mac = zvni_mac_lookup(zvni, &macaddr);
4864 if (ipa_len)
4865 n = zvni_neigh_lookup(zvni, &ip);
4866
4867 if (n && !mac) {
4868 zlog_err(
4869 "Failed to locate MAC %s for neigh %s VNI %u",
4870 prefix_mac2str(&macaddr, buf, sizeof(buf)),
4871 ipaddr2str(&ip, buf1, sizeof(buf1)), vni);
4872 continue;
4873 }
4874
4875 /* If the remote mac or neighbor doesn't exist there is nothing
4876 * more
4877 * to do. Otherwise, uninstall the entry and then remove it.
4878 */
4879 if (!mac && !n)
4880 continue;
4881
4882 /* Uninstall remote neighbor or MAC. */
4883 if (n) {
4884 /* When the MAC changes for an IP, it is possible the
4885 * client may
4886 * update the new MAC before trying to delete the "old"
4887 * neighbor
4888 * (as these are two different MACIP routes). Do the
4889 * delete only
4890 * if the MAC matches.
4891 */
4892 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
4893 && (memcmp(n->emac.octet, macaddr.octet,
4894 ETH_ALEN)
4895 == 0)) {
4896 zvni_neigh_uninstall(zvni, n);
4897 zvni_neigh_del(zvni, n);
4898 zvni_deref_ip2mac(zvni, mac, 1);
4899 }
4900 } else {
4901 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
4902 zvni_process_neigh_on_remote_mac_del(zvni,
4903 mac);
4904
4905 if (list_isempty(mac->neigh_list)) {
4906 zvni_mac_uninstall(zvni, mac, 0);
4907 zvni_mac_del(zvni, mac);
4908 } else
4909 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
4910 }
4911 }
4912 }
4913
4914 stream_failure:
4915 return 0;
4916 }
4917
4918 /*
4919 * Handle message from client to add a remote MACIP for a VNI. This
4920 * could be just the add of a MAC address or the add of a neighbor
4921 * (IP+MAC).
4922 */
4923 int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
4924 struct zebra_vrf *zvrf)
4925 {
4926 struct stream *s;
4927 vni_t vni;
4928 struct ethaddr macaddr;
4929 struct ipaddr ip;
4930 struct in_addr vtep_ip;
4931 zebra_vni_t *zvni;
4932 zebra_vtep_t *zvtep;
4933 zebra_mac_t *mac, *old_mac;
4934 zebra_neigh_t *n;
4935 u_short l = 0, ipa_len;
4936 int update_mac = 0, update_neigh = 0;
4937 char buf[ETHER_ADDR_STRLEN];
4938 char buf1[INET6_ADDRSTRLEN];
4939 u_char sticky;
4940 struct interface *ifp = NULL;
4941 struct zebra_if *zif = NULL;
4942
4943 memset(&macaddr, 0, sizeof(struct ethaddr));
4944 memset(&ip, 0, sizeof(struct ipaddr));
4945 memset(&vtep_ip, 0, sizeof(struct in_addr));
4946
4947 if (!EVPN_ENABLED(zvrf)) {
4948 zlog_warn("%s: EVPN Not turned on yet we have received a remote_macip add zapi callback",
4949 __PRETTY_FUNCTION__);
4950 return -1;
4951 }
4952
4953 s = client->ibuf;
4954
4955 while (l < length) {
4956 /* Obtain each remote MACIP and process. */
4957 /* Message contains VNI, followed by MAC followed by IP (if any)
4958 * followed by remote VTEP IP.
4959 */
4960 update_mac = update_neigh = 0;
4961 mac = NULL;
4962 n = NULL;
4963 memset(&ip, 0, sizeof(ip));
4964 STREAM_GETL(s, vni);
4965 STREAM_GET(&macaddr.octet, s, ETH_ALEN);
4966 STREAM_GETL(s, ipa_len);
4967 if (ipa_len) {
4968 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
4969 : IPADDR_V6;
4970 STREAM_GET(&ip.ip.addr, s, ipa_len);
4971 }
4972 l += 4 + ETH_ALEN + 4 + ipa_len;
4973 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
4974 l += IPV4_MAX_BYTELEN;
4975
4976 /* Get 'sticky' flag. */
4977 STREAM_GETC(s, sticky);
4978 l++;
4979
4980 if (IS_ZEBRA_DEBUG_VXLAN)
4981 zlog_debug(
4982 "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
4983 sticky ? "sticky " : "",
4984 prefix_mac2str(&macaddr, buf, sizeof(buf)),
4985 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
4986 inet_ntoa(vtep_ip),
4987 zebra_route_string(client->proto));
4988
4989 /* Locate VNI hash entry - expected to exist. */
4990 zvni = zvni_lookup(vni);
4991 if (!zvni) {
4992 zlog_err(
4993 "Failed to locate VNI hash upon remote MACIP ADD, VNI %u",
4994 vni);
4995 continue;
4996 }
4997 ifp = zvni->vxlan_if;
4998 if (!ifp) {
4999 zlog_err(
5000 "VNI %u hash %p doesn't have intf upon remote MACIP add",
5001 vni, zvni);
5002 continue;
5003 }
5004 zif = ifp->info;
5005
5006 /* If down or not mapped to a bridge, we're done. */
5007 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5008 continue;
5009
5010 /* The remote VTEP specified should normally exist, but it is
5011 * possible
5012 * that when peering comes up, peer may advertise MACIP routes
5013 * before
5014 * advertising type-3 routes.
5015 */
5016 zvtep = zvni_vtep_find(zvni, &vtep_ip);
5017 if (!zvtep) {
5018 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
5019 zlog_err(
5020 "Failed to add remote VTEP, VNI %u zvni %p",
5021 vni, zvni);
5022 continue;
5023 }
5024
5025 zvni_vtep_install(zvni, &vtep_ip);
5026 }
5027
5028 /* First, check if the remote MAC is unknown or has a change. If
5029 * so,
5030 * that needs to be updated first. Note that client could
5031 * install
5032 * MAC and MACIP separately or just install the latter.
5033 */
5034 mac = zvni_mac_lookup(zvni, &macaddr);
5035 if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
5036 || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
5037 != sticky
5038 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
5039 update_mac = 1;
5040
5041 if (update_mac) {
5042 if (!mac) {
5043 mac = zvni_mac_add(zvni, &macaddr);
5044 if (!mac) {
5045 zlog_warn(
5046 "Failed to add MAC %s VNI %u Remote VTEP %s",
5047 prefix_mac2str(&macaddr, buf,
5048 sizeof(buf)),
5049 vni, inet_ntoa(vtep_ip));
5050 return -1;
5051 }
5052
5053 /* Is this MAC created for a MACIP? */
5054 if (ipa_len)
5055 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5056 }
5057
5058 /* Set "auto" and "remote" forwarding info. */
5059 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5060 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
5061 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5062 mac->fwd_info.r_vtep_ip = vtep_ip;
5063
5064 if (sticky)
5065 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5066 else
5067 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5068
5069 zvni_process_neigh_on_remote_mac_add(zvni, mac);
5070
5071 /* Install the entry. */
5072 zvni_mac_install(zvni, mac);
5073 }
5074
5075 /* If there is no IP, continue - after clearing AUTO flag of
5076 * MAC. */
5077 if (!ipa_len) {
5078 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5079 continue;
5080 }
5081
5082 /* Check if the remote neighbor itself is unknown or has a
5083 * change.
5084 * If so, create or update and then install the entry.
5085 */
5086 n = zvni_neigh_lookup(zvni, &ip);
5087 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
5088 || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
5089 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
5090 update_neigh = 1;
5091
5092 if (update_neigh) {
5093 if (!n) {
5094 n = zvni_neigh_add(zvni, &ip, &macaddr);
5095 if (!n) {
5096 zlog_warn(
5097 "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
5098 ipaddr2str(&ip, buf1,
5099 sizeof(buf1)),
5100 prefix_mac2str(&macaddr, buf,
5101 sizeof(buf)),
5102 vni, inet_ntoa(vtep_ip));
5103 return -1;
5104 }
5105
5106 } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
5107 != 0) {
5108 /* MAC change, update neigh list for old and new
5109 * mac */
5110 old_mac = zvni_mac_lookup(zvni, &n->emac);
5111 if (old_mac) {
5112 listnode_delete(old_mac->neigh_list, n);
5113 zvni_deref_ip2mac(zvni, old_mac, 1);
5114 }
5115 listnode_add_sort(mac->neigh_list, n);
5116 memcpy(&n->emac, &macaddr, ETH_ALEN);
5117 }
5118
5119 /* Set "remote" forwarding info. */
5120 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
5121 /* TODO: Handle MAC change. */
5122 n->r_vtep_ip = vtep_ip;
5123 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
5124
5125 /* Install the entry. */
5126 zvni_neigh_install(zvni, n);
5127 }
5128 }
5129
5130 stream_failure:
5131 return 0;
5132 }
5133
5134 /*
5135 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
5136 * us, this must involve a multihoming scenario. Treat this as implicit delete
5137 * of any prior local MAC.
5138 */
5139 int zebra_vxlan_check_del_local_mac(struct interface *ifp,
5140 struct interface *br_if,
5141 struct ethaddr *macaddr, vlanid_t vid)
5142 {
5143 struct zebra_if *zif;
5144 struct zebra_l2info_vxlan *vxl;
5145 vni_t vni;
5146 zebra_vni_t *zvni;
5147 zebra_mac_t *mac;
5148 char buf[ETHER_ADDR_STRLEN];
5149 u_char sticky;
5150
5151 zif = ifp->info;
5152 assert(zif);
5153 vxl = &zif->l2info.vxl;
5154 vni = vxl->vni;
5155
5156 /* Check if EVPN is enabled. */
5157 if (!is_evpn_enabled())
5158 return 0;
5159
5160 /* Locate hash entry; it is expected to exist. */
5161 zvni = zvni_lookup(vni);
5162 if (!zvni)
5163 return 0;
5164
5165 /* If entry doesn't exist, nothing to do. */
5166 mac = zvni_mac_lookup(zvni, macaddr);
5167 if (!mac)
5168 return 0;
5169
5170 /* Is it a local entry? */
5171 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
5172 return 0;
5173
5174 if (IS_ZEBRA_DEBUG_VXLAN)
5175 zlog_debug(
5176 "Add/update remote MAC %s intf %s(%u) VNI %u - del local",
5177 prefix_mac2str(macaddr, buf, sizeof(buf)),
5178 ifp->name, ifp->ifindex, vni);
5179
5180 /* Remove MAC from BGP. */
5181 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
5182 zvni_mac_send_del_to_client(zvni->vni, macaddr,
5183 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
5184
5185 /*
5186 * If there are no neigh associated with the mac delete the mac
5187 * else mark it as AUTO for forward reference
5188 */
5189 if (!listcount(mac->neigh_list)) {
5190 zvni_mac_del(zvni, mac);
5191 } else {
5192 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5193 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5194 }
5195
5196 return 0;
5197 }
5198
5199 /*
5200 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
5201 * This can happen because the remote MAC entries are also added as "dynamic",
5202 * so the kernel can ageout the entry.
5203 */
5204 int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
5205 struct interface *br_if,
5206 struct ethaddr *macaddr, vlanid_t vid)
5207 {
5208 struct zebra_if *zif;
5209 struct zebra_l2info_vxlan *vxl;
5210 vni_t vni;
5211 zebra_vni_t *zvni;
5212 zebra_mac_t *mac;
5213 char buf[ETHER_ADDR_STRLEN];
5214
5215 zif = ifp->info;
5216 assert(zif);
5217 vxl = &zif->l2info.vxl;
5218 vni = vxl->vni;
5219
5220 /* Check if EVPN is enabled. */
5221 if (!is_evpn_enabled())
5222 return 0;
5223
5224 /* Locate hash entry; it is expected to exist. */
5225 zvni = zvni_lookup(vni);
5226 if (!zvni)
5227 return 0;
5228
5229 /* If entry doesn't exist, nothing to do. */
5230 mac = zvni_mac_lookup(zvni, macaddr);
5231 if (!mac)
5232 return 0;
5233
5234 /* Is it a remote entry? */
5235 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
5236 return 0;
5237
5238 if (IS_ZEBRA_DEBUG_VXLAN)
5239 zlog_debug("Del remote MAC %s intf %s(%u) VNI %u - readd",
5240 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
5241 ifp->ifindex, vni);
5242
5243 zvni_mac_install(zvni, mac);
5244 return 0;
5245 }
5246
5247 /*
5248 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
5249 */
5250 int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
5251 struct ethaddr *macaddr, vlanid_t vid)
5252 {
5253 zebra_vni_t *zvni;
5254 zebra_mac_t *mac;
5255 char buf[ETHER_ADDR_STRLEN];
5256 u_char sticky;
5257
5258 /* We are interested in MACs only on ports or (port, VLAN) that
5259 * map to a VNI.
5260 */
5261 zvni = zvni_map_vlan(ifp, br_if, vid);
5262 if (!zvni)
5263 return 0;
5264 if (!zvni->vxlan_if) {
5265 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
5266 zvni->vni, zvni);
5267 return -1;
5268 }
5269
5270 if (IS_ZEBRA_DEBUG_VXLAN)
5271 zlog_debug("Del MAC %s intf %s(%u) VID %u -> VNI %u",
5272 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
5273 ifp->ifindex, vid, zvni->vni);
5274
5275 /* If entry doesn't exist, nothing to do. */
5276 mac = zvni_mac_lookup(zvni, macaddr);
5277 if (!mac)
5278 return 0;
5279
5280 /* Is it a local entry? */
5281 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
5282 return 0;
5283
5284 /* Remove MAC from BGP. */
5285 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
5286 zvni_mac_send_del_to_client(zvni->vni, macaddr,
5287 (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
5288
5289 /* Update all the neigh entries associated with this mac */
5290 zvni_process_neigh_on_local_mac_del(zvni, mac);
5291
5292 /*
5293 * If there are no neigh associated with the mac delete the mac
5294 * else mark it as AUTO for forward reference
5295 */
5296 if (!listcount(mac->neigh_list)) {
5297 zvni_mac_del(zvni, mac);
5298 } else {
5299 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5300 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5301 }
5302
5303 return 0;
5304 }
5305
5306 /*
5307 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
5308 */
5309 int zebra_vxlan_local_mac_add_update(struct interface *ifp,
5310 struct interface *br_if,
5311 struct ethaddr *macaddr, vlanid_t vid,
5312 u_char sticky)
5313 {
5314 zebra_vni_t *zvni;
5315 zebra_mac_t *mac;
5316 char buf[ETHER_ADDR_STRLEN];
5317 int add = 1;
5318 u_char mac_sticky;
5319
5320 /* We are interested in MACs only on ports or (port, VLAN) that
5321 * map to a VNI.
5322 */
5323 zvni = zvni_map_vlan(ifp, br_if, vid);
5324 if (!zvni) {
5325 if (IS_ZEBRA_DEBUG_VXLAN)
5326 zlog_debug(
5327 "Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
5328 sticky ? "sticky " : "",
5329 prefix_mac2str(macaddr, buf, sizeof(buf)),
5330 ifp->name, ifp->ifindex, vid);
5331 return 0;
5332 }
5333
5334 if (!zvni->vxlan_if) {
5335 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
5336 zvni->vni, zvni);
5337 return -1;
5338 }
5339
5340 if (IS_ZEBRA_DEBUG_VXLAN)
5341 zlog_debug(
5342 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
5343 sticky ? "sticky " : "",
5344 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
5345 ifp->ifindex, vid, zvni->vni);
5346
5347 /* If same entry already exists, nothing to do. */
5348 mac = zvni_mac_lookup(zvni, macaddr);
5349 if (mac) {
5350 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
5351 mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
5352 ? 1
5353 : 0;
5354
5355
5356 /*
5357 * return if nothing has changed.
5358 * inform bgp if sticky flag has changed
5359 * update locally and do not inform bgp if local
5360 * parameters like interface has changed
5361 */
5362 if (mac_sticky == sticky
5363 && mac->fwd_info.local.ifindex == ifp->ifindex
5364 && mac->fwd_info.local.vid == vid) {
5365 if (IS_ZEBRA_DEBUG_VXLAN)
5366 zlog_debug(
5367 "Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
5368 "entry exists and has not changed ",
5369 sticky ? "sticky " : "",
5370 prefix_mac2str(macaddr, buf,
5371 sizeof(buf)),
5372 ifp->name, ifp->ifindex, vid,
5373 zvni->vni);
5374 return 0;
5375 } else if (mac_sticky != sticky) {
5376 add = 1;
5377 } else {
5378 add = 0; /* This is an update of local
5379 interface. */
5380 }
5381 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
5382 /*
5383 * If we have already learned the MAC as a remote sticky
5384 * MAC,
5385 * this is a operator error and we must log a warning
5386 */
5387 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
5388 zlog_warn(
5389 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
5390 prefix_mac2str(macaddr, buf,
5391 sizeof(buf)),
5392 inet_ntoa(mac->fwd_info.r_vtep_ip),
5393 zvni->vni);
5394 return 0;
5395 }
5396 }
5397 }
5398
5399 if (!mac) {
5400 mac = zvni_mac_add(zvni, macaddr);
5401 if (!mac) {
5402 zlog_err("Failed to add MAC %s intf %s(%u) VID %u",
5403 prefix_mac2str(macaddr, buf, sizeof(buf)),
5404 ifp->name, ifp->ifindex, vid);
5405 return -1;
5406 }
5407 }
5408
5409 /* Set "local" forwarding info. */
5410 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
5411 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
5412 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
5413 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
5414 mac->fwd_info.local.ifindex = ifp->ifindex;
5415 mac->fwd_info.local.vid = vid;
5416
5417 if (sticky)
5418 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5419 else
5420 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
5421
5422 /* Inform BGP if required. */
5423 if (add) {
5424 zvni_process_neigh_on_local_mac_add(zvni, mac);
5425 return zvni_mac_send_add_to_client(zvni->vni, macaddr,
5426 sticky);
5427 }
5428
5429 return 0;
5430 }
5431
5432 /*
5433 * Handle message from client to delete a remote VTEP for a VNI.
5434 */
5435 int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
5436 struct zebra_vrf *zvrf)
5437 {
5438 struct stream *s;
5439 u_short l = 0;
5440 vni_t vni;
5441 struct in_addr vtep_ip;
5442 zebra_vni_t *zvni;
5443 zebra_vtep_t *zvtep;
5444 struct interface *ifp;
5445 struct zebra_if *zif;
5446
5447 if (!is_evpn_enabled()) {
5448 zlog_warn("%s: EVPN is not enabled yet we have received a vtep del command",
5449 __PRETTY_FUNCTION__);
5450 return -1;
5451 }
5452
5453 if (zvrf_id(zvrf) != VRF_DEFAULT) {
5454 zlog_err("Recv MACIP DEL for non-default VRF %u",
5455 zvrf_id(zvrf));
5456 return -1;
5457 }
5458
5459 s = client->ibuf;
5460
5461 while (l < length) {
5462 /* Obtain each remote VTEP and process. */
5463 STREAM_GETL(s, vni);
5464 l += 4;
5465 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
5466 l += IPV4_MAX_BYTELEN;
5467
5468 if (IS_ZEBRA_DEBUG_VXLAN)
5469 zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
5470 inet_ntoa(vtep_ip), vni,
5471 zebra_route_string(client->proto));
5472
5473 /* Locate VNI hash entry - expected to exist. */
5474 zvni = zvni_lookup(vni);
5475 if (!zvni) {
5476 if (IS_ZEBRA_DEBUG_VXLAN)
5477 zlog_debug(
5478 "Failed to locate VNI hash upon remote VTEP DEL, "
5479 "VNI %u",
5480 vni);
5481 continue;
5482 }
5483
5484 ifp = zvni->vxlan_if;
5485 if (!ifp) {
5486 zlog_err(
5487 "VNI %u hash %p doesn't have intf upon remote VTEP DEL",
5488 zvni->vni, zvni);
5489 continue;
5490 }
5491 zif = ifp->info;
5492
5493 /* If down or not mapped to a bridge, we're done. */
5494 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5495 continue;
5496
5497 /* If the remote VTEP does not exist, there's nothing more to
5498 * do.
5499 * Otherwise, uninstall any remote MACs pointing to this VTEP
5500 * and
5501 * then, the VTEP entry itself and remove it.
5502 */
5503 zvtep = zvni_vtep_find(zvni, &vtep_ip);
5504 if (!zvtep)
5505 continue;
5506
5507 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
5508 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
5509 zvni_vtep_uninstall(zvni, &vtep_ip);
5510 zvni_vtep_del(zvni, zvtep);
5511 }
5512
5513 stream_failure:
5514 return 0;
5515 }
5516
5517 /*
5518 * Handle message from client to add a remote VTEP for a VNI.
5519 */
5520 int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
5521 struct zebra_vrf *zvrf)
5522 {
5523 struct stream *s;
5524 u_short l = 0;
5525 vni_t vni;
5526 struct in_addr vtep_ip;
5527 zebra_vni_t *zvni;
5528 struct interface *ifp;
5529 struct zebra_if *zif;
5530
5531 if (!is_evpn_enabled()) {
5532 zlog_warn("%s: EVPN not enabled yet we received a vtep_add zapi call",
5533 __PRETTY_FUNCTION__);
5534 return -1;
5535 }
5536
5537 if (zvrf_id(zvrf) != VRF_DEFAULT) {
5538 zlog_err("Recv MACIP ADD for non-default VRF %u",
5539 zvrf_id(zvrf));
5540 return -1;
5541 }
5542
5543 s = client->ibuf;
5544
5545 while (l < length) {
5546 /* Obtain each remote VTEP and process. */
5547 STREAM_GETL(s, vni);
5548 l += 4;
5549 STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
5550 l += IPV4_MAX_BYTELEN;
5551
5552 if (IS_ZEBRA_DEBUG_VXLAN)
5553 zlog_debug("Recv VTEP_ADD %s VNI %u from %s",
5554 inet_ntoa(vtep_ip), vni,
5555 zebra_route_string(client->proto));
5556
5557 /* Locate VNI hash entry - expected to exist. */
5558 zvni = zvni_lookup(vni);
5559 if (!zvni) {
5560 zlog_err(
5561 "Failed to locate VNI hash upon remote VTEP ADD, VNI %u",
5562 vni);
5563 continue;
5564 }
5565
5566 ifp = zvni->vxlan_if;
5567 if (!ifp) {
5568 zlog_err(
5569 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
5570 zvni->vni, zvni);
5571 continue;
5572 }
5573
5574 zif = ifp->info;
5575
5576 /* If down or not mapped to a bridge, we're done. */
5577 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
5578 continue;
5579
5580 /* If the remote VTEP already exists,
5581 there's nothing more to do. */
5582 if (zvni_vtep_find(zvni, &vtep_ip))
5583 continue;
5584
5585 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
5586 zlog_err(
5587 "Failed to add remote VTEP, VNI %u zvni %p",
5588 vni, zvni);
5589 continue;
5590 }
5591
5592 zvni_vtep_install(zvni, &vtep_ip);
5593 }
5594
5595 stream_failure:
5596 return 0;
5597 }
5598
5599 /*
5600 * Add/Del gateway macip to evpn
5601 * g/w can be:
5602 * 1. SVI interface on a vlan aware bridge
5603 * 2. SVI interface on a vlan unaware bridge
5604 * 3. vrr interface (MACVLAN) associated to a SVI
5605 * We advertise macip routes for an interface if it is associated to VxLan vlan
5606 */
5607 int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
5608 int add)
5609 {
5610 struct ipaddr ip;
5611 struct ethaddr macaddr;
5612 zebra_vni_t *zvni = NULL;
5613
5614 memset(&ip, 0, sizeof(struct ipaddr));
5615 memset(&macaddr, 0, sizeof(struct ethaddr));
5616
5617 /* Check if EVPN is enabled. */
5618 if (!is_evpn_enabled())
5619 return 0;
5620
5621 if (IS_ZEBRA_IF_MACVLAN(ifp)) {
5622 struct interface *svi_if =
5623 NULL; /* SVI corresponding to the MACVLAN */
5624 struct zebra_if *ifp_zif =
5625 NULL; /* Zebra daemon specific info for MACVLAN */
5626 struct zebra_if *svi_if_zif =
5627 NULL; /* Zebra daemon specific info for SVI*/
5628
5629 ifp_zif = ifp->info;
5630 if (!ifp_zif)
5631 return -1;
5632
5633 /*
5634 * for a MACVLAN interface the link represents the svi_if
5635 */
5636 svi_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
5637 ifp_zif->link_ifindex);
5638 if (!svi_if) {
5639 zlog_err("MACVLAN %s(%u) without link information",
5640 ifp->name, ifp->ifindex);
5641 return -1;
5642 }
5643
5644 if (IS_ZEBRA_IF_VLAN(svi_if)) {
5645 /*
5646 * If it is a vlan aware bridge then the link gives the
5647 * bridge information
5648 */
5649 struct interface *svi_if_link = NULL;
5650
5651 svi_if_zif = svi_if->info;
5652 if (svi_if_zif) {
5653 svi_if_link = if_lookup_by_index_per_ns(
5654 zebra_ns_lookup(NS_DEFAULT),
5655 svi_if_zif->link_ifindex);
5656 zvni = zvni_from_svi(svi_if, svi_if_link);
5657 }
5658 } else if (IS_ZEBRA_IF_BRIDGE(svi_if)) {
5659 /*
5660 * If it is a vlan unaware bridge then svi is the bridge
5661 * itself
5662 */
5663 zvni = zvni_from_svi(svi_if, svi_if);
5664 }
5665 } else if (IS_ZEBRA_IF_VLAN(ifp)) {
5666 struct zebra_if *svi_if_zif =
5667 NULL; /* Zebra daemon specific info for SVI */
5668 struct interface *svi_if_link =
5669 NULL; /* link info for the SVI = bridge info */
5670
5671 svi_if_zif = ifp->info;
5672 svi_if_link = if_lookup_by_index_per_ns(
5673 zebra_ns_lookup(NS_DEFAULT), svi_if_zif->link_ifindex);
5674 if (svi_if_zif && svi_if_link)
5675 zvni = zvni_from_svi(ifp, svi_if_link);
5676 } else if (IS_ZEBRA_IF_BRIDGE(ifp)) {
5677 zvni = zvni_from_svi(ifp, ifp);
5678 }
5679
5680 if (!zvni)
5681 return 0;
5682
5683 if (!zvni->vxlan_if) {
5684 zlog_err("VNI %u hash %p doesn't have intf upon MACVLAN up",
5685 zvni->vni, zvni);
5686 return -1;
5687 }
5688
5689
5690 /* check if we are advertising gw macip routes */
5691 if (!advertise_gw_macip_enabled(zvni))
5692 return 0;
5693
5694 memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
5695
5696 if (p->family == AF_INET) {
5697 ip.ipa_type = IPADDR_V4;
5698 memcpy(&(ip.ipaddr_v4), &(p->u.prefix4),
5699 sizeof(struct in_addr));
5700 } else if (p->family == AF_INET6) {
5701 ip.ipa_type = IPADDR_V6;
5702 memcpy(&(ip.ipaddr_v6), &(p->u.prefix6),
5703 sizeof(struct in6_addr));
5704 }
5705
5706
5707 if (add)
5708 zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
5709 else
5710 zvni_gw_macip_del(ifp, zvni, &ip);
5711
5712 return 0;
5713 }
5714
5715 /*
5716 * Handle SVI interface going down.
5717 * SVI can be associated to either L3-VNI or L2-VNI.
5718 * For L2-VNI: At this point, this is a NOP since
5719 * the kernel deletes the neighbor entries on this SVI (if any).
5720 * We only need to update the vrf corresponding to zvni.
5721 * For L3-VNI: L3-VNI is operationally down, update mac-ip routes and delete
5722 * from bgp
5723 */
5724 int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
5725 {
5726 zebra_l3vni_t *zl3vni = NULL;
5727
5728 zl3vni = zl3vni_from_svi(ifp, link_if);
5729 if (zl3vni) {
5730
5731 /* process l3-vni down */
5732 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5733
5734 /* remove association with svi-if */
5735 zl3vni->svi_if = NULL;
5736 } else {
5737 zebra_vni_t *zvni = NULL;
5738
5739 /* since we dont have svi corresponding to zvni, we associate it
5740 * to default vrf. Note: the corresponding neigh entries on the
5741 * SVI would have already been deleted */
5742 zvni = zvni_from_svi(ifp, link_if);
5743 if (zvni) {
5744 zvni->vrf_id = VRF_DEFAULT;
5745
5746 /* update the tenant vrf in BGP */
5747 zvni_send_add_to_client(zvni);
5748 }
5749 }
5750 return 0;
5751 }
5752
5753 /*
5754 * Handle SVI interface coming up.
5755 * SVI can be associated to L3-VNI (l3vni vxlan interface) or L2-VNI (l2-vni
5756 * vxlan intf).
5757 * For L2-VNI: we need to install any remote neighbors entried (used for
5758 * apr-suppression)
5759 * For L3-VNI: SVI will be used to get the rmac to be used with L3-VNI
5760 */
5761 int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
5762 {
5763 zebra_vni_t *zvni = NULL;
5764 zebra_l3vni_t *zl3vni = NULL;
5765
5766 zl3vni = zl3vni_from_svi(ifp, link_if);
5767 if (zl3vni) {
5768
5769 /* associate with svi */
5770 zl3vni->svi_if = ifp;
5771
5772 /* process oper-up */
5773 if (is_l3vni_oper_up(zl3vni))
5774 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5775 } else {
5776
5777 /* process SVI up for l2-vni */
5778 struct neigh_walk_ctx n_wctx;
5779
5780 zvni = zvni_from_svi(ifp, link_if);
5781 if (!zvni)
5782 return 0;
5783
5784 if (!zvni->vxlan_if) {
5785 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
5786 zvni->vni, zvni);
5787 return -1;
5788 }
5789
5790 if (IS_ZEBRA_DEBUG_VXLAN)
5791 zlog_debug("SVI %s(%u) VNI %u VRF %s is UP, installing neighbors",
5792 ifp->name, ifp->ifindex, zvni->vni,
5793 vrf_id_to_name(ifp->vrf_id));
5794
5795 /* update the vrf information for l2-vni and inform bgp */
5796 zvni->vrf_id = ifp->vrf_id;
5797 zvni_send_add_to_client(zvni);
5798
5799 /* Install any remote neighbors for this VNI. */
5800 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
5801 n_wctx.zvni = zvni;
5802 hash_iterate(zvni->neigh_table,
5803 zvni_install_neigh_hash,
5804 &n_wctx);
5805 }
5806
5807 return 0;
5808 }
5809
5810 /*
5811 * Handle VxLAN interface down
5812 */
5813 int zebra_vxlan_if_down(struct interface *ifp)
5814 {
5815 vni_t vni;
5816 struct zebra_if *zif = NULL;
5817 struct zebra_l2info_vxlan *vxl = NULL;
5818
5819 /* Check if EVPN is enabled. */
5820 if (!is_evpn_enabled())
5821 return 0;
5822
5823 zif = ifp->info;
5824 assert(zif);
5825 vxl = &zif->l2info.vxl;
5826 vni = vxl->vni;
5827
5828
5829 if (is_vni_l3(vni)) {
5830
5831 /* process-if-down for l3-vni */
5832 zebra_l3vni_t *zl3vni = NULL;
5833
5834 if (IS_ZEBRA_DEBUG_VXLAN)
5835 zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
5836 ifp->name, ifp->ifindex, vni);
5837
5838 zl3vni = zl3vni_lookup(vni);
5839 if (!zl3vni) {
5840 zlog_err(
5841 "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u",
5842 ifp->name, ifp->ifindex, vni);
5843 return -1;
5844 }
5845
5846 zebra_vxlan_process_l3vni_oper_down(zl3vni);
5847
5848 } else {
5849 /* process if-down for l2-vni */
5850 zebra_vni_t *zvni;
5851
5852 if (IS_ZEBRA_DEBUG_VXLAN)
5853 zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
5854 ifp->name, ifp->ifindex, vni);
5855
5856 /* Locate hash entry; it is expected to exist. */
5857 zvni = zvni_lookup(vni);
5858 if (!zvni) {
5859 zlog_err(
5860 "Failed to locate VNI hash at DOWN, IF %s(%u) VNI %u",
5861 ifp->name, ifp->ifindex, vni);
5862 return -1;
5863 }
5864
5865 assert(zvni->vxlan_if == ifp);
5866
5867 /* Delete this VNI from BGP. */
5868 zvni_send_del_to_client(zvni->vni);
5869
5870 /* Free up all neighbors and MACs, if any. */
5871 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
5872 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
5873
5874 /* Free up all remote VTEPs, if any. */
5875 zvni_vtep_del_all(zvni, 1);
5876 }
5877 return 0;
5878 }
5879
5880 /*
5881 * Handle VxLAN interface up - update BGP if required.
5882 */
5883 int zebra_vxlan_if_up(struct interface *ifp)
5884 {
5885 vni_t vni;
5886 struct zebra_if *zif = NULL;
5887 struct zebra_l2info_vxlan *vxl = NULL;
5888
5889 /* Check if EVPN is enabled. */
5890 if (!is_evpn_enabled())
5891 return 0;
5892
5893 zif = ifp->info;
5894 assert(zif);
5895 vxl = &zif->l2info.vxl;
5896 vni = vxl->vni;
5897
5898 if (is_vni_l3(vni)) {
5899
5900 /* Handle L3-VNI add */
5901 zebra_l3vni_t *zl3vni = NULL;
5902
5903 if (IS_ZEBRA_DEBUG_VXLAN)
5904 zlog_debug("Intf %s(%u) L3-VNI %u is UP",
5905 ifp->name, ifp->ifindex, vni);
5906
5907 zl3vni = zl3vni_lookup(vni);
5908 if (!zl3vni) {
5909 zlog_err(
5910 "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
5911 ifp->name, ifp->ifindex, vni);
5912 return -1;
5913 }
5914
5915 /* we need to associate with SVI, if any, we can associate with
5916 * svi-if only after association with vxlan-intf is complete
5917 */
5918 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
5919
5920 if (is_l3vni_oper_up(zl3vni))
5921 zebra_vxlan_process_l3vni_oper_up(zl3vni);
5922 } else {
5923 /* Handle L2-VNI add */
5924
5925 zebra_vni_t *zvni = NULL;
5926 zebra_l3vni_t *zl3vni = NULL;
5927 struct interface *vlan_if = NULL;
5928
5929 if (IS_ZEBRA_DEBUG_VXLAN)
5930 zlog_debug("Intf %s(%u) L2-VNI %u is UP",
5931 ifp->name, ifp->ifindex, vni);
5932
5933 /* Locate hash entry; it is expected to exist. */
5934 zvni = zvni_lookup(vni);
5935 if (!zvni) {
5936 zlog_err(
5937 "Failed to locate VNI hash at UP, IF %s(%u) VNI %u",
5938 ifp->name, ifp->ifindex, vni);
5939 return -1;
5940 }
5941
5942 assert(zvni->vxlan_if == ifp);
5943 vlan_if = zvni_map_to_svi(vxl->access_vlan,
5944 zif->brslave_info.br_if);
5945 if (vlan_if) {
5946 zvni->vrf_id = vlan_if->vrf_id;
5947 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
5948 if (zl3vni)
5949 listnode_add_sort(zl3vni->l2vnis, zvni);
5950 }
5951
5952 /* If part of a bridge, inform BGP about this VNI. */
5953 /* Also, read and populate local MACs and neighbors. */
5954 if (zif->brslave_info.br_if) {
5955 zvni_send_add_to_client(zvni);
5956 zvni_read_mac_neigh(zvni, ifp);
5957 }
5958 }
5959
5960 return 0;
5961 }
5962
5963 /*
5964 * Handle VxLAN interface delete. Locate and remove entry in hash table
5965 * and update BGP, if required.
5966 */
5967 int zebra_vxlan_if_del(struct interface *ifp)
5968 {
5969 vni_t vni;
5970 struct zebra_if *zif = NULL;
5971 struct zebra_l2info_vxlan *vxl = NULL;
5972
5973 /* Check if EVPN is enabled. */
5974 if (!is_evpn_enabled())
5975 return 0;
5976
5977 zif = ifp->info;
5978 assert(zif);
5979 vxl = &zif->l2info.vxl;
5980 vni = vxl->vni;
5981
5982 if (is_vni_l3(vni)) {
5983
5984 /* process if-del for l3-vni */
5985 zebra_l3vni_t *zl3vni = NULL;
5986
5987 if (IS_ZEBRA_DEBUG_VXLAN)
5988 zlog_debug("Del L3-VNI %u intf %s(%u)",
5989 vni, ifp->name, ifp->ifindex);
5990
5991 zl3vni = zl3vni_lookup(vni);
5992 if (!zl3vni) {
5993 zlog_err(
5994 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
5995 ifp->name, ifp->ifindex, vni);
5996 return 0;
5997 }
5998
5999 /* process oper-down for l3-vni */
6000 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6001
6002 /* remove the association with vxlan_if */
6003 memset(&zl3vni->local_vtep_ip, 0, sizeof(struct in_addr));
6004 zl3vni->vxlan_if = NULL;
6005 } else {
6006
6007 /* process if-del for l2-vni*/
6008 zebra_vni_t *zvni = NULL;
6009 zebra_l3vni_t *zl3vni = NULL;
6010
6011 if (IS_ZEBRA_DEBUG_VXLAN)
6012 zlog_debug("Del L2-VNI %u intf %s(%u)",
6013 vni, ifp->name, ifp->ifindex);
6014
6015 /* Locate hash entry; it is expected to exist. */
6016 zvni = zvni_lookup(vni);
6017 if (!zvni) {
6018 zlog_err(
6019 "Failed to locate VNI hash at del, IF %s(%u) VNI %u",
6020 ifp->name, ifp->ifindex, vni);
6021 return 0;
6022 }
6023
6024 /* remove from l3-vni list */
6025 zl3vni = zl3vni_from_vrf(zvni->vrf_id);
6026 if (zl3vni)
6027 listnode_delete(zl3vni->l2vnis, zvni);
6028
6029 /* Delete VNI from BGP. */
6030 zvni_send_del_to_client(zvni->vni);
6031
6032 /* Free up all neighbors and MAC, if any. */
6033 zvni_neigh_del_all(zvni, 0, 0, DEL_ALL_NEIGH);
6034 zvni_mac_del_all(zvni, 0, 0, DEL_ALL_MAC);
6035
6036 /* Free up all remote VTEPs, if any. */
6037 zvni_vtep_del_all(zvni, 0);
6038
6039 /* Delete the hash entry. */
6040 if (zvni_del(zvni)) {
6041 zlog_err("Failed to del VNI hash %p, IF %s(%u) VNI %u",
6042 zvni, ifp->name, ifp->ifindex, zvni->vni);
6043 return -1;
6044 }
6045 }
6046
6047 return 0;
6048 }
6049
6050 /*
6051 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
6052 */
6053 int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
6054 {
6055 vni_t vni;
6056 struct zebra_if *zif = NULL;
6057 struct zebra_l2info_vxlan *vxl = NULL;
6058
6059 /* Check if EVPN is enabled. */
6060 if (!is_evpn_enabled())
6061 return 0;
6062
6063 zif = ifp->info;
6064 assert(zif);
6065 vxl = &zif->l2info.vxl;
6066 vni = vxl->vni;
6067
6068 if (is_vni_l3(vni)) {
6069 zebra_l3vni_t *zl3vni = NULL;
6070
6071 zl3vni = zl3vni_lookup(vni);
6072 if (!zl3vni) {
6073 zlog_err(
6074 "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
6075 ifp->name, ifp->ifindex, vni);
6076 return -1;
6077 }
6078
6079 if (IS_ZEBRA_DEBUG_VXLAN)
6080 zlog_debug(
6081 "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6082 vni, ifp->name, ifp->ifindex,
6083 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6084 zif->brslave_info.bridge_ifindex, chgflags);
6085
6086 /* Removed from bridge? Cleanup and return */
6087 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
6088 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
6089 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6090 return 0;
6091 }
6092
6093 /* access-vlan change - process oper down, associate with new
6094 * svi_if and then process oper up again
6095 */
6096 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
6097 if (if_is_operative(ifp)) {
6098 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6099 zl3vni->svi_if = NULL;
6100 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6101 if (is_l3vni_oper_up(zl3vni))
6102 zebra_vxlan_process_l3vni_oper_up(
6103 zl3vni);
6104 }
6105 }
6106
6107 /* if we have a valid new master, process l3-vni oper up */
6108 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) {
6109 if (is_l3vni_oper_up(zl3vni))
6110 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6111 }
6112 } else {
6113 zebra_vni_t *zvni = NULL;
6114
6115 /* Update VNI hash. */
6116 zvni = zvni_lookup(vni);
6117 if (!zvni) {
6118 zlog_err(
6119 "Failed to find L2-VNI hash on update, IF %s(%u) VNI %u",
6120 ifp->name, ifp->ifindex, vni);
6121 return -1;
6122 }
6123
6124 if (IS_ZEBRA_DEBUG_VXLAN)
6125 zlog_debug(
6126 "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
6127 vni, ifp->name, ifp->ifindex,
6128 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6129 zif->brslave_info.bridge_ifindex, chgflags);
6130
6131 /* Removed from bridge? Cleanup and return */
6132 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
6133 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
6134 /* Delete from client, remove all remote VTEPs */
6135 /* Also, free up all MACs and neighbors. */
6136 zvni_send_del_to_client(zvni->vni);
6137 zvni_neigh_del_all(zvni, 1, 0, DEL_ALL_NEIGH);
6138 zvni_mac_del_all(zvni, 1, 0, DEL_ALL_MAC);
6139 zvni_vtep_del_all(zvni, 1);
6140 return 0;
6141 }
6142
6143 /* Handle other changes. */
6144 if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
6145 /* Remove all existing local neigh and MACs for this VNI
6146 * (including from BGP)
6147 */
6148 zvni_neigh_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
6149 zvni_mac_del_all(zvni, 0, 1, DEL_LOCAL_MAC);
6150 }
6151
6152 zvni->local_vtep_ip = vxl->vtep_ip;
6153 zvni->vxlan_if = ifp;
6154
6155 /* Take further actions needed.
6156 * Note that if we are here, there is a change of interest.
6157 */
6158 /* If down or not mapped to a bridge, we're done. */
6159 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6160 return 0;
6161
6162 /* Inform BGP, if there is a change of interest. */
6163 if (chgflags
6164 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
6165 zvni_send_add_to_client(zvni);
6166
6167 /* If there is a valid new master or a VLAN mapping change,
6168 * read and populate local MACs and neighbors.
6169 * Also, reinstall any remote MACs and neighbors
6170 * for this VNI (based on new VLAN).
6171 */
6172 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
6173 zvni_read_mac_neigh(zvni, ifp);
6174 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
6175 struct mac_walk_ctx m_wctx;
6176 struct neigh_walk_ctx n_wctx;
6177
6178 zvni_read_mac_neigh(zvni, ifp);
6179
6180 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
6181 m_wctx.zvni = zvni;
6182 hash_iterate(zvni->mac_table,
6183 zvni_install_mac_hash,
6184 &m_wctx);
6185
6186 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
6187 n_wctx.zvni = zvni;
6188 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
6189 &n_wctx);
6190 }
6191 }
6192
6193 return 0;
6194 }
6195
6196 /*
6197 * Handle VxLAN interface add.
6198 */
6199 int zebra_vxlan_if_add(struct interface *ifp)
6200 {
6201 vni_t vni;
6202 struct zebra_if *zif = NULL;
6203 struct zebra_l2info_vxlan *vxl = NULL;
6204
6205 /* Check if EVPN is enabled. */
6206 if (!is_evpn_enabled())
6207 return 0;
6208
6209 zif = ifp->info;
6210 assert(zif);
6211 vxl = &zif->l2info.vxl;
6212 vni = vxl->vni;
6213
6214 if (is_vni_l3(vni)) {
6215
6216 /* process if-add for l3-vni*/
6217 zebra_l3vni_t *zl3vni = NULL;
6218
6219 if (IS_ZEBRA_DEBUG_VXLAN)
6220 zlog_debug(
6221 "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
6222 vni, ifp->name, ifp->ifindex,
6223 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6224 zif->brslave_info.bridge_ifindex);
6225
6226 /*
6227 * we expect the l3-vni has entry to be present here.
6228 * The only place l3-vni is created in zebra is vrf-vni mapping
6229 * command. This might change when we have the switchd support
6230 * for l3-vxlan interface.
6231 */
6232 zl3vni = zl3vni_lookup(vni);
6233 if (!zl3vni) {
6234 zlog_err(
6235 "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
6236 ifp->name, ifp->ifindex, vni);
6237 return 0;
6238 }
6239
6240 /* associate with vxlan_if */
6241 zl3vni->local_vtep_ip = vxl->vtep_ip;
6242 zl3vni->vxlan_if = ifp;
6243
6244 /* Associate with SVI, if any. We can associate with svi-if only
6245 * after association with vxlan_if is complete */
6246 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6247
6248 if (is_l3vni_oper_up(zl3vni))
6249 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6250 } else {
6251
6252 /* process if-add for l2-vni */
6253 zebra_vni_t *zvni = NULL;
6254 zebra_l3vni_t *zl3vni = NULL;
6255 struct interface *vlan_if = NULL;
6256
6257 /* Create or update VNI hash. */
6258 zvni = zvni_lookup(vni);
6259 if (!zvni) {
6260 zvni = zvni_add(vni);
6261 if (!zvni) {
6262 zlog_err(
6263 "Failed to add VNI hash, IF %s(%u) VNI %u",
6264 ifp->name, ifp->ifindex, vni);
6265 return -1;
6266 }
6267 }
6268
6269 zvni->local_vtep_ip = vxl->vtep_ip;
6270 zvni->vxlan_if = ifp;
6271 vlan_if = zvni_map_to_svi(vxl->access_vlan,
6272 zif->brslave_info.br_if);
6273 if (vlan_if) {
6274 zvni->vrf_id = vlan_if->vrf_id;
6275 zl3vni = zl3vni_from_vrf(vlan_if->vrf_id);
6276 if (zl3vni)
6277 listnode_add_sort(zl3vni->l2vnis, zvni);
6278 }
6279
6280 if (IS_ZEBRA_DEBUG_VXLAN)
6281 zlog_debug(
6282 "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
6283 vni,
6284 vlan_if ? vrf_id_to_name(vlan_if->vrf_id) :
6285 "Default",
6286 ifp->name, ifp->ifindex,
6287 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
6288 zif->brslave_info.bridge_ifindex);
6289
6290 /* If down or not mapped to a bridge, we're done. */
6291 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6292 return 0;
6293
6294 /* Inform BGP */
6295 zvni_send_add_to_client(zvni);
6296
6297 /* Read and populate local MACs and neighbors */
6298 zvni_read_mac_neigh(zvni, ifp);
6299 }
6300
6301 return 0;
6302 }
6303
6304 int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf,
6305 vni_t vni,
6306 char *err, int err_str_sz,
6307 int add)
6308 {
6309 zebra_l3vni_t *zl3vni = NULL;
6310 struct zebra_vrf *zvrf_default = NULL;
6311
6312 zvrf_default = zebra_vrf_lookup_by_id(VRF_DEFAULT);
6313 if (!zvrf_default)
6314 return -1;
6315
6316 if (IS_ZEBRA_DEBUG_VXLAN)
6317 zlog_debug("vrf %s vni %u %s",
6318 zvrf_name(zvrf),
6319 vni,
6320 add ? "ADD" : "DEL");
6321
6322 if (add) {
6323
6324 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
6325
6326 /* check if the vni is already present under zvrf */
6327 if (zvrf->l3vni) {
6328 snprintf(err, err_str_sz,
6329 "VNI is already configured under the vrf");
6330 return -1;
6331 }
6332
6333 /* check if this VNI is already present in the system */
6334 zl3vni = zl3vni_lookup(vni);
6335 if (zl3vni) {
6336 snprintf(err, err_str_sz,
6337 "VNI is already configured as L3-VNI");
6338 return -1;
6339 }
6340
6341 /* add the L3-VNI to the global table */
6342 zl3vni = zl3vni_add(vni, zvrf_id(zvrf));
6343 if (!zl3vni) {
6344 snprintf(err, err_str_sz,
6345 "Could not add L3-VNI");
6346 return -1;
6347 }
6348
6349 /* associate the vrf with vni */
6350 zvrf->l3vni = vni;
6351
6352 /* associate with vxlan-intf;
6353 * we need to associate with the vxlan-intf first
6354 */
6355 zl3vni->vxlan_if = zl3vni_map_to_vxlan_if(zl3vni);
6356
6357 /* associate with corresponding SVI interface, we can associate
6358 * with svi-if only after vxlan interface association is
6359 * complete
6360 */
6361 zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni);
6362
6363 /* formulate l2vni list */
6364 hash_iterate(zvrf_default->vni_table,
6365 zvni_add_to_l3vni_list, zl3vni);
6366
6367 if (is_l3vni_oper_up(zl3vni))
6368 zebra_vxlan_process_l3vni_oper_up(zl3vni);
6369
6370 } else {
6371 zl3vni = zl3vni_lookup(vni);
6372 if (!zl3vni) {
6373 snprintf(err, err_str_sz, "VNI doesn't exist");
6374 return -1;
6375 }
6376
6377 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6378
6379 /* delete and uninstall all rmacs */
6380 hash_iterate(zl3vni->rmac_table,
6381 zl3vni_del_rmac_hash_entry,
6382 zl3vni);
6383
6384 /* delete and uninstall all next-hops */
6385 hash_iterate(zl3vni->nh_table,
6386 zl3vni_del_nh_hash_entry,
6387 zl3vni);
6388
6389 zvrf->l3vni = 0;
6390 zl3vni_del(zl3vni);
6391
6392 zebra_vxlan_handle_vni_transition(zvrf, vni, add);
6393 }
6394 return 0;
6395 }
6396
6397 int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
6398 {
6399 zebra_l3vni_t *zl3vni = NULL;
6400
6401 zl3vni = zl3vni_from_vrf(zvrf_id(zvrf));
6402 if (!zl3vni)
6403 return 0;
6404
6405 zebra_vxlan_process_l3vni_oper_down(zl3vni);
6406 zl3vni_del(zl3vni);
6407 zebra_vxlan_handle_vni_transition(zvrf, zl3vni->vni, 0);
6408
6409 return 0;
6410 }
6411
6412 /*
6413 * Handle message from client to enable/disable advertisement of g/w macip
6414 * routes
6415 */
6416 int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
6417 struct zebra_vrf *zvrf)
6418 {
6419 struct stream *s;
6420 int advertise;
6421 vni_t vni = 0;
6422 zebra_vni_t *zvni = NULL;
6423 struct interface *ifp = NULL;
6424
6425 if (zvrf_id(zvrf) != VRF_DEFAULT) {
6426 zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
6427 zvrf_id(zvrf));
6428 return -1;
6429 }
6430
6431 s = client->ibuf;
6432 STREAM_GETC(s, advertise);
6433 STREAM_GET(&vni, s, 3);
6434
6435 if (!vni) {
6436 if (IS_ZEBRA_DEBUG_VXLAN)
6437 zlog_debug("EVPN gateway macip Adv %s, currently %s",
6438 advertise ? "enabled" : "disabled",
6439 advertise_gw_macip_enabled(NULL)
6440 ? "enabled"
6441 : "disabled");
6442
6443 if (zvrf->advertise_gw_macip == advertise)
6444 return 0;
6445
6446 zvrf->advertise_gw_macip = advertise;
6447
6448 if (advertise_gw_macip_enabled(zvni))
6449 hash_iterate(zvrf->vni_table,
6450 zvni_gw_macip_add_for_vni_hash, NULL);
6451 else
6452 hash_iterate(zvrf->vni_table,
6453 zvni_gw_macip_del_for_vni_hash, NULL);
6454
6455 } else {
6456 struct zebra_if *zif = NULL;
6457 struct zebra_l2info_vxlan zl2_info;
6458 struct interface *vlan_if = NULL;
6459 struct interface *vrr_if = NULL;
6460
6461 if (IS_ZEBRA_DEBUG_VXLAN)
6462 zlog_debug(
6463 "EVPN gateway macip Adv %s on VNI %d , currently %s",
6464 advertise ? "enabled" : "disabled", vni,
6465 advertise_gw_macip_enabled(zvni)
6466 ? "enabled"
6467 : "disabled");
6468
6469 zvni = zvni_lookup(vni);
6470 if (!zvni)
6471 return 0;
6472
6473 if (zvni->advertise_gw_macip == advertise)
6474 return 0;
6475
6476 zvni->advertise_gw_macip = advertise;
6477
6478 ifp = zvni->vxlan_if;
6479 if (!ifp)
6480 return 0;
6481
6482 zif = ifp->info;
6483
6484 /* If down or not mapped to a bridge, we're done. */
6485 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
6486 return 0;
6487
6488 zl2_info = zif->l2info.vxl;
6489
6490 vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
6491 zif->brslave_info.br_if);
6492 if (!vlan_if)
6493 return 0;
6494
6495 if (advertise_gw_macip_enabled(zvni)) {
6496 /* Add primary SVI MAC-IP */
6497 zvni_add_macip_for_intf(vlan_if, zvni);
6498
6499 /* Add VRR MAC-IP - if any*/
6500 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
6501 if (vrr_if)
6502 zvni_add_macip_for_intf(vrr_if, zvni);
6503 } else {
6504 /* Del primary MAC-IP */
6505 zvni_del_macip_for_intf(vlan_if, zvni);
6506
6507 /* Del VRR MAC-IP - if any*/
6508 vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
6509 if (vrr_if)
6510 zvni_del_macip_for_intf(vrr_if, zvni);
6511 }
6512 }
6513
6514 stream_failure:
6515 return 0;
6516 }
6517
6518
6519 /*
6520 * Handle message from client to learn (or stop learning) about VNIs and MACs.
6521 * When enabled, the VNI hash table will be built and MAC FDB table read;
6522 * when disabled, the entries should be deleted and remote VTEPs and MACs
6523 * uninstalled from the kernel.
6524 */
6525 int zebra_vxlan_advertise_all_vni(struct zserv *client,
6526 u_short length, struct zebra_vrf *zvrf)
6527 {
6528 struct stream *s = NULL;
6529 int advertise = 0;
6530 struct zebra_ns *zns = NULL;
6531
6532 if (zvrf_id(zvrf) != VRF_DEFAULT) {
6533 zlog_err("EVPN VNI Adv for non-default VRF %u",
6534 zvrf_id(zvrf));
6535 return -1;
6536 }
6537
6538 s = client->ibuf;
6539 STREAM_GETC(s, advertise);
6540
6541 if (IS_ZEBRA_DEBUG_VXLAN)
6542 zlog_debug("EVPN VNI Adv %s, currently %s",
6543 advertise ? "enabled" : "disabled",
6544 is_evpn_enabled() ? "enabled" : "disabled");
6545
6546 if (zvrf->advertise_all_vni == advertise)
6547 return 0;
6548
6549 zvrf->advertise_all_vni = advertise;
6550 if (is_evpn_enabled()) {
6551 /* Build VNI hash table and inform BGP. */
6552 zvni_build_hash_table();
6553
6554 /* Add all SVI (L3 GW) MACs to BGP*/
6555 hash_iterate(zvrf->vni_table, zvni_gw_macip_add_for_vni_hash,
6556 NULL);
6557
6558 /* Read the MAC FDB */
6559 macfdb_read(zvrf->zns);
6560
6561 /* Read neighbors */
6562 neigh_read(zvrf->zns);
6563 } else {
6564 /* Cleanup VTEPs for all VNIs - uninstall from
6565 * kernel and free entries.
6566 */
6567 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
6568
6569 /* cleanup all l3vnis */
6570 zns = zebra_ns_lookup(NS_DEFAULT);
6571 if (!zns)
6572 return -1;
6573
6574 hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL);
6575 }
6576
6577 stream_failure:
6578 return 0;
6579 }
6580
6581 /*
6582 * Allocate VNI hash table for this VRF and do other initialization.
6583 * NOTE: Currently supported only for default VRF.
6584 */
6585 void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
6586 {
6587 if (!zvrf)
6588 return;
6589 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
6590 "Zebra VRF VNI Table");
6591 }
6592
6593 /* Close all VNI handling */
6594 void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
6595 {
6596 if (!zvrf)
6597 return;
6598 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
6599 hash_free(zvrf->vni_table);
6600 }
6601
6602 /* init the l3vni table */
6603 void zebra_vxlan_ns_init(struct zebra_ns *zns)
6604 {
6605 zns->l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
6606 "Zebra VRF L3 VNI table");
6607 }
6608
6609 /* free l3vni table */
6610 void zebra_vxlan_ns_disable(struct zebra_ns *zns)
6611 {
6612 hash_free(zns->l3vni_table);
6613 }
6614
6615 /* get the l3vni svi ifindex */
6616 ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id)
6617 {
6618 zebra_l3vni_t *zl3vni = NULL;
6619
6620 zl3vni = zl3vni_from_vrf(vrf_id);
6621 if (!zl3vni || !is_l3vni_oper_up(zl3vni))
6622 return 0;
6623
6624 return zl3vni->svi_if->ifindex;
6625 }