]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vxlan.c
zebra: fix mac mobility code path
[mirror_frr.git] / zebra / zebra_vxlan.c
CommitLineData
13d60d35 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
d62a17ae 50DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
13d60d35 51DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
d62a17ae 52DEFINE_MTYPE_STATIC(ZEBRA, MAC, "VNI MAC");
53DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
13d60d35 54
55/* definitions */
56
57
58/* static function declarations */
d62a17ae 59static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt);
60static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
61static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
62 void *ctxt);
63static void zvni_print_mac(zebra_mac_t *mac, void *ctxt);
64static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
65static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
66static void zvni_print(zebra_vni_t *zvni, void *ctxt);
67static void zvni_print_hash(struct hash_backet *backet, void *ctxt);
68
69static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
70 struct ethaddr *macaddr,
71 struct ipaddr *ip, u_char sticky,
72 u_int16_t cmd);
73static unsigned int neigh_hash_keymake(void *p);
74static int neigh_cmp(const void *p1, const void *p2);
75static void *zvni_neigh_alloc(void *p);
76static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip);
77static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n);
78static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg);
79static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
80 struct in_addr *r_vtep_ip);
81static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
82 int uninstall, int upd_client, u_int32_t flags);
83static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip);
84static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
85 struct ipaddr *ip,
86 struct ethaddr *macaddr);
87static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
88 struct ipaddr *ip,
89 struct ethaddr *macaddr);
90static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
91static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
92static zebra_vni_t *zvni_map_svi(struct interface *ifp,
93 struct interface *br_if);
94static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
95 struct interface *br_if);
96
97static unsigned int mac_hash_keymake(void *p);
98static int mac_cmp(const void *p1, const void *p2);
99static void *zvni_mac_alloc(void *p);
100static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr);
101static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac);
102static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg);
103static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
104 struct in_addr *r_vtep_ip);
105static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
106 int uninstall, int upd_client, u_int32_t flags);
107static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
108static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
109 struct ethaddr *macaddr, u_char sticky);
110static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
111 struct ethaddr *macaddr, u_char sticky);
112static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
113 struct interface *br_if, vlanid_t vid);
114static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
115static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local);
116static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt);
117
118static unsigned int vni_hash_keymake(void *p);
119static int vni_hash_cmp(const void *p1, const void *p2);
120static void *zvni_alloc(void *p);
121static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni);
122static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni);
123static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni);
124static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni);
125static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni);
126static void zvni_build_hash_table(struct zebra_vrf *zvrf);
127static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
128static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
129static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
130static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep);
131static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall);
132static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip);
133static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip);
13d60d35 134
135
136/* Private functions */
137
cec2e17d 138/*
139 * Helper function to determine maximum width of neighbor IP address for
140 * display - just because we're dealing with IPv6 addresses that can
141 * widely vary.
142 */
d62a17ae 143static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
cec2e17d 144{
d62a17ae 145 zebra_neigh_t *n;
146 char buf[INET6_ADDRSTRLEN];
147 struct neigh_walk_ctx *wctx = ctxt;
148 int width;
cec2e17d 149
d62a17ae 150 n = (zebra_neigh_t *)backet->data;
151 if (!n)
152 return;
cec2e17d 153
d62a17ae 154 ipaddr2str(&n->ip, buf, sizeof(buf)), width = strlen(buf);
155 if (width > wctx->addr_width)
156 wctx->addr_width = width;
cec2e17d 157}
158
159/*
160 * Print a specific neighbor entry.
161 */
d62a17ae 162static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt)
cec2e17d 163{
d62a17ae 164 struct vty *vty;
165 char buf1[ETHER_ADDR_STRLEN];
166 char buf2[INET6_ADDRSTRLEN];
cec2e17d 167
d62a17ae 168 ipaddr2str(&n->ip, buf2, sizeof(buf2)), vty = (struct vty *)ctxt;
169 vty_out(vty, "IP: %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2)));
170 vty_out(vty, " MAC: %s", prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
171 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
172 vty_out(vty, " Remote VTEP: %s", inet_ntoa(n->r_vtep_ip));
173 vty_out(vty, "\n");
cec2e17d 174}
175
176/*
177 * Print neighbor hash entry - called for display of all neighbors.
178 */
d62a17ae 179static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
180{
181 struct vty *vty;
182 zebra_neigh_t *n;
183 char buf1[ETHER_ADDR_STRLEN];
184 char buf2[INET6_ADDRSTRLEN];
185 struct neigh_walk_ctx *wctx = ctxt;
186
187 vty = wctx->vty;
188 n = (zebra_neigh_t *)backet->data;
189 if (!n)
190 return;
191
192 prefix_mac2str(&n->emac, buf1, sizeof(buf1));
193 ipaddr2str(&n->ip, buf2, sizeof(buf2));
194 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
195 && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
196 vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width, buf2,
197 "local", buf1);
198 wctx->count++;
199 } else {
200 if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
201 if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
202 if (wctx->count == 0)
203 vty_out(vty, "%*s %-6s %-17s %-21s\n",
204 -wctx->addr_width, "Neighbor",
205 "Type", "MAC", "Remote VTEP");
206 vty_out(vty, "%*s %-6s %-17s %-21s\n",
207 -wctx->addr_width, buf2, "remote", buf1,
208 inet_ntoa(n->r_vtep_ip));
209 wctx->count++;
210 }
211 } else {
212 vty_out(vty, "%*s %-6s %-17s %-21s\n",
213 -wctx->addr_width, buf2, "remote", buf1,
214 inet_ntoa(n->r_vtep_ip));
215 wctx->count++;
216 }
217 }
cec2e17d 218}
219
220/*
221 * Print neighbors for all VNI.
222 */
d62a17ae 223static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
224 void *ctxt)
cec2e17d 225{
d62a17ae 226 struct vty *vty;
227 zebra_vni_t *zvni;
228 u_int32_t num_neigh;
229 struct neigh_walk_ctx wctx;
cec2e17d 230
d62a17ae 231 vty = (struct vty *)ctxt;
232 zvni = (zebra_vni_t *)backet->data;
233 if (!zvni)
234 return;
cec2e17d 235
d62a17ae 236 num_neigh = hashcount(zvni->neigh_table);
237 vty_out(vty, "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
238 zvni->vni, num_neigh);
239 if (!num_neigh)
240 return;
cec2e17d 241
d62a17ae 242 /* Since we have IPv6 addresses to deal with which can vary widely in
243 * size, we try to be a bit more elegant in display by first computing
244 * the maximum width.
245 */
246 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
247 wctx.zvni = zvni;
248 wctx.vty = vty;
249 wctx.addr_width = 15;
250 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
cec2e17d 251
d62a17ae 252 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", "Type",
253 "MAC", "Remote VTEP");
254 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
cec2e17d 255}
256
257/*
258 * Print a specific MAC entry.
259 */
d62a17ae 260static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
261{
262 struct vty *vty;
263 char buf1[20];
264
265 vty = (struct vty *)ctxt;
266 vty_out(vty, "MAC: %s",
267 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
268 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
269 struct zebra_ns *zns;
270 struct interface *ifp;
271 ifindex_t ifindex;
272
273 ifindex = mac->fwd_info.local.ifindex;
274 zns = zebra_ns_lookup(NS_DEFAULT);
275 ifp = if_lookup_by_index_per_ns(zns, ifindex);
276 if (!ifp) // unexpected
277 return;
278 vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
279 if (mac->fwd_info.local.vid)
280 vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
281 } else {
282 vty_out(vty, " Remote VTEP: %s",
283 inet_ntoa(mac->fwd_info.r_vtep_ip));
284 }
285 vty_out(vty, " ARP ref: %u", mac->neigh_refcnt);
286 vty_out(vty, "\n");
cec2e17d 287}
288
289/*
290 * Print MAC hash entry - called for display of all MACs.
291 */
d62a17ae 292static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
293{
294 struct vty *vty;
295 zebra_mac_t *mac;
296 char buf1[20];
297 struct mac_walk_ctx *wctx = ctxt;
298
299 vty = wctx->vty;
300 mac = (zebra_mac_t *)backet->data;
301 if (!mac)
302 return;
303
304 prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
305 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
306 && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
307 struct zebra_ns *zns;
308 ifindex_t ifindex;
309 struct interface *ifp;
310 vlanid_t vid;
311
312 zns = zebra_ns_lookup(NS_DEFAULT);
313 ifindex = mac->fwd_info.local.ifindex;
314 ifp = if_lookup_by_index_per_ns(zns, ifindex);
315 if (!ifp) // unexpected
316 return;
317 vid = mac->fwd_info.local.vid;
318 vty_out(vty, "%-17s %-6s %-21s", buf1, "local", ifp->name);
319 if (vid)
320 vty_out(vty, " %-5u", vid);
321 vty_out(vty, "\n");
322 wctx->count++;
323 } else {
324 if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
325 if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
326 &wctx->r_vtep_ip)) {
327 if (wctx->count == 0) {
328 vty_out(vty, "\nVNI %u",
329 wctx->zvni->vni);
330 vty_out(vty, "%-17s %-6s %-21s %-5s",
331 "MAC", "Type",
332 "Intf/Remote VTEP", "VLAN");
333 }
334 vty_out(vty, "%-17s %-6s %-21s", buf1, "remote",
335 inet_ntoa(mac->fwd_info.r_vtep_ip));
336 wctx->count++;
337 }
338 } else {
339 vty_out(vty, "%-17s %-6s %-21s", buf1, "remote",
340 inet_ntoa(mac->fwd_info.r_vtep_ip));
341 wctx->count++;
342 }
343 }
cec2e17d 344}
345
346/*
347 * Print MACs for all VNI.
348 */
d62a17ae 349static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
cec2e17d 350{
d62a17ae 351 struct vty *vty;
352 zebra_vni_t *zvni;
353 u_int32_t num_macs;
354 struct mac_walk_ctx *wctx = ctxt;
cec2e17d 355
d62a17ae 356 vty = (struct vty *)wctx->vty;
cec2e17d 357
d62a17ae 358 zvni = (zebra_vni_t *)backet->data;
359 if (!zvni)
360 return;
361 wctx->zvni = zvni;
cec2e17d 362
d62a17ae 363 /*We are iterating over a new VNI, set the count to 0*/
364 wctx->count = 0;
cec2e17d 365
d62a17ae 366 num_macs = hashcount(zvni->mac_table);
367 if (!num_macs)
368 return;
369 if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
370 vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
371 zvni->vni, num_macs);
372 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
373 "Intf/Remote VTEP", "VLAN");
374 }
cec2e17d 375
d62a17ae 376 hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
cec2e17d 377}
378
379/*
380 * Print a specific VNI entry.
381 */
d62a17ae 382static void zvni_print(zebra_vni_t *zvni, void *ctxt)
383{
384 struct vty *vty;
385 zebra_vtep_t *zvtep;
386 u_int32_t num_macs;
387 u_int32_t num_neigh;
388
389 vty = (struct vty *)ctxt;
390
391 vty_out(vty, "VNI: %u\n", zvni->vni);
392 if (!zvni->vxlan_if) { // unexpected
393 vty_out(vty, " VxLAN interface: unknown\n");
394 return;
395 }
396 vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
397 zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
398 inet_ntoa(zvni->local_vtep_ip));
399
400 if (!zvni->vteps) {
401 vty_out(vty, " No remote VTEPs known for this VNI\n");
402 } else {
403 vty_out(vty, " Remote VTEPs for this VNI:\n");
404 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next)
405 vty_out(vty, " %s\n", inet_ntoa(zvtep->vtep_ip));
406 }
407 num_macs = hashcount(zvni->mac_table);
408 vty_out(vty,
409 " Number of MACs (local and remote) known for this VNI: %u\n",
410 num_macs);
411 num_neigh = hashcount(zvni->neigh_table);
412 vty_out(vty,
413 " Number of ARPs (IPv4 and IPv6, local and remote) "
414 "known for this VNI: %u",
415 num_neigh);
cec2e17d 416}
417
418/*
419 * Print a VNI hash entry - called for display of all VNIs.
420 */
d62a17ae 421static void zvni_print_hash(struct hash_backet *backet, void *ctxt)
cec2e17d 422{
d62a17ae 423 struct vty *vty;
424 zebra_vni_t *zvni;
425 zebra_vtep_t *zvtep;
426 u_int32_t num_vteps = 0;
427 u_int32_t num_macs = 0;
428 u_int32_t num_neigh = 0;
cec2e17d 429
d62a17ae 430 vty = (struct vty *)ctxt;
431 zvni = (zebra_vni_t *)backet->data;
432 if (!zvni)
433 return;
cec2e17d 434
d62a17ae 435 zvtep = zvni->vteps;
436 while (zvtep) {
437 num_vteps++;
438 zvtep = zvtep->next;
439 }
cec2e17d 440
d62a17ae 441 num_macs = hashcount(zvni->mac_table);
442 num_neigh = hashcount(zvni->neigh_table);
443 vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni->vni,
444 zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
445 inet_ntoa(zvni->local_vtep_ip), num_macs, num_neigh, num_vteps);
cec2e17d 446}
447
13d60d35 448/*
2232a77c 449 * Inform BGP about local MACIP.
450 */
d62a17ae 451static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
452 struct ethaddr *macaddr,
453 struct ipaddr *ip, u_char sticky,
454 u_int16_t cmd)
455{
456 struct zserv *client;
457 struct stream *s;
458 int ipa_len;
459 char buf[ETHER_ADDR_STRLEN];
460 char buf2[INET6_ADDRSTRLEN];
461
462 client = zebra_find_client(ZEBRA_ROUTE_BGP);
463 /* BGP may not be running. */
464 if (!client)
465 return 0;
466
467 s = client->obuf;
468 stream_reset(s);
469
470 zserv_create_header(s, cmd, zvrf_id(zvrf));
471 stream_putl(s, vni);
ff8b7eb8 472 stream_put(s, macaddr->octet, ETH_ALEN);
d62a17ae 473 if (ip) {
474 ipa_len = 0;
475 if (IS_IPADDR_V4(ip))
476 ipa_len = IPV4_MAX_BYTELEN;
477 else if (IS_IPADDR_V6(ip))
478 ipa_len = IPV6_MAX_BYTELEN;
479
480 stream_putl(s, ipa_len); /* IP address length */
481 if (ipa_len)
482 stream_put(s, &ip->ip.addr, ipa_len); /* IP address */
483 } else
484 stream_putl(s, 0); /* Just MAC. */
485
486 stream_putc(s, sticky); /* Sticky MAC? */
487
488 /* Write packet size. */
489 stream_putw_at(s, 0, stream_get_endp(s));
490
491 if (IS_ZEBRA_DEBUG_VXLAN)
492 zlog_debug("%u:Send MACIP %s %sMAC %s IP %s VNI %u to %s",
493 zvrf_id(zvrf),
494 (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del",
495 sticky ? "sticky " : "",
496 prefix_mac2str(macaddr, buf, sizeof(buf)),
497 ipaddr2str(ip, buf2, sizeof(buf2)), vni,
498 zebra_route_string(client->proto));
499
500 if (cmd == ZEBRA_MACIP_ADD)
501 client->macipadd_cnt++;
502 else
503 client->macipdel_cnt++;
504
505 return zebra_server_send_message(client);
2232a77c 506}
507
508/*
509 * Make hash key for neighbors.
13d60d35 510 */
d62a17ae 511static unsigned int neigh_hash_keymake(void *p)
13d60d35 512{
d62a17ae 513 zebra_neigh_t *n = p;
514 struct ipaddr *ip = &n->ip;
13d60d35 515
d62a17ae 516 if (IS_IPADDR_V4(ip))
517 return jhash_1word(ip->ipaddr_v4.s_addr, 0);
2232a77c 518
d62a17ae 519 return jhash2(ip->ipaddr_v6.s6_addr32,
520 ZEBRA_NUM_OF(ip->ipaddr_v6.s6_addr32), 0);
13d60d35 521}
522
523/*
2232a77c 524 * Compare two neighbor hash structures.
13d60d35 525 */
d62a17ae 526static int neigh_cmp(const void *p1, const void *p2)
13d60d35 527{
d62a17ae 528 const zebra_neigh_t *n1 = p1;
529 const zebra_neigh_t *n2 = p2;
13d60d35 530
d62a17ae 531 if (n1 == NULL && n2 == NULL)
532 return 1;
2232a77c 533
d62a17ae 534 if (n1 == NULL || n2 == NULL)
535 return 0;
2232a77c 536
d62a17ae 537 return (memcmp(&n1->ip, &n2->ip, sizeof(struct ipaddr)) == 0);
13d60d35 538}
539
540/*
2232a77c 541 * Callback to allocate neighbor hash entry.
13d60d35 542 */
d62a17ae 543static void *zvni_neigh_alloc(void *p)
13d60d35 544{
d62a17ae 545 const zebra_neigh_t *tmp_n = p;
546 zebra_neigh_t *n;
13d60d35 547
d62a17ae 548 n = XCALLOC(MTYPE_NEIGH, sizeof(zebra_neigh_t));
549 *n = *tmp_n;
2232a77c 550
d62a17ae 551 return ((void *)n);
13d60d35 552}
553
554/*
2232a77c 555 * Add neighbor entry.
13d60d35 556 */
d62a17ae 557static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip)
13d60d35 558{
d62a17ae 559 zebra_neigh_t tmp_n;
560 zebra_neigh_t *n = NULL;
13d60d35 561
d62a17ae 562 memset(&tmp_n, 0, sizeof(zebra_neigh_t));
563 memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
564 n = hash_get(zvni->neigh_table, &tmp_n, zvni_neigh_alloc);
565 assert(n);
13d60d35 566
d62a17ae 567 return n;
13d60d35 568}
569
570/*
2232a77c 571 * Delete neighbor entry.
13d60d35 572 */
d62a17ae 573static int zvni_neigh_del(zebra_vni_t *zvni, zebra_neigh_t *n)
13d60d35 574{
d62a17ae 575 zebra_neigh_t *tmp_n;
13d60d35 576
d62a17ae 577 /* Free the VNI hash entry and allocated memory. */
578 tmp_n = hash_release(zvni->neigh_table, n);
579 if (tmp_n)
580 XFREE(MTYPE_NEIGH, tmp_n);
13d60d35 581
d62a17ae 582 return 0;
13d60d35 583}
584
585/*
2232a77c 586 * Free neighbor hash entry (callback)
13d60d35 587 */
d62a17ae 588static int zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
13d60d35 589{
d62a17ae 590 struct neigh_walk_ctx *wctx = arg;
591 zebra_neigh_t *n = backet->data;
2232a77c 592
d62a17ae 593 if (((wctx->flags & DEL_LOCAL_NEIGH) && (n->flags & ZEBRA_NEIGH_LOCAL))
594 || ((wctx->flags & DEL_REMOTE_NEIGH)
595 && (n->flags & ZEBRA_NEIGH_REMOTE))
596 || ((wctx->flags & DEL_REMOTE_NEIGH_FROM_VTEP)
597 && (n->flags & ZEBRA_NEIGH_REMOTE)
598 && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
599 if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
600 zvni_neigh_send_del_to_client(
601 wctx->zvrf, wctx->zvni->vni, &n->ip, &n->emac);
13d60d35 602
d62a17ae 603 if (wctx->uninstall)
604 zvni_neigh_uninstall(wctx->zvni, n);
13d60d35 605
d62a17ae 606 return zvni_neigh_del(wctx->zvni, n);
607 }
13d60d35 608
d62a17ae 609 return 0;
13d60d35 610}
611
612/*
2232a77c 613 * Delete all neighbor entries from specific VTEP for a particular VNI.
13d60d35 614 */
d62a17ae 615static void zvni_neigh_del_from_vtep(zebra_vni_t *zvni, int uninstall,
616 struct in_addr *r_vtep_ip)
13d60d35 617{
d62a17ae 618 struct neigh_walk_ctx wctx;
13d60d35 619
d62a17ae 620 if (!zvni->neigh_table)
621 return;
13d60d35 622
d62a17ae 623 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
624 wctx.zvni = zvni;
625 wctx.uninstall = uninstall;
626 wctx.flags = DEL_REMOTE_NEIGH_FROM_VTEP;
627 wctx.r_vtep_ip = *r_vtep_ip;
13d60d35 628
d62a17ae 629 hash_iterate(zvni->neigh_table,
630 (void (*)(struct hash_backet *,
631 void *))zvni_neigh_del_hash_entry,
632 &wctx);
2232a77c 633}
13d60d35 634
2232a77c 635/*
636 * Delete all neighbor entries for this VNI.
637 */
d62a17ae 638static void zvni_neigh_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
639 int uninstall, int upd_client, u_int32_t flags)
2232a77c 640{
d62a17ae 641 struct neigh_walk_ctx wctx;
13d60d35 642
d62a17ae 643 if (!zvni->neigh_table)
644 return;
13d60d35 645
d62a17ae 646 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
647 wctx.zvni = zvni;
648 wctx.zvrf = zvrf;
649 wctx.uninstall = uninstall;
650 wctx.upd_client = upd_client;
651 wctx.flags = flags;
2232a77c 652
d62a17ae 653 hash_iterate(zvni->neigh_table,
654 (void (*)(struct hash_backet *,
655 void *))zvni_neigh_del_hash_entry,
656 &wctx);
13d60d35 657}
658
659/*
2232a77c 660 * Look up neighbor hash entry.
661 */
d62a17ae 662static zebra_neigh_t *zvni_neigh_lookup(zebra_vni_t *zvni, struct ipaddr *ip)
2232a77c 663{
d62a17ae 664 zebra_neigh_t tmp;
665 zebra_neigh_t *n;
2232a77c 666
d62a17ae 667 memset(&tmp, 0, sizeof(tmp));
668 memcpy(&tmp.ip, ip, sizeof(struct ipaddr));
669 n = hash_lookup(zvni->neigh_table, &tmp);
2232a77c 670
d62a17ae 671 return n;
2232a77c 672}
673
674/*
675 * Inform BGP about local neighbor addition.
13d60d35 676 */
d62a17ae 677static int zvni_neigh_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
678 struct ipaddr *ip,
679 struct ethaddr *macaddr)
13d60d35 680{
d62a17ae 681 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, 0,
682 ZEBRA_MACIP_ADD);
2232a77c 683}
13d60d35 684
2232a77c 685/*
686 * Inform BGP about local neighbor deletion.
687 */
d62a17ae 688static int zvni_neigh_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
689 struct ipaddr *ip,
690 struct ethaddr *macaddr)
2232a77c 691{
d62a17ae 692 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, ip, 0,
693 ZEBRA_MACIP_DEL);
2232a77c 694}
695
696/*
697 * Install remote neighbor into the kernel.
698 */
d62a17ae 699static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n)
2232a77c 700{
d62a17ae 701 struct zebra_vrf *zvrf;
702 struct zebra_if *zif;
703 struct zebra_l2info_vxlan *vxl;
704 struct interface *vlan_if;
2232a77c 705
d62a17ae 706 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
707 return 0;
13d60d35 708
d62a17ae 709 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
710 assert(zvrf);
711 zif = zvni->vxlan_if->info;
712 if (!zif)
713 return -1;
714 vxl = &zif->l2info.vxl;
13d60d35 715
d62a17ae 716 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
717 zif->brslave_info.br_if);
718 if (!vlan_if)
719 return -1;
13d60d35 720
d62a17ae 721 return kernel_add_neigh(vlan_if, &n->ip, &n->emac);
2232a77c 722}
13d60d35 723
2232a77c 724/*
725 * Uninstall remote neighbor from the kernel.
726 */
d62a17ae 727static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
2232a77c 728{
d62a17ae 729 struct zebra_vrf *zvrf;
730 struct zebra_if *zif;
731 struct zebra_l2info_vxlan *vxl;
732 struct interface *vlan_if;
13d60d35 733
d62a17ae 734 if (!(n->flags & ZEBRA_NEIGH_REMOTE))
735 return 0;
2232a77c 736
d62a17ae 737 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
738 assert(zvrf);
739 if (!zvni->vxlan_if) {
740 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
741 zvni->vni, zvni);
742 return -1;
743 }
2232a77c 744
d62a17ae 745 zif = zvni->vxlan_if->info;
746 if (!zif)
747 return -1;
748 vxl = &zif->l2info.vxl;
749 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
750 zif->brslave_info.br_if);
751 if (!vlan_if)
752 return -1;
2232a77c 753
d62a17ae 754 return kernel_del_neigh(vlan_if, &n->ip);
13d60d35 755}
756
757/*
2232a77c 758 * Install neighbor hash entry - called upon access VLAN change.
13d60d35 759 */
d62a17ae 760static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt)
13d60d35 761{
d62a17ae 762 zebra_neigh_t *n;
763 struct neigh_walk_ctx *wctx = ctxt;
13d60d35 764
d62a17ae 765 n = (zebra_neigh_t *)backet->data;
766 if (!n)
767 return;
13d60d35 768
d62a17ae 769 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
770 zvni_neigh_install(wctx->zvni, n);
2232a77c 771}
13d60d35 772
2232a77c 773/*
774 * Make hash key for MAC.
775 */
d62a17ae 776static unsigned int mac_hash_keymake(void *p)
2232a77c 777{
d62a17ae 778 zebra_mac_t *pmac = p;
25331def
DS
779 const void *pnt = (void *)pmac->macaddr.octet;
780
ff8b7eb8 781 return jhash(pnt, ETH_ALEN, 0xa5a5a55a);
2232a77c 782}
13d60d35 783
2232a77c 784/*
785 * Compare two MAC addresses.
786 */
d62a17ae 787static int mac_cmp(const void *p1, const void *p2)
2232a77c 788{
d62a17ae 789 const zebra_mac_t *pmac1 = p1;
790 const zebra_mac_t *pmac2 = p2;
2232a77c 791
d62a17ae 792 if (pmac1 == NULL && pmac2 == NULL)
793 return 1;
2232a77c 794
d62a17ae 795 if (pmac1 == NULL || pmac2 == NULL)
796 return 0;
2232a77c 797
d62a17ae 798 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet,
ff8b7eb8 799 ETH_ALEN)
d62a17ae 800 == 0);
2232a77c 801}
802
803/*
804 * Callback to allocate MAC hash entry.
805 */
d62a17ae 806static void *zvni_mac_alloc(void *p)
2232a77c 807{
d62a17ae 808 const zebra_mac_t *tmp_mac = p;
809 zebra_mac_t *mac;
2232a77c 810
d62a17ae 811 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
812 *mac = *tmp_mac;
2232a77c 813
d62a17ae 814 return ((void *)mac);
2232a77c 815}
816
817/*
818 * Add MAC entry.
819 */
d62a17ae 820static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
2232a77c 821{
d62a17ae 822 zebra_mac_t tmp_mac;
823 zebra_mac_t *mac = NULL;
2232a77c 824
d62a17ae 825 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
ff8b7eb8 826 memcpy(&tmp_mac.macaddr, macaddr, ETH_ALEN);
d62a17ae 827 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
828 assert(mac);
2232a77c 829
d62a17ae 830 return mac;
2232a77c 831}
832
833/*
834 * Delete MAC entry.
835 */
d62a17ae 836static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
2232a77c 837{
d62a17ae 838 zebra_mac_t *tmp_mac;
2232a77c 839
d62a17ae 840 /* Free the VNI hash entry and allocated memory. */
841 tmp_mac = hash_release(zvni->mac_table, mac);
842 if (tmp_mac)
843 XFREE(MTYPE_MAC, tmp_mac);
2232a77c 844
d62a17ae 845 return 0;
2232a77c 846}
847
848/*
849 * Free MAC hash entry (callback)
850 */
d62a17ae 851static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
2232a77c 852{
d62a17ae 853 struct mac_walk_ctx *wctx = arg;
854 zebra_mac_t *mac = backet->data;
855 u_char sticky = 0;
2232a77c 856
d62a17ae 857 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
858 || ((wctx->flags & DEL_REMOTE_MAC)
859 && (mac->flags & ZEBRA_MAC_REMOTE))
860 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
861 && (mac->flags & ZEBRA_MAC_REMOTE)
862 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
863 &wctx->r_vtep_ip))) {
864 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
865 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
866 : 0;
867 zvni_mac_send_del_to_client(wctx->zvrf, wctx->zvni->vni,
868 &mac->macaddr, sticky);
869 }
2232a77c 870
d62a17ae 871 if (wctx->uninstall)
872 zvni_mac_uninstall(wctx->zvni, mac, 0);
2232a77c 873
d62a17ae 874 return zvni_mac_del(wctx->zvni, mac);
875 }
2232a77c 876
d62a17ae 877 return 0;
2232a77c 878}
879
880/*
881 * Delete all MAC entries from specific VTEP for a particular VNI.
882 */
d62a17ae 883static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
884 struct in_addr *r_vtep_ip)
2232a77c 885{
d62a17ae 886 struct mac_walk_ctx wctx;
2232a77c 887
d62a17ae 888 if (!zvni->mac_table)
889 return;
2232a77c 890
d62a17ae 891 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
892 wctx.zvni = zvni;
893 wctx.uninstall = uninstall;
894 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
895 wctx.r_vtep_ip = *r_vtep_ip;
2232a77c 896
9d303b37
DL
897 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
898 void *))zvni_mac_del_hash_entry,
899 &wctx);
2232a77c 900}
901
902/*
903 * Delete all MAC entries for this VNI.
904 */
d62a17ae 905static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
906 int uninstall, int upd_client, u_int32_t flags)
2232a77c 907{
d62a17ae 908 struct mac_walk_ctx wctx;
2232a77c 909
d62a17ae 910 if (!zvni->mac_table)
911 return;
2232a77c 912
d62a17ae 913 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
914 wctx.zvni = zvni;
915 wctx.zvrf = zvrf;
916 wctx.uninstall = uninstall;
917 wctx.upd_client = upd_client;
918 wctx.flags = flags;
2232a77c 919
9d303b37
DL
920 hash_iterate(zvni->mac_table, (void (*)(struct hash_backet *,
921 void *))zvni_mac_del_hash_entry,
922 &wctx);
2232a77c 923}
924
925/*
926 * Look up MAC hash entry.
927 */
d62a17ae 928static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
2232a77c 929{
d62a17ae 930 zebra_mac_t tmp;
931 zebra_mac_t *pmac;
2232a77c 932
d62a17ae 933 memset(&tmp, 0, sizeof(tmp));
ff8b7eb8 934 memcpy(&tmp.macaddr, mac, ETH_ALEN);
d62a17ae 935 pmac = hash_lookup(zvni->mac_table, &tmp);
2232a77c 936
d62a17ae 937 return pmac;
2232a77c 938}
939
940/*
941 * Inform BGP about local MAC addition.
942 */
d62a17ae 943static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
944 struct ethaddr *macaddr, u_char sticky)
2232a77c 945{
d62a17ae 946 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, sticky,
947 ZEBRA_MACIP_ADD);
2232a77c 948}
949
950/*
951 * Inform BGP about local MAC deletion.
952 */
d62a17ae 953static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
954 struct ethaddr *macaddr, u_char sticky)
2232a77c 955{
d62a17ae 956 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, sticky,
957 ZEBRA_MACIP_DEL);
2232a77c 958}
959
960/*
961 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
962 * notifications, to see if there are of interest.
963 * TODO: Need to make this as a hash table.
964 */
d62a17ae 965static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
966 struct interface *br_if, vlanid_t vid)
2232a77c 967{
d62a17ae 968 struct zebra_vrf *zvrf;
969 struct listnode *node;
970 struct interface *tmp_if;
971 struct zebra_if *zif;
972 struct zebra_l2info_bridge *br;
973 struct zebra_l2info_vxlan *vxl;
974 u_char bridge_vlan_aware;
975 zebra_vni_t *zvni;
2232a77c 976
d62a17ae 977 /* Locate VRF corresponding to interface. */
978 zvrf = vrf_info_lookup(ifp->vrf_id);
979 assert(zvrf);
2232a77c 980
d62a17ae 981 /* Determine if bridge is VLAN-aware or not */
982 zif = br_if->info;
983 assert(zif);
984 br = &zif->l2info.br;
985 bridge_vlan_aware = br->vlan_aware;
2232a77c 986
d62a17ae 987 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
988 /* TODO: Optimize with a hash. */
989 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
990 zif = tmp_if->info;
991 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
992 continue;
993 if (!if_is_operative(tmp_if))
994 continue;
995 vxl = &zif->l2info.vxl;
2232a77c 996
d62a17ae 997 if (zif->brslave_info.br_if != br_if)
998 continue;
2232a77c 999
d62a17ae 1000 if (!bridge_vlan_aware)
1001 break;
2232a77c 1002
d62a17ae 1003 if (vxl->access_vlan == vid)
1004 break;
1005 }
2232a77c 1006
d62a17ae 1007 if (!tmp_if)
1008 return NULL;
2232a77c 1009
d62a17ae 1010 zvni = zvni_lookup(zvrf, vxl->vni);
1011 return zvni;
2232a77c 1012}
1013
1014/*
1015 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1016 * neighbor notifications, to see if they are of interest.
1017 * TODO: Need to make this as a hash table.
1018 */
d62a17ae 1019static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
1020{
1021 struct zebra_vrf *zvrf;
1022 struct listnode *node;
1023 struct interface *tmp_if;
1024 struct zebra_if *zif;
1025 struct zebra_l2info_bridge *br;
1026 struct zebra_l2info_vxlan *vxl;
1027 u_char bridge_vlan_aware;
1028 vlanid_t vid = 0;
1029 zebra_vni_t *zvni;
1030
1031 /* Make sure the linked interface is a bridge. */
1032 if (!IS_ZEBRA_IF_BRIDGE(br_if))
1033 return NULL;
1034
1035 /* Locate VRF corresponding to interface. */
1036 zvrf = vrf_info_lookup(ifp->vrf_id);
1037 assert(zvrf);
1038
1039 /* Determine if bridge is VLAN-aware or not */
1040 zif = br_if->info;
1041 assert(zif);
1042 br = &zif->l2info.br;
1043 bridge_vlan_aware = br->vlan_aware;
1044 if (bridge_vlan_aware) {
1045 struct zebra_l2info_vlan *vl;
1046
1047 if (!IS_ZEBRA_IF_VLAN(ifp))
1048 return NULL;
1049
1050 zif = ifp->info;
1051 assert(zif);
1052 vl = &zif->l2info.vl;
1053 vid = vl->vid;
1054 }
1055
1056 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1057 /* TODO: Optimize with a hash. */
1058 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1059 zif = tmp_if->info;
1060 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1061 continue;
1062 if (!if_is_operative(tmp_if))
1063 continue;
1064 vxl = &zif->l2info.vxl;
1065
1066 if (zif->brslave_info.br_if != br_if)
1067 continue;
1068
1069 if (!bridge_vlan_aware)
1070 break;
1071
1072 if (vxl->access_vlan == vid)
1073 break;
1074 }
1075
1076 if (!tmp_if)
1077 return NULL;
1078
1079 zvni = zvni_lookup(zvrf, vxl->vni);
1080 return zvni;
2232a77c 1081}
1082
1083/* Map to SVI on bridge corresponding to specified VLAN. This can be one
1084 * of two cases:
1085 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1086 * linked to the bridge
1087 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1088 * itself
1089 */
d62a17ae 1090static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
1091 struct interface *br_if)
1092{
1093 struct listnode *node;
1094 struct interface *tmp_if;
1095 struct zebra_if *zif;
1096 struct zebra_l2info_bridge *br;
1097 struct zebra_l2info_vlan *vl;
1098 u_char bridge_vlan_aware;
1099
1100 /* Determine if bridge is VLAN-aware or not */
1101 zif = br_if->info;
1102 assert(zif);
1103 br = &zif->l2info.br;
1104 bridge_vlan_aware = br->vlan_aware;
1105
1106 /* Check oper status of the SVI. */
1107 if (!bridge_vlan_aware)
1108 return if_is_operative(br_if) ? br_if : NULL;
1109
1110 /* Identify corresponding VLAN interface. */
1111 /* TODO: Optimize with a hash. */
1112 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1113 /* Check oper status of the SVI. */
1114 if (!if_is_operative(tmp_if))
1115 continue;
1116 zif = tmp_if->info;
1117 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
1118 || zif->link != br_if)
1119 continue;
1120 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
1121
1122 if (vl->vid == vid)
1123 break;
1124 }
1125
1126 return tmp_if;
2232a77c 1127}
1128
1129/*
1130 * Install remote MAC into the kernel.
1131 */
d62a17ae 1132static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
2232a77c 1133{
d62a17ae 1134 struct zebra_if *zif;
1135 struct zebra_l2info_vxlan *vxl;
1136 u_char sticky;
2232a77c 1137
d62a17ae 1138 if (!(mac->flags & ZEBRA_MAC_REMOTE))
1139 return 0;
2232a77c 1140
d62a17ae 1141 zif = zvni->vxlan_if->info;
1142 if (!zif)
1143 return -1;
1144 vxl = &zif->l2info.vxl;
2232a77c 1145
d62a17ae 1146 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
c85c03c7 1147
d62a17ae 1148 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
1149 mac->fwd_info.r_vtep_ip, sticky);
2232a77c 1150}
1151
1152/*
1153 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1154 * moves to remote, we have to uninstall any existing local entry first.
1155 */
d62a17ae 1156static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
2232a77c 1157{
d62a17ae 1158 struct zebra_if *zif;
1159 struct zebra_l2info_vxlan *vxl;
1160 struct in_addr vtep_ip = {.s_addr = 0};
1161 struct zebra_ns *zns;
1162 struct interface *ifp;
2232a77c 1163
d62a17ae 1164 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
1165 return 0;
2232a77c 1166
d62a17ae 1167 if (!zvni->vxlan_if) {
1168 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1169 zvni->vni, zvni);
1170 return -1;
1171 }
2232a77c 1172
d62a17ae 1173 zif = zvni->vxlan_if->info;
1174 if (!zif)
1175 return -1;
1176 vxl = &zif->l2info.vxl;
2232a77c 1177
d62a17ae 1178 if (local) {
1179 zns = zebra_ns_lookup(NS_DEFAULT);
1180 ifp = if_lookup_by_index_per_ns(zns,
1181 mac->fwd_info.local.ifindex);
1182 if (!ifp) // unexpected
1183 return -1;
1184 } else {
1185 ifp = zvni->vxlan_if;
1186 vtep_ip = mac->fwd_info.r_vtep_ip;
1187 }
2232a77c 1188
d62a17ae 1189 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
1190 local);
2232a77c 1191}
1192
1193/*
1194 * Install MAC hash entry - called upon access VLAN change.
1195 */
d62a17ae 1196static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
2232a77c 1197{
d62a17ae 1198 zebra_mac_t *mac;
1199 struct mac_walk_ctx *wctx = ctxt;
2232a77c 1200
d62a17ae 1201 mac = (zebra_mac_t *)backet->data;
1202 if (!mac)
1203 return;
2232a77c 1204
d62a17ae 1205 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
1206 zvni_mac_install(wctx->zvni, mac);
2232a77c 1207}
1208
1209/*
1210 * Decrement neighbor refcount of MAC; uninstall and free it if
1211 * appropriate.
1212 */
d62a17ae 1213static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
1214 int uninstall)
2232a77c 1215{
d62a17ae 1216 if (mac->neigh_refcnt)
1217 mac->neigh_refcnt--;
2232a77c 1218
d62a17ae 1219 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) || mac->neigh_refcnt > 0)
1220 return;
2232a77c 1221
d62a17ae 1222 if (uninstall)
1223 zvni_mac_uninstall(zvni, mac, 0);
2232a77c 1224
d62a17ae 1225 zvni_mac_del(zvni, mac);
2232a77c 1226}
1227
1228/*
1229 * Read and populate local MACs and neighbors corresponding to this VNI.
1230 */
d62a17ae 1231static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
1232 struct interface *ifp)
2232a77c 1233{
d62a17ae 1234 struct zebra_if *zif;
1235 struct interface *vlan_if;
1236 struct zebra_l2info_vxlan *vxl;
2232a77c 1237
d62a17ae 1238 zif = ifp->info;
1239 vxl = &zif->l2info.vxl;
2232a77c 1240
d62a17ae 1241 if (IS_ZEBRA_DEBUG_VXLAN)
1242 zlog_debug(
1243 "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1244 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
1245 zif->brslave_info.bridge_ifindex);
2232a77c 1246
d62a17ae 1247 macfdb_read_for_bridge(zvrf->zns, ifp, zif->brslave_info.br_if);
1248 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
1249 zif->brslave_info.br_if);
1250 if (vlan_if)
1251 neigh_read_for_vlan(zvrf->zns, vlan_if);
2232a77c 1252}
1253
1254/*
1255 * Hash function for VNI.
1256 */
d62a17ae 1257static unsigned int vni_hash_keymake(void *p)
2232a77c 1258{
d62a17ae 1259 const zebra_vni_t *zvni = p;
2232a77c 1260
d62a17ae 1261 return (jhash_1word(zvni->vni, 0));
2232a77c 1262}
1263
1264/*
1265 * Compare 2 VNI hash entries.
1266 */
d62a17ae 1267static int vni_hash_cmp(const void *p1, const void *p2)
2232a77c 1268{
d62a17ae 1269 const zebra_vni_t *zvni1 = p1;
1270 const zebra_vni_t *zvni2 = p2;
2232a77c 1271
d62a17ae 1272 return (zvni1->vni == zvni2->vni);
2232a77c 1273}
1274
1275/*
1276 * Callback to allocate VNI hash entry.
1277 */
d62a17ae 1278static void *zvni_alloc(void *p)
2232a77c 1279{
d62a17ae 1280 const zebra_vni_t *tmp_vni = p;
1281 zebra_vni_t *zvni;
2232a77c 1282
d62a17ae 1283 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
1284 zvni->vni = tmp_vni->vni;
1285 return ((void *)zvni);
2232a77c 1286}
1287
1288/*
1289 * Look up VNI hash entry.
1290 */
d62a17ae 1291static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni)
2232a77c 1292{
d62a17ae 1293 zebra_vni_t tmp_vni;
1294 zebra_vni_t *zvni = NULL;
2232a77c 1295
d62a17ae 1296 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
1297 tmp_vni.vni = vni;
1298 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
2232a77c 1299
d62a17ae 1300 return zvni;
2232a77c 1301}
1302
1303/*
1304 * Add VNI hash entry.
1305 */
d62a17ae 1306static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni)
2232a77c 1307{
d62a17ae 1308 zebra_vni_t tmp_zvni;
1309 zebra_vni_t *zvni = NULL;
2232a77c 1310
d62a17ae 1311 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
1312 tmp_zvni.vni = vni;
1313 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
1314 assert(zvni);
2232a77c 1315
d62a17ae 1316 /* Create hash table for MAC */
1317 zvni->mac_table =
1318 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
2232a77c 1319
d62a17ae 1320 /* Create hash table for neighbors */
1321 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
1322 "Zebra VNI Neighbor Table");
2232a77c 1323
d62a17ae 1324 return zvni;
2232a77c 1325}
1326
1327/*
1328 * Delete VNI hash entry.
1329 */
d62a17ae 1330static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
2232a77c 1331{
d62a17ae 1332 zebra_vni_t *tmp_zvni;
2232a77c 1333
d62a17ae 1334 zvni->vxlan_if = NULL;
2232a77c 1335
d62a17ae 1336 /* Free the neighbor hash table. */
1337 hash_free(zvni->neigh_table);
1338 zvni->neigh_table = NULL;
2232a77c 1339
d62a17ae 1340 /* Free the MAC hash table. */
1341 hash_free(zvni->mac_table);
1342 zvni->mac_table = NULL;
2232a77c 1343
d62a17ae 1344 /* Free the VNI hash entry and allocated memory. */
1345 tmp_zvni = hash_release(zvrf->vni_table, zvni);
1346 if (tmp_zvni)
1347 XFREE(MTYPE_ZVNI, tmp_zvni);
2232a77c 1348
d62a17ae 1349 return 0;
2232a77c 1350}
1351
1352/*
1353 * Inform BGP about local VNI addition.
1354 */
d62a17ae 1355static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
2232a77c 1356{
d62a17ae 1357 struct zserv *client;
1358 struct stream *s;
2232a77c 1359
d62a17ae 1360 client = zebra_find_client(ZEBRA_ROUTE_BGP);
1361 /* BGP may not be running. */
1362 if (!client)
1363 return 0;
2232a77c 1364
d62a17ae 1365 s = client->obuf;
1366 stream_reset(s);
2232a77c 1367
d62a17ae 1368 zserv_create_header(s, ZEBRA_VNI_ADD, zvrf_id(zvrf));
1369 stream_putl(s, zvni->vni);
1370 stream_put_in_addr(s, &zvni->local_vtep_ip);
2232a77c 1371
d62a17ae 1372 /* Write packet size. */
1373 stream_putw_at(s, 0, stream_get_endp(s));
2232a77c 1374
d62a17ae 1375 if (IS_ZEBRA_DEBUG_VXLAN)
1376 zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf),
1377 zvni->vni, inet_ntoa(zvni->local_vtep_ip),
1378 zebra_route_string(client->proto));
2232a77c 1379
d62a17ae 1380 client->vniadd_cnt++;
1381 return zebra_server_send_message(client);
2232a77c 1382}
1383
1384/*
1385 * Inform BGP about local VNI deletion.
1386 */
d62a17ae 1387static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni)
2232a77c 1388{
d62a17ae 1389 struct zserv *client;
1390 struct stream *s;
2232a77c 1391
d62a17ae 1392 client = zebra_find_client(ZEBRA_ROUTE_BGP);
1393 /* BGP may not be running. */
1394 if (!client)
1395 return 0;
2232a77c 1396
d62a17ae 1397 s = client->obuf;
1398 stream_reset(s);
2232a77c 1399
d62a17ae 1400 zserv_create_header(s, ZEBRA_VNI_DEL, zvrf_id(zvrf));
1401 stream_putl(s, vni);
2232a77c 1402
d62a17ae 1403 /* Write packet size. */
1404 stream_putw_at(s, 0, stream_get_endp(s));
2232a77c 1405
d62a17ae 1406 if (IS_ZEBRA_DEBUG_VXLAN)
1407 zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf), vni,
1408 zebra_route_string(client->proto));
2232a77c 1409
d62a17ae 1410 client->vnidel_cnt++;
1411 return zebra_server_send_message(client);
2232a77c 1412}
1413
1414/*
1415 * Build the VNI hash table by going over the VxLAN interfaces. This
1416 * is called when EVPN (advertise-all-vni) is enabled.
1417 */
d62a17ae 1418static void zvni_build_hash_table(struct zebra_vrf *zvrf)
2232a77c 1419{
d62a17ae 1420 struct listnode *node;
1421 struct interface *ifp;
2232a77c 1422
d62a17ae 1423 /* Walk VxLAN interfaces and create VNI hash. */
1424 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, ifp)) {
1425 struct zebra_if *zif;
1426 struct zebra_l2info_vxlan *vxl;
1427 zebra_vni_t *zvni;
1428 vni_t vni;
2232a77c 1429
d62a17ae 1430 zif = ifp->info;
1431 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1432 continue;
1433 vxl = &zif->l2info.vxl;
2232a77c 1434
d62a17ae 1435 vni = vxl->vni;
2232a77c 1436
d62a17ae 1437 if (IS_ZEBRA_DEBUG_VXLAN)
1438 zlog_debug(
1439 "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
1440 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni,
1441 inet_ntoa(vxl->vtep_ip));
2232a77c 1442
d62a17ae 1443 /* VNI hash entry is not expected to exist. */
1444 zvni = zvni_lookup(zvrf, vni);
1445 if (zvni) {
1446 zlog_err(
1447 "VNI hash already present for VRF %d IF %s(%u) VNI %u",
1448 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
1449 continue;
1450 }
2232a77c 1451
d62a17ae 1452 zvni = zvni_add(zvrf, vni);
1453 if (!zvni) {
1454 zlog_err(
1455 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
1456 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
1457 return;
1458 }
2232a77c 1459
d62a17ae 1460 zvni->local_vtep_ip = vxl->vtep_ip;
1461 zvni->vxlan_if = ifp;
2232a77c 1462
d62a17ae 1463 /* Inform BGP if interface is up and mapped to bridge. */
1464 if (if_is_operative(ifp) && zif->brslave_info.br_if)
1465 zvni_send_add_to_client(zvrf, zvni);
1466 }
2232a77c 1467}
1468
1469/*
1470 * See if remote VTEP matches with prefix.
1471 */
d62a17ae 1472static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
2232a77c 1473{
d62a17ae 1474 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
2232a77c 1475}
1476
1477/*
1478 * Locate remote VTEP in VNI hash table.
1479 */
d62a17ae 1480static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1481{
d62a17ae 1482 zebra_vtep_t *zvtep;
2232a77c 1483
d62a17ae 1484 if (!zvni)
1485 return NULL;
2232a77c 1486
d62a17ae 1487 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1488 if (zvni_vtep_match(vtep_ip, zvtep))
1489 break;
1490 }
2232a77c 1491
d62a17ae 1492 return zvtep;
2232a77c 1493}
1494
1495/*
1496 * Add remote VTEP to VNI hash table.
1497 */
d62a17ae 1498static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1499{
d62a17ae 1500 zebra_vtep_t *zvtep;
2232a77c 1501
d62a17ae 1502 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
1503 if (!zvtep) {
1504 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni->vni);
1505 return NULL;
1506 }
2232a77c 1507
d62a17ae 1508 zvtep->vtep_ip = *vtep_ip;
2232a77c 1509
d62a17ae 1510 if (zvni->vteps)
1511 zvni->vteps->prev = zvtep;
1512 zvtep->next = zvni->vteps;
1513 zvni->vteps = zvtep;
2232a77c 1514
d62a17ae 1515 return zvtep;
2232a77c 1516}
1517
1518/*
1519 * Remove remote VTEP from VNI hash table.
1520 */
d62a17ae 1521static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
2232a77c 1522{
d62a17ae 1523 if (zvtep->next)
1524 zvtep->next->prev = zvtep->prev;
1525 if (zvtep->prev)
1526 zvtep->prev->next = zvtep->next;
1527 else
1528 zvni->vteps = zvtep->next;
2232a77c 1529
d62a17ae 1530 zvtep->prev = zvtep->next = NULL;
1531 XFREE(MTYPE_ZVNI_VTEP, zvtep);
2232a77c 1532
d62a17ae 1533 return 0;
2232a77c 1534}
1535
1536/*
1537 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
1538 * uninstall from kernel if asked to.
1539 */
d62a17ae 1540static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
2232a77c 1541{
d62a17ae 1542 zebra_vtep_t *zvtep, *zvtep_next;
2232a77c 1543
d62a17ae 1544 if (!zvni)
1545 return -1;
2232a77c 1546
d62a17ae 1547 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
1548 zvtep_next = zvtep->next;
1549 if (uninstall)
1550 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
1551 zvni_vtep_del(zvni, zvtep);
1552 }
2232a77c 1553
d62a17ae 1554 return 0;
2232a77c 1555}
1556
1557/*
1558 * Install remote VTEP into the kernel.
1559 */
d62a17ae 1560static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1561{
d62a17ae 1562 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2232a77c 1563}
1564
1565/*
1566 * Uninstall remote VTEP from the kernel.
1567 */
d62a17ae 1568static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1569{
d62a17ae 1570 if (!zvni->vxlan_if) {
1571 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1572 zvni->vni, zvni);
1573 return -1;
1574 }
2232a77c 1575
d62a17ae 1576 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2232a77c 1577}
1578
1579/*
1580 * Cleanup VNI/VTEP and update kernel
1581 */
d62a17ae 1582static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
2232a77c 1583{
d62a17ae 1584 zebra_vni_t *zvni;
2232a77c 1585
d62a17ae 1586 zvni = (zebra_vni_t *)backet->data;
1587 if (!zvni)
1588 return;
2232a77c 1589
d62a17ae 1590 /* Free up all neighbors and MACs, if any. */
1591 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
1592 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
2232a77c 1593
d62a17ae 1594 /* Free up all remote VTEPs, if any. */
1595 zvni_vtep_del_all(zvni, 1);
2232a77c 1596
d62a17ae 1597 /* Delete the hash entry. */
1598 zvni_del(zvrf, zvni);
2232a77c 1599}
1600
1601
1602/* Public functions */
1603
cec2e17d 1604/*
1605 * Display Neighbors for a VNI (VTY command handler).
1606 */
d62a17ae 1607void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
1608 vni_t vni)
1609{
1610 zebra_vni_t *zvni;
1611 u_int32_t num_neigh;
1612 struct neigh_walk_ctx wctx;
1613
1614 if (!EVPN_ENABLED(zvrf))
1615 return;
1616 zvni = zvni_lookup(zvrf, vni);
1617 if (!zvni) {
1618 vty_out(vty, "%% VNI %u does not exist\n", vni);
1619 return;
1620 }
1621 num_neigh = hashcount(zvni->neigh_table);
1622 if (!num_neigh)
1623 return;
1624
1625 /* Since we have IPv6 addresses to deal with which can vary widely in
1626 * size, we try to be a bit more elegant in display by first computing
1627 * the maximum width.
1628 */
1629 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1630 wctx.zvni = zvni;
1631 wctx.vty = vty;
1632 wctx.addr_width = 15;
1633 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
1634
1635 vty_out(vty,
1636 "Number of ARPs (local and remote) known for this VNI: %u\n",
1637 num_neigh);
1638 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", "Type",
1639 "MAC", "Remote VTEP");
1640
1641 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
cec2e17d 1642}
1643
1644/*
1645 * Display neighbors across all VNIs (VTY command handler).
1646 */
d62a17ae 1647void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
cec2e17d 1648{
d62a17ae 1649 if (!EVPN_ENABLED(zvrf))
1650 return;
1651 hash_iterate(zvrf->vni_table, zvni_print_neigh_hash_all_vni, vty);
cec2e17d 1652}
1653
1654/*
1655 * Display specific neighbor for a VNI, if present (VTY command handler).
1656 */
d62a17ae 1657void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
1658 struct zebra_vrf *zvrf, vni_t vni,
1659 struct ipaddr *ip)
cec2e17d 1660{
d62a17ae 1661 zebra_vni_t *zvni;
1662 zebra_neigh_t *n;
cec2e17d 1663
d62a17ae 1664 if (!EVPN_ENABLED(zvrf))
1665 return;
1666 zvni = zvni_lookup(zvrf, vni);
1667 if (!zvni) {
1668 vty_out(vty, "%% VNI %u does not exist", vni);
1669 return;
1670 }
1671 n = zvni_neigh_lookup(zvni, ip);
1672 if (!n) {
1673 vty_out(vty, "%% Requested neighbor does not exist in VNI %u\n",
1674 vni);
1675 return;
1676 }
cec2e17d 1677
d62a17ae 1678 zvni_print_neigh(n, vty);
cec2e17d 1679}
1680
1681/*
1682 * Display neighbors for a VNI from specific VTEP (VTY command handler).
1683 * By definition, these are remote neighbors.
1684 */
d62a17ae 1685void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
1686 vni_t vni, struct in_addr vtep_ip)
cec2e17d 1687{
d62a17ae 1688 zebra_vni_t *zvni;
1689 u_int32_t num_neigh;
1690 struct neigh_walk_ctx wctx;
cec2e17d 1691
d62a17ae 1692 if (!EVPN_ENABLED(zvrf))
1693 return;
1694 zvni = zvni_lookup(zvrf, vni);
1695 if (!zvni) {
1696 vty_out(vty, "%% VNI %u does not exist\n", vni);
1697 return;
1698 }
1699 num_neigh = hashcount(zvni->neigh_table);
1700 if (!num_neigh)
1701 return;
cec2e17d 1702
d62a17ae 1703 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1704 wctx.zvni = zvni;
1705 wctx.vty = vty;
1706 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
1707 wctx.r_vtep_ip = vtep_ip;
cec2e17d 1708
d62a17ae 1709 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
cec2e17d 1710}
1711
1712/*
1713 * Display MACs for a VNI (VTY command handler).
1714 */
d62a17ae 1715void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
1716 vni_t vni)
cec2e17d 1717{
d62a17ae 1718 zebra_vni_t *zvni;
1719 u_int32_t num_macs;
1720 struct mac_walk_ctx wctx;
cec2e17d 1721
d62a17ae 1722 if (!EVPN_ENABLED(zvrf))
1723 return;
1724 zvni = zvni_lookup(zvrf, vni);
1725 if (!zvni) {
1726 vty_out(vty, "%% VNI %u does not exist\n", vni);
1727 return;
1728 }
1729 num_macs = hashcount(zvni->mac_table);
1730 if (!num_macs)
1731 return;
cec2e17d 1732
d62a17ae 1733 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1734 wctx.zvni = zvni;
1735 wctx.vty = vty;
cec2e17d 1736
d62a17ae 1737 vty_out(vty,
1738 "Number of MACs (local and remote) known for this VNI: %u\n",
1739 num_macs);
1740 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
1741 "Intf/Remote VTEP", "VLAN");
cec2e17d 1742
d62a17ae 1743 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
cec2e17d 1744}
1745
1746/*
1747 * Display MACs for all VNIs (VTY command handler).
1748 */
d62a17ae 1749void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
cec2e17d 1750{
d62a17ae 1751 struct mac_walk_ctx wctx;
cec2e17d 1752
d62a17ae 1753 if (!EVPN_ENABLED(zvrf))
1754 return;
1755 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1756 wctx.vty = vty;
1757 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
cec2e17d 1758}
1759
1760/*
1761 * Display MACs for all VNIs (VTY command handler).
1762 */
d62a17ae 1763void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
1764 struct zebra_vrf *zvrf,
1765 struct in_addr vtep_ip)
cec2e17d 1766{
d62a17ae 1767 struct mac_walk_ctx wctx;
cec2e17d 1768
d62a17ae 1769 if (!EVPN_ENABLED(zvrf))
1770 return;
1771 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1772 wctx.vty = vty;
1773 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
1774 wctx.r_vtep_ip = vtep_ip;
1775 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
cec2e17d 1776}
1777
1778/*
1779 * Display specific MAC for a VNI, if present (VTY command handler).
1780 */
d62a17ae 1781void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
1782 vni_t vni, struct ethaddr *macaddr)
cec2e17d 1783{
d62a17ae 1784 zebra_vni_t *zvni;
1785 zebra_mac_t *mac;
cec2e17d 1786
d62a17ae 1787 if (!EVPN_ENABLED(zvrf))
1788 return;
1789 zvni = zvni_lookup(zvrf, vni);
1790 if (!zvni) {
1791 vty_out(vty, "%% VNI %u does not exist\n", vni);
1792 return;
1793 }
1794 mac = zvni_mac_lookup(zvni, macaddr);
1795 if (!mac) {
1796 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
1797 vni);
1798 return;
1799 }
cec2e17d 1800
d62a17ae 1801 zvni_print_mac(mac, vty);
cec2e17d 1802}
1803
1804/*
1805 * Display MACs for a VNI from specific VTEP (VTY command handler).
1806 */
d62a17ae 1807void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
1808 vni_t vni, struct in_addr vtep_ip)
cec2e17d 1809{
d62a17ae 1810 zebra_vni_t *zvni;
1811 u_int32_t num_macs;
1812 struct mac_walk_ctx wctx;
cec2e17d 1813
d62a17ae 1814 if (!EVPN_ENABLED(zvrf))
1815 return;
1816 zvni = zvni_lookup(zvrf, vni);
1817 if (!zvni) {
1818 vty_out(vty, "%% VNI %u does not exist\n", vni);
1819 return;
1820 }
1821 num_macs = hashcount(zvni->mac_table);
1822 if (!num_macs)
1823 return;
1824 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1825 wctx.zvni = zvni;
1826 wctx.vty = vty;
1827 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
1828 wctx.r_vtep_ip = vtep_ip;
1829 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
cec2e17d 1830}
1831
1832
1833/*
1834 * Display VNI information (VTY command handler).
1835 */
d62a17ae 1836void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni)
cec2e17d 1837{
d62a17ae 1838 zebra_vni_t *zvni;
cec2e17d 1839
d62a17ae 1840 if (!EVPN_ENABLED(zvrf))
1841 return;
1842 zvni = zvni_lookup(zvrf, vni);
1843 if (!zvni) {
1844 vty_out(vty, "%% VNI %u does not exist\n", vni);
1845 return;
1846 }
1847 zvni_print(zvni, (void *)vty);
cec2e17d 1848}
1849
1850/*
1851 * Display VNI hash table (VTY command handler).
1852 */
d62a17ae 1853void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf)
cec2e17d 1854{
d62a17ae 1855 u_int32_t num_vnis;
cec2e17d 1856
d62a17ae 1857 if (!EVPN_ENABLED(zvrf))
1858 return;
1859 num_vnis = hashcount(zvrf->vni_table);
1860 if (!num_vnis)
1861 return;
1862 vty_out(vty, "Number of VNIs: %u\n", num_vnis);
1863 vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI", "VxLAN IF",
1864 "VTEP IP", "# MACs", "# ARPs", "# Remote VTEPs");
1865 hash_iterate(zvrf->vni_table, zvni_print_hash, vty);
cec2e17d 1866}
1867
2232a77c 1868/*
1869 * Handle neighbor delete (on a VLAN device / L3 interface) from the
1870 * kernel. This may result in either the neighbor getting deleted from
1871 * our database or being re-added to the kernel (if it is a valid
1872 * remote neighbor).
1873 */
d62a17ae 1874int zebra_vxlan_local_neigh_del(struct interface *ifp,
1875 struct interface *link_if, struct ipaddr *ip)
1876{
1877 zebra_vni_t *zvni;
1878 zebra_neigh_t *n;
1879 struct zebra_vrf *zvrf;
1880 char buf[INET6_ADDRSTRLEN];
1881
1882 /* We are only interested in neighbors on an SVI that resides on top
1883 * of a VxLAN bridge.
1884 */
1885 zvni = zvni_map_svi(ifp, link_if);
1886 if (!zvni)
1887 return 0;
1888 if (!zvni->vxlan_if) {
1889 zlog_err(
1890 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
1891 zvni->vni, zvni);
1892 return -1;
1893 }
1894
1895 if (IS_ZEBRA_DEBUG_VXLAN)
1896 zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u",
1897 ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)),
1898 ifp->name, ifp->ifindex, zvni->vni);
1899
1900 /* If entry doesn't exist, nothing to do. */
1901 n = zvni_neigh_lookup(zvni, ip);
1902 if (!n)
1903 return 0;
1904
1905 /* If it is a remote entry, the kernel has aged this out or someone has
1906 * deleted it, it needs to be re-installed as Quagga is the owner.
1907 */
1908 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1909 zvni_neigh_install(zvni, n);
1910 return 0;
1911 }
1912
1913 /* Locate VRF corresponding to interface. */
1914 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1915 assert(zvrf);
1916
1917 /* Remove neighbor from BGP. */
1918 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac);
1919
1920 /* Delete this neighbor entry. */
1921 zvni_neigh_del(zvni, n);
1922
1923 return 0;
2232a77c 1924}
1925
1926/*
1927 * Handle neighbor add or update (on a VLAN device / L3 interface)
1928 * from the kernel.
1929 */
d62a17ae 1930int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
1931 struct interface *link_if,
1932 struct ipaddr *ip,
1933 struct ethaddr *macaddr, u_int16_t state,
1934 u_char ext_learned)
1935{
1936 zebra_vni_t *zvni;
1937 zebra_neigh_t *n;
1938 struct zebra_vrf *zvrf;
1939 char buf[ETHER_ADDR_STRLEN];
1940 char buf2[INET6_ADDRSTRLEN];
1941 int send_upd = 1, send_del = 0;
1942
1943 /* We are only interested in neighbors on an SVI that resides on top
1944 * of a VxLAN bridge.
1945 */
1946 zvni = zvni_map_svi(ifp, link_if);
1947 if (!zvni)
1948 return 0;
1949
1950 /* Locate VRF corresponding to interface. */
1951 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1952 assert(zvrf);
1953
1954 if (IS_ZEBRA_DEBUG_VXLAN)
1955 zlog_debug(
1956 "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
1957 "%s-> VNI %u",
1958 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
1959 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
1960 ifp->ifindex, state, ext_learned ? "ext-learned " : "",
1961 zvni->vni);
1962
1963 /* If same entry already exists, it might be a change or it might be a
1964 * move from remote to local.
1965 */
1966 n = zvni_neigh_lookup(zvni, ip);
1967 if (n) {
1968 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1969 if (memcmp(n->emac.octet, macaddr->octet,
ff8b7eb8 1970 ETH_ALEN)
d62a17ae 1971 == 0) {
1972 if (n->ifindex == ifp->ifindex)
1973 /* we're not interested in whatever has
1974 * changed. */
1975 return 0;
1976 /* client doesn't care about a purely local
1977 * change. */
1978 send_upd = 0;
1979 } else
1980 /* If the MAC has changed, issue a delete first
1981 * as this means a
1982 * different MACIP route.
1983 */
1984 send_del = 1;
1985 } else if (ext_learned)
1986 /* The neighbor is remote and that is the notification we got.
9d303b37 1987 */
d62a17ae 1988 {
1989 /* TODO: Evaluate if we need to do anything here. */
1990 return 0;
1991 } else
1992 /* Neighbor has moved from remote to local. */
1993 {
1994 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
1995 n->r_vtep_ip.s_addr = 0;
1996 }
1997 } else {
1998 n = zvni_neigh_add(zvni, ip);
1999 if (!n) {
2000 zlog_err(
2001 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2002 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
2003 prefix_mac2str(macaddr, buf, sizeof(buf)),
2004 ifp->name, ifp->ifindex, zvni->vni);
2005 return -1;
2006 }
2007 }
2008
2009 /* Issue delete for older info, if needed. */
2010 if (send_del)
2011 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip,
2012 &n->emac);
2013
2014 /* Set "local" forwarding info. */
2015 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
ff8b7eb8 2016 memcpy(&n->emac, macaddr, ETH_ALEN);
d62a17ae 2017 n->ifindex = ifp->ifindex;
2018
2019 /* Inform BGP if required. */
2020 if (send_upd)
2021 return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip,
2022 macaddr);
2023
2024 return 0;
2232a77c 2025}
2026
2027/*
2028 * Handle message from client to delete a remote MACIP for a VNI.
2029 */
d62a17ae 2030int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
2031 struct zebra_vrf *zvrf)
2032{
2033 struct stream *s;
2034 vni_t vni;
2035 struct ethaddr macaddr;
2036 struct ipaddr ip;
2037 struct in_addr vtep_ip;
2038 zebra_vni_t *zvni;
2039 zebra_mac_t *mac;
2040 zebra_neigh_t *n;
2041 u_short l = 0, ipa_len;
2042 char buf[ETHER_ADDR_STRLEN];
2043 char buf1[INET6_ADDRSTRLEN];
2044
2045 s = client->ibuf;
2046
2047 while (l < length) {
2048 /* Obtain each remote MACIP and process. */
2049 /* Message contains VNI, followed by MAC followed by IP (if any)
2050 * followed by remote VTEP IP.
2051 */
2052 mac = NULL;
2053 n = NULL;
2054 memset(&ip, 0, sizeof(ip));
2055 vni = (vni_t)stream_getl(s);
ff8b7eb8 2056 stream_get(&macaddr.octet, s, ETH_ALEN);
d62a17ae 2057 ipa_len = stream_getl(s);
2058 if (ipa_len) {
2059 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
2060 : IPADDR_V6;
2061 stream_get(&ip.ip.addr, s, ipa_len);
2062 }
ff8b7eb8 2063 l += 4 + ETH_ALEN + 4 + ipa_len;
d62a17ae 2064 vtep_ip.s_addr = stream_get_ipv4(s);
2065 l += IPV4_MAX_BYTELEN;
2066
2067 if (IS_ZEBRA_DEBUG_VXLAN)
2068 zlog_debug(
2069 "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
2070 zvrf_id(zvrf),
2071 prefix_mac2str(&macaddr, buf, sizeof(buf)),
2072 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
2073 inet_ntoa(vtep_ip),
2074 zebra_route_string(client->proto));
2075
2076 /* Locate VNI hash entry - expected to exist. */
2077 zvni = zvni_lookup(zvrf, vni);
2078 if (!zvni) {
2079 if (IS_ZEBRA_DEBUG_VXLAN)
2080 zlog_debug(
2081 "Failed to locate VNI hash upon remote MACIP DEL, "
2082 "VRF %d VNI %u",
2083 zvrf_id(zvrf), vni);
2084 continue;
2085 }
2086 if (!zvni->vxlan_if) {
2087 zlog_err(
2088 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
2089 vni, zvni);
2090 continue;
2091 }
2092
2093 /* The remote VTEP specified is normally expected to exist, but
2094 * it is
2095 * possible that the peer may delete the VTEP before deleting
2096 * any MACs
2097 * referring to the VTEP, in which case the handler (see
2098 * remote_vtep_del)
2099 * would have already deleted the MACs.
2100 */
2101 if (!zvni_vtep_find(zvni, &vtep_ip))
2102 continue;
2103
2104 /* If the local VxLAN interface is not up (should be a transient
2105 * event), there's nothing more to do.
2106 */
2107 if (!if_is_operative(zvni->vxlan_if))
2108 continue;
2109
2110 mac = zvni_mac_lookup(zvni, &macaddr);
2111 if (ipa_len)
2112 n = zvni_neigh_lookup(zvni, &ip);
2113
2114 if (n && !mac) {
2115 zlog_err(
2116 "failed to locate MAC %s for neigh %s in VRF %u VNI %u",
2117 prefix_mac2str(&macaddr, buf, sizeof(buf)),
2118 ipaddr2str(&ip, buf1, sizeof(buf1)),
2119 zvrf_id(zvrf), vni);
2120 continue;
2121 }
2122
2123 /* If the remote mac or neighbor doesn't exist there is nothing
2124 * more
2125 * to do. Otherwise, uninstall the entry and then remove it.
2126 */
2127 if (!mac && !n)
2128 continue;
2129
2130 /* Uninstall remote neighbor or MAC. */
2131 if (n) {
2132 /* When the MAC changes for an IP, it is possible the
2133 * client may
2134 * update the new MAC before trying to delete the "old"
2135 * neighbor
2136 * (as these are two different MACIP routes). Do the
2137 * delete only
2138 * if the MAC matches.
2139 */
2140 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2141 && (memcmp(n->emac.octet, macaddr.octet,
ff8b7eb8 2142 ETH_ALEN)
d62a17ae 2143 == 0)) {
2144 zvni_neigh_uninstall(zvni, n);
2145 zvni_neigh_del(zvni, n);
2146 zvni_deref_ip2mac(zvni, mac, 1);
2147 }
2148 } else {
2149 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
2150 if (!mac->neigh_refcnt) {
2151 zvni_mac_uninstall(zvni, mac, 0);
2152 zvni_mac_del(zvni, mac);
2153 } else
2154 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2155 }
2156 }
2157 }
2158
2159 return 0;
2232a77c 2160}
2161
2162/*
2163 * Handle message from client to add a remote MACIP for a VNI. This
2164 * could be just the add of a MAC address or the add of a neighbor
2165 * (IP+MAC).
2166 */
d62a17ae 2167int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
2168 struct zebra_vrf *zvrf)
2169{
2170 struct stream *s;
2171 vni_t vni;
2172 struct ethaddr macaddr;
2173 struct ipaddr ip;
2174 struct in_addr vtep_ip;
2175 zebra_vni_t *zvni;
2176 zebra_vtep_t *zvtep;
2177 zebra_mac_t *mac, *old_mac;
2178 zebra_neigh_t *n;
2179 u_short l = 0, ipa_len;
2180 int update_mac = 0, update_neigh = 0;
2181 char buf[ETHER_ADDR_STRLEN];
2182 char buf1[INET6_ADDRSTRLEN];
2183 u_char sticky;
2184
2185 assert(EVPN_ENABLED(zvrf));
2186
2187 s = client->ibuf;
2188
2189 while (l < length) {
2190 /* Obtain each remote MACIP and process. */
2191 /* Message contains VNI, followed by MAC followed by IP (if any)
2192 * followed by remote VTEP IP.
2193 */
2194 update_mac = update_neigh = 0;
2195 mac = NULL;
2196 n = NULL;
2197 memset(&ip, 0, sizeof(ip));
2198 vni = (vni_t)stream_getl(s);
ff8b7eb8 2199 stream_get(&macaddr.octet, s, ETH_ALEN);
d62a17ae 2200 ipa_len = stream_getl(s);
2201 if (ipa_len) {
2202 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
2203 : IPADDR_V6;
2204 stream_get(&ip.ip.addr, s, ipa_len);
2205 }
ff8b7eb8 2206 l += 4 + ETH_ALEN + 4 + ipa_len;
d62a17ae 2207 vtep_ip.s_addr = stream_get_ipv4(s);
2208 l += IPV4_MAX_BYTELEN;
2209
2210 /* Get 'sticky' flag. */
2211 sticky = stream_getc(s);
2212 l++;
2213
2214 if (IS_ZEBRA_DEBUG_VXLAN)
2215 zlog_debug(
2216 "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
2217 zvrf_id(zvrf), sticky ? "sticky " : "",
2218 prefix_mac2str(&macaddr, buf, sizeof(buf)),
2219 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
2220 inet_ntoa(vtep_ip),
2221 zebra_route_string(client->proto));
2222
2223 /* Locate VNI hash entry - expected to exist. */
2224 zvni = zvni_lookup(zvrf, vni);
2225 if (!zvni) {
2226 zlog_err(
2227 "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
2228 zvrf_id(zvrf), vni);
2229 continue;
2230 }
2231 if (!zvni->vxlan_if) {
2232 zlog_err(
2233 "VNI %u hash %p doesn't have intf upon remote MACIP add",
2234 vni, zvni);
2235 continue;
2236 }
2237 /* If the local VxLAN interface is not up (should be a transient
2238 * event), there's nothing more to do.
2239 */
2240 if (!if_is_operative(zvni->vxlan_if))
2241 continue;
2242
2243 /* The remote VTEP specified should normally exist, but it is
2244 * possible
2245 * that when peering comes up, peer may advertise MACIP routes
2246 * before
2247 * advertising type-3 routes.
2248 */
2249 zvtep = zvni_vtep_find(zvni, &vtep_ip);
2250 if (!zvtep) {
2251 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
2252 zlog_err(
2253 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2254 zvrf_id(zvrf), vni, zvni);
2255 continue;
2256 }
2257
2258 zvni_vtep_install(zvni, &vtep_ip);
2259 }
2260
2261 /* First, check if the remote MAC is unknown or has a change. If
2262 * so,
2263 * that needs to be updated first. Note that client could
2264 * install
2265 * MAC and MACIP separately or just install the latter.
2266 */
2267 mac = zvni_mac_lookup(zvni, &macaddr);
2268 if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
2269 || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
2270 != sticky
2271 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
2272 update_mac = 1;
2273
2274 if (update_mac) {
2275 if (!mac) {
2276 mac = zvni_mac_add(zvni, &macaddr);
2277 if (!mac) {
2278 zlog_warn(
2279 "%u:Failed to add MAC %s VNI %u Remote VTEP %s",
2280 zvrf_id(zvrf),
2281 prefix_mac2str(&macaddr, buf,
2282 sizeof(buf)),
2283 vni, inet_ntoa(vtep_ip));
2284 return -1;
2285 }
2286
2287 /* Is this MAC created for a MACIP? */
2288 if (ipa_len)
2289 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2290 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
2291 /* Moving from local to remote, issue delete. */
2292 zvni_mac_uninstall(zvni, mac, 1);
2293 }
2294
2295 /* Set "auto" and "remote" forwarding info. */
2296 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2297 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2298 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
2299 mac->fwd_info.r_vtep_ip = vtep_ip;
2300
2301 if (sticky)
2302 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2303 else
2304 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2305
2306 /* Install the entry. */
2307 zvni_mac_install(zvni, mac);
2308 }
2309
2310 /* If there is no IP, continue - after clearing AUTO flag of
2311 * MAC. */
2312 if (!ipa_len) {
2313 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2314 continue;
2315 }
2316
2317 /* Check if the remote neighbor itself is unknown or has a
2318 * change.
2319 * If so, create or update and then install the entry.
2320 */
2321 n = zvni_neigh_lookup(zvni, &ip);
2322 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2323 || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
2324 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
2325 update_neigh = 1;
2326
2327 if (update_neigh) {
2328 if (!n) {
2329 n = zvni_neigh_add(zvni, &ip);
2330 if (!n) {
2331 zlog_warn(
2332 "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
2333 zvrf_id(zvrf),
2334 ipaddr2str(&ip, buf1,
2335 sizeof(buf1)),
2336 prefix_mac2str(&macaddr, buf,
2337 sizeof(buf)),
2338 vni, inet_ntoa(vtep_ip));
2339 return -1;
2340 }
2341
2342 /* New neighbor referring to this MAC. */
2343 mac->neigh_refcnt++;
2344 } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
2345 != 0) {
2346 /* MAC change, update ref counts for old and new
2347 * MAC. */
2348 old_mac = zvni_mac_lookup(zvni, &n->emac);
2349 if (old_mac)
2350 zvni_deref_ip2mac(zvni, old_mac, 1);
2351 mac->neigh_refcnt++;
2352 }
2353
2354 /* Set "remote" forwarding info. */
2355 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2356 /* TODO: Handle MAC change. */
ff8b7eb8 2357 memcpy(&n->emac, &macaddr, ETH_ALEN);
d62a17ae 2358 n->r_vtep_ip = vtep_ip;
2359 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2360
2361 /* Install the entry. */
2362 zvni_neigh_install(zvni, n);
2363 }
2364 }
2365
2366 return 0;
13d60d35 2367}
2368
2369/*
2232a77c 2370 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
2371 * us, this must involve a multihoming scenario. Treat this as implicit delete
2372 * of any prior local MAC.
13d60d35 2373 */
d62a17ae 2374int zebra_vxlan_check_del_local_mac(struct interface *ifp,
2375 struct interface *br_if,
2376 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2377{
d62a17ae 2378 struct zebra_if *zif;
2379 struct zebra_vrf *zvrf;
2380 struct zebra_l2info_vxlan *vxl;
2381 vni_t vni;
2382 zebra_vni_t *zvni;
2383 zebra_mac_t *mac;
2384 char buf[ETHER_ADDR_STRLEN];
2385 u_char sticky;
13d60d35 2386
d62a17ae 2387 zif = ifp->info;
2388 assert(zif);
2389 vxl = &zif->l2info.vxl;
2390 vni = vxl->vni;
13d60d35 2391
d62a17ae 2392 /* Locate VRF corresponding to interface. */
2393 zvrf = vrf_info_lookup(ifp->vrf_id);
2394 assert(zvrf);
13d60d35 2395
d62a17ae 2396 /* If EVPN is not enabled, nothing to do. */
2397 if (!EVPN_ENABLED(zvrf))
2398 return 0;
13d60d35 2399
d62a17ae 2400 /* Locate hash entry; it is expected to exist. */
2401 zvni = zvni_lookup(zvrf, vni);
2402 if (!zvni)
2403 return 0;
13d60d35 2404
d62a17ae 2405 /* If entry doesn't exist, nothing to do. */
2406 mac = zvni_mac_lookup(zvni, macaddr);
2407 if (!mac)
2408 return 0;
13d60d35 2409
d62a17ae 2410 /* Is it a local entry? */
2411 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
2412 return 0;
13d60d35 2413
d62a17ae 2414 if (IS_ZEBRA_DEBUG_VXLAN)
2415 zlog_debug(
2416 "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
2417 ifp->vrf_id, prefix_mac2str(macaddr, buf, sizeof(buf)),
2418 ifp->name, ifp->ifindex, vni);
13d60d35 2419
d62a17ae 2420 /* Remove MAC from BGP. */
2421 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
2422 zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr, sticky);
13d60d35 2423
d62a17ae 2424 /* Delete this MAC entry. */
2425 zvni_mac_del(zvni, mac);
13d60d35 2426
d62a17ae 2427 return 0;
13d60d35 2428}
2429
2430/*
2232a77c 2431 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
2432 * This can happen because the remote MAC entries are also added as "dynamic",
2433 * so the kernel can ageout the entry.
13d60d35 2434 */
d62a17ae 2435int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
2436 struct interface *br_if,
2437 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2438{
d62a17ae 2439 struct zebra_if *zif;
2440 struct zebra_vrf *zvrf;
2441 struct zebra_l2info_vxlan *vxl;
2442 vni_t vni;
2443 zebra_vni_t *zvni;
2444 zebra_mac_t *mac;
2445 char buf[ETHER_ADDR_STRLEN];
2232a77c 2446
d62a17ae 2447 zif = ifp->info;
2448 assert(zif);
2449 vxl = &zif->l2info.vxl;
2450 vni = vxl->vni;
2232a77c 2451
d62a17ae 2452 /* Locate VRF corresponding to interface. */
2453 zvrf = vrf_info_lookup(ifp->vrf_id);
2454 assert(zvrf);
13d60d35 2455
d62a17ae 2456 /* If EVPN is not enabled, nothing to do. */
2457 if (!EVPN_ENABLED(zvrf))
2458 return 0;
2232a77c 2459
d62a17ae 2460 /* Locate hash entry; it is expected to exist. */
2461 zvni = zvni_lookup(zvrf, vni);
2462 if (!zvni)
2463 return 0;
13d60d35 2464
d62a17ae 2465 /* If entry doesn't exist, nothing to do. */
2466 mac = zvni_mac_lookup(zvni, macaddr);
2467 if (!mac)
2468 return 0;
2232a77c 2469
d62a17ae 2470 /* Is it a remote entry? */
2471 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
2472 return 0;
2232a77c 2473
d62a17ae 2474 if (IS_ZEBRA_DEBUG_VXLAN)
2475 zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
2476 ifp->vrf_id,
2477 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2478 ifp->ifindex, vni);
13d60d35 2479
d62a17ae 2480 zvni_mac_install(zvni, mac);
2481 return 0;
13d60d35 2482}
2483
2484/*
2232a77c 2485 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
13d60d35 2486 */
d62a17ae 2487int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
2488 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2489{
d62a17ae 2490 zebra_vni_t *zvni;
2491 zebra_mac_t *mac;
2492 struct zebra_vrf *zvrf;
2493 char buf[ETHER_ADDR_STRLEN];
2494 u_char sticky;
13d60d35 2495
d62a17ae 2496 /* We are interested in MACs only on ports or (port, VLAN) that
2497 * map to a VNI.
2498 */
2499 zvni = zvni_map_vlan(ifp, br_if, vid);
2500 if (!zvni)
2501 return 0;
2502 if (!zvni->vxlan_if) {
2503 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
2504 zvni->vni, zvni);
2505 return -1;
2506 }
13d60d35 2507
d62a17ae 2508 if (IS_ZEBRA_DEBUG_VXLAN)
2509 zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
2510 ifp->vrf_id,
2511 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2512 ifp->ifindex, vid, zvni->vni);
2232a77c 2513
d62a17ae 2514 /* If entry doesn't exist, nothing to do. */
2515 mac = zvni_mac_lookup(zvni, macaddr);
2516 if (!mac)
2517 return 0;
2232a77c 2518
d62a17ae 2519 /* Is it a local entry? */
2520 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
2521 return 0;
2232a77c 2522
d62a17ae 2523 /* Locate VRF corresponding to interface. */
2524 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2525 assert(zvrf);
2232a77c 2526
d62a17ae 2527 /* Remove MAC from BGP. */
2528 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
2529 zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr, sticky);
2232a77c 2530
d62a17ae 2531 /* Delete this MAC entry. */
2532 zvni_mac_del(zvni, mac);
2232a77c 2533
d62a17ae 2534 return 0;
13d60d35 2535}
2536
2537/*
2232a77c 2538 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
13d60d35 2539 */
d62a17ae 2540int zebra_vxlan_local_mac_add_update(struct interface *ifp,
2541 struct interface *br_if,
2542 struct ethaddr *macaddr, vlanid_t vid,
2543 u_char sticky)
2544{
2545 zebra_vni_t *zvni;
2546 zebra_mac_t *mac;
2547 struct zebra_vrf *zvrf;
2548 char buf[ETHER_ADDR_STRLEN];
2549 int add = 1;
2550 u_char mac_sticky;
2551
2552 /* We are interested in MACs only on ports or (port, VLAN) that
2553 * map to a VNI.
2554 */
2555 zvni = zvni_map_vlan(ifp, br_if, vid);
2556 if (!zvni) {
2557 if (IS_ZEBRA_DEBUG_VXLAN)
2558 zlog_debug(
2559 "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
2560 ifp->vrf_id, sticky ? "sticky " : "",
2561 prefix_mac2str(macaddr, buf, sizeof(buf)),
2562 ifp->name, ifp->ifindex, vid);
2563 return 0;
2564 }
2565
2566 if (!zvni->vxlan_if) {
2567 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
2568 zvni->vni, zvni);
2569 return -1;
2570 }
2571
2572 if (IS_ZEBRA_DEBUG_VXLAN)
2573 zlog_debug(
2574 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
2575 ifp->vrf_id, sticky ? "sticky " : "",
2576 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2577 ifp->ifindex, vid, zvni->vni);
2578
2579 /* If same entry already exists, nothing to do. */
2580 mac = zvni_mac_lookup(zvni, macaddr);
2581 if (mac) {
2582 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
2583 mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
2584 ? 1
2585 : 0;
2586
b8ce75a5
MK
2587 /*
2588 * return if nothing has changed.
2589 * inform bgp if sticky flag has changed
2590 * update locally and do not inform bgp if local
2591 * parameters like interface has changed
2592 */
d62a17ae 2593 if (mac_sticky == sticky
2594 && mac->fwd_info.local.ifindex == ifp->ifindex
2595 && mac->fwd_info.local.vid == vid) {
2596 if (IS_ZEBRA_DEBUG_VXLAN)
2597 zlog_debug(
2598 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
2599 "entry exists and has not changed ",
2600 ifp->vrf_id,
2601 sticky ? "sticky " : "",
2602 prefix_mac2str(macaddr, buf,
2603 sizeof(buf)),
2604 ifp->name, ifp->ifindex, vid,
2605 zvni->vni);
2606 return 0;
b8ce75a5
MK
2607 } else if (mac_sticky != sticky)
2608 add = 1;
2609 else
2610 add = 0; /* This is an update of local
2611 interface. */
421bb26a
MK
2612 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
2613 /*
2614 * If we have already learned the MAC as a remote sticky
2615 * MAC,
2616 * this is a operator error and we must log a warning
2617 */
8f4b98ee 2618 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
421bb26a
MK
2619 zlog_warn(
2620 "MAC %s is already learnt as a remote sticky mac behind VTEP %s VNI %d",
2621 prefix_mac2str(macaddr, buf,
2622 sizeof(buf)),
2623 inet_ntoa(mac->fwd_info.r_vtep_ip),
2624 zvni->vni);
8f4b98ee
MK
2625 return 0;
2626 }
d62a17ae 2627 }
2628 }
2629
2630 /* Locate VRF corresponding to interface. */
2631 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2632 assert(zvrf);
2633
2634 if (!mac) {
2635 mac = zvni_mac_add(zvni, macaddr);
2636 if (!mac) {
2637 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
2638 ifp->vrf_id,
2639 prefix_mac2str(macaddr, buf, sizeof(buf)),
2640 ifp->name, ifp->ifindex, vid);
2641 return -1;
2642 }
2643 }
2644
2645 /* Set "local" forwarding info. */
2646 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
2647 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2648 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2649 mac->fwd_info.local.ifindex = ifp->ifindex;
2650 mac->fwd_info.local.vid = vid;
2651
2652 if (sticky)
2653 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2654 else
2655 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2656
2657 /* Inform BGP if required. */
2658 if (add)
2659 return zvni_mac_send_add_to_client(zvrf, zvni->vni, macaddr,
2660 sticky);
2661
2662 return 0;
2232a77c 2663}
13d60d35 2664
2665/*
2666 * Handle message from client to delete a remote VTEP for a VNI.
2667 */
d62a17ae 2668int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
2669 struct zebra_vrf *zvrf)
2670{
2671 struct stream *s;
2672 u_short l = 0;
2673 vni_t vni;
2674 struct in_addr vtep_ip;
2675 zebra_vni_t *zvni;
2676 zebra_vtep_t *zvtep;
2677
2678 s = client->ibuf;
2679
2680 while (l < length) {
2681 /* Obtain each remote VTEP and process. */
2682 vni = (vni_t)stream_getl(s);
2683 l += 4;
2684 vtep_ip.s_addr = stream_get_ipv4(s);
2685 l += IPV4_MAX_BYTELEN;
2686
2687 if (IS_ZEBRA_DEBUG_VXLAN)
2688 zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s",
2689 zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
2690 zebra_route_string(client->proto));
2691
2692 /* Locate VNI hash entry - expected to exist. */
2693 zvni = zvni_lookup(zvrf, vni);
2694 if (!zvni) {
2695 if (IS_ZEBRA_DEBUG_VXLAN)
2696 zlog_debug(
2697 "Failed to locate VNI hash upon remote VTEP DEL, "
2698 "VRF %d VNI %u",
2699 zvrf_id(zvrf), vni);
2700 continue;
2701 }
2702
2703 /* If the remote VTEP does not exist, there's nothing more to
2704 * do.
2705 * Otherwise, uninstall any remote MACs pointing to this VTEP
2706 * and
2707 * then, the VTEP entry itself and remove it.
2708 */
2709 zvtep = zvni_vtep_find(zvni, &vtep_ip);
2710 if (!zvtep)
2711 continue;
2712
2713 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
2714 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
2715 zvni_vtep_uninstall(zvni, &vtep_ip);
2716 zvni_vtep_del(zvni, zvtep);
2717 }
2718
2719 return 0;
13d60d35 2720}
2721
2722/*
2723 * Handle message from client to add a remote VTEP for a VNI.
2724 */
d62a17ae 2725int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
2726 struct zebra_vrf *zvrf)
2727{
2728 struct stream *s;
2729 u_short l = 0;
2730 vni_t vni;
2731 struct in_addr vtep_ip;
2732 zebra_vni_t *zvni;
2733
2734 assert(EVPN_ENABLED(zvrf));
2735
2736 s = client->ibuf;
2737
2738 while (l < length) {
2739 /* Obtain each remote VTEP and process. */
2740 vni = (vni_t)stream_getl(s);
2741 l += 4;
2742 vtep_ip.s_addr = stream_get_ipv4(s);
2743 l += IPV4_MAX_BYTELEN;
2744
2745 if (IS_ZEBRA_DEBUG_VXLAN)
2746 zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s",
2747 zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
2748 zebra_route_string(client->proto));
2749
2750 /* Locate VNI hash entry - expected to exist. */
2751 zvni = zvni_lookup(zvrf, vni);
2752 if (!zvni) {
2753 zlog_err(
2754 "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
2755 zvrf_id(zvrf), vni);
2756 continue;
2757 }
2758 if (!zvni->vxlan_if) {
2759 zlog_err(
2760 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
2761 zvni->vni, zvni);
2762 continue;
2763 }
2764
2765
2766 /* If the remote VTEP already exists, or the local VxLAN
2767 * interface is
2768 * not up (should be a transient event), there's nothing more
2769 * to do.
2770 * Otherwise, add and install the entry.
2771 */
2772 if (zvni_vtep_find(zvni, &vtep_ip))
2773 continue;
2774
2775 if (!if_is_operative(zvni->vxlan_if))
2776 continue;
2777
2778 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
2779 zlog_err(
2780 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2781 zvrf_id(zvrf), vni, zvni);
2782 continue;
2783 }
2784
2785 zvni_vtep_install(zvni, &vtep_ip);
2786 }
2787
2788 return 0;
13d60d35 2789}
2790
2232a77c 2791/*
2792 * Handle SVI interface going down. At this point, this is a NOP since
2793 * the kernel deletes the neighbor entries on this SVI (if any).
2794 */
d62a17ae 2795int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
2232a77c 2796{
d62a17ae 2797 return 0;
2232a77c 2798}
2799
2800/*
2801 * Handle SVI interface coming up. This may or may not be of interest,
2802 * but if this is a SVI on a VxLAN bridge, we need to install any remote
2803 * neighbor entries (which will be used for EVPN ARP suppression).
2804 */
d62a17ae 2805int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
2232a77c 2806{
d62a17ae 2807 zebra_vni_t *zvni;
2808 struct neigh_walk_ctx n_wctx;
2232a77c 2809
d62a17ae 2810 zvni = zvni_map_svi(ifp, link_if);
2811 if (!zvni)
2812 return 0;
2232a77c 2813
d62a17ae 2814 if (!zvni->vxlan_if) {
2815 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
2816 zvni->vni, zvni);
2817 return -1;
2818 }
2232a77c 2819
d62a17ae 2820 if (IS_ZEBRA_DEBUG_VXLAN)
2821 zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
2822 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
2232a77c 2823
d62a17ae 2824 /* Install any remote neighbors for this VNI. */
2825 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
2826 n_wctx.zvni = zvni;
2827 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash, &n_wctx);
2232a77c 2828
d62a17ae 2829 return 0;
2232a77c 2830}
2831
13d60d35 2832/*
2833 * Handle VxLAN interface down - update BGP if required, and do
2834 * internal cleanup.
2835 */
d62a17ae 2836int zebra_vxlan_if_down(struct interface *ifp)
13d60d35 2837{
d62a17ae 2838 struct zebra_if *zif;
2839 struct zebra_vrf *zvrf;
2840 zebra_vni_t *zvni;
2841 struct zebra_l2info_vxlan *vxl;
2842 vni_t vni;
13d60d35 2843
d62a17ae 2844 /* Locate VRF corresponding to interface. */
2845 zvrf = vrf_info_lookup(ifp->vrf_id);
2846 assert(zvrf);
13d60d35 2847
d62a17ae 2848 /* If EVPN is not enabled, nothing further to be done. */
2849 if (!EVPN_ENABLED(zvrf))
2850 return 0;
13d60d35 2851
d62a17ae 2852 zif = ifp->info;
2853 assert(zif);
2854 vxl = &zif->l2info.vxl;
2855 vni = vxl->vni;
13d60d35 2856
d62a17ae 2857 if (IS_ZEBRA_DEBUG_VXLAN)
2858 zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp->vrf_id,
2859 ifp->name, ifp->ifindex, vni);
13d60d35 2860
d62a17ae 2861 /* Locate hash entry; it is expected to exist. */
2862 zvni = zvni_lookup(zvrf, vni);
2863 if (!zvni) {
2864 zlog_err(
2865 "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
2866 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2867 return -1;
2868 }
13d60d35 2869
d62a17ae 2870 assert(zvni->vxlan_if == ifp);
13d60d35 2871
d62a17ae 2872 /* Delete this VNI from BGP. */
2873 zvni_send_del_to_client(zvrf, zvni->vni);
13d60d35 2874
d62a17ae 2875 /* Free up all neighbors and MACs, if any. */
2876 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
2877 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
2232a77c 2878
d62a17ae 2879 /* Free up all remote VTEPs, if any. */
2880 zvni_vtep_del_all(zvni, 1);
13d60d35 2881
d62a17ae 2882 return 0;
13d60d35 2883}
2884
2885/*
2886 * Handle VxLAN interface up - update BGP if required.
2887 */
d62a17ae 2888int zebra_vxlan_if_up(struct interface *ifp)
13d60d35 2889{
d62a17ae 2890 struct zebra_if *zif;
2891 struct zebra_vrf *zvrf;
2892 zebra_vni_t *zvni;
2893 struct zebra_l2info_vxlan *vxl;
2894 vni_t vni;
13d60d35 2895
d62a17ae 2896 /* Locate VRF corresponding to interface. */
2897 zvrf = vrf_info_lookup(ifp->vrf_id);
2898 assert(zvrf);
13d60d35 2899
d62a17ae 2900 /* If EVPN is not enabled, nothing further to be done. */
2901 if (!EVPN_ENABLED(zvrf))
2902 return 0;
13d60d35 2903
d62a17ae 2904 zif = ifp->info;
2905 assert(zif);
2906 vxl = &zif->l2info.vxl;
2907 vni = vxl->vni;
13d60d35 2908
d62a17ae 2909 if (IS_ZEBRA_DEBUG_VXLAN)
2910 zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp->vrf_id,
2911 ifp->name, ifp->ifindex, vni);
13d60d35 2912
d62a17ae 2913 /* Locate hash entry; it is expected to exist. */
2914 zvni = zvni_lookup(zvrf, vni);
2915 if (!zvni) {
2916 zlog_err(
2917 "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
2918 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2919 return -1;
2920 }
13d60d35 2921
d62a17ae 2922 assert(zvni->vxlan_if == ifp);
13d60d35 2923
d62a17ae 2924 /* If part of a bridge, inform BGP about this VNI. */
2925 /* Also, read and populate local MACs and neighbors. */
2926 if (zif->brslave_info.br_if) {
2927 zvni_send_add_to_client(zvrf, zvni);
2928 zvni_read_mac_neigh(zvrf, zvni, ifp);
2929 }
13d60d35 2930
d62a17ae 2931 return 0;
13d60d35 2932}
2933
2934/*
2935 * Handle VxLAN interface delete. Locate and remove entry in hash table
2936 * and update BGP, if required.
2937 */
d62a17ae 2938int zebra_vxlan_if_del(struct interface *ifp)
13d60d35 2939{
d62a17ae 2940 struct zebra_if *zif;
2941 struct zebra_vrf *zvrf;
2942 zebra_vni_t *zvni;
2943 struct zebra_l2info_vxlan *vxl;
2944 vni_t vni;
13d60d35 2945
d62a17ae 2946 /* Locate VRF corresponding to interface. */
2947 zvrf = vrf_info_lookup(ifp->vrf_id);
2948 assert(zvrf);
13d60d35 2949
d62a17ae 2950 /* If EVPN is not enabled, nothing further to be done. */
2951 if (!EVPN_ENABLED(zvrf))
2952 return 0;
13d60d35 2953
d62a17ae 2954 zif = ifp->info;
2955 assert(zif);
2956 vxl = &zif->l2info.vxl;
2957 vni = vxl->vni;
13d60d35 2958
d62a17ae 2959 if (IS_ZEBRA_DEBUG_VXLAN)
2960 zlog_debug("%u:Del VNI %u intf %s(%u)", ifp->vrf_id, vni,
2961 ifp->name, ifp->ifindex);
13d60d35 2962
d62a17ae 2963 /* Locate hash entry; it is expected to exist. */
2964 zvni = zvni_lookup(zvrf, vni);
2965 if (!zvni) {
2966 zlog_err(
2967 "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
2968 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2969 return 0;
2970 }
13d60d35 2971
d62a17ae 2972 /* Delete VNI from BGP. */
2973 zvni_send_del_to_client(zvrf, zvni->vni);
13d60d35 2974
d62a17ae 2975 /* Free up all neighbors and MAC, if any. */
2976 zvni_neigh_del_all(zvrf, zvni, 0, 0, DEL_ALL_NEIGH);
2977 zvni_mac_del_all(zvrf, zvni, 0, 0, DEL_ALL_MAC);
2232a77c 2978
d62a17ae 2979 /* Free up all remote VTEPs, if any. */
2980 zvni_vtep_del_all(zvni, 0);
13d60d35 2981
d62a17ae 2982 /* Delete the hash entry. */
2983 if (zvni_del(zvrf, zvni)) {
2984 zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
2985 zvni, ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
2986 return -1;
2987 }
13d60d35 2988
d62a17ae 2989 return 0;
13d60d35 2990}
2991
2992/*
2993 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
2994 */
d62a17ae 2995int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
2996{
2997 struct zebra_if *zif;
2998 struct zebra_vrf *zvrf;
2999 zebra_vni_t *zvni;
3000 struct zebra_l2info_vxlan *vxl;
3001 vni_t vni;
3002
3003 /* Locate VRF corresponding to interface. */
3004 zvrf = vrf_info_lookup(ifp->vrf_id);
3005 assert(zvrf);
3006
3007 /* If EVPN is not enabled, nothing further to be done. */
3008 if (!EVPN_ENABLED(zvrf))
3009 return 0;
3010
3011 zif = ifp->info;
3012 assert(zif);
3013 vxl = &zif->l2info.vxl;
3014 vni = vxl->vni;
3015
3016 /* Update VNI hash. */
3017 zvni = zvni_lookup(zvrf, vni);
3018 if (!zvni) {
3019 zlog_err(
3020 "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
3021 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3022 return -1;
3023 }
3024
3025 if (IS_ZEBRA_DEBUG_VXLAN)
3026 zlog_debug(
3027 "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
3028 "master %u chg 0x%x",
3029 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
3030 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
3031 zif->brslave_info.bridge_ifindex, chgflags);
3032
3033 /* Removed from bridge? */
3034 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
3035 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
3036 /* Delete from client, remove all remote VTEPs */
3037 /* Also, free up all MACs and neighbors. */
3038 zvni_send_del_to_client(zvrf, zvni->vni);
3039 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
3040 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
3041 zvni_vtep_del_all(zvni, 1);
3042 } else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
3043 /* Remove all existing local neighbors and MACs for this VNI
3044 * (including from BGP)
3045 */
3046 zvni_neigh_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
3047 zvni_mac_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
3048 }
3049
3050 zvni->local_vtep_ip = vxl->vtep_ip;
3051 zvni->vxlan_if = ifp;
3052
3053 /* Take further actions needed. Note that if we are here, there is a
3054 * change of interest.
3055 */
3056 /* If down or not mapped to a bridge, we're done. */
3057 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3058 return 0;
3059
3060 /* Inform BGP, if there is a change of interest. */
3061 if (chgflags
3062 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
3063 zvni_send_add_to_client(zvrf, zvni);
3064
3065 /* If there is a valid new master or a VLAN mapping change, read and
3066 * populate local MACs and neighbors. Also, reinstall any remote MACs
3067 * and neighbors for this VNI (based on new VLAN).
3068 */
3069 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
3070 zvni_read_mac_neigh(zvrf, zvni, ifp);
3071 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
3072 struct mac_walk_ctx m_wctx;
3073 struct neigh_walk_ctx n_wctx;
3074
3075 zvni_read_mac_neigh(zvrf, zvni, ifp);
3076
3077 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
3078 m_wctx.zvni = zvni;
3079 hash_iterate(zvni->mac_table, zvni_install_mac_hash, &m_wctx);
3080
3081 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
3082 n_wctx.zvni = zvni;
3083 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
3084 &n_wctx);
3085 }
3086
3087 return 0;
13d60d35 3088}
3089
3090/*
3091 * Handle VxLAN interface add.
3092 */
d62a17ae 3093int zebra_vxlan_if_add(struct interface *ifp)
13d60d35 3094{
d62a17ae 3095 struct zebra_if *zif;
3096 struct zebra_vrf *zvrf;
3097 zebra_vni_t *zvni;
3098 struct zebra_l2info_vxlan *vxl;
3099 vni_t vni;
13d60d35 3100
d62a17ae 3101 /* Locate VRF corresponding to interface. */
3102 zvrf = vrf_info_lookup(ifp->vrf_id);
3103 assert(zvrf);
13d60d35 3104
d62a17ae 3105 /* If EVPN is not enabled, nothing further to be done. */
3106 if (!EVPN_ENABLED(zvrf))
3107 return 0;
13d60d35 3108
d62a17ae 3109 zif = ifp->info;
3110 assert(zif);
3111 vxl = &zif->l2info.vxl;
3112 vni = vxl->vni;
13d60d35 3113
d62a17ae 3114 if (IS_ZEBRA_DEBUG_VXLAN)
3115 zlog_debug(
3116 "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
3117 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
3118 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
3119 zif->brslave_info.bridge_ifindex);
13d60d35 3120
d62a17ae 3121 /* Create or update VNI hash. */
3122 zvni = zvni_lookup(zvrf, vni);
3123 if (!zvni) {
3124 zvni = zvni_add(zvrf, vni);
3125 if (!zvni) {
3126 zlog_err(
3127 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
3128 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3129 return -1;
3130 }
3131 }
13d60d35 3132
d62a17ae 3133 zvni->local_vtep_ip = vxl->vtep_ip;
3134 zvni->vxlan_if = ifp;
13d60d35 3135
d62a17ae 3136 /* If down or not mapped to a bridge, we're done. */
3137 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3138 return 0;
13d60d35 3139
d62a17ae 3140 /* Inform BGP */
3141 zvni_send_add_to_client(zvrf, zvni);
13d60d35 3142
d62a17ae 3143 /* Read and populate local MACs and neighbors */
3144 zvni_read_mac_neigh(zvrf, zvni, ifp);
2232a77c 3145
d62a17ae 3146 return 0;
13d60d35 3147}
3148
3149/*
3150 * Handle message from client to learn (or stop learning) about VNIs and MACs.
3151 * When enabled, the VNI hash table will be built and MAC FDB table read;
3152 * when disabled, the entries should be deleted and remote VTEPs and MACs
3153 * uninstalled from the kernel.
3154 */
d62a17ae 3155int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
3156 u_short length, struct zebra_vrf *zvrf)
13d60d35 3157{
d62a17ae 3158 struct stream *s;
3159 int advertise;
13d60d35 3160
d62a17ae 3161 s = client->ibuf;
3162 advertise = stream_getc(s);
13d60d35 3163
d62a17ae 3164 if (IS_ZEBRA_DEBUG_VXLAN)
3165 zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf),
3166 advertise ? "enabled" : "disabled",
3167 EVPN_ENABLED(zvrf) ? "enabled" : "disabled");
13d60d35 3168
d62a17ae 3169 if (zvrf->advertise_all_vni == advertise)
3170 return 0;
13d60d35 3171
d62a17ae 3172 zvrf->advertise_all_vni = advertise;
3173 if (EVPN_ENABLED(zvrf)) {
3174 /* Build VNI hash table and inform BGP. */
3175 zvni_build_hash_table(zvrf);
2232a77c 3176
d62a17ae 3177 /* Read the MAC FDB */
3178 macfdb_read(zvrf->zns);
2232a77c 3179
d62a17ae 3180 /* Read neighbors */
3181 neigh_read(zvrf->zns);
3182 } else {
3183 /* Cleanup VTEPs for all VNIs - uninstall from
3184 * kernel and free entries.
3185 */
3186 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
3187 }
13d60d35 3188
d62a17ae 3189 return 0;
13d60d35 3190}
3191
3192/*
3193 * Allocate VNI hash table for this VRF and do other initialization.
3194 * NOTE: Currently supported only for default VRF.
3195 */
d62a17ae 3196void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
13d60d35 3197{
d62a17ae 3198 if (!zvrf)
3199 return;
3200 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
3201 "Zebra VRF VNI Table");
13d60d35 3202}
3203
3204/* Close all VNI handling */
d62a17ae 3205void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
13d60d35 3206{
d62a17ae 3207 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
13d60d35 3208}