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