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