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