]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_evpn_mh.h
zebra: dplane APIs for programming evpn-mh access port attributes
[mirror_frr.git] / zebra / zebra_evpn_mh.h
CommitLineData
ce5160c0
AK
1/*
2 * Zebra EVPN MH Data structures and definitions
3 *
4 * Copyright (C) 2019 Cumulus Networks, Inc.
5 * Anuradha Karuppiah
6 *
7 * This file is part of FRR.
8 *
9 * FRR is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
12 * later version.
13 *
14 * FRR is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#ifndef _ZEBRA_EVPN_MH_H
21#define _ZEBRA_EVPN_MH_H
22
23#include <zebra.h>
24
25#include "if.h"
26#include "linklist.h"
27#include "bitfield.h"
28#include "zebra_vxlan.h"
29#include "zebra_vxlan_private.h"
30
31#define EVPN_MH_VTY_STR "Multihoming\n"
32
33/* Ethernet Segment entry -
34 * - Local and remote ESs are maintained in a global RB tree,
35 * zmh_info->es_rb_tree using ESI as key
36 * - Local ESs are added via zebra config (ZEBRA_EVPNES_LOCAL) when an
37 * access port is associated with an ES-ID
38 * - Remotes ESs are added by BGP based on received/remote EAD/Type-1 routes
39 * (ZEBRA_EVPNES_REMOTE)
40 * - An ES can be simulatenously LOCAL and REMOTE; infact all LOCAL ESs are
41 * expected to have REMOTE ES peers.
42 */
43struct zebra_evpn_es {
44 esi_t esi;
45 char esi_str[ESI_STR_LEN];
46
47 /* ES flags */
48 uint32_t flags;
49#define ZEBRA_EVPNES_LOCAL (1 << 0) /* configured in zebra */
50#define ZEBRA_EVPNES_REMOTE (1 << 1) /* added by bgp */
51#define ZEBRA_EVPNES_OPER_UP (1 << 2) /* es->ifp is oper-up */
52#define ZEBRA_EVPNES_READY_FOR_BGP (1 << 3) /* ready to be sent to BGP */
53#define ZEBRA_EVPNES_NHG_ACTIVE (1 << 4) /* NHG has been installed */
1103c5c6
AK
54/* This flag is only applicable to local ESs and signifies that this
55 * VTEP is not the DF
56 */
57#define ZEBRA_EVPNES_NON_DF (1 << 5)
ce5160c0
AK
58
59 /* memory used for adding the es to zmh_info->es_rb_tree */
60 RB_ENTRY(zebra_evpn_es) rb_node;
61
62 /* [EVPNES_LOCAL] memory used for linking the es to
63 * zmh_info->local_es_list
64 */
65 struct listnode local_es_listnode;
66
67 /* [EVPNES_LOCAL] corresponding interface */
68 struct zebra_if *zif;
69
70 /* list of ES-EVIs associated with the ES */
71 struct list *es_evi_list;
72
73 /* [!EVPNES_LOCAL] List of remote VTEPs (zebra_evpn_es_vtep) */
74 struct list *es_vtep_list;
75
b169fd6f
AK
76 /* list of zebra_mac entries using this ES as destination */
77 struct list *mac_list;
ce5160c0
AK
78
79 /* Nexthop group id */
80 uint32_t nhg_id;
1103c5c6
AK
81
82 /* Preference config for BUM-DF election. Sent to BGP and
83 * advertised via the ESR
84 */
85 uint16_t df_pref;
ce5160c0
AK
86};
87RB_HEAD(zebra_es_rb_head, zebra_evpn_es);
88RB_PROTOTYPE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp);
89
90/* ES per-EVI info
87d76d54
PR
91 * - ES-EVIs are maintained per-EVPN (vni->es_evi_rb_tree)
92 * - Local ES-EVIs are linked to per-EVPN list for quick access
ce5160c0
AK
93 * - Although some infrastucture is present for remote ES-EVIs, currently
94 * BGP does NOT send remote ES-EVIs to zebra. This may change in the
95 * future (but must be changed thoughtfully and only if needed as ES-EVI
96 * can get prolific and come in the way of rapid failovers)
97 */
98struct zebra_evpn_es_evi {
99 struct zebra_evpn_es *es;
87d76d54 100 zebra_evpn_t *zevpn;
ce5160c0
AK
101
102 /* ES-EVI flags */
103 uint32_t flags;
104 /* local ES-EVI */
105#define ZEBRA_EVPNES_EVI_LOCAL (1 << 0) /* created by zebra */
106#define ZEBRA_EVPNES_EVI_READY_FOR_BGP (1 << 1) /* ready to be sent to BGP */
107
108 /* memory used for adding the es_evi to
87d76d54 109 * es_evi->zevpn->es_evi_rb_tree
ce5160c0
AK
110 */
111 RB_ENTRY(zebra_evpn_es_evi) rb_node;
112 /* memory used for linking the es_evi to
87d76d54 113 * es_evi->zevpn->local_es_evi_list
ce5160c0
AK
114 */
115 struct listnode l2vni_listnode;
116 /* memory used for linking the es_evi to
117 * es_evi->es->es_evi_list
118 */
119 struct listnode es_listnode;
120};
121
122/* PE attached to an ES */
123struct zebra_evpn_es_vtep {
124 struct zebra_evpn_es *es; /* parent ES */
125 struct in_addr vtep_ip;
126
1103c5c6
AK
127 uint32_t flags;
128 /* Rxed Type-4 route from this VTEP */
129#define ZEBRA_EVPNES_VTEP_RXED_ESR (1 << 0)
130
ce5160c0
AK
131 /* memory used for adding the entry to es->es_vtep_list */
132 struct listnode es_listnode;
133
134 /* MAC nexthop */
135 uint32_t nh_id;
136
1103c5c6
AK
137 /* Parameters for DF election */
138 uint8_t df_alg;
139 uint32_t df_pref;
140
ce5160c0
AK
141 /* XXX - maintain a backpointer to zebra_vtep_t */
142};
143
144/* Local/access-side broadcast domain - zebra_evpn_access_bd is added to -
145 * zrouter->evpn_vlan_table (for VLAN aware bridges) OR
146 * zrouter->evpn_bridge_table (for VLAN unaware bridges)
147 * XXX - support for VLAN unaware bridges is yet to be flushed out
148 */
149struct zebra_evpn_access_bd {
150 vlanid_t vid;
151
152 struct zebra_if *vxlan_zif; /* vxlan device */
153 /* list of members associated with the BD i.e. (potential) ESs */
154 struct list *mbr_zifs;
87d76d54
PR
155 /* presence of zevpn activates the EVI on all the ESs in mbr_zifs */
156 zebra_evpn_t *zevpn;
ce5160c0
AK
157};
158
159/* multihoming information stored in zrouter */
160#define zmh_info (zrouter.mh_info)
161struct zebra_evpn_mh_info {
162 /* RB tree of Ethernet segments (used for EVPN-MH) */
163 struct zebra_es_rb_head es_rb_tree;
164 /* List of local ESs */
165 struct list *local_es_list;
166
167 /* EVPN MH broadcast domains indexed by the VID */
168 struct hash *evpn_vlan_table;
169
170 /* A base L2-VNI is maintained to derive parameters such as
171 * ES originator-IP.
172 * XXX: once single vxlan device model becomes available this will
173 * not be necessary
174 */
87d76d54 175 zebra_evpn_t *es_base_evpn;
ce5160c0
AK
176 struct in_addr es_originator_ip;
177
178 /* L2 NH and NHG ids -
179 * Most significant 8 bits is type. Lower 24 bits is the value
180 * allocated from the nh_id_bitmap.
181 */
182 bitfield_t nh_id_bitmap;
183#define EVPN_NH_ID_MAX (16*1024)
184#define EVPN_NH_ID_VAL_MASK 0xffffff
185#define EVPN_NH_ID_TYPE_POS 24
186/* The purpose of using different types for NHG and NH is NOT to manage the
187 * id space separately. It is simply to make debugging easier.
188 */
189#define EVPN_NH_ID_TYPE_BIT (1 << EVPN_NH_ID_TYPE_POS)
190#define EVPN_NHG_ID_TYPE_BIT (2 << EVPN_NH_ID_TYPE_POS)
b169fd6f
AK
191
192 /* XXX - re-visit the default hold timer value */
193#define EVPN_MH_MAC_HOLD_TIME_DEF (18 * 60)
194 long mac_hold_time;
195#define EVPN_MH_NEIGH_HOLD_TIME_DEF (18 * 60)
196 long neigh_hold_time;
ce5160c0
AK
197};
198
199static inline bool zebra_evpn_mac_is_es_local(zebra_mac_t *mac)
200{
201 return mac->es && (mac->es->flags & ZEBRA_EVPNES_LOCAL);
202}
203
204/* Returns true if the id is of L2-NHG or L2-NH type */
205static inline bool zebra_evpn_mh_is_fdb_nh(uint32_t id)
206{
207 return ((id & EVPN_NHG_ID_TYPE_BIT) ||
208 (id & EVPN_NH_ID_TYPE_BIT));
209}
210
211/*****************************************************************************/
212extern esi_t *zero_esi;
213extern void zebra_evpn_mh_init(void);
214extern void zebra_evpn_mh_terminate(void);
215extern bool zebra_evpn_is_if_es_capable(struct zebra_if *zif);
216extern void zebra_evpn_if_init(struct zebra_if *zif);
217extern void zebra_evpn_if_cleanup(struct zebra_if *zif);
945ee7b2
AK
218extern void zebra_evpn_es_evi_init(zebra_evpn_t *zevpn);
219extern void zebra_evpn_es_evi_cleanup(zebra_evpn_t *zevpn);
87d76d54 220extern void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, zebra_evpn_t *zevpn,
ce5160c0 221 bool set);
87d76d54
PR
222extern void zebra_evpn_es_set_base_evpn(zebra_evpn_t *zevpn);
223extern void zebra_evpn_es_clear_base_evpn(zebra_evpn_t *zevpn);
ce5160c0
AK
224extern void zebra_evpn_vl_vxl_ref(uint16_t vid, struct zebra_if *vxlan_zif);
225extern void zebra_evpn_vl_vxl_deref(uint16_t vid, struct zebra_if *vxlan_zif);
226extern void zebra_evpn_vl_mbr_ref(uint16_t vid, struct zebra_if *zif);
227extern void zebra_evpn_vl_mbr_deref(uint16_t vid, struct zebra_if *zif);
228extern void zebra_evpn_es_send_all_to_client(bool add);
229extern void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up);
230extern void zebra_evpn_es_show(struct vty *vty, bool uj);
231extern void zebra_evpn_es_show_detail(struct vty *vty, bool uj);
232extern void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi);
87d76d54 233extern void zebra_evpn_update_all_es(zebra_evpn_t *zevpn);
ce5160c0
AK
234extern void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS);
235extern void zebra_evpn_es_evi_show(struct vty *vty, bool uj, int detail);
236extern void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj,
237 vni_t vni, int detail);
238extern void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac);
239extern bool zebra_evpn_es_mac_ref_entry(zebra_mac_t *mac,
240 struct zebra_evpn_es *es);
b169fd6f 241extern bool zebra_evpn_es_mac_ref(zebra_mac_t *mac, esi_t *esi);
ce5160c0
AK
242extern struct zebra_evpn_es *zebra_evpn_es_find(esi_t *esi);
243extern void zebra_evpn_interface_init(void);
244extern int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp);
245extern void zebra_evpn_acc_vl_show(struct vty *vty, bool uj);
246extern void zebra_evpn_acc_vl_show_detail(struct vty *vty, bool uj);
247extern void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid);
248extern void zebra_evpn_if_es_print(struct vty *vty, struct zebra_if *zif);
249extern void zebra_evpn_es_cleanup(void);
b169fd6f
AK
250extern int zebra_evpn_mh_mac_holdtime_update(struct vty *vty,
251 uint32_t duration, bool set_default);
252void zebra_evpn_mh_config_write(struct vty *vty);
253int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty,
254 uint32_t duration, bool set_default);
ce5160c0
AK
255
256#endif /* _ZEBRA_EVPN_MH_H */