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