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