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