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