2 * Zebra VxLAN (EVPN) Data structures and definitions
3 * These are "internal" to this function.
4 * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
6 * This file is part of FRR.
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with FRR; see the file COPYING. If not, write to the Free
20 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 #ifndef _ZEBRA_VXLAN_PRIVATE_H
25 #define _ZEBRA_VXLAN_PRIVATE_H
31 #include "zebra_vxlan.h"
37 #define ERR_STR_SZ 256
40 typedef struct zebra_vni_t_ zebra_vni_t
;
41 typedef struct zebra_vtep_t_ zebra_vtep_t
;
42 typedef struct zebra_mac_t_ zebra_mac_t
;
43 typedef struct zebra_neigh_t_ zebra_neigh_t
;
44 typedef struct zebra_l3vni_t_ zebra_l3vni_t
;
49 * Right now, this just has each remote VTEP's IP address.
51 struct zebra_vtep_t_
{
53 /* NOTE: Can only be IPv4 right now. */
54 struct in_addr vtep_ip
;
55 /* Flood mode (one of enum vxlan_flood_control) based on the PMSI
56 * tunnel type advertised by the remote VTEP
61 struct zebra_vtep_t_
*next
;
62 struct zebra_vtep_t_
*prev
;
69 * Contains information pertaining to a VNI:
70 * - the list of remote VTEPs (with this VNI)
76 /* Flag for advertising gw macip */
77 uint8_t advertise_gw_macip
;
79 /* Flag for advertising svi macip */
80 uint8_t advertise_svi_macip
;
82 /* Flag for advertising gw macip */
83 uint8_t advertise_subnet
;
85 /* Corresponding VxLAN interface. */
86 struct interface
*vxlan_if
;
88 /* List of remote VTEPs */
92 struct in_addr local_vtep_ip
;
94 /* PIM-SM MDT group for BUM flooding */
95 struct in_addr mcast_grp
;
97 /* tenant VRF, if any */
100 /* List of local or remote MAC */
101 struct hash
*mac_table
;
103 /* List of local or remote neighbors (MAC+IP) */
104 struct hash
*neigh_table
;
107 /* L3 VNI hash table */
108 struct zebra_l3vni_t_
{
117 #define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */
120 struct in_addr local_vtep_ip
;
122 /* kernel interface for l3vni */
123 struct interface
*vxlan_if
;
125 /* SVI interface corresponding to the l3vni */
126 struct interface
*svi_if
;
128 struct interface
*mac_vlan_if
;
130 /* list of L2 VNIs associated with the L3 VNI */
133 /* list of remote router-macs */
134 struct hash
*rmac_table
;
136 /* list of remote vtep-ip neigh */
137 struct hash
*nh_table
;
140 /* get the vx-intf name for l3vni */
141 static inline const char *zl3vni_vxlan_if_name(zebra_l3vni_t
*zl3vni
)
143 return zl3vni
->vxlan_if
? zl3vni
->vxlan_if
->name
: "None";
146 /* get the svi intf name for l3vni */
147 static inline const char *zl3vni_svi_if_name(zebra_l3vni_t
*zl3vni
)
149 return zl3vni
->svi_if
? zl3vni
->svi_if
->name
: "None";
152 /* get the vrf name for l3vni */
153 static inline const char *zl3vni_vrf_name(zebra_l3vni_t
*zl3vni
)
155 return vrf_id_to_name(zl3vni
->vrf_id
);
158 /* get the rmac string */
159 static inline const char *zl3vni_rmac2str(zebra_l3vni_t
*zl3vni
, char *buf
,
165 ptr
= XMALLOC(MTYPE_TMP
, ETHER_ADDR_STRLEN
* sizeof(char));
167 assert(size
>= ETHER_ADDR_STRLEN
);
171 if (zl3vni
->mac_vlan_if
)
172 snprintf(ptr
, (ETHER_ADDR_STRLEN
),
173 "%02x:%02x:%02x:%02x:%02x:%02x",
174 (uint8_t)zl3vni
->mac_vlan_if
->hw_addr
[0],
175 (uint8_t)zl3vni
->mac_vlan_if
->hw_addr
[1],
176 (uint8_t)zl3vni
->mac_vlan_if
->hw_addr
[2],
177 (uint8_t)zl3vni
->mac_vlan_if
->hw_addr
[3],
178 (uint8_t)zl3vni
->mac_vlan_if
->hw_addr
[4],
179 (uint8_t)zl3vni
->mac_vlan_if
->hw_addr
[5]);
180 else if (zl3vni
->svi_if
)
181 snprintf(ptr
, (ETHER_ADDR_STRLEN
),
182 "%02x:%02x:%02x:%02x:%02x:%02x",
183 (uint8_t)zl3vni
->svi_if
->hw_addr
[0],
184 (uint8_t)zl3vni
->svi_if
->hw_addr
[1],
185 (uint8_t)zl3vni
->svi_if
->hw_addr
[2],
186 (uint8_t)zl3vni
->svi_if
->hw_addr
[3],
187 (uint8_t)zl3vni
->svi_if
->hw_addr
[4],
188 (uint8_t)zl3vni
->svi_if
->hw_addr
[5]);
190 snprintf(ptr
, ETHER_ADDR_STRLEN
, "None");
195 /* get the sys mac string */
196 static inline const char *zl3vni_sysmac2str(zebra_l3vni_t
*zl3vni
, char *buf
,
202 ptr
= XMALLOC(MTYPE_TMP
, ETHER_ADDR_STRLEN
* sizeof(char));
204 assert(size
>= ETHER_ADDR_STRLEN
);
209 snprintf(ptr
, (ETHER_ADDR_STRLEN
),
210 "%02x:%02x:%02x:%02x:%02x:%02x",
211 (uint8_t)zl3vni
->svi_if
->hw_addr
[0],
212 (uint8_t)zl3vni
->svi_if
->hw_addr
[1],
213 (uint8_t)zl3vni
->svi_if
->hw_addr
[2],
214 (uint8_t)zl3vni
->svi_if
->hw_addr
[3],
215 (uint8_t)zl3vni
->svi_if
->hw_addr
[4],
216 (uint8_t)zl3vni
->svi_if
->hw_addr
[5]);
218 snprintf(ptr
, ETHER_ADDR_STRLEN
, "None");
224 * l3-vni is oper up when:
225 * 0. if EVPN is enabled (advertise-all-vni cfged)
226 * 1. it is associated to a vxlan-intf
227 * 2. Associated vxlan-intf is oper up
228 * 3. it is associated to an SVI
229 * 4. associated SVI is oper up
231 static inline int is_l3vni_oper_up(zebra_l3vni_t
*zl3vni
)
233 return (is_evpn_enabled() && zl3vni
&& (zl3vni
->vrf_id
!= VRF_UNKNOWN
)
234 && zl3vni
->vxlan_if
&& if_is_operative(zl3vni
->vxlan_if
)
235 && zl3vni
->svi_if
&& if_is_operative(zl3vni
->svi_if
));
238 static inline const char *zl3vni_state2str(zebra_l3vni_t
*zl3vni
)
243 if (is_l3vni_oper_up(zl3vni
))
251 static inline vrf_id_t
zl3vni_vrf_id(zebra_l3vni_t
*zl3vni
)
253 return zl3vni
->vrf_id
;
256 static inline void zl3vni_get_svi_rmac(zebra_l3vni_t
*zl3vni
,
257 struct ethaddr
*rmac
)
262 if (!is_l3vni_oper_up(zl3vni
))
265 if (zl3vni
->svi_if
&& if_is_operative(zl3vni
->svi_if
))
266 memcpy(rmac
->octet
, zl3vni
->svi_if
->hw_addr
, ETH_ALEN
);
269 struct host_rb_entry
{
270 RB_ENTRY(host_rb_entry
) hl_entry
;
275 RB_HEAD(host_rb_tree_entry
, host_rb_entry
);
276 RB_PROTOTYPE(host_rb_tree_entry
, host_rb_entry
, hl_entry
,
277 host_rb_entry_compare
);
281 * This table contains the MAC addresses pertaining to this VNI.
282 * This includes local MACs learnt on an attached VLAN that maps
283 * to this VNI as well as remote MACs learnt and installed by BGP.
284 * Local MACs will be known either on a VLAN sub-interface or
285 * on (port, VLAN); however, it is sufficient for zebra to maintain
286 * against the VNI i.e., it does not need to retain the local "port"
287 * information. The correct VNI will be obtained as zebra maintains
288 * the mapping (of VLAN to VNI).
290 struct zebra_mac_t_
{
292 struct ethaddr macaddr
;
295 #define ZEBRA_MAC_LOCAL 0x01
296 #define ZEBRA_MAC_REMOTE 0x02
297 #define ZEBRA_MAC_AUTO 0x04 /* Auto created for neighbor. */
298 #define ZEBRA_MAC_STICKY 0x08 /* Static MAC */
299 #define ZEBRA_MAC_REMOTE_RMAC 0x10 /* remote router mac */
300 #define ZEBRA_MAC_DEF_GW 0x20
301 /* remote VTEP advertised MAC as default GW */
302 #define ZEBRA_MAC_REMOTE_DEF_GW 0x40
303 #define ZEBRA_MAC_DUPLICATE 0x80
304 #define ZEBRA_MAC_FPM_SENT 0x100 /* whether or not this entry was sent. */
306 /* back pointer to zvni */
309 /* Local or remote info. */
316 struct in_addr r_vtep_ip
;
319 /* Mobility sequence numbers associated with this entry. */
323 /* List of neigh associated with this mac */
324 struct list
*neigh_list
;
326 /* list of hosts pointing to this remote RMAC */
327 struct host_rb_tree_entry host_rb
;
329 /* Duplicate mac detection */
332 struct thread
*dad_mac_auto_recovery_timer
;
334 struct timeval detect_start_time
;
336 time_t dad_dup_detect_time
;
340 * Context for MAC hash walk - used by callbacks.
342 struct mac_walk_ctx
{
343 zebra_vni_t
*zvni
; /* VNI hash */
344 struct zebra_vrf
*zvrf
; /* VRF - for client notification. */
345 int uninstall
; /* uninstall from kernel? */
346 int upd_client
; /* uninstall from client? */
349 #define DEL_LOCAL_MAC 0x1
350 #define DEL_REMOTE_MAC 0x2
351 #define DEL_ALL_MAC (DEL_LOCAL_MAC | DEL_REMOTE_MAC)
352 #define DEL_REMOTE_MAC_FROM_VTEP 0x4
353 #define SHOW_REMOTE_MAC_FROM_VTEP 0x8
355 struct in_addr r_vtep_ip
; /* To walk MACs from specific VTEP */
357 struct vty
*vty
; /* Used by VTY handlers */
358 uint32_t count
; /* Used by VTY handlers */
359 struct json_object
*json
; /* Used for JSON Output */
360 bool print_dup
; /* Used to print dup addr list */
363 struct rmac_walk_ctx
{
365 struct json_object
*json
;
368 #define IS_ZEBRA_NEIGH_ACTIVE(n) (n->state == ZEBRA_NEIGH_ACTIVE)
370 #define IS_ZEBRA_NEIGH_INACTIVE(n) (n->state == ZEBRA_NEIGH_INACTIVE)
372 #define ZEBRA_NEIGH_SET_ACTIVE(n) n->state = ZEBRA_NEIGH_ACTIVE
374 #define ZEBRA_NEIGH_SET_INACTIVE(n) n->state = ZEBRA_NEIGH_INACTIVE
377 * Neighbor hash table.
379 * This table contains the neighbors (IP to MAC bindings) pertaining to
380 * this VNI. This includes local neighbors learnt on the attached VLAN
381 * device that maps to this VNI as well as remote neighbors learnt and
383 * Local neighbors will be known against the VLAN device (SVI); however,
384 * it is sufficient for zebra to maintain against the VNI. The correct
385 * VNI will be obtained as zebra maintains the mapping (of VLAN to VNI).
387 struct zebra_neigh_t_
{
394 /* Underlying interface. */
400 #define ZEBRA_NEIGH_LOCAL 0x01
401 #define ZEBRA_NEIGH_REMOTE 0x02
402 #define ZEBRA_NEIGH_REMOTE_NH 0x04 /* neigh entry for remote vtep */
403 #define ZEBRA_NEIGH_DEF_GW 0x08
404 #define ZEBRA_NEIGH_ROUTER_FLAG 0x10
405 #define ZEBRA_NEIGH_DUPLICATE 0x20
406 #define ZEBRA_NEIGH_SVI_IP 0x40
408 enum zebra_neigh_state state
;
410 /* Remote VTEP IP - applicable only for remote neighbors. */
411 struct in_addr r_vtep_ip
;
414 * Mobility sequence numbers associated with this entry. The rem_seq
415 * represents the sequence number from the client (BGP) for the most
416 * recent add or update of this entry while the loc_seq represents
417 * the sequence number informed (or to be informed) by zebra to BGP
423 /* list of hosts pointing to this remote NH entry */
424 struct host_rb_tree_entry host_rb
;
426 /* Duplicate ip detection */
429 struct thread
*dad_ip_auto_recovery_timer
;
431 struct timeval detect_start_time
;
433 time_t dad_dup_detect_time
;
437 * Context for neighbor hash walk - used by callbacks.
439 struct neigh_walk_ctx
{
440 zebra_vni_t
*zvni
; /* VNI hash */
441 struct zebra_vrf
*zvrf
; /* VRF - for client notification. */
442 int uninstall
; /* uninstall from kernel? */
443 int upd_client
; /* uninstall from client? */
446 #define DEL_LOCAL_NEIGH 0x1
447 #define DEL_REMOTE_NEIGH 0x2
448 #define DEL_ALL_NEIGH (DEL_LOCAL_NEIGH | DEL_REMOTE_NEIGH)
449 #define DEL_REMOTE_NEIGH_FROM_VTEP 0x4
450 #define SHOW_REMOTE_NEIGH_FROM_VTEP 0x8
452 struct in_addr r_vtep_ip
; /* To walk neighbors from specific VTEP */
454 struct vty
*vty
; /* Used by VTY handlers */
455 uint32_t count
; /* Used by VTY handlers */
456 uint8_t addr_width
; /* Used by VTY handlers */
457 struct json_object
*json
; /* Used for JSON Output */
460 /* context for neigh hash walk - update l3vni and rmac */
461 struct neigh_l3info_walk_ctx
{
464 zebra_l3vni_t
*zl3vni
;
471 struct json_object
*json
;
474 extern zebra_l3vni_t
*zl3vni_from_vrf(vrf_id_t vrf_id
);
475 extern struct interface
*zl3vni_map_to_vxlan_if(zebra_l3vni_t
*zl3vni
);
476 extern struct interface
*zl3vni_map_to_svi_if(zebra_l3vni_t
*zl3vni
);
477 extern struct interface
*zl3vni_map_to_mac_vlan_if(zebra_l3vni_t
*zl3vni
);
479 DECLARE_HOOK(zebra_rmac_update
, (zebra_mac_t
*rmac
, zebra_l3vni_t
*zl3vni
,
480 bool delete, const char *reason
), (rmac
, zl3vni
, delete, reason
))
488 * Multicast hash table.
490 * This table contains -
491 * 1. The (S, G) entries used for encapsulating and forwarding BUM traffic.
492 * S is the local VTEP-IP and G is a BUM mcast group address.
493 * 2. The (X, G) entries used for terminating a BUM flow.
494 * Multiple L2-VNIs can share the same MDT hence the need to maintain
495 * an aggregated table that pimd can consume without much
498 typedef struct zebra_vxlan_sg_
{
499 struct zebra_vrf
*zvrf
;
502 char sg_str
[PREFIX_SG_STR_LEN
];
504 /* For SG - num of L2 VNIs using this entry for sending BUM traffic */
505 /* For XG - num of SG using this as parent */
509 #endif /* _ZEBRA_VXLAN_PRIVATE_H */