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