diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:16:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:16:35 +0000 |
commit | e2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch) | |
tree | f0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /zebra/zebra_vxlan_private.h | |
parent | Initial commit. (diff) | |
download | frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip |
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'zebra/zebra_vxlan_private.h')
-rw-r--r-- | zebra/zebra_vxlan_private.h | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h new file mode 100644 index 0000000..002fc7d --- /dev/null +++ b/zebra/zebra_vxlan_private.h @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Zebra VxLAN (EVPN) Data structures and definitions + * These are "internal" to this function. + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + */ + +#ifndef _ZEBRA_VXLAN_PRIVATE_H +#define _ZEBRA_VXLAN_PRIVATE_H + +#include <zebra.h> + +#include "if.h" +#include "linklist.h" +#include "zebra_vxlan.h" +#include "zebra_vxlan_if.h" +#include "zebra_evpn.h" +#include "zebra_evpn_mac.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ERR_STR_SZ 256 + +/* L3 VNI hash table */ +struct zebra_l3vni { + + /* VNI key */ + vni_t vni; + + /* vrf_id */ + vrf_id_t vrf_id; + + uint32_t filter; +#define PREFIX_ROUTES_ONLY (1 << 0) /* l3-vni used for prefix routes only */ + + /* Corresponding Bridge information */ + vlanid_t vid; + struct interface *bridge_if; + + /* Local IP */ + struct in_addr local_vtep_ip; + + /* kernel interface for l3vni */ + struct interface *vxlan_if; + + /* SVI interface corresponding to the l3vni */ + struct interface *svi_if; + + struct interface *mac_vlan_if; + + /* list of L2 VNIs associated with the L3 VNI */ + struct list *l2vnis; + + /* list of remote router-macs */ + struct hash *rmac_table; + + /* list of remote vtep-ip neigh */ + struct hash *nh_table; +}; + +#define IS_ZL3VNI_SVD_BACKED(zl3vni) \ + (zl3vni->vxlan_if && zl3vni->vxlan_if->info && \ + IS_ZEBRA_VXLAN_IF_SVD((struct zebra_if *)zl3vni->vxlan_if->info)) + +/* get the vx-intf name for l3vni */ +static inline const char *zl3vni_vxlan_if_name(struct zebra_l3vni *zl3vni) +{ + return zl3vni->vxlan_if ? zl3vni->vxlan_if->name : "None"; +} + +/* get the svi intf name for l3vni */ +static inline const char *zl3vni_svi_if_name(struct zebra_l3vni *zl3vni) +{ + return zl3vni->svi_if ? zl3vni->svi_if->name : "None"; +} + +/* get the vrf name for l3vni */ +static inline const char *zl3vni_vrf_name(struct zebra_l3vni *zl3vni) +{ + return vrf_id_to_name(zl3vni->vrf_id); +} + +/* get the rmac string */ +static inline const char *zl3vni_rmac2str(struct zebra_l3vni *zl3vni, char *buf, + int size) +{ + char *ptr; + + if (!buf) + ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char)); + else { + assert(size >= ETHER_ADDR_STRLEN); + ptr = buf; + } + + if (zl3vni->mac_vlan_if) + snprintf(ptr, (ETHER_ADDR_STRLEN), + "%02x:%02x:%02x:%02x:%02x:%02x", + (uint8_t)zl3vni->mac_vlan_if->hw_addr[0], + (uint8_t)zl3vni->mac_vlan_if->hw_addr[1], + (uint8_t)zl3vni->mac_vlan_if->hw_addr[2], + (uint8_t)zl3vni->mac_vlan_if->hw_addr[3], + (uint8_t)zl3vni->mac_vlan_if->hw_addr[4], + (uint8_t)zl3vni->mac_vlan_if->hw_addr[5]); + else if (zl3vni->svi_if) + snprintf(ptr, (ETHER_ADDR_STRLEN), + "%02x:%02x:%02x:%02x:%02x:%02x", + (uint8_t)zl3vni->svi_if->hw_addr[0], + (uint8_t)zl3vni->svi_if->hw_addr[1], + (uint8_t)zl3vni->svi_if->hw_addr[2], + (uint8_t)zl3vni->svi_if->hw_addr[3], + (uint8_t)zl3vni->svi_if->hw_addr[4], + (uint8_t)zl3vni->svi_if->hw_addr[5]); + else + snprintf(ptr, ETHER_ADDR_STRLEN, "None"); + + return ptr; +} + +/* get the sys mac string */ +static inline const char *zl3vni_sysmac2str(struct zebra_l3vni *zl3vni, + char *buf, int size) +{ + char *ptr; + + if (!buf) + ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char)); + else { + assert(size >= ETHER_ADDR_STRLEN); + ptr = buf; + } + + if (zl3vni->svi_if) + snprintf(ptr, (ETHER_ADDR_STRLEN), + "%02x:%02x:%02x:%02x:%02x:%02x", + (uint8_t)zl3vni->svi_if->hw_addr[0], + (uint8_t)zl3vni->svi_if->hw_addr[1], + (uint8_t)zl3vni->svi_if->hw_addr[2], + (uint8_t)zl3vni->svi_if->hw_addr[3], + (uint8_t)zl3vni->svi_if->hw_addr[4], + (uint8_t)zl3vni->svi_if->hw_addr[5]); + else + snprintf(ptr, ETHER_ADDR_STRLEN, "None"); + + return ptr; +} + +/* + * l3-vni is oper up when: + * 0. if EVPN is enabled (advertise-all-vni cfged) + * 1. it is associated to a vxlan-intf + * 2. Associated vxlan-intf is oper up + * 3. it is associated to an SVI + * 4. associated SVI is oper up + */ +static inline int is_l3vni_oper_up(struct zebra_l3vni *zl3vni) +{ + return (is_evpn_enabled() && zl3vni && (zl3vni->vrf_id != VRF_UNKNOWN) + && zl3vni->vxlan_if && if_is_operative(zl3vni->vxlan_if) + && zl3vni->svi_if && if_is_operative(zl3vni->svi_if)); +} + +static inline const char *zl3vni_state2str(struct zebra_l3vni *zl3vni) +{ + if (!zl3vni) + return NULL; + + if (is_l3vni_oper_up(zl3vni)) + return "Up"; + else + return "Down"; + + return NULL; +} + +static inline vrf_id_t zl3vni_vrf_id(struct zebra_l3vni *zl3vni) +{ + return zl3vni->vrf_id; +} + +static inline void zl3vni_get_svi_rmac(struct zebra_l3vni *zl3vni, + struct ethaddr *rmac) +{ + if (!zl3vni) + return; + + if (!is_l3vni_oper_up(zl3vni)) + return; + + if (zl3vni->svi_if && if_is_operative(zl3vni->svi_if)) + memcpy(rmac->octet, zl3vni->svi_if->hw_addr, ETH_ALEN); +} + + +/* context for neigh hash walk - update l3vni and rmac */ +struct neigh_l3info_walk_ctx { + + struct zebra_evpn *zevpn; + struct zebra_l3vni *zl3vni; + int add; +}; + +struct nh_walk_ctx { + + struct vty *vty; + struct json_object *json; +}; + +extern struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id); +extern struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni); +extern struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni); +extern struct interface *zl3vni_map_to_mac_vlan_if(struct zebra_l3vni *zl3vni); +extern struct zebra_l3vni *zl3vni_lookup(vni_t vni); +extern vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if); + +DECLARE_HOOK(zebra_rmac_update, + (struct zebra_mac * rmac, struct zebra_l3vni *zl3vni, bool delete, + const char *reason), + (rmac, zl3vni, delete, reason)); + + +#ifdef __cplusplus +} +#endif + +/* + * Multicast hash table. + * + * This table contains - + * 1. The (S, G) entries used for encapsulating and forwarding BUM traffic. + * S is the local VTEP-IP and G is a BUM mcast group address. + * 2. The (X, G) entries used for terminating a BUM flow. + * Multiple L2-VNIs can share the same MDT hence the need to maintain + * an aggregated table that pimd can consume without much + * re-interpretation. + */ +struct zebra_vxlan_sg { + struct zebra_vrf *zvrf; + + struct prefix_sg sg; + char sg_str[PREFIX_SG_STR_LEN]; + + /* For SG - num of L2 VNIs using this entry for sending BUM traffic */ + /* For XG - num of SG using this as parent */ + uint32_t ref_cnt; +}; + +extern struct zebra_evpn *zevpn_lookup(vni_t vni); +extern void zebra_vxlan_sync_mac_dp_install(struct zebra_mac *mac, + bool set_inactive, + bool force_clear_static, + const char *caller); +extern bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf); +extern void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, + struct in_addr mcast_grp); +extern void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, + struct in_addr mcast_grp); +extern void zebra_vxlan_process_l3vni_oper_up(struct zebra_l3vni *zl3vni); +extern void zebra_vxlan_process_l3vni_oper_down(struct zebra_l3vni *zl3vni); +extern int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn); + +#endif /* _ZEBRA_VXLAN_PRIVATE_H */ |