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