]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vxlan.c
*: add git-reindent-branch.py
[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);
472 stream_put(s, macaddr->octet, ETHER_ADDR_LEN);
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;
779 char *pnt = (char *)pmac->macaddr.octet;
780 unsigned int key = 0;
781 int c = 0;
2232a77c 782
d62a17ae 783 key += pnt[c];
784 key += pnt[c + 1];
785 key += pnt[c + 2];
786 key += pnt[c + 3];
787 key += pnt[c + 4];
788 key += pnt[c + 5];
2232a77c 789
d62a17ae 790 return (key);
2232a77c 791}
13d60d35 792
2232a77c 793/*
794 * Compare two MAC addresses.
795 */
d62a17ae 796static int mac_cmp(const void *p1, const void *p2)
2232a77c 797{
d62a17ae 798 const zebra_mac_t *pmac1 = p1;
799 const zebra_mac_t *pmac2 = p2;
2232a77c 800
d62a17ae 801 if (pmac1 == NULL && pmac2 == NULL)
802 return 1;
2232a77c 803
d62a17ae 804 if (pmac1 == NULL || pmac2 == NULL)
805 return 0;
2232a77c 806
d62a17ae 807 return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet,
808 ETHER_ADDR_LEN)
809 == 0);
2232a77c 810}
811
812/*
813 * Callback to allocate MAC hash entry.
814 */
d62a17ae 815static void *zvni_mac_alloc(void *p)
2232a77c 816{
d62a17ae 817 const zebra_mac_t *tmp_mac = p;
818 zebra_mac_t *mac;
2232a77c 819
d62a17ae 820 mac = XCALLOC(MTYPE_MAC, sizeof(zebra_mac_t));
821 *mac = *tmp_mac;
2232a77c 822
d62a17ae 823 return ((void *)mac);
2232a77c 824}
825
826/*
827 * Add MAC entry.
828 */
d62a17ae 829static zebra_mac_t *zvni_mac_add(zebra_vni_t *zvni, struct ethaddr *macaddr)
2232a77c 830{
d62a17ae 831 zebra_mac_t tmp_mac;
832 zebra_mac_t *mac = NULL;
2232a77c 833
d62a17ae 834 memset(&tmp_mac, 0, sizeof(zebra_mac_t));
835 memcpy(&tmp_mac.macaddr, macaddr, ETHER_ADDR_LEN);
836 mac = hash_get(zvni->mac_table, &tmp_mac, zvni_mac_alloc);
837 assert(mac);
2232a77c 838
d62a17ae 839 return mac;
2232a77c 840}
841
842/*
843 * Delete MAC entry.
844 */
d62a17ae 845static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac)
2232a77c 846{
d62a17ae 847 zebra_mac_t *tmp_mac;
2232a77c 848
d62a17ae 849 /* Free the VNI hash entry and allocated memory. */
850 tmp_mac = hash_release(zvni->mac_table, mac);
851 if (tmp_mac)
852 XFREE(MTYPE_MAC, tmp_mac);
2232a77c 853
d62a17ae 854 return 0;
2232a77c 855}
856
857/*
858 * Free MAC hash entry (callback)
859 */
d62a17ae 860static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
2232a77c 861{
d62a17ae 862 struct mac_walk_ctx *wctx = arg;
863 zebra_mac_t *mac = backet->data;
864 u_char sticky = 0;
2232a77c 865
d62a17ae 866 if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
867 || ((wctx->flags & DEL_REMOTE_MAC)
868 && (mac->flags & ZEBRA_MAC_REMOTE))
869 || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP)
870 && (mac->flags & ZEBRA_MAC_REMOTE)
871 && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
872 &wctx->r_vtep_ip))) {
873 if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
874 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
875 : 0;
876 zvni_mac_send_del_to_client(wctx->zvrf, wctx->zvni->vni,
877 &mac->macaddr, sticky);
878 }
2232a77c 879
d62a17ae 880 if (wctx->uninstall)
881 zvni_mac_uninstall(wctx->zvni, mac, 0);
2232a77c 882
d62a17ae 883 return zvni_mac_del(wctx->zvni, mac);
884 }
2232a77c 885
d62a17ae 886 return 0;
2232a77c 887}
888
889/*
890 * Delete all MAC entries from specific VTEP for a particular VNI.
891 */
d62a17ae 892static void zvni_mac_del_from_vtep(zebra_vni_t *zvni, int uninstall,
893 struct in_addr *r_vtep_ip)
2232a77c 894{
d62a17ae 895 struct mac_walk_ctx wctx;
2232a77c 896
d62a17ae 897 if (!zvni->mac_table)
898 return;
2232a77c 899
d62a17ae 900 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
901 wctx.zvni = zvni;
902 wctx.uninstall = uninstall;
903 wctx.flags = DEL_REMOTE_MAC_FROM_VTEP;
904 wctx.r_vtep_ip = *r_vtep_ip;
2232a77c 905
c14777c6 906 hash_iterate(
907 zvni->mac_table,
908 (void (*)(struct hash_backet *, void *))zvni_mac_del_hash_entry,
909 &wctx);
2232a77c 910}
911
912/*
913 * Delete all MAC entries for this VNI.
914 */
d62a17ae 915static void zvni_mac_del_all(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
916 int uninstall, int upd_client, u_int32_t flags)
2232a77c 917{
d62a17ae 918 struct mac_walk_ctx wctx;
2232a77c 919
d62a17ae 920 if (!zvni->mac_table)
921 return;
2232a77c 922
d62a17ae 923 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
924 wctx.zvni = zvni;
925 wctx.zvrf = zvrf;
926 wctx.uninstall = uninstall;
927 wctx.upd_client = upd_client;
928 wctx.flags = flags;
2232a77c 929
c14777c6 930 hash_iterate(
931 zvni->mac_table,
932 (void (*)(struct hash_backet *, void *))zvni_mac_del_hash_entry,
933 &wctx);
2232a77c 934}
935
936/*
937 * Look up MAC hash entry.
938 */
d62a17ae 939static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
2232a77c 940{
d62a17ae 941 zebra_mac_t tmp;
942 zebra_mac_t *pmac;
2232a77c 943
d62a17ae 944 memset(&tmp, 0, sizeof(tmp));
945 memcpy(&tmp.macaddr, mac, ETHER_ADDR_LEN);
946 pmac = hash_lookup(zvni->mac_table, &tmp);
2232a77c 947
d62a17ae 948 return pmac;
2232a77c 949}
950
951/*
952 * Inform BGP about local MAC addition.
953 */
d62a17ae 954static int zvni_mac_send_add_to_client(struct zebra_vrf *zvrf, vni_t vni,
955 struct ethaddr *macaddr, u_char sticky)
2232a77c 956{
d62a17ae 957 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, sticky,
958 ZEBRA_MACIP_ADD);
2232a77c 959}
960
961/*
962 * Inform BGP about local MAC deletion.
963 */
d62a17ae 964static int zvni_mac_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni,
965 struct ethaddr *macaddr, u_char sticky)
2232a77c 966{
d62a17ae 967 return zvni_macip_send_msg_to_client(zvrf, vni, macaddr, NULL, sticky,
968 ZEBRA_MACIP_DEL);
2232a77c 969}
970
971/*
972 * Map port or (port, VLAN) to a VNI. This is invoked upon getting MAC
973 * notifications, to see if there are of interest.
974 * TODO: Need to make this as a hash table.
975 */
d62a17ae 976static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
977 struct interface *br_if, vlanid_t vid)
2232a77c 978{
d62a17ae 979 struct zebra_vrf *zvrf;
980 struct listnode *node;
981 struct interface *tmp_if;
982 struct zebra_if *zif;
983 struct zebra_l2info_bridge *br;
984 struct zebra_l2info_vxlan *vxl;
985 u_char bridge_vlan_aware;
986 zebra_vni_t *zvni;
2232a77c 987
d62a17ae 988 /* Locate VRF corresponding to interface. */
989 zvrf = vrf_info_lookup(ifp->vrf_id);
990 assert(zvrf);
2232a77c 991
d62a17ae 992 /* Determine if bridge is VLAN-aware or not */
993 zif = br_if->info;
994 assert(zif);
995 br = &zif->l2info.br;
996 bridge_vlan_aware = br->vlan_aware;
2232a77c 997
d62a17ae 998 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
999 /* TODO: Optimize with a hash. */
1000 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1001 zif = tmp_if->info;
1002 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1003 continue;
1004 if (!if_is_operative(tmp_if))
1005 continue;
1006 vxl = &zif->l2info.vxl;
2232a77c 1007
d62a17ae 1008 if (zif->brslave_info.br_if != br_if)
1009 continue;
2232a77c 1010
d62a17ae 1011 if (!bridge_vlan_aware)
1012 break;
2232a77c 1013
d62a17ae 1014 if (vxl->access_vlan == vid)
1015 break;
1016 }
2232a77c 1017
d62a17ae 1018 if (!tmp_if)
1019 return NULL;
2232a77c 1020
d62a17ae 1021 zvni = zvni_lookup(zvrf, vxl->vni);
1022 return zvni;
2232a77c 1023}
1024
1025/*
1026 * Map SVI and associated bridge to a VNI. This is invoked upon getting
1027 * neighbor notifications, to see if they are of interest.
1028 * TODO: Need to make this as a hash table.
1029 */
d62a17ae 1030static zebra_vni_t *zvni_map_svi(struct interface *ifp, struct interface *br_if)
1031{
1032 struct zebra_vrf *zvrf;
1033 struct listnode *node;
1034 struct interface *tmp_if;
1035 struct zebra_if *zif;
1036 struct zebra_l2info_bridge *br;
1037 struct zebra_l2info_vxlan *vxl;
1038 u_char bridge_vlan_aware;
1039 vlanid_t vid = 0;
1040 zebra_vni_t *zvni;
1041
1042 /* Make sure the linked interface is a bridge. */
1043 if (!IS_ZEBRA_IF_BRIDGE(br_if))
1044 return NULL;
1045
1046 /* Locate VRF corresponding to interface. */
1047 zvrf = vrf_info_lookup(ifp->vrf_id);
1048 assert(zvrf);
1049
1050 /* Determine if bridge is VLAN-aware or not */
1051 zif = br_if->info;
1052 assert(zif);
1053 br = &zif->l2info.br;
1054 bridge_vlan_aware = br->vlan_aware;
1055 if (bridge_vlan_aware) {
1056 struct zebra_l2info_vlan *vl;
1057
1058 if (!IS_ZEBRA_IF_VLAN(ifp))
1059 return NULL;
1060
1061 zif = ifp->info;
1062 assert(zif);
1063 vl = &zif->l2info.vl;
1064 vid = vl->vid;
1065 }
1066
1067 /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
1068 /* TODO: Optimize with a hash. */
1069 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1070 zif = tmp_if->info;
1071 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1072 continue;
1073 if (!if_is_operative(tmp_if))
1074 continue;
1075 vxl = &zif->l2info.vxl;
1076
1077 if (zif->brslave_info.br_if != br_if)
1078 continue;
1079
1080 if (!bridge_vlan_aware)
1081 break;
1082
1083 if (vxl->access_vlan == vid)
1084 break;
1085 }
1086
1087 if (!tmp_if)
1088 return NULL;
1089
1090 zvni = zvni_lookup(zvrf, vxl->vni);
1091 return zvni;
2232a77c 1092}
1093
1094/* Map to SVI on bridge corresponding to specified VLAN. This can be one
1095 * of two cases:
1096 * (a) In the case of a VLAN-aware bridge, the SVI is a L3 VLAN interface
1097 * linked to the bridge
1098 * (b) In the case of a VLAN-unaware bridge, the SVI is the bridge inteface
1099 * itself
1100 */
d62a17ae 1101static struct interface *zvni_map_to_svi(struct zebra_vrf *zvrf, vlanid_t vid,
1102 struct interface *br_if)
1103{
1104 struct listnode *node;
1105 struct interface *tmp_if;
1106 struct zebra_if *zif;
1107 struct zebra_l2info_bridge *br;
1108 struct zebra_l2info_vlan *vl;
1109 u_char bridge_vlan_aware;
1110
1111 /* Determine if bridge is VLAN-aware or not */
1112 zif = br_if->info;
1113 assert(zif);
1114 br = &zif->l2info.br;
1115 bridge_vlan_aware = br->vlan_aware;
1116
1117 /* Check oper status of the SVI. */
1118 if (!bridge_vlan_aware)
1119 return if_is_operative(br_if) ? br_if : NULL;
1120
1121 /* Identify corresponding VLAN interface. */
1122 /* TODO: Optimize with a hash. */
1123 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, tmp_if)) {
1124 /* Check oper status of the SVI. */
1125 if (!if_is_operative(tmp_if))
1126 continue;
1127 zif = tmp_if->info;
1128 if (!zif || zif->zif_type != ZEBRA_IF_VLAN
1129 || zif->link != br_if)
1130 continue;
1131 vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
1132
1133 if (vl->vid == vid)
1134 break;
1135 }
1136
1137 return tmp_if;
2232a77c 1138}
1139
1140/*
1141 * Install remote MAC into the kernel.
1142 */
d62a17ae 1143static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac)
2232a77c 1144{
d62a17ae 1145 struct zebra_if *zif;
1146 struct zebra_l2info_vxlan *vxl;
1147 u_char sticky;
2232a77c 1148
d62a17ae 1149 if (!(mac->flags & ZEBRA_MAC_REMOTE))
1150 return 0;
2232a77c 1151
d62a17ae 1152 zif = zvni->vxlan_if->info;
1153 if (!zif)
1154 return -1;
1155 vxl = &zif->l2info.vxl;
2232a77c 1156
d62a17ae 1157 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
c85c03c7 1158
d62a17ae 1159 return kernel_add_mac(zvni->vxlan_if, vxl->access_vlan, &mac->macaddr,
1160 mac->fwd_info.r_vtep_ip, sticky);
2232a77c 1161}
1162
1163/*
1164 * Uninstall remote MAC from the kernel. In the scenario where the MAC
1165 * moves to remote, we have to uninstall any existing local entry first.
1166 */
d62a17ae 1167static int zvni_mac_uninstall(zebra_vni_t *zvni, zebra_mac_t *mac, int local)
2232a77c 1168{
d62a17ae 1169 struct zebra_if *zif;
1170 struct zebra_l2info_vxlan *vxl;
1171 struct in_addr vtep_ip = {.s_addr = 0};
1172 struct zebra_ns *zns;
1173 struct interface *ifp;
2232a77c 1174
d62a17ae 1175 if (!local && !(mac->flags & ZEBRA_MAC_REMOTE))
1176 return 0;
2232a77c 1177
d62a17ae 1178 if (!zvni->vxlan_if) {
1179 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1180 zvni->vni, zvni);
1181 return -1;
1182 }
2232a77c 1183
d62a17ae 1184 zif = zvni->vxlan_if->info;
1185 if (!zif)
1186 return -1;
1187 vxl = &zif->l2info.vxl;
2232a77c 1188
d62a17ae 1189 if (local) {
1190 zns = zebra_ns_lookup(NS_DEFAULT);
1191 ifp = if_lookup_by_index_per_ns(zns,
1192 mac->fwd_info.local.ifindex);
1193 if (!ifp) // unexpected
1194 return -1;
1195 } else {
1196 ifp = zvni->vxlan_if;
1197 vtep_ip = mac->fwd_info.r_vtep_ip;
1198 }
2232a77c 1199
d62a17ae 1200 return kernel_del_mac(ifp, vxl->access_vlan, &mac->macaddr, vtep_ip,
1201 local);
2232a77c 1202}
1203
1204/*
1205 * Install MAC hash entry - called upon access VLAN change.
1206 */
d62a17ae 1207static void zvni_install_mac_hash(struct hash_backet *backet, void *ctxt)
2232a77c 1208{
d62a17ae 1209 zebra_mac_t *mac;
1210 struct mac_walk_ctx *wctx = ctxt;
2232a77c 1211
d62a17ae 1212 mac = (zebra_mac_t *)backet->data;
1213 if (!mac)
1214 return;
2232a77c 1215
d62a17ae 1216 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
1217 zvni_mac_install(wctx->zvni, mac);
2232a77c 1218}
1219
1220/*
1221 * Decrement neighbor refcount of MAC; uninstall and free it if
1222 * appropriate.
1223 */
d62a17ae 1224static void zvni_deref_ip2mac(zebra_vni_t *zvni, zebra_mac_t *mac,
1225 int uninstall)
2232a77c 1226{
d62a17ae 1227 if (mac->neigh_refcnt)
1228 mac->neigh_refcnt--;
2232a77c 1229
d62a17ae 1230 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) || mac->neigh_refcnt > 0)
1231 return;
2232a77c 1232
d62a17ae 1233 if (uninstall)
1234 zvni_mac_uninstall(zvni, mac, 0);
2232a77c 1235
d62a17ae 1236 zvni_mac_del(zvni, mac);
2232a77c 1237}
1238
1239/*
1240 * Read and populate local MACs and neighbors corresponding to this VNI.
1241 */
d62a17ae 1242static void zvni_read_mac_neigh(struct zebra_vrf *zvrf, zebra_vni_t *zvni,
1243 struct interface *ifp)
2232a77c 1244{
d62a17ae 1245 struct zebra_if *zif;
1246 struct interface *vlan_if;
1247 struct zebra_l2info_vxlan *vxl;
2232a77c 1248
d62a17ae 1249 zif = ifp->info;
1250 vxl = &zif->l2info.vxl;
2232a77c 1251
d62a17ae 1252 if (IS_ZEBRA_DEBUG_VXLAN)
1253 zlog_debug(
1254 "%u:Reading MAC FDB and Neighbors for intf %s(%u) VNI %u master %u",
1255 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni,
1256 zif->brslave_info.bridge_ifindex);
2232a77c 1257
d62a17ae 1258 macfdb_read_for_bridge(zvrf->zns, ifp, zif->brslave_info.br_if);
1259 vlan_if = zvni_map_to_svi(zvrf, vxl->access_vlan,
1260 zif->brslave_info.br_if);
1261 if (vlan_if)
1262 neigh_read_for_vlan(zvrf->zns, vlan_if);
2232a77c 1263}
1264
1265/*
1266 * Hash function for VNI.
1267 */
d62a17ae 1268static unsigned int vni_hash_keymake(void *p)
2232a77c 1269{
d62a17ae 1270 const zebra_vni_t *zvni = p;
2232a77c 1271
d62a17ae 1272 return (jhash_1word(zvni->vni, 0));
2232a77c 1273}
1274
1275/*
1276 * Compare 2 VNI hash entries.
1277 */
d62a17ae 1278static int vni_hash_cmp(const void *p1, const void *p2)
2232a77c 1279{
d62a17ae 1280 const zebra_vni_t *zvni1 = p1;
1281 const zebra_vni_t *zvni2 = p2;
2232a77c 1282
d62a17ae 1283 return (zvni1->vni == zvni2->vni);
2232a77c 1284}
1285
1286/*
1287 * Callback to allocate VNI hash entry.
1288 */
d62a17ae 1289static void *zvni_alloc(void *p)
2232a77c 1290{
d62a17ae 1291 const zebra_vni_t *tmp_vni = p;
1292 zebra_vni_t *zvni;
2232a77c 1293
d62a17ae 1294 zvni = XCALLOC(MTYPE_ZVNI, sizeof(zebra_vni_t));
1295 zvni->vni = tmp_vni->vni;
1296 return ((void *)zvni);
2232a77c 1297}
1298
1299/*
1300 * Look up VNI hash entry.
1301 */
d62a17ae 1302static zebra_vni_t *zvni_lookup(struct zebra_vrf *zvrf, vni_t vni)
2232a77c 1303{
d62a17ae 1304 zebra_vni_t tmp_vni;
1305 zebra_vni_t *zvni = NULL;
2232a77c 1306
d62a17ae 1307 memset(&tmp_vni, 0, sizeof(zebra_vni_t));
1308 tmp_vni.vni = vni;
1309 zvni = hash_lookup(zvrf->vni_table, &tmp_vni);
2232a77c 1310
d62a17ae 1311 return zvni;
2232a77c 1312}
1313
1314/*
1315 * Add VNI hash entry.
1316 */
d62a17ae 1317static zebra_vni_t *zvni_add(struct zebra_vrf *zvrf, vni_t vni)
2232a77c 1318{
d62a17ae 1319 zebra_vni_t tmp_zvni;
1320 zebra_vni_t *zvni = NULL;
2232a77c 1321
d62a17ae 1322 memset(&tmp_zvni, 0, sizeof(zebra_vni_t));
1323 tmp_zvni.vni = vni;
1324 zvni = hash_get(zvrf->vni_table, &tmp_zvni, zvni_alloc);
1325 assert(zvni);
2232a77c 1326
d62a17ae 1327 /* Create hash table for MAC */
1328 zvni->mac_table =
1329 hash_create(mac_hash_keymake, mac_cmp, "Zebra VNI MAC Table");
2232a77c 1330
d62a17ae 1331 /* Create hash table for neighbors */
1332 zvni->neigh_table = hash_create(neigh_hash_keymake, neigh_cmp,
1333 "Zebra VNI Neighbor Table");
2232a77c 1334
d62a17ae 1335 return zvni;
2232a77c 1336}
1337
1338/*
1339 * Delete VNI hash entry.
1340 */
d62a17ae 1341static int zvni_del(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
2232a77c 1342{
d62a17ae 1343 zebra_vni_t *tmp_zvni;
2232a77c 1344
d62a17ae 1345 zvni->vxlan_if = NULL;
2232a77c 1346
d62a17ae 1347 /* Free the neighbor hash table. */
1348 hash_free(zvni->neigh_table);
1349 zvni->neigh_table = NULL;
2232a77c 1350
d62a17ae 1351 /* Free the MAC hash table. */
1352 hash_free(zvni->mac_table);
1353 zvni->mac_table = NULL;
2232a77c 1354
d62a17ae 1355 /* Free the VNI hash entry and allocated memory. */
1356 tmp_zvni = hash_release(zvrf->vni_table, zvni);
1357 if (tmp_zvni)
1358 XFREE(MTYPE_ZVNI, tmp_zvni);
2232a77c 1359
d62a17ae 1360 return 0;
2232a77c 1361}
1362
1363/*
1364 * Inform BGP about local VNI addition.
1365 */
d62a17ae 1366static int zvni_send_add_to_client(struct zebra_vrf *zvrf, zebra_vni_t *zvni)
2232a77c 1367{
d62a17ae 1368 struct zserv *client;
1369 struct stream *s;
2232a77c 1370
d62a17ae 1371 client = zebra_find_client(ZEBRA_ROUTE_BGP);
1372 /* BGP may not be running. */
1373 if (!client)
1374 return 0;
2232a77c 1375
d62a17ae 1376 s = client->obuf;
1377 stream_reset(s);
2232a77c 1378
d62a17ae 1379 zserv_create_header(s, ZEBRA_VNI_ADD, zvrf_id(zvrf));
1380 stream_putl(s, zvni->vni);
1381 stream_put_in_addr(s, &zvni->local_vtep_ip);
2232a77c 1382
d62a17ae 1383 /* Write packet size. */
1384 stream_putw_at(s, 0, stream_get_endp(s));
2232a77c 1385
d62a17ae 1386 if (IS_ZEBRA_DEBUG_VXLAN)
1387 zlog_debug("%u:Send VNI_ADD %u %s to %s", zvrf_id(zvrf),
1388 zvni->vni, inet_ntoa(zvni->local_vtep_ip),
1389 zebra_route_string(client->proto));
2232a77c 1390
d62a17ae 1391 client->vniadd_cnt++;
1392 return zebra_server_send_message(client);
2232a77c 1393}
1394
1395/*
1396 * Inform BGP about local VNI deletion.
1397 */
d62a17ae 1398static int zvni_send_del_to_client(struct zebra_vrf *zvrf, vni_t vni)
2232a77c 1399{
d62a17ae 1400 struct zserv *client;
1401 struct stream *s;
2232a77c 1402
d62a17ae 1403 client = zebra_find_client(ZEBRA_ROUTE_BGP);
1404 /* BGP may not be running. */
1405 if (!client)
1406 return 0;
2232a77c 1407
d62a17ae 1408 s = client->obuf;
1409 stream_reset(s);
2232a77c 1410
d62a17ae 1411 zserv_create_header(s, ZEBRA_VNI_DEL, zvrf_id(zvrf));
1412 stream_putl(s, vni);
2232a77c 1413
d62a17ae 1414 /* Write packet size. */
1415 stream_putw_at(s, 0, stream_get_endp(s));
2232a77c 1416
d62a17ae 1417 if (IS_ZEBRA_DEBUG_VXLAN)
1418 zlog_debug("%u:Send VNI_DEL %u to %s", zvrf_id(zvrf), vni,
1419 zebra_route_string(client->proto));
2232a77c 1420
d62a17ae 1421 client->vnidel_cnt++;
1422 return zebra_server_send_message(client);
2232a77c 1423}
1424
1425/*
1426 * Build the VNI hash table by going over the VxLAN interfaces. This
1427 * is called when EVPN (advertise-all-vni) is enabled.
1428 */
d62a17ae 1429static void zvni_build_hash_table(struct zebra_vrf *zvrf)
2232a77c 1430{
d62a17ae 1431 struct listnode *node;
1432 struct interface *ifp;
2232a77c 1433
d62a17ae 1434 /* Walk VxLAN interfaces and create VNI hash. */
1435 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(zvrf_id(zvrf)), node, ifp)) {
1436 struct zebra_if *zif;
1437 struct zebra_l2info_vxlan *vxl;
1438 zebra_vni_t *zvni;
1439 vni_t vni;
2232a77c 1440
d62a17ae 1441 zif = ifp->info;
1442 if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
1443 continue;
1444 vxl = &zif->l2info.vxl;
2232a77c 1445
d62a17ae 1446 vni = vxl->vni;
2232a77c 1447
d62a17ae 1448 if (IS_ZEBRA_DEBUG_VXLAN)
1449 zlog_debug(
1450 "%u:Create VNI hash for intf %s(%u) VNI %u local IP %s",
1451 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni,
1452 inet_ntoa(vxl->vtep_ip));
2232a77c 1453
d62a17ae 1454 /* VNI hash entry is not expected to exist. */
1455 zvni = zvni_lookup(zvrf, vni);
1456 if (zvni) {
1457 zlog_err(
1458 "VNI hash already present for VRF %d IF %s(%u) VNI %u",
1459 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
1460 continue;
1461 }
2232a77c 1462
d62a17ae 1463 zvni = zvni_add(zvrf, vni);
1464 if (!zvni) {
1465 zlog_err(
1466 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
1467 zvrf_id(zvrf), ifp->name, ifp->ifindex, vni);
1468 return;
1469 }
2232a77c 1470
d62a17ae 1471 zvni->local_vtep_ip = vxl->vtep_ip;
1472 zvni->vxlan_if = ifp;
2232a77c 1473
d62a17ae 1474 /* Inform BGP if interface is up and mapped to bridge. */
1475 if (if_is_operative(ifp) && zif->brslave_info.br_if)
1476 zvni_send_add_to_client(zvrf, zvni);
1477 }
2232a77c 1478}
1479
1480/*
1481 * See if remote VTEP matches with prefix.
1482 */
d62a17ae 1483static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep)
2232a77c 1484{
d62a17ae 1485 return (IPV4_ADDR_SAME(vtep_ip, &zvtep->vtep_ip));
2232a77c 1486}
1487
1488/*
1489 * Locate remote VTEP in VNI hash table.
1490 */
d62a17ae 1491static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1492{
d62a17ae 1493 zebra_vtep_t *zvtep;
2232a77c 1494
d62a17ae 1495 if (!zvni)
1496 return NULL;
2232a77c 1497
d62a17ae 1498 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
1499 if (zvni_vtep_match(vtep_ip, zvtep))
1500 break;
1501 }
2232a77c 1502
d62a17ae 1503 return zvtep;
2232a77c 1504}
1505
1506/*
1507 * Add remote VTEP to VNI hash table.
1508 */
d62a17ae 1509static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1510{
d62a17ae 1511 zebra_vtep_t *zvtep;
2232a77c 1512
d62a17ae 1513 zvtep = XCALLOC(MTYPE_ZVNI_VTEP, sizeof(zebra_vtep_t));
1514 if (!zvtep) {
1515 zlog_err("Failed to alloc VTEP entry, VNI %u", zvni->vni);
1516 return NULL;
1517 }
2232a77c 1518
d62a17ae 1519 zvtep->vtep_ip = *vtep_ip;
2232a77c 1520
d62a17ae 1521 if (zvni->vteps)
1522 zvni->vteps->prev = zvtep;
1523 zvtep->next = zvni->vteps;
1524 zvni->vteps = zvtep;
2232a77c 1525
d62a17ae 1526 return zvtep;
2232a77c 1527}
1528
1529/*
1530 * Remove remote VTEP from VNI hash table.
1531 */
d62a17ae 1532static int zvni_vtep_del(zebra_vni_t *zvni, zebra_vtep_t *zvtep)
2232a77c 1533{
d62a17ae 1534 if (zvtep->next)
1535 zvtep->next->prev = zvtep->prev;
1536 if (zvtep->prev)
1537 zvtep->prev->next = zvtep->next;
1538 else
1539 zvni->vteps = zvtep->next;
2232a77c 1540
d62a17ae 1541 zvtep->prev = zvtep->next = NULL;
1542 XFREE(MTYPE_ZVNI_VTEP, zvtep);
2232a77c 1543
d62a17ae 1544 return 0;
2232a77c 1545}
1546
1547/*
1548 * Delete all remote VTEPs for this VNI (upon VNI delete). Also
1549 * uninstall from kernel if asked to.
1550 */
d62a17ae 1551static int zvni_vtep_del_all(zebra_vni_t *zvni, int uninstall)
2232a77c 1552{
d62a17ae 1553 zebra_vtep_t *zvtep, *zvtep_next;
2232a77c 1554
d62a17ae 1555 if (!zvni)
1556 return -1;
2232a77c 1557
d62a17ae 1558 for (zvtep = zvni->vteps; zvtep; zvtep = zvtep_next) {
1559 zvtep_next = zvtep->next;
1560 if (uninstall)
1561 zvni_vtep_uninstall(zvni, &zvtep->vtep_ip);
1562 zvni_vtep_del(zvni, zvtep);
1563 }
2232a77c 1564
d62a17ae 1565 return 0;
2232a77c 1566}
1567
1568/*
1569 * Install remote VTEP into the kernel.
1570 */
d62a17ae 1571static int zvni_vtep_install(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1572{
d62a17ae 1573 return kernel_add_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2232a77c 1574}
1575
1576/*
1577 * Uninstall remote VTEP from the kernel.
1578 */
d62a17ae 1579static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
2232a77c 1580{
d62a17ae 1581 if (!zvni->vxlan_if) {
1582 zlog_err("VNI %u hash %p couldn't be uninstalled - no intf",
1583 zvni->vni, zvni);
1584 return -1;
1585 }
2232a77c 1586
d62a17ae 1587 return kernel_del_vtep(zvni->vni, zvni->vxlan_if, vtep_ip);
2232a77c 1588}
1589
1590/*
1591 * Cleanup VNI/VTEP and update kernel
1592 */
d62a17ae 1593static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
2232a77c 1594{
d62a17ae 1595 zebra_vni_t *zvni;
2232a77c 1596
d62a17ae 1597 zvni = (zebra_vni_t *)backet->data;
1598 if (!zvni)
1599 return;
2232a77c 1600
d62a17ae 1601 /* Free up all neighbors and MACs, if any. */
1602 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
1603 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
2232a77c 1604
d62a17ae 1605 /* Free up all remote VTEPs, if any. */
1606 zvni_vtep_del_all(zvni, 1);
2232a77c 1607
d62a17ae 1608 /* Delete the hash entry. */
1609 zvni_del(zvrf, zvni);
2232a77c 1610}
1611
1612
1613/* Public functions */
1614
cec2e17d 1615/*
1616 * Display Neighbors for a VNI (VTY command handler).
1617 */
d62a17ae 1618void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
1619 vni_t vni)
1620{
1621 zebra_vni_t *zvni;
1622 u_int32_t num_neigh;
1623 struct neigh_walk_ctx wctx;
1624
1625 if (!EVPN_ENABLED(zvrf))
1626 return;
1627 zvni = zvni_lookup(zvrf, vni);
1628 if (!zvni) {
1629 vty_out(vty, "%% VNI %u does not exist\n", vni);
1630 return;
1631 }
1632 num_neigh = hashcount(zvni->neigh_table);
1633 if (!num_neigh)
1634 return;
1635
1636 /* Since we have IPv6 addresses to deal with which can vary widely in
1637 * size, we try to be a bit more elegant in display by first computing
1638 * the maximum width.
1639 */
1640 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1641 wctx.zvni = zvni;
1642 wctx.vty = vty;
1643 wctx.addr_width = 15;
1644 hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
1645
1646 vty_out(vty,
1647 "Number of ARPs (local and remote) known for this VNI: %u\n",
1648 num_neigh);
1649 vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", "Type",
1650 "MAC", "Remote VTEP");
1651
1652 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
cec2e17d 1653}
1654
1655/*
1656 * Display neighbors across all VNIs (VTY command handler).
1657 */
d62a17ae 1658void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
cec2e17d 1659{
d62a17ae 1660 if (!EVPN_ENABLED(zvrf))
1661 return;
1662 hash_iterate(zvrf->vni_table, zvni_print_neigh_hash_all_vni, vty);
cec2e17d 1663}
1664
1665/*
1666 * Display specific neighbor for a VNI, if present (VTY command handler).
1667 */
d62a17ae 1668void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
1669 struct zebra_vrf *zvrf, vni_t vni,
1670 struct ipaddr *ip)
cec2e17d 1671{
d62a17ae 1672 zebra_vni_t *zvni;
1673 zebra_neigh_t *n;
cec2e17d 1674
d62a17ae 1675 if (!EVPN_ENABLED(zvrf))
1676 return;
1677 zvni = zvni_lookup(zvrf, vni);
1678 if (!zvni) {
1679 vty_out(vty, "%% VNI %u does not exist", vni);
1680 return;
1681 }
1682 n = zvni_neigh_lookup(zvni, ip);
1683 if (!n) {
1684 vty_out(vty, "%% Requested neighbor does not exist in VNI %u\n",
1685 vni);
1686 return;
1687 }
cec2e17d 1688
d62a17ae 1689 zvni_print_neigh(n, vty);
cec2e17d 1690}
1691
1692/*
1693 * Display neighbors for a VNI from specific VTEP (VTY command handler).
1694 * By definition, these are remote neighbors.
1695 */
d62a17ae 1696void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
1697 vni_t vni, struct in_addr vtep_ip)
cec2e17d 1698{
d62a17ae 1699 zebra_vni_t *zvni;
1700 u_int32_t num_neigh;
1701 struct neigh_walk_ctx wctx;
cec2e17d 1702
d62a17ae 1703 if (!EVPN_ENABLED(zvrf))
1704 return;
1705 zvni = zvni_lookup(zvrf, vni);
1706 if (!zvni) {
1707 vty_out(vty, "%% VNI %u does not exist\n", vni);
1708 return;
1709 }
1710 num_neigh = hashcount(zvni->neigh_table);
1711 if (!num_neigh)
1712 return;
cec2e17d 1713
d62a17ae 1714 memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
1715 wctx.zvni = zvni;
1716 wctx.vty = vty;
1717 wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
1718 wctx.r_vtep_ip = vtep_ip;
cec2e17d 1719
d62a17ae 1720 hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
cec2e17d 1721}
1722
1723/*
1724 * Display MACs for a VNI (VTY command handler).
1725 */
d62a17ae 1726void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
1727 vni_t vni)
cec2e17d 1728{
d62a17ae 1729 zebra_vni_t *zvni;
1730 u_int32_t num_macs;
1731 struct mac_walk_ctx wctx;
cec2e17d 1732
d62a17ae 1733 if (!EVPN_ENABLED(zvrf))
1734 return;
1735 zvni = zvni_lookup(zvrf, vni);
1736 if (!zvni) {
1737 vty_out(vty, "%% VNI %u does not exist\n", vni);
1738 return;
1739 }
1740 num_macs = hashcount(zvni->mac_table);
1741 if (!num_macs)
1742 return;
cec2e17d 1743
d62a17ae 1744 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1745 wctx.zvni = zvni;
1746 wctx.vty = vty;
cec2e17d 1747
d62a17ae 1748 vty_out(vty,
1749 "Number of MACs (local and remote) known for this VNI: %u\n",
1750 num_macs);
1751 vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
1752 "Intf/Remote VTEP", "VLAN");
cec2e17d 1753
d62a17ae 1754 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
cec2e17d 1755}
1756
1757/*
1758 * Display MACs for all VNIs (VTY command handler).
1759 */
d62a17ae 1760void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
cec2e17d 1761{
d62a17ae 1762 struct mac_walk_ctx wctx;
cec2e17d 1763
d62a17ae 1764 if (!EVPN_ENABLED(zvrf))
1765 return;
1766 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1767 wctx.vty = vty;
1768 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
cec2e17d 1769}
1770
1771/*
1772 * Display MACs for all VNIs (VTY command handler).
1773 */
d62a17ae 1774void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
1775 struct zebra_vrf *zvrf,
1776 struct in_addr vtep_ip)
cec2e17d 1777{
d62a17ae 1778 struct mac_walk_ctx wctx;
cec2e17d 1779
d62a17ae 1780 if (!EVPN_ENABLED(zvrf))
1781 return;
1782 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1783 wctx.vty = vty;
1784 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
1785 wctx.r_vtep_ip = vtep_ip;
1786 hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
cec2e17d 1787}
1788
1789/*
1790 * Display specific MAC for a VNI, if present (VTY command handler).
1791 */
d62a17ae 1792void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
1793 vni_t vni, struct ethaddr *macaddr)
cec2e17d 1794{
d62a17ae 1795 zebra_vni_t *zvni;
1796 zebra_mac_t *mac;
cec2e17d 1797
d62a17ae 1798 if (!EVPN_ENABLED(zvrf))
1799 return;
1800 zvni = zvni_lookup(zvrf, vni);
1801 if (!zvni) {
1802 vty_out(vty, "%% VNI %u does not exist\n", vni);
1803 return;
1804 }
1805 mac = zvni_mac_lookup(zvni, macaddr);
1806 if (!mac) {
1807 vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
1808 vni);
1809 return;
1810 }
cec2e17d 1811
d62a17ae 1812 zvni_print_mac(mac, vty);
cec2e17d 1813}
1814
1815/*
1816 * Display MACs for a VNI from specific VTEP (VTY command handler).
1817 */
d62a17ae 1818void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
1819 vni_t vni, struct in_addr vtep_ip)
cec2e17d 1820{
d62a17ae 1821 zebra_vni_t *zvni;
1822 u_int32_t num_macs;
1823 struct mac_walk_ctx wctx;
cec2e17d 1824
d62a17ae 1825 if (!EVPN_ENABLED(zvrf))
1826 return;
1827 zvni = zvni_lookup(zvrf, vni);
1828 if (!zvni) {
1829 vty_out(vty, "%% VNI %u does not exist\n", vni);
1830 return;
1831 }
1832 num_macs = hashcount(zvni->mac_table);
1833 if (!num_macs)
1834 return;
1835 memset(&wctx, 0, sizeof(struct mac_walk_ctx));
1836 wctx.zvni = zvni;
1837 wctx.vty = vty;
1838 wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
1839 wctx.r_vtep_ip = vtep_ip;
1840 hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
cec2e17d 1841}
1842
1843
1844/*
1845 * Display VNI information (VTY command handler).
1846 */
d62a17ae 1847void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni)
cec2e17d 1848{
d62a17ae 1849 zebra_vni_t *zvni;
cec2e17d 1850
d62a17ae 1851 if (!EVPN_ENABLED(zvrf))
1852 return;
1853 zvni = zvni_lookup(zvrf, vni);
1854 if (!zvni) {
1855 vty_out(vty, "%% VNI %u does not exist\n", vni);
1856 return;
1857 }
1858 zvni_print(zvni, (void *)vty);
cec2e17d 1859}
1860
1861/*
1862 * Display VNI hash table (VTY command handler).
1863 */
d62a17ae 1864void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf)
cec2e17d 1865{
d62a17ae 1866 u_int32_t num_vnis;
cec2e17d 1867
d62a17ae 1868 if (!EVPN_ENABLED(zvrf))
1869 return;
1870 num_vnis = hashcount(zvrf->vni_table);
1871 if (!num_vnis)
1872 return;
1873 vty_out(vty, "Number of VNIs: %u\n", num_vnis);
1874 vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI", "VxLAN IF",
1875 "VTEP IP", "# MACs", "# ARPs", "# Remote VTEPs");
1876 hash_iterate(zvrf->vni_table, zvni_print_hash, vty);
cec2e17d 1877}
1878
2232a77c 1879/*
1880 * Handle neighbor delete (on a VLAN device / L3 interface) from the
1881 * kernel. This may result in either the neighbor getting deleted from
1882 * our database or being re-added to the kernel (if it is a valid
1883 * remote neighbor).
1884 */
d62a17ae 1885int zebra_vxlan_local_neigh_del(struct interface *ifp,
1886 struct interface *link_if, struct ipaddr *ip)
1887{
1888 zebra_vni_t *zvni;
1889 zebra_neigh_t *n;
1890 struct zebra_vrf *zvrf;
1891 char buf[INET6_ADDRSTRLEN];
1892
1893 /* We are only interested in neighbors on an SVI that resides on top
1894 * of a VxLAN bridge.
1895 */
1896 zvni = zvni_map_svi(ifp, link_if);
1897 if (!zvni)
1898 return 0;
1899 if (!zvni->vxlan_if) {
1900 zlog_err(
1901 "VNI %u hash %p doesn't have intf upon local neighbor DEL",
1902 zvni->vni, zvni);
1903 return -1;
1904 }
1905
1906 if (IS_ZEBRA_DEBUG_VXLAN)
1907 zlog_debug("%u:Del neighbor %s intf %s(%u) -> VNI %u",
1908 ifp->vrf_id, ipaddr2str(ip, buf, sizeof(buf)),
1909 ifp->name, ifp->ifindex, zvni->vni);
1910
1911 /* If entry doesn't exist, nothing to do. */
1912 n = zvni_neigh_lookup(zvni, ip);
1913 if (!n)
1914 return 0;
1915
1916 /* If it is a remote entry, the kernel has aged this out or someone has
1917 * deleted it, it needs to be re-installed as Quagga is the owner.
1918 */
1919 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
1920 zvni_neigh_install(zvni, n);
1921 return 0;
1922 }
1923
1924 /* Locate VRF corresponding to interface. */
1925 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1926 assert(zvrf);
1927
1928 /* Remove neighbor from BGP. */
1929 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip, &n->emac);
1930
1931 /* Delete this neighbor entry. */
1932 zvni_neigh_del(zvni, n);
1933
1934 return 0;
2232a77c 1935}
1936
1937/*
1938 * Handle neighbor add or update (on a VLAN device / L3 interface)
1939 * from the kernel.
1940 */
d62a17ae 1941int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
1942 struct interface *link_if,
1943 struct ipaddr *ip,
1944 struct ethaddr *macaddr, u_int16_t state,
1945 u_char ext_learned)
1946{
1947 zebra_vni_t *zvni;
1948 zebra_neigh_t *n;
1949 struct zebra_vrf *zvrf;
1950 char buf[ETHER_ADDR_STRLEN];
1951 char buf2[INET6_ADDRSTRLEN];
1952 int send_upd = 1, send_del = 0;
1953
1954 /* We are only interested in neighbors on an SVI that resides on top
1955 * of a VxLAN bridge.
1956 */
1957 zvni = zvni_map_svi(ifp, link_if);
1958 if (!zvni)
1959 return 0;
1960
1961 /* Locate VRF corresponding to interface. */
1962 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
1963 assert(zvrf);
1964
1965 if (IS_ZEBRA_DEBUG_VXLAN)
1966 zlog_debug(
1967 "%u:Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x "
1968 "%s-> VNI %u",
1969 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
1970 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
1971 ifp->ifindex, state, ext_learned ? "ext-learned " : "",
1972 zvni->vni);
1973
1974 /* If same entry already exists, it might be a change or it might be a
1975 * move from remote to local.
1976 */
1977 n = zvni_neigh_lookup(zvni, ip);
1978 if (n) {
1979 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
1980 if (memcmp(n->emac.octet, macaddr->octet,
1981 ETHER_ADDR_LEN)
1982 == 0) {
1983 if (n->ifindex == ifp->ifindex)
1984 /* we're not interested in whatever has
1985 * changed. */
1986 return 0;
1987 /* client doesn't care about a purely local
1988 * change. */
1989 send_upd = 0;
1990 } else
1991 /* If the MAC has changed, issue a delete first
1992 * as this means a
1993 * different MACIP route.
1994 */
1995 send_del = 1;
1996 } else if (ext_learned)
1997 /* The neighbor is remote and that is the notification we got.
c14777c6 1998 */
d62a17ae 1999 {
2000 /* TODO: Evaluate if we need to do anything here. */
2001 return 0;
2002 } else
2003 /* Neighbor has moved from remote to local. */
2004 {
2005 UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2006 n->r_vtep_ip.s_addr = 0;
2007 }
2008 } else {
2009 n = zvni_neigh_add(zvni, ip);
2010 if (!n) {
2011 zlog_err(
2012 "%u:Failed to add neighbor %s MAC %s intf %s(%u) -> VNI %u",
2013 ifp->vrf_id, ipaddr2str(ip, buf2, sizeof(buf2)),
2014 prefix_mac2str(macaddr, buf, sizeof(buf)),
2015 ifp->name, ifp->ifindex, zvni->vni);
2016 return -1;
2017 }
2018 }
2019
2020 /* Issue delete for older info, if needed. */
2021 if (send_del)
2022 zvni_neigh_send_del_to_client(zvrf, zvni->vni, &n->ip,
2023 &n->emac);
2024
2025 /* Set "local" forwarding info. */
2026 SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2027 memcpy(&n->emac, macaddr, ETHER_ADDR_LEN);
2028 n->ifindex = ifp->ifindex;
2029
2030 /* Inform BGP if required. */
2031 if (send_upd)
2032 return zvni_neigh_send_add_to_client(zvrf, zvni->vni, ip,
2033 macaddr);
2034
2035 return 0;
2232a77c 2036}
2037
2038/*
2039 * Handle message from client to delete a remote MACIP for a VNI.
2040 */
d62a17ae 2041int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
2042 struct zebra_vrf *zvrf)
2043{
2044 struct stream *s;
2045 vni_t vni;
2046 struct ethaddr macaddr;
2047 struct ipaddr ip;
2048 struct in_addr vtep_ip;
2049 zebra_vni_t *zvni;
2050 zebra_mac_t *mac;
2051 zebra_neigh_t *n;
2052 u_short l = 0, ipa_len;
2053 char buf[ETHER_ADDR_STRLEN];
2054 char buf1[INET6_ADDRSTRLEN];
2055
2056 s = client->ibuf;
2057
2058 while (l < length) {
2059 /* Obtain each remote MACIP and process. */
2060 /* Message contains VNI, followed by MAC followed by IP (if any)
2061 * followed by remote VTEP IP.
2062 */
2063 mac = NULL;
2064 n = NULL;
2065 memset(&ip, 0, sizeof(ip));
2066 vni = (vni_t)stream_getl(s);
2067 stream_get(&macaddr.octet, s, ETHER_ADDR_LEN);
2068 ipa_len = stream_getl(s);
2069 if (ipa_len) {
2070 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
2071 : IPADDR_V6;
2072 stream_get(&ip.ip.addr, s, ipa_len);
2073 }
2074 l += 4 + ETHER_ADDR_LEN + 4 + ipa_len;
2075 vtep_ip.s_addr = stream_get_ipv4(s);
2076 l += IPV4_MAX_BYTELEN;
2077
2078 if (IS_ZEBRA_DEBUG_VXLAN)
2079 zlog_debug(
2080 "%u:Recv MACIP Del MAC %s IP %s VNI %u Remote VTEP %s from %s",
2081 zvrf_id(zvrf),
2082 prefix_mac2str(&macaddr, buf, sizeof(buf)),
2083 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
2084 inet_ntoa(vtep_ip),
2085 zebra_route_string(client->proto));
2086
2087 /* Locate VNI hash entry - expected to exist. */
2088 zvni = zvni_lookup(zvrf, vni);
2089 if (!zvni) {
2090 if (IS_ZEBRA_DEBUG_VXLAN)
2091 zlog_debug(
2092 "Failed to locate VNI hash upon remote MACIP DEL, "
2093 "VRF %d VNI %u",
2094 zvrf_id(zvrf), vni);
2095 continue;
2096 }
2097 if (!zvni->vxlan_if) {
2098 zlog_err(
2099 "VNI %u hash %p doesn't have intf upon remote MACIP DEL",
2100 vni, zvni);
2101 continue;
2102 }
2103
2104 /* The remote VTEP specified is normally expected to exist, but
2105 * it is
2106 * possible that the peer may delete the VTEP before deleting
2107 * any MACs
2108 * referring to the VTEP, in which case the handler (see
2109 * remote_vtep_del)
2110 * would have already deleted the MACs.
2111 */
2112 if (!zvni_vtep_find(zvni, &vtep_ip))
2113 continue;
2114
2115 /* If the local VxLAN interface is not up (should be a transient
2116 * event), there's nothing more to do.
2117 */
2118 if (!if_is_operative(zvni->vxlan_if))
2119 continue;
2120
2121 mac = zvni_mac_lookup(zvni, &macaddr);
2122 if (ipa_len)
2123 n = zvni_neigh_lookup(zvni, &ip);
2124
2125 if (n && !mac) {
2126 zlog_err(
2127 "failed to locate MAC %s for neigh %s in VRF %u VNI %u",
2128 prefix_mac2str(&macaddr, buf, sizeof(buf)),
2129 ipaddr2str(&ip, buf1, sizeof(buf1)),
2130 zvrf_id(zvrf), vni);
2131 continue;
2132 }
2133
2134 /* If the remote mac or neighbor doesn't exist there is nothing
2135 * more
2136 * to do. Otherwise, uninstall the entry and then remove it.
2137 */
2138 if (!mac && !n)
2139 continue;
2140
2141 /* Uninstall remote neighbor or MAC. */
2142 if (n) {
2143 /* When the MAC changes for an IP, it is possible the
2144 * client may
2145 * update the new MAC before trying to delete the "old"
2146 * neighbor
2147 * (as these are two different MACIP routes). Do the
2148 * delete only
2149 * if the MAC matches.
2150 */
2151 if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2152 && (memcmp(n->emac.octet, macaddr.octet,
2153 ETHER_ADDR_LEN)
2154 == 0)) {
2155 zvni_neigh_uninstall(zvni, n);
2156 zvni_neigh_del(zvni, n);
2157 zvni_deref_ip2mac(zvni, mac, 1);
2158 }
2159 } else {
2160 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
2161 if (!mac->neigh_refcnt) {
2162 zvni_mac_uninstall(zvni, mac, 0);
2163 zvni_mac_del(zvni, mac);
2164 } else
2165 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2166 }
2167 }
2168 }
2169
2170 return 0;
2232a77c 2171}
2172
2173/*
2174 * Handle message from client to add a remote MACIP for a VNI. This
2175 * could be just the add of a MAC address or the add of a neighbor
2176 * (IP+MAC).
2177 */
d62a17ae 2178int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
2179 struct zebra_vrf *zvrf)
2180{
2181 struct stream *s;
2182 vni_t vni;
2183 struct ethaddr macaddr;
2184 struct ipaddr ip;
2185 struct in_addr vtep_ip;
2186 zebra_vni_t *zvni;
2187 zebra_vtep_t *zvtep;
2188 zebra_mac_t *mac, *old_mac;
2189 zebra_neigh_t *n;
2190 u_short l = 0, ipa_len;
2191 int update_mac = 0, update_neigh = 0;
2192 char buf[ETHER_ADDR_STRLEN];
2193 char buf1[INET6_ADDRSTRLEN];
2194 u_char sticky;
2195
2196 assert(EVPN_ENABLED(zvrf));
2197
2198 s = client->ibuf;
2199
2200 while (l < length) {
2201 /* Obtain each remote MACIP and process. */
2202 /* Message contains VNI, followed by MAC followed by IP (if any)
2203 * followed by remote VTEP IP.
2204 */
2205 update_mac = update_neigh = 0;
2206 mac = NULL;
2207 n = NULL;
2208 memset(&ip, 0, sizeof(ip));
2209 vni = (vni_t)stream_getl(s);
2210 stream_get(&macaddr.octet, s, ETHER_ADDR_LEN);
2211 ipa_len = stream_getl(s);
2212 if (ipa_len) {
2213 ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
2214 : IPADDR_V6;
2215 stream_get(&ip.ip.addr, s, ipa_len);
2216 }
2217 l += 4 + ETHER_ADDR_LEN + 4 + ipa_len;
2218 vtep_ip.s_addr = stream_get_ipv4(s);
2219 l += IPV4_MAX_BYTELEN;
2220
2221 /* Get 'sticky' flag. */
2222 sticky = stream_getc(s);
2223 l++;
2224
2225 if (IS_ZEBRA_DEBUG_VXLAN)
2226 zlog_debug(
2227 "%u:Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
2228 zvrf_id(zvrf), sticky ? "sticky " : "",
2229 prefix_mac2str(&macaddr, buf, sizeof(buf)),
2230 ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
2231 inet_ntoa(vtep_ip),
2232 zebra_route_string(client->proto));
2233
2234 /* Locate VNI hash entry - expected to exist. */
2235 zvni = zvni_lookup(zvrf, vni);
2236 if (!zvni) {
2237 zlog_err(
2238 "Failed to locate VNI hash upon remote MACIP ADD, VRF %d VNI %u",
2239 zvrf_id(zvrf), vni);
2240 continue;
2241 }
2242 if (!zvni->vxlan_if) {
2243 zlog_err(
2244 "VNI %u hash %p doesn't have intf upon remote MACIP add",
2245 vni, zvni);
2246 continue;
2247 }
2248 /* If the local VxLAN interface is not up (should be a transient
2249 * event), there's nothing more to do.
2250 */
2251 if (!if_is_operative(zvni->vxlan_if))
2252 continue;
2253
2254 /* The remote VTEP specified should normally exist, but it is
2255 * possible
2256 * that when peering comes up, peer may advertise MACIP routes
2257 * before
2258 * advertising type-3 routes.
2259 */
2260 zvtep = zvni_vtep_find(zvni, &vtep_ip);
2261 if (!zvtep) {
2262 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
2263 zlog_err(
2264 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2265 zvrf_id(zvrf), vni, zvni);
2266 continue;
2267 }
2268
2269 zvni_vtep_install(zvni, &vtep_ip);
2270 }
2271
2272 /* First, check if the remote MAC is unknown or has a change. If
2273 * so,
2274 * that needs to be updated first. Note that client could
2275 * install
2276 * MAC and MACIP separately or just install the latter.
2277 */
2278 mac = zvni_mac_lookup(zvni, &macaddr);
2279 if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
2280 || (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
2281 != sticky
2282 || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip))
2283 update_mac = 1;
2284
2285 if (update_mac) {
2286 if (!mac) {
2287 mac = zvni_mac_add(zvni, &macaddr);
2288 if (!mac) {
2289 zlog_warn(
2290 "%u:Failed to add MAC %s VNI %u Remote VTEP %s",
2291 zvrf_id(zvrf),
2292 prefix_mac2str(&macaddr, buf,
2293 sizeof(buf)),
2294 vni, inet_ntoa(vtep_ip));
2295 return -1;
2296 }
2297
2298 /* Is this MAC created for a MACIP? */
2299 if (ipa_len)
2300 SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2301 } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
2302 /* Moving from local to remote, issue delete. */
2303 zvni_mac_uninstall(zvni, mac, 1);
2304 }
2305
2306 /* Set "auto" and "remote" forwarding info. */
2307 UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2308 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2309 SET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
2310 mac->fwd_info.r_vtep_ip = vtep_ip;
2311
2312 if (sticky)
2313 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2314 else
2315 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2316
2317 /* Install the entry. */
2318 zvni_mac_install(zvni, mac);
2319 }
2320
2321 /* If there is no IP, continue - after clearing AUTO flag of
2322 * MAC. */
2323 if (!ipa_len) {
2324 UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
2325 continue;
2326 }
2327
2328 /* Check if the remote neighbor itself is unknown or has a
2329 * change.
2330 * If so, create or update and then install the entry.
2331 */
2332 n = zvni_neigh_lookup(zvni, &ip);
2333 if (!n || !CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)
2334 || (memcmp(&n->emac, &macaddr, sizeof(macaddr)) != 0)
2335 || !IPV4_ADDR_SAME(&n->r_vtep_ip, &vtep_ip))
2336 update_neigh = 1;
2337
2338 if (update_neigh) {
2339 if (!n) {
2340 n = zvni_neigh_add(zvni, &ip);
2341 if (!n) {
2342 zlog_warn(
2343 "%u:Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
2344 zvrf_id(zvrf),
2345 ipaddr2str(&ip, buf1,
2346 sizeof(buf1)),
2347 prefix_mac2str(&macaddr, buf,
2348 sizeof(buf)),
2349 vni, inet_ntoa(vtep_ip));
2350 return -1;
2351 }
2352
2353 /* New neighbor referring to this MAC. */
2354 mac->neigh_refcnt++;
2355 } else if (memcmp(&n->emac, &macaddr, sizeof(macaddr))
2356 != 0) {
2357 /* MAC change, update ref counts for old and new
2358 * MAC. */
2359 old_mac = zvni_mac_lookup(zvni, &n->emac);
2360 if (old_mac)
2361 zvni_deref_ip2mac(zvni, old_mac, 1);
2362 mac->neigh_refcnt++;
2363 }
2364
2365 /* Set "remote" forwarding info. */
2366 UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
2367 /* TODO: Handle MAC change. */
2368 memcpy(&n->emac, &macaddr, ETHER_ADDR_LEN);
2369 n->r_vtep_ip = vtep_ip;
2370 SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
2371
2372 /* Install the entry. */
2373 zvni_neigh_install(zvni, n);
2374 }
2375 }
2376
2377 return 0;
13d60d35 2378}
2379
2380/*
2232a77c 2381 * Handle notification of MAC add/update over VxLAN. If the kernel is notifying
2382 * us, this must involve a multihoming scenario. Treat this as implicit delete
2383 * of any prior local MAC.
13d60d35 2384 */
d62a17ae 2385int zebra_vxlan_check_del_local_mac(struct interface *ifp,
2386 struct interface *br_if,
2387 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2388{
d62a17ae 2389 struct zebra_if *zif;
2390 struct zebra_vrf *zvrf;
2391 struct zebra_l2info_vxlan *vxl;
2392 vni_t vni;
2393 zebra_vni_t *zvni;
2394 zebra_mac_t *mac;
2395 char buf[ETHER_ADDR_STRLEN];
2396 u_char sticky;
13d60d35 2397
d62a17ae 2398 zif = ifp->info;
2399 assert(zif);
2400 vxl = &zif->l2info.vxl;
2401 vni = vxl->vni;
13d60d35 2402
d62a17ae 2403 /* Locate VRF corresponding to interface. */
2404 zvrf = vrf_info_lookup(ifp->vrf_id);
2405 assert(zvrf);
13d60d35 2406
d62a17ae 2407 /* If EVPN is not enabled, nothing to do. */
2408 if (!EVPN_ENABLED(zvrf))
2409 return 0;
13d60d35 2410
d62a17ae 2411 /* Locate hash entry; it is expected to exist. */
2412 zvni = zvni_lookup(zvrf, vni);
2413 if (!zvni)
2414 return 0;
13d60d35 2415
d62a17ae 2416 /* If entry doesn't exist, nothing to do. */
2417 mac = zvni_mac_lookup(zvni, macaddr);
2418 if (!mac)
2419 return 0;
13d60d35 2420
d62a17ae 2421 /* Is it a local entry? */
2422 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
2423 return 0;
13d60d35 2424
d62a17ae 2425 if (IS_ZEBRA_DEBUG_VXLAN)
2426 zlog_debug(
2427 "%u:Add/update remote MAC %s intf %s(%u) VNI %u - del local",
2428 ifp->vrf_id, prefix_mac2str(macaddr, buf, sizeof(buf)),
2429 ifp->name, ifp->ifindex, vni);
13d60d35 2430
d62a17ae 2431 /* Remove MAC from BGP. */
2432 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
2433 zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr, sticky);
13d60d35 2434
d62a17ae 2435 /* Delete this MAC entry. */
2436 zvni_mac_del(zvni, mac);
13d60d35 2437
d62a17ae 2438 return 0;
13d60d35 2439}
2440
2441/*
2232a77c 2442 * Handle remote MAC delete by kernel; readd the remote MAC if we have it.
2443 * This can happen because the remote MAC entries are also added as "dynamic",
2444 * so the kernel can ageout the entry.
13d60d35 2445 */
d62a17ae 2446int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
2447 struct interface *br_if,
2448 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2449{
d62a17ae 2450 struct zebra_if *zif;
2451 struct zebra_vrf *zvrf;
2452 struct zebra_l2info_vxlan *vxl;
2453 vni_t vni;
2454 zebra_vni_t *zvni;
2455 zebra_mac_t *mac;
2456 char buf[ETHER_ADDR_STRLEN];
2232a77c 2457
d62a17ae 2458 zif = ifp->info;
2459 assert(zif);
2460 vxl = &zif->l2info.vxl;
2461 vni = vxl->vni;
2232a77c 2462
d62a17ae 2463 /* Locate VRF corresponding to interface. */
2464 zvrf = vrf_info_lookup(ifp->vrf_id);
2465 assert(zvrf);
13d60d35 2466
d62a17ae 2467 /* If EVPN is not enabled, nothing to do. */
2468 if (!EVPN_ENABLED(zvrf))
2469 return 0;
2232a77c 2470
d62a17ae 2471 /* Locate hash entry; it is expected to exist. */
2472 zvni = zvni_lookup(zvrf, vni);
2473 if (!zvni)
2474 return 0;
13d60d35 2475
d62a17ae 2476 /* If entry doesn't exist, nothing to do. */
2477 mac = zvni_mac_lookup(zvni, macaddr);
2478 if (!mac)
2479 return 0;
2232a77c 2480
d62a17ae 2481 /* Is it a remote entry? */
2482 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
2483 return 0;
2232a77c 2484
d62a17ae 2485 if (IS_ZEBRA_DEBUG_VXLAN)
2486 zlog_debug("%u:Del remote MAC %s intf %s(%u) VNI %u - readd",
2487 ifp->vrf_id,
2488 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2489 ifp->ifindex, vni);
13d60d35 2490
d62a17ae 2491 zvni_mac_install(zvni, mac);
2492 return 0;
13d60d35 2493}
2494
2495/*
2232a77c 2496 * Handle local MAC delete (on a port or VLAN corresponding to this VNI).
13d60d35 2497 */
d62a17ae 2498int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
2499 struct ethaddr *macaddr, vlanid_t vid)
13d60d35 2500{
d62a17ae 2501 zebra_vni_t *zvni;
2502 zebra_mac_t *mac;
2503 struct zebra_vrf *zvrf;
2504 char buf[ETHER_ADDR_STRLEN];
2505 u_char sticky;
13d60d35 2506
d62a17ae 2507 /* We are interested in MACs only on ports or (port, VLAN) that
2508 * map to a VNI.
2509 */
2510 zvni = zvni_map_vlan(ifp, br_if, vid);
2511 if (!zvni)
2512 return 0;
2513 if (!zvni->vxlan_if) {
2514 zlog_err("VNI %u hash %p doesn't have intf upon local MAC DEL",
2515 zvni->vni, zvni);
2516 return -1;
2517 }
13d60d35 2518
d62a17ae 2519 if (IS_ZEBRA_DEBUG_VXLAN)
2520 zlog_debug("%u:Del MAC %s intf %s(%u) VID %u -> VNI %u",
2521 ifp->vrf_id,
2522 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2523 ifp->ifindex, vid, zvni->vni);
2232a77c 2524
d62a17ae 2525 /* If entry doesn't exist, nothing to do. */
2526 mac = zvni_mac_lookup(zvni, macaddr);
2527 if (!mac)
2528 return 0;
2232a77c 2529
d62a17ae 2530 /* Is it a local entry? */
2531 if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
2532 return 0;
2232a77c 2533
d62a17ae 2534 /* Locate VRF corresponding to interface. */
2535 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2536 assert(zvrf);
2232a77c 2537
d62a17ae 2538 /* Remove MAC from BGP. */
2539 sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
2540 zvni_mac_send_del_to_client(zvrf, zvni->vni, macaddr, sticky);
2232a77c 2541
d62a17ae 2542 /* Delete this MAC entry. */
2543 zvni_mac_del(zvni, mac);
2232a77c 2544
d62a17ae 2545 return 0;
13d60d35 2546}
2547
2548/*
2232a77c 2549 * Handle local MAC add (on a port or VLAN corresponding to this VNI).
13d60d35 2550 */
d62a17ae 2551int zebra_vxlan_local_mac_add_update(struct interface *ifp,
2552 struct interface *br_if,
2553 struct ethaddr *macaddr, vlanid_t vid,
2554 u_char sticky)
2555{
2556 zebra_vni_t *zvni;
2557 zebra_mac_t *mac;
2558 struct zebra_vrf *zvrf;
2559 char buf[ETHER_ADDR_STRLEN];
2560 int add = 1;
2561 u_char mac_sticky;
2562
2563 /* We are interested in MACs only on ports or (port, VLAN) that
2564 * map to a VNI.
2565 */
2566 zvni = zvni_map_vlan(ifp, br_if, vid);
2567 if (!zvni) {
2568 if (IS_ZEBRA_DEBUG_VXLAN)
2569 zlog_debug(
2570 "%u:Add/Update %sMAC %s intf %s(%u) VID %u, could not find VNI",
2571 ifp->vrf_id, sticky ? "sticky " : "",
2572 prefix_mac2str(macaddr, buf, sizeof(buf)),
2573 ifp->name, ifp->ifindex, vid);
2574 return 0;
2575 }
2576
2577 if (!zvni->vxlan_if) {
2578 zlog_err("VNI %u hash %p doesn't have intf upon local MAC ADD",
2579 zvni->vni, zvni);
2580 return -1;
2581 }
2582
2583 if (IS_ZEBRA_DEBUG_VXLAN)
2584 zlog_debug(
2585 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u",
2586 ifp->vrf_id, sticky ? "sticky " : "",
2587 prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name,
2588 ifp->ifindex, vid, zvni->vni);
2589
2590 /* If same entry already exists, nothing to do. */
2591 mac = zvni_mac_lookup(zvni, macaddr);
2592 if (mac) {
2593 if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
2594 mac_sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)
2595 ? 1
2596 : 0;
2597
2598 if (mac_sticky == sticky
2599 && mac->fwd_info.local.ifindex == ifp->ifindex
2600 && mac->fwd_info.local.vid == vid) {
2601 if (IS_ZEBRA_DEBUG_VXLAN)
2602 zlog_debug(
2603 "%u:Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u, "
2604 "entry exists and has not changed ",
2605 ifp->vrf_id,
2606 sticky ? "sticky " : "",
2607 prefix_mac2str(macaddr, buf,
2608 sizeof(buf)),
2609 ifp->name, ifp->ifindex, vid,
2610 zvni->vni);
2611 return 0;
2612 }
2613
2614 add = 0; /* This is an update of local interface. */
2615 }
2616 }
2617
2618 /* Locate VRF corresponding to interface. */
2619 zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
2620 assert(zvrf);
2621
2622 if (!mac) {
2623 mac = zvni_mac_add(zvni, macaddr);
2624 if (!mac) {
2625 zlog_err("%u:Failed to add MAC %s intf %s(%u) VID %u",
2626 ifp->vrf_id,
2627 prefix_mac2str(macaddr, buf, sizeof(buf)),
2628 ifp->name, ifp->ifindex, vid);
2629 return -1;
2630 }
2631 }
2632
2633 /* Set "local" forwarding info. */
2634 UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
2635 memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
2636 SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
2637 mac->fwd_info.local.ifindex = ifp->ifindex;
2638 mac->fwd_info.local.vid = vid;
2639
2640 if (sticky)
2641 SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2642 else
2643 UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
2644
2645 /* Inform BGP if required. */
2646 if (add)
2647 return zvni_mac_send_add_to_client(zvrf, zvni->vni, macaddr,
2648 sticky);
2649
2650 return 0;
2232a77c 2651}
13d60d35 2652
2653/*
2654 * Handle message from client to delete a remote VTEP for a VNI.
2655 */
d62a17ae 2656int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
2657 struct zebra_vrf *zvrf)
2658{
2659 struct stream *s;
2660 u_short l = 0;
2661 vni_t vni;
2662 struct in_addr vtep_ip;
2663 zebra_vni_t *zvni;
2664 zebra_vtep_t *zvtep;
2665
2666 s = client->ibuf;
2667
2668 while (l < length) {
2669 /* Obtain each remote VTEP and process. */
2670 vni = (vni_t)stream_getl(s);
2671 l += 4;
2672 vtep_ip.s_addr = stream_get_ipv4(s);
2673 l += IPV4_MAX_BYTELEN;
2674
2675 if (IS_ZEBRA_DEBUG_VXLAN)
2676 zlog_debug("%u:Recv VTEP_DEL %s VNI %u from %s",
2677 zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
2678 zebra_route_string(client->proto));
2679
2680 /* Locate VNI hash entry - expected to exist. */
2681 zvni = zvni_lookup(zvrf, vni);
2682 if (!zvni) {
2683 if (IS_ZEBRA_DEBUG_VXLAN)
2684 zlog_debug(
2685 "Failed to locate VNI hash upon remote VTEP DEL, "
2686 "VRF %d VNI %u",
2687 zvrf_id(zvrf), vni);
2688 continue;
2689 }
2690
2691 /* If the remote VTEP does not exist, there's nothing more to
2692 * do.
2693 * Otherwise, uninstall any remote MACs pointing to this VTEP
2694 * and
2695 * then, the VTEP entry itself and remove it.
2696 */
2697 zvtep = zvni_vtep_find(zvni, &vtep_ip);
2698 if (!zvtep)
2699 continue;
2700
2701 zvni_neigh_del_from_vtep(zvni, 1, &vtep_ip);
2702 zvni_mac_del_from_vtep(zvni, 1, &vtep_ip);
2703 zvni_vtep_uninstall(zvni, &vtep_ip);
2704 zvni_vtep_del(zvni, zvtep);
2705 }
2706
2707 return 0;
13d60d35 2708}
2709
2710/*
2711 * Handle message from client to add a remote VTEP for a VNI.
2712 */
d62a17ae 2713int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
2714 struct zebra_vrf *zvrf)
2715{
2716 struct stream *s;
2717 u_short l = 0;
2718 vni_t vni;
2719 struct in_addr vtep_ip;
2720 zebra_vni_t *zvni;
2721
2722 assert(EVPN_ENABLED(zvrf));
2723
2724 s = client->ibuf;
2725
2726 while (l < length) {
2727 /* Obtain each remote VTEP and process. */
2728 vni = (vni_t)stream_getl(s);
2729 l += 4;
2730 vtep_ip.s_addr = stream_get_ipv4(s);
2731 l += IPV4_MAX_BYTELEN;
2732
2733 if (IS_ZEBRA_DEBUG_VXLAN)
2734 zlog_debug("%u:Recv VTEP_ADD %s VNI %u from %s",
2735 zvrf_id(zvrf), inet_ntoa(vtep_ip), vni,
2736 zebra_route_string(client->proto));
2737
2738 /* Locate VNI hash entry - expected to exist. */
2739 zvni = zvni_lookup(zvrf, vni);
2740 if (!zvni) {
2741 zlog_err(
2742 "Failed to locate VNI hash upon remote VTEP ADD, VRF %d VNI %u",
2743 zvrf_id(zvrf), vni);
2744 continue;
2745 }
2746 if (!zvni->vxlan_if) {
2747 zlog_err(
2748 "VNI %u hash %p doesn't have intf upon remote VTEP ADD",
2749 zvni->vni, zvni);
2750 continue;
2751 }
2752
2753
2754 /* If the remote VTEP already exists, or the local VxLAN
2755 * interface is
2756 * not up (should be a transient event), there's nothing more
2757 * to do.
2758 * Otherwise, add and install the entry.
2759 */
2760 if (zvni_vtep_find(zvni, &vtep_ip))
2761 continue;
2762
2763 if (!if_is_operative(zvni->vxlan_if))
2764 continue;
2765
2766 if (zvni_vtep_add(zvni, &vtep_ip) == NULL) {
2767 zlog_err(
2768 "Failed to add remote VTEP, VRF %d VNI %u zvni %p",
2769 zvrf_id(zvrf), vni, zvni);
2770 continue;
2771 }
2772
2773 zvni_vtep_install(zvni, &vtep_ip);
2774 }
2775
2776 return 0;
13d60d35 2777}
2778
2232a77c 2779/*
2780 * Handle SVI interface going down. At this point, this is a NOP since
2781 * the kernel deletes the neighbor entries on this SVI (if any).
2782 */
d62a17ae 2783int zebra_vxlan_svi_down(struct interface *ifp, struct interface *link_if)
2232a77c 2784{
d62a17ae 2785 return 0;
2232a77c 2786}
2787
2788/*
2789 * Handle SVI interface coming up. This may or may not be of interest,
2790 * but if this is a SVI on a VxLAN bridge, we need to install any remote
2791 * neighbor entries (which will be used for EVPN ARP suppression).
2792 */
d62a17ae 2793int zebra_vxlan_svi_up(struct interface *ifp, struct interface *link_if)
2232a77c 2794{
d62a17ae 2795 zebra_vni_t *zvni;
2796 struct neigh_walk_ctx n_wctx;
2232a77c 2797
d62a17ae 2798 zvni = zvni_map_svi(ifp, link_if);
2799 if (!zvni)
2800 return 0;
2232a77c 2801
d62a17ae 2802 if (!zvni->vxlan_if) {
2803 zlog_err("VNI %u hash %p doesn't have intf upon SVI up",
2804 zvni->vni, zvni);
2805 return -1;
2806 }
2232a77c 2807
d62a17ae 2808 if (IS_ZEBRA_DEBUG_VXLAN)
2809 zlog_debug("%u:SVI %s(%u) VNI %u is UP, installing neighbors",
2810 ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
2232a77c 2811
d62a17ae 2812 /* Install any remote neighbors for this VNI. */
2813 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
2814 n_wctx.zvni = zvni;
2815 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash, &n_wctx);
2232a77c 2816
d62a17ae 2817 return 0;
2232a77c 2818}
2819
13d60d35 2820/*
2821 * Handle VxLAN interface down - update BGP if required, and do
2822 * internal cleanup.
2823 */
d62a17ae 2824int zebra_vxlan_if_down(struct interface *ifp)
13d60d35 2825{
d62a17ae 2826 struct zebra_if *zif;
2827 struct zebra_vrf *zvrf;
2828 zebra_vni_t *zvni;
2829 struct zebra_l2info_vxlan *vxl;
2830 vni_t vni;
13d60d35 2831
d62a17ae 2832 /* Locate VRF corresponding to interface. */
2833 zvrf = vrf_info_lookup(ifp->vrf_id);
2834 assert(zvrf);
13d60d35 2835
d62a17ae 2836 /* If EVPN is not enabled, nothing further to be done. */
2837 if (!EVPN_ENABLED(zvrf))
2838 return 0;
13d60d35 2839
d62a17ae 2840 zif = ifp->info;
2841 assert(zif);
2842 vxl = &zif->l2info.vxl;
2843 vni = vxl->vni;
13d60d35 2844
d62a17ae 2845 if (IS_ZEBRA_DEBUG_VXLAN)
2846 zlog_debug("%u:Intf %s(%u) VNI %u is DOWN", ifp->vrf_id,
2847 ifp->name, ifp->ifindex, vni);
13d60d35 2848
d62a17ae 2849 /* Locate hash entry; it is expected to exist. */
2850 zvni = zvni_lookup(zvrf, vni);
2851 if (!zvni) {
2852 zlog_err(
2853 "Failed to locate VNI hash at DOWN, VRF %d IF %s(%u) VNI %u",
2854 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2855 return -1;
2856 }
13d60d35 2857
d62a17ae 2858 assert(zvni->vxlan_if == ifp);
13d60d35 2859
d62a17ae 2860 /* Delete this VNI from BGP. */
2861 zvni_send_del_to_client(zvrf, zvni->vni);
13d60d35 2862
d62a17ae 2863 /* Free up all neighbors and MACs, if any. */
2864 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
2865 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
2232a77c 2866
d62a17ae 2867 /* Free up all remote VTEPs, if any. */
2868 zvni_vtep_del_all(zvni, 1);
13d60d35 2869
d62a17ae 2870 return 0;
13d60d35 2871}
2872
2873/*
2874 * Handle VxLAN interface up - update BGP if required.
2875 */
d62a17ae 2876int zebra_vxlan_if_up(struct interface *ifp)
13d60d35 2877{
d62a17ae 2878 struct zebra_if *zif;
2879 struct zebra_vrf *zvrf;
2880 zebra_vni_t *zvni;
2881 struct zebra_l2info_vxlan *vxl;
2882 vni_t vni;
13d60d35 2883
d62a17ae 2884 /* Locate VRF corresponding to interface. */
2885 zvrf = vrf_info_lookup(ifp->vrf_id);
2886 assert(zvrf);
13d60d35 2887
d62a17ae 2888 /* If EVPN is not enabled, nothing further to be done. */
2889 if (!EVPN_ENABLED(zvrf))
2890 return 0;
13d60d35 2891
d62a17ae 2892 zif = ifp->info;
2893 assert(zif);
2894 vxl = &zif->l2info.vxl;
2895 vni = vxl->vni;
13d60d35 2896
d62a17ae 2897 if (IS_ZEBRA_DEBUG_VXLAN)
2898 zlog_debug("%u:Intf %s(%u) VNI %u is UP", ifp->vrf_id,
2899 ifp->name, ifp->ifindex, vni);
13d60d35 2900
d62a17ae 2901 /* Locate hash entry; it is expected to exist. */
2902 zvni = zvni_lookup(zvrf, vni);
2903 if (!zvni) {
2904 zlog_err(
2905 "Failed to locate VNI hash at UP, VRF %d IF %s(%u) VNI %u",
2906 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2907 return -1;
2908 }
13d60d35 2909
d62a17ae 2910 assert(zvni->vxlan_if == ifp);
13d60d35 2911
d62a17ae 2912 /* If part of a bridge, inform BGP about this VNI. */
2913 /* Also, read and populate local MACs and neighbors. */
2914 if (zif->brslave_info.br_if) {
2915 zvni_send_add_to_client(zvrf, zvni);
2916 zvni_read_mac_neigh(zvrf, zvni, ifp);
2917 }
13d60d35 2918
d62a17ae 2919 return 0;
13d60d35 2920}
2921
2922/*
2923 * Handle VxLAN interface delete. Locate and remove entry in hash table
2924 * and update BGP, if required.
2925 */
d62a17ae 2926int zebra_vxlan_if_del(struct interface *ifp)
13d60d35 2927{
d62a17ae 2928 struct zebra_if *zif;
2929 struct zebra_vrf *zvrf;
2930 zebra_vni_t *zvni;
2931 struct zebra_l2info_vxlan *vxl;
2932 vni_t vni;
13d60d35 2933
d62a17ae 2934 /* Locate VRF corresponding to interface. */
2935 zvrf = vrf_info_lookup(ifp->vrf_id);
2936 assert(zvrf);
13d60d35 2937
d62a17ae 2938 /* If EVPN is not enabled, nothing further to be done. */
2939 if (!EVPN_ENABLED(zvrf))
2940 return 0;
13d60d35 2941
d62a17ae 2942 zif = ifp->info;
2943 assert(zif);
2944 vxl = &zif->l2info.vxl;
2945 vni = vxl->vni;
13d60d35 2946
d62a17ae 2947 if (IS_ZEBRA_DEBUG_VXLAN)
2948 zlog_debug("%u:Del VNI %u intf %s(%u)", ifp->vrf_id, vni,
2949 ifp->name, ifp->ifindex);
13d60d35 2950
d62a17ae 2951 /* Locate hash entry; it is expected to exist. */
2952 zvni = zvni_lookup(zvrf, vni);
2953 if (!zvni) {
2954 zlog_err(
2955 "Failed to locate VNI hash at del, VRF %d IF %s(%u) VNI %u",
2956 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
2957 return 0;
2958 }
13d60d35 2959
d62a17ae 2960 /* Delete VNI from BGP. */
2961 zvni_send_del_to_client(zvrf, zvni->vni);
13d60d35 2962
d62a17ae 2963 /* Free up all neighbors and MAC, if any. */
2964 zvni_neigh_del_all(zvrf, zvni, 0, 0, DEL_ALL_NEIGH);
2965 zvni_mac_del_all(zvrf, zvni, 0, 0, DEL_ALL_MAC);
2232a77c 2966
d62a17ae 2967 /* Free up all remote VTEPs, if any. */
2968 zvni_vtep_del_all(zvni, 0);
13d60d35 2969
d62a17ae 2970 /* Delete the hash entry. */
2971 if (zvni_del(zvrf, zvni)) {
2972 zlog_err("Failed to del VNI hash %p, VRF %d IF %s(%u) VNI %u",
2973 zvni, ifp->vrf_id, ifp->name, ifp->ifindex, zvni->vni);
2974 return -1;
2975 }
13d60d35 2976
d62a17ae 2977 return 0;
13d60d35 2978}
2979
2980/*
2981 * Handle VxLAN interface update - change to tunnel IP, master or VLAN.
2982 */
d62a17ae 2983int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
2984{
2985 struct zebra_if *zif;
2986 struct zebra_vrf *zvrf;
2987 zebra_vni_t *zvni;
2988 struct zebra_l2info_vxlan *vxl;
2989 vni_t vni;
2990
2991 /* Locate VRF corresponding to interface. */
2992 zvrf = vrf_info_lookup(ifp->vrf_id);
2993 assert(zvrf);
2994
2995 /* If EVPN is not enabled, nothing further to be done. */
2996 if (!EVPN_ENABLED(zvrf))
2997 return 0;
2998
2999 zif = ifp->info;
3000 assert(zif);
3001 vxl = &zif->l2info.vxl;
3002 vni = vxl->vni;
3003
3004 /* Update VNI hash. */
3005 zvni = zvni_lookup(zvrf, vni);
3006 if (!zvni) {
3007 zlog_err(
3008 "Failed to find VNI hash on update, VRF %d IF %s(%u) VNI %u",
3009 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3010 return -1;
3011 }
3012
3013 if (IS_ZEBRA_DEBUG_VXLAN)
3014 zlog_debug(
3015 "%u:Update VNI %u intf %s(%u) VLAN %u local IP %s "
3016 "master %u chg 0x%x",
3017 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
3018 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
3019 zif->brslave_info.bridge_ifindex, chgflags);
3020
3021 /* Removed from bridge? */
3022 if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
3023 && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) {
3024 /* Delete from client, remove all remote VTEPs */
3025 /* Also, free up all MACs and neighbors. */
3026 zvni_send_del_to_client(zvrf, zvni->vni);
3027 zvni_neigh_del_all(zvrf, zvni, 1, 0, DEL_ALL_NEIGH);
3028 zvni_mac_del_all(zvrf, zvni, 1, 0, DEL_ALL_MAC);
3029 zvni_vtep_del_all(zvni, 1);
3030 } else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
3031 /* Remove all existing local neighbors and MACs for this VNI
3032 * (including from BGP)
3033 */
3034 zvni_neigh_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
3035 zvni_mac_del_all(zvrf, zvni, 0, 1, DEL_LOCAL_MAC);
3036 }
3037
3038 zvni->local_vtep_ip = vxl->vtep_ip;
3039 zvni->vxlan_if = ifp;
3040
3041 /* Take further actions needed. Note that if we are here, there is a
3042 * change of interest.
3043 */
3044 /* If down or not mapped to a bridge, we're done. */
3045 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3046 return 0;
3047
3048 /* Inform BGP, if there is a change of interest. */
3049 if (chgflags
3050 & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE))
3051 zvni_send_add_to_client(zvrf, zvni);
3052
3053 /* If there is a valid new master or a VLAN mapping change, read and
3054 * populate local MACs and neighbors. Also, reinstall any remote MACs
3055 * and neighbors for this VNI (based on new VLAN).
3056 */
3057 if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
3058 zvni_read_mac_neigh(zvrf, zvni, ifp);
3059 else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) {
3060 struct mac_walk_ctx m_wctx;
3061 struct neigh_walk_ctx n_wctx;
3062
3063 zvni_read_mac_neigh(zvrf, zvni, ifp);
3064
3065 memset(&m_wctx, 0, sizeof(struct mac_walk_ctx));
3066 m_wctx.zvni = zvni;
3067 hash_iterate(zvni->mac_table, zvni_install_mac_hash, &m_wctx);
3068
3069 memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx));
3070 n_wctx.zvni = zvni;
3071 hash_iterate(zvni->neigh_table, zvni_install_neigh_hash,
3072 &n_wctx);
3073 }
3074
3075 return 0;
13d60d35 3076}
3077
3078/*
3079 * Handle VxLAN interface add.
3080 */
d62a17ae 3081int zebra_vxlan_if_add(struct interface *ifp)
13d60d35 3082{
d62a17ae 3083 struct zebra_if *zif;
3084 struct zebra_vrf *zvrf;
3085 zebra_vni_t *zvni;
3086 struct zebra_l2info_vxlan *vxl;
3087 vni_t vni;
13d60d35 3088
d62a17ae 3089 /* Locate VRF corresponding to interface. */
3090 zvrf = vrf_info_lookup(ifp->vrf_id);
3091 assert(zvrf);
13d60d35 3092
d62a17ae 3093 /* If EVPN is not enabled, nothing further to be done. */
3094 if (!EVPN_ENABLED(zvrf))
3095 return 0;
13d60d35 3096
d62a17ae 3097 zif = ifp->info;
3098 assert(zif);
3099 vxl = &zif->l2info.vxl;
3100 vni = vxl->vni;
13d60d35 3101
d62a17ae 3102 if (IS_ZEBRA_DEBUG_VXLAN)
3103 zlog_debug(
3104 "%u:Add VNI %u intf %s(%u) VLAN %u local IP %s master %u",
3105 ifp->vrf_id, vni, ifp->name, ifp->ifindex,
3106 vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
3107 zif->brslave_info.bridge_ifindex);
13d60d35 3108
d62a17ae 3109 /* Create or update VNI hash. */
3110 zvni = zvni_lookup(zvrf, vni);
3111 if (!zvni) {
3112 zvni = zvni_add(zvrf, vni);
3113 if (!zvni) {
3114 zlog_err(
3115 "Failed to add VNI hash, VRF %d IF %s(%u) VNI %u",
3116 ifp->vrf_id, ifp->name, ifp->ifindex, vni);
3117 return -1;
3118 }
3119 }
13d60d35 3120
d62a17ae 3121 zvni->local_vtep_ip = vxl->vtep_ip;
3122 zvni->vxlan_if = ifp;
13d60d35 3123
d62a17ae 3124 /* If down or not mapped to a bridge, we're done. */
3125 if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
3126 return 0;
13d60d35 3127
d62a17ae 3128 /* Inform BGP */
3129 zvni_send_add_to_client(zvrf, zvni);
13d60d35 3130
d62a17ae 3131 /* Read and populate local MACs and neighbors */
3132 zvni_read_mac_neigh(zvrf, zvni, ifp);
2232a77c 3133
d62a17ae 3134 return 0;
13d60d35 3135}
3136
3137/*
3138 * Handle message from client to learn (or stop learning) about VNIs and MACs.
3139 * When enabled, the VNI hash table will be built and MAC FDB table read;
3140 * when disabled, the entries should be deleted and remote VTEPs and MACs
3141 * uninstalled from the kernel.
3142 */
d62a17ae 3143int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
3144 u_short length, struct zebra_vrf *zvrf)
13d60d35 3145{
d62a17ae 3146 struct stream *s;
3147 int advertise;
13d60d35 3148
d62a17ae 3149 s = client->ibuf;
3150 advertise = stream_getc(s);
13d60d35 3151
d62a17ae 3152 if (IS_ZEBRA_DEBUG_VXLAN)
3153 zlog_debug("%u:EVPN VNI Adv %s, currently %s", zvrf_id(zvrf),
3154 advertise ? "enabled" : "disabled",
3155 EVPN_ENABLED(zvrf) ? "enabled" : "disabled");
13d60d35 3156
d62a17ae 3157 if (zvrf->advertise_all_vni == advertise)
3158 return 0;
13d60d35 3159
d62a17ae 3160 zvrf->advertise_all_vni = advertise;
3161 if (EVPN_ENABLED(zvrf)) {
3162 /* Build VNI hash table and inform BGP. */
3163 zvni_build_hash_table(zvrf);
2232a77c 3164
d62a17ae 3165 /* Read the MAC FDB */
3166 macfdb_read(zvrf->zns);
2232a77c 3167
d62a17ae 3168 /* Read neighbors */
3169 neigh_read(zvrf->zns);
3170 } else {
3171 /* Cleanup VTEPs for all VNIs - uninstall from
3172 * kernel and free entries.
3173 */
3174 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
3175 }
13d60d35 3176
d62a17ae 3177 return 0;
13d60d35 3178}
3179
3180/*
3181 * Allocate VNI hash table for this VRF and do other initialization.
3182 * NOTE: Currently supported only for default VRF.
3183 */
d62a17ae 3184void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
13d60d35 3185{
d62a17ae 3186 if (!zvrf)
3187 return;
3188 zvrf->vni_table = hash_create(vni_hash_keymake, vni_hash_cmp,
3189 "Zebra VRF VNI Table");
13d60d35 3190}
3191
3192/* Close all VNI handling */
d62a17ae 3193void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
13d60d35 3194{
d62a17ae 3195 hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
13d60d35 3196}