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