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