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