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