]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_evpn_mh.h
Merge pull request #7639 from qlyoung/frr-lua
[mirror_frr.git] / bgpd / bgp_evpn_mh.h
1 /* EVPN header for multihoming procedures
2 *
3 * Copyright (C) 2019 Cumulus Networks
4 * Anuradha Karuppiah
5 *
6 * This file is part of FRRouting.
7 *
8 * FRRouting 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
11 * later version.
12 *
13 * FRRouting 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.
17 *
18 */
19
20 #ifndef _FRR_BGP_EVPN_MH_H
21 #define _FRR_BGP_EVPN_MH_H
22
23 #include "vxlan.h"
24 #include "bgpd.h"
25 #include "bgp_evpn.h"
26 #include "bgp_evpn_private.h"
27
28 #define BGP_EVPN_AD_ES_ETH_TAG 0xffffffff
29 #define BGP_EVPN_AD_EVI_ETH_TAG 0
30
31 #define BGP_EVPNES_INCONS_STR_SZ 80
32 #define BGP_EVPN_FLAG_STR_SZ 5
33 #define BGP_EVPN_VTEPS_FLAG_STR_SZ (BGP_EVPN_FLAG_STR_SZ * ES_VTEP_MAX_CNT)
34
35 #define BGP_EVPN_CONS_CHECK_INTERVAL 60
36
37 #define BGP_EVPN_MH_USE_ES_L3NHG_DEF true
38
39 /* Ethernet Segment entry -
40 * - Local and remote ESs are maintained in a global RB tree,
41 * bgp_mh_info->es_rb_tree using ESI as key
42 * - Local ESs are received from zebra (BGP_EVPNES_LOCAL)
43 * - Remotes ESs are implicitly created (by reference) by a remote ES-EVI
44 * (BGP_EVPNES_REMOTE)
45 * - An ES can be simulatenously LOCAL and REMOTE; infact all LOCAL ESs are
46 * expected to have REMOTE ES peers.
47 */
48 struct bgp_evpn_es {
49 /* Ethernet Segment Identifier */
50 esi_t esi;
51 char esi_str[ESI_STR_LEN];
52
53 /* es flags */
54 uint32_t flags;
55 /* created via zebra config */
56 #define BGP_EVPNES_LOCAL (1 << 0)
57 /* created implicitly by a remote ES-EVI reference */
58 #define BGP_EVPNES_REMOTE (1 << 1)
59 /* local ES link is oper-up */
60 #define BGP_EVPNES_OPER_UP (1 << 2)
61 /* enable generation of EAD-EVI routes */
62 #define BGP_EVPNES_ADV_EVI (1 << 3)
63 /* consistency checks pending */
64 #define BGP_EVPNES_CONS_CHECK_PEND (1 << 4)
65
66 /* memory used for adding the es to bgp->es_rb_tree */
67 RB_ENTRY(bgp_evpn_es) rb_node;
68
69 /* [EVPNES_LOCAL] memory used for linking the es to
70 * bgp_mh_info->local_es_list
71 */
72 struct listnode es_listnode;
73
74 /* memory used for linking the es to "processing" pending list
75 * bgp_mh_info->pend_es_list
76 */
77 struct listnode pend_es_listnode;
78
79 /* [EVPNES_LOCAL] Id for deriving the RD automatically for this ESI */
80 uint16_t rd_id;
81
82 /* [EVPNES_LOCAL] RD for this ES */
83 struct prefix_rd prd;
84
85 /* [EVPNES_LOCAL] originator ip address */
86 struct in_addr originator_ip;
87
88 /* [EVPNES_LOCAL] Route table for EVPN routes for this ESI-
89 * - Type-4 local and remote routes
90 * - Type-1 local routes
91 */
92 struct bgp_table *route_table;
93
94 /* list of PEs (bgp_evpn_es_vtep) attached to the ES */
95 struct list *es_vtep_list;
96
97 /* List of ES-EVIs associated with this ES */
98 struct list *es_evi_list;
99
100 /* List of ES-VRFs associated with this ES */
101 struct list *es_vrf_list;
102
103 /* List of MAC-IP VNI paths using this ES as destination -
104 * element is bgp_path_info_extra->es_info
105 */
106 struct list *macip_path_list;
107
108 /* Number of remote VNIs referencing this ES */
109 uint32_t remote_es_evi_cnt;
110
111 uint32_t inconsistencies;
112 /* there are one or more EVIs whose VTEP list doesn't match
113 * with the ES's VTEP list
114 */
115 #define BGP_EVPNES_INCONS_VTEP_LIST (1 << 0)
116
117 /* number of es-evi entries whose VTEP list doesn't match
118 * with the ES's
119 */
120 uint32_t incons_evi_vtep_cnt;
121
122 /* preference config for BUM-DF election. advertised via the ESR. */
123 uint16_t df_pref;
124
125 QOBJ_FIELDS
126 };
127 DECLARE_QOBJ_TYPE(bgp_evpn_es)
128 RB_HEAD(bgp_es_rb_head, bgp_evpn_es);
129 RB_PROTOTYPE(bgp_es_rb_head, bgp_evpn_es, rb_node, bgp_es_rb_cmp);
130
131 /* PE attached to an ES */
132 struct bgp_evpn_es_vtep {
133 struct bgp_evpn_es *es; /* parent ES */
134 struct in_addr vtep_ip;
135
136 uint32_t flags;
137 /* Rxed a Type4 route from this PE */
138 #define BGP_EVPNES_VTEP_ESR (1 << 0)
139 /* Active (rxed EAD-ES and EAD-EVI) and can be included as
140 * a nexthop
141 */
142 #define BGP_EVPNES_VTEP_ACTIVE (1 << 1)
143
144 uint32_t evi_cnt; /* es_evis referencing this vtep as an active path */
145
146 /* Algorithm and preference for DF election. Rxed via the ESR */
147 uint8_t df_alg;
148 uint16_t df_pref;
149
150 /* memory used for adding the entry to es->es_vtep_list */
151 struct listnode es_listnode;
152 };
153
154 /* ES-VRF element needed for managing L3 NHGs. It is implicitly created
155 * when an ES-EVI is associated with a tenant VRF
156 */
157 struct bgp_evpn_es_vrf {
158 struct bgp_evpn_es *es;
159 struct bgp *bgp_vrf;
160
161 uint32_t flags;
162 /* NHG can only be activated if there are active VTEPs in the ES and
163 * there is a valid L3-VNI associated with the VRF
164 */
165 #define BGP_EVPNES_VRF_NHG_ACTIVE (1 << 0)
166
167 /* memory used for adding the es_vrf to
168 * es_vrf->bgp_vrf->es_vrf_rb_tree
169 */
170 RB_ENTRY(bgp_evpn_es_vrf) rb_node;
171
172 /* memory used for linking the es_vrf to es_vrf->es->es_vrf_list */
173 struct listnode es_listnode;
174
175 uint32_t nhg_id;
176 uint32_t v6_nhg_id;
177
178 /* Number of ES-EVI entries associated with this ES-VRF */
179 uint32_t ref_cnt;
180 };
181
182 /* ES per-EVI info
183 * - ES-EVIs are maintained per-L2-VNI (vpn->es_evi_rb_tree)
184 * - ES-EVIs are also linked to the parent ES (es->es_evi_list)
185 * - Local ES-EVIs are created by zebra (via config). They are linked to a
186 * per-VNI list (vpn->local_es_evi_list) for quick access
187 * - Remote ES-EVIs are created implicitly when a bgp_evpn_es_evi_vtep
188 * references it.
189 */
190 struct bgp_evpn_es_evi {
191 struct bgp_evpn_es *es;
192 struct bgpevpn *vpn;
193
194 /* ES-EVI flags */
195 uint32_t flags;
196 /* local ES-EVI, created by zebra */
197 #define BGP_EVPNES_EVI_LOCAL (1 << 0)
198 /* created via a remote VTEP imported by BGP */
199 #define BGP_EVPNES_EVI_REMOTE (1 << 1)
200 #define BGP_EVPNES_EVI_INCONS_VTEP_LIST (1 << 2)
201
202 /* memory used for adding the es_evi to es_evi->vpn->es_evi_rb_tree */
203 RB_ENTRY(bgp_evpn_es_evi) rb_node;
204 /* memory used for linking the es_evi to
205 * es_evi->vpn->local_es_evi_list
206 */
207 struct listnode l2vni_listnode;
208 /* memory used for linking the es_evi to
209 * es_evi->es->es_evi_list
210 */
211 struct listnode es_listnode;
212
213 /* list of PEs (bgp_evpn_es_evi_vtep) attached to the ES for this VNI */
214 struct list *es_evi_vtep_list;
215
216 struct bgp_evpn_es_vrf *es_vrf;
217 };
218
219 /* PE attached to an ES for a VNI. This entry is created when an EAD-per-ES
220 * or EAD-per-EVI Type1 route is imported into the VNI.
221 */
222 struct bgp_evpn_es_evi_vtep {
223 struct bgp_evpn_es_evi *es_evi; /* parent ES-EVI */
224 struct in_addr vtep_ip;
225
226 uint32_t flags;
227 /* Rxed an EAD-per-ES route from the PE */
228 #define BGP_EVPN_EVI_VTEP_EAD_PER_ES (1 << 0) /* rxed EAD-per-ES */
229 /* Rxed an EAD-per-EVI route from the PE */
230 #define BGP_EVPN_EVI_VTEP_EAD_PER_EVI (1 << 1) /* rxed EAD-per-EVI */
231 /* VTEP is active i.e. will result in the creation of an es-vtep */
232 #define BGP_EVPN_EVI_VTEP_ACTIVE (1 << 2)
233 #define BGP_EVPN_EVI_VTEP_EAD (BGP_EVPN_EVI_VTEP_EAD_PER_ES |\
234 BGP_EVPN_EVI_VTEP_EAD_PER_EVI)
235
236 /* memory used for adding the entry to es_evi->es_evi_vtep_list */
237 struct listnode es_evi_listnode;
238 struct bgp_evpn_es_vtep *es_vtep;
239 };
240
241 /* multihoming information stored in bgp_master */
242 #define bgp_mh_info (bm->mh_info)
243 struct bgp_evpn_mh_info {
244 /* RB tree of Ethernet segments (used for EVPN-MH) */
245 struct bgp_es_rb_head es_rb_tree;
246 /* List of local ESs */
247 struct list *local_es_list;
248 /* List of ESs with pending/periodic processing */
249 struct list *pend_es_list;
250 /* periodic timer for running background consistency checks */
251 struct thread *t_cons_check;
252
253 /* config knobs for optimizing or interop */
254 /* Generate EAD-EVI routes even if the ES is oper-down. This can be
255 * enabled as an optimization to avoid a storm of updates when an ES
256 * link flaps.
257 */
258 bool ead_evi_adv_for_down_links;
259 /* Enable ES consistency checking */
260 bool consistency_checking;
261 /* Use L3 NHGs for host routes in symmetric IRB */
262 bool install_l3nhg;
263 bool host_routes_use_l3nhg;
264 };
265
266 /****************************************************************************/
267 static inline int bgp_evpn_is_es_local(struct bgp_evpn_es *es)
268 {
269 return CHECK_FLAG(es->flags, BGP_EVPNES_LOCAL) ? 1 : 0;
270 }
271
272 extern esi_t *zero_esi;
273 static inline bool bgp_evpn_is_esi_valid(esi_t *esi)
274 {
275 return !!memcmp(esi, zero_esi, sizeof(esi_t));
276 }
277
278 static inline esi_t *bgp_evpn_attr_get_esi(struct attr *attr)
279 {
280 return attr ? &attr->esi : zero_esi;
281 }
282
283 static inline bool bgp_evpn_attr_is_sync(struct attr *attr)
284 {
285 return attr ? !!(attr->es_flags &
286 (ATTR_ES_PEER_PROXY | ATTR_ES_PEER_ACTIVE)) : false;
287 }
288
289 static inline uint32_t bgp_evpn_attr_get_sync_seq(struct attr *attr)
290 {
291 return attr ? attr->mm_sync_seqnum : 0;
292 }
293
294 static inline bool bgp_evpn_attr_is_active_on_peer(struct attr *attr)
295 {
296 return attr ?
297 !!(attr->es_flags & ATTR_ES_PEER_ACTIVE) : false;
298 }
299
300 static inline bool bgp_evpn_attr_is_router_on_peer(struct attr *attr)
301 {
302 return attr ?
303 !!(attr->es_flags & ATTR_ES_PEER_ROUTER) : false;
304 }
305
306 static inline bool bgp_evpn_attr_is_proxy(struct attr *attr)
307 {
308 return attr ? !!(attr->es_flags & ATTR_ES_PROXY_ADVERT) : false;
309 }
310
311 static inline bool bgp_evpn_attr_is_local_es(struct attr *attr)
312 {
313 return attr ? !!(attr->es_flags & ATTR_ES_IS_LOCAL) : false;
314 }
315
316 static inline uint32_t bgp_evpn_attr_get_df_pref(struct attr *attr)
317 {
318 return (attr) ? attr->df_pref : 0;
319 }
320
321 /****************************************************************************/
322 extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp,
323 struct bgp_evpn_es *es, afi_t afi, safi_t safi,
324 struct prefix_evpn *evp, struct bgp_path_info *pi,
325 int install);
326 int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi,
327 struct attr *attr, uint8_t *pfx, int psize,
328 uint32_t addpath_id);
329 int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi,
330 struct attr *attr, uint8_t *pfx, int psize,
331 uint32_t addpath_id);
332 extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
333 struct in_addr originator_ip, bool oper_up,
334 uint16_t df_pref);
335 extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi);
336 extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni);
337 extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni);
338 extern int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
339 const struct prefix_evpn *p);
340 extern int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
341 const struct prefix_evpn *p);
342 extern void bgp_evpn_mh_init(void);
343 extern void bgp_evpn_mh_finish(void);
344 void bgp_evpn_vni_es_init(struct bgpevpn *vpn);
345 void bgp_evpn_vni_es_cleanup(struct bgpevpn *vpn);
346 void bgp_evpn_es_show_esi(struct vty *vty, esi_t *esi, bool uj);
347 void bgp_evpn_es_show(struct vty *vty, bool uj, bool detail);
348 void bgp_evpn_es_evi_show_vni(struct vty *vty, vni_t vni,
349 bool uj, bool detail);
350 void bgp_evpn_es_evi_show(struct vty *vty, bool uj, bool detail);
351 struct bgp_evpn_es *bgp_evpn_es_find(const esi_t *esi);
352 extern bool bgp_evpn_is_esi_local(esi_t *esi);
353 extern void bgp_evpn_vrf_es_init(struct bgp *bgp_vrf);
354 extern void bgp_evpn_es_vrf_deref(struct bgp_evpn_es_evi *es_evi);
355 extern void bgp_evpn_es_vrf_ref(struct bgp_evpn_es_evi *es_evi,
356 struct bgp *bgp_vrf);
357 extern void bgp_evpn_path_es_info_free(struct bgp_path_es_info *es_info);
358 extern void bgp_evpn_path_es_unlink(struct bgp_path_es_info *es_info);
359 extern void bgp_evpn_path_es_link(struct bgp_path_info *pi, vni_t vni,
360 esi_t *esi);
361 extern bool bgp_evpn_es_is_vtep_active(esi_t *esi, struct in_addr nh);
362 extern bool bgp_evpn_path_es_use_nhg(struct bgp *bgp_vrf,
363 struct bgp_path_info *pi, uint32_t *nhg_p);
364 extern void bgp_evpn_es_vrf_show(struct vty *vty, bool uj,
365 struct bgp_evpn_es *es);
366 extern void bgp_evpn_es_vrf_show_esi(struct vty *vty, esi_t *esi, bool uj);
367
368 #endif /* _FRR_BGP_EVPN_MH_H */