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