/src/frr/bgpd/bgp_evpn_mh.h
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* EVPN header for multihoming procedures |
3 | | * |
4 | | * Copyright (C) 2019 Cumulus Networks |
5 | | * Anuradha Karuppiah |
6 | | * |
7 | | */ |
8 | | |
9 | | #ifndef _FRR_BGP_EVPN_MH_H |
10 | | #define _FRR_BGP_EVPN_MH_H |
11 | | |
12 | | #include "vxlan.h" |
13 | | #include "bgpd.h" |
14 | | #include "bgp_evpn.h" |
15 | | #include "bgp_evpn_private.h" |
16 | | |
17 | 0 | #define BGP_EVPN_AD_ES_ETH_TAG 0xffffffff |
18 | 0 | #define BGP_EVPN_AD_EVI_ETH_TAG 0 |
19 | | |
20 | | #define BGP_EVPNES_INCONS_STR_SZ 80 |
21 | | #define BGP_EVPN_VTEPS_FLAG_STR_SZ (BGP_EVPN_FLAG_STR_SZ * ES_VTEP_MAX_CNT) |
22 | | |
23 | | #define BGP_EVPN_CONS_CHECK_INTERVAL 60 |
24 | | |
25 | 1 | #define BGP_EVPN_MH_USE_ES_L3NHG_DEF true |
26 | | |
27 | | /* XXX - tune this */ |
28 | 1 | #define BGP_EVPN_MAX_EVI_PER_ES_FRAG 128 |
29 | | |
30 | | /* An ES can result in multiple EAD-per-ES route. Each EAD fragment is |
31 | | * associated with an unique RD |
32 | | */ |
33 | | struct bgp_evpn_es_frag { |
34 | | /* frag is associated with a parent ES */ |
35 | | struct bgp_evpn_es *es; |
36 | | |
37 | | /* Id for deriving the RD automatically for this ES fragment */ |
38 | | uint16_t rd_id; |
39 | | /* RD for this ES fragment */ |
40 | | struct prefix_rd prd; |
41 | | |
42 | | /* Memory used for linking bgp_evpn_es_frag to |
43 | | * bgp_evpn_es->es_frag_list |
44 | | */ |
45 | | struct listnode es_listnode; |
46 | | |
47 | | /* List of ES-EVIs associated with this fragment */ |
48 | | struct list *es_evi_frag_list; |
49 | | }; |
50 | | |
51 | | /* Ethernet Segment entry - |
52 | | * - Local and remote ESs are maintained in a global RB tree, |
53 | | * bgp_mh_info->es_rb_tree using ESI as key |
54 | | * - Local ESs are received from zebra (BGP_EVPNES_LOCAL) |
55 | | * - Remotes ESs are implicitly created (by reference) by a remote ES-EVI |
56 | | * (BGP_EVPNES_REMOTE) |
57 | | * - An ES can be simultaneously LOCAL and REMOTE; infact all LOCAL ESs are |
58 | | * expected to have REMOTE ES peers. |
59 | | */ |
60 | | struct bgp_evpn_es { |
61 | | /* Ethernet Segment Identifier */ |
62 | | esi_t esi; |
63 | | char esi_str[ESI_STR_LEN]; |
64 | | |
65 | | /* es flags */ |
66 | | uint32_t flags; |
67 | | /* created via zebra config */ |
68 | 0 | #define BGP_EVPNES_LOCAL (1 << 0) |
69 | | /* created implicitly by a remote ES-EVI reference */ |
70 | 0 | #define BGP_EVPNES_REMOTE (1 << 1) |
71 | | /* local ES link is oper-up */ |
72 | 0 | #define BGP_EVPNES_OPER_UP (1 << 2) |
73 | | /* enable generation of EAD-EVI routes */ |
74 | 0 | #define BGP_EVPNES_ADV_EVI (1 << 3) |
75 | | /* consistency checks pending */ |
76 | | #define BGP_EVPNES_CONS_CHECK_PEND (1 << 4) |
77 | | /* ES is in LACP bypass mode - don't advertise EAD-ES or ESR */ |
78 | 0 | #define BGP_EVPNES_BYPASS (1 << 5) |
79 | | /* bits needed for printing the flags + null */ |
80 | | #define BGP_EVPN_FLAG_STR_SZ 7 |
81 | | |
82 | | /* memory used for adding the es to bgp->es_rb_tree */ |
83 | | RB_ENTRY(bgp_evpn_es) rb_node; |
84 | | |
85 | | /* [EVPNES_LOCAL] memory used for linking the es to |
86 | | * bgp_mh_info->local_es_list |
87 | | */ |
88 | | struct listnode es_listnode; |
89 | | |
90 | | /* memory used for linking the es to "processing" pending list |
91 | | * bgp_mh_info->pend_es_list |
92 | | */ |
93 | | struct listnode pend_es_listnode; |
94 | | |
95 | | /* [EVPNES_LOCAL] List of RDs for this ES (bgp_evpn_es_frag) */ |
96 | | struct list *es_frag_list; |
97 | | struct bgp_evpn_es_frag *es_base_frag; |
98 | | |
99 | | /* [EVPNES_LOCAL] originator ip address */ |
100 | | struct in_addr originator_ip; |
101 | | |
102 | | /* [EVPNES_LOCAL] Route table for EVPN routes for this ESI- |
103 | | * - Type-4 local and remote routes |
104 | | * - Type-1 local routes |
105 | | */ |
106 | | struct bgp_table *route_table; |
107 | | |
108 | | /* list of PEs (bgp_evpn_es_vtep) attached to the ES */ |
109 | | struct list *es_vtep_list; |
110 | | |
111 | | /* List of ES-EVIs associated with this ES */ |
112 | | struct list *es_evi_list; |
113 | | |
114 | | /* List of ES-VRFs associated with this ES */ |
115 | | struct list *es_vrf_list; |
116 | | |
117 | | /* List of MAC-IP VNI paths using this ES as destination - |
118 | | * element is bgp_path_info_extra->es_info |
119 | | * Note: Only local/zebra-added MACIP paths in the VNI |
120 | | * routing table are linked to this list |
121 | | */ |
122 | | struct list *macip_evi_path_list; |
123 | | |
124 | | /* List of MAC-IP paths in the global routing table using this |
125 | | * ES as destination - data is bgp_path_info_extra->es_info |
126 | | * Note: Only non-local/imported MACIP paths in the global |
127 | | * routing table are linked to this list |
128 | | */ |
129 | | struct list *macip_global_path_list; |
130 | | |
131 | | /* Number of remote VNIs referencing this ES */ |
132 | | uint32_t remote_es_evi_cnt; |
133 | | |
134 | | uint32_t inconsistencies; |
135 | | /* there are one or more EVIs whose VTEP list doesn't match |
136 | | * with the ES's VTEP list |
137 | | */ |
138 | 0 | #define BGP_EVPNES_INCONS_VTEP_LIST (1 << 0) |
139 | | |
140 | | /* number of es-evi entries whose VTEP list doesn't match |
141 | | * with the ES's |
142 | | */ |
143 | | uint32_t incons_evi_vtep_cnt; |
144 | | |
145 | | /* preference config for BUM-DF election. advertised via the ESR. */ |
146 | | uint16_t df_pref; |
147 | | |
148 | | QOBJ_FIELDS; |
149 | | }; |
150 | | DECLARE_QOBJ_TYPE(bgp_evpn_es); |
151 | | RB_HEAD(bgp_es_rb_head, bgp_evpn_es); |
152 | | RB_PROTOTYPE(bgp_es_rb_head, bgp_evpn_es, rb_node, bgp_es_rb_cmp); |
153 | | |
154 | | /* PE attached to an ES */ |
155 | | struct bgp_evpn_es_vtep { |
156 | | struct bgp_evpn_es *es; /* parent ES */ |
157 | | struct in_addr vtep_ip; |
158 | | |
159 | | char vtep_str[INET6_ADDRSTRLEN]; |
160 | | |
161 | | uint32_t flags; |
162 | | /* Rxed a Type4 route from this PE */ |
163 | 0 | #define BGP_EVPNES_VTEP_ESR (1 << 0) |
164 | | /* Active (rxed EAD-ES and EAD-EVI) and can be included as |
165 | | * a nexthop |
166 | | */ |
167 | 0 | #define BGP_EVPNES_VTEP_ACTIVE (1 << 1) |
168 | | |
169 | | uint32_t evi_cnt; /* es_evis referencing this vtep as an active path */ |
170 | | |
171 | | /* Algorithm and preference for DF election. Rxed via the ESR */ |
172 | | uint8_t df_alg; |
173 | | uint16_t df_pref; |
174 | | |
175 | | /* memory used for adding the entry to es->es_vtep_list */ |
176 | | struct listnode es_listnode; |
177 | | }; |
178 | | |
179 | | /* ES-VRF element needed for managing L3 NHGs. It is implicitly created |
180 | | * when an ES-EVI is associated with a tenant VRF |
181 | | */ |
182 | | struct bgp_evpn_es_vrf { |
183 | | struct bgp_evpn_es *es; |
184 | | struct bgp *bgp_vrf; |
185 | | |
186 | | uint32_t flags; |
187 | | /* NHG can only be activated if there are active VTEPs in the ES and |
188 | | * there is a valid L3-VNI associated with the VRF |
189 | | */ |
190 | 0 | #define BGP_EVPNES_VRF_NHG_ACTIVE (1 << 0) |
191 | | |
192 | | /* memory used for adding the es_vrf to |
193 | | * es_vrf->bgp_vrf->es_vrf_rb_tree |
194 | | */ |
195 | | RB_ENTRY(bgp_evpn_es_vrf) rb_node; |
196 | | |
197 | | /* memory used for linking the es_vrf to es_vrf->es->es_vrf_list */ |
198 | | struct listnode es_listnode; |
199 | | |
200 | | uint32_t nhg_id; |
201 | | uint32_t v6_nhg_id; |
202 | | |
203 | | /* Number of ES-EVI entries associated with this ES-VRF */ |
204 | | uint32_t ref_cnt; |
205 | | }; |
206 | | |
207 | | /* ES per-EVI info |
208 | | * - ES-EVIs are maintained per-L2-VNI (vpn->es_evi_rb_tree) |
209 | | * - ES-EVIs are also linked to the parent ES (es->es_evi_list) |
210 | | * - Local ES-EVIs are created by zebra (via config). They are linked to a |
211 | | * per-VNI list (vpn->local_es_evi_list) for quick access |
212 | | * - Remote ES-EVIs are created implicitly when a bgp_evpn_es_evi_vtep |
213 | | * references it. |
214 | | */ |
215 | | struct bgp_evpn_es_evi { |
216 | | struct bgp_evpn_es *es; |
217 | | /* Only applicableif EVI_LOCAL */ |
218 | | struct bgp_evpn_es_frag *es_frag; |
219 | | struct bgpevpn *vpn; |
220 | | |
221 | | /* ES-EVI flags */ |
222 | | uint32_t flags; |
223 | | /* local ES-EVI, created by zebra */ |
224 | 0 | #define BGP_EVPNES_EVI_LOCAL (1 << 0) |
225 | | /* created via a remote VTEP imported by BGP */ |
226 | 0 | #define BGP_EVPNES_EVI_REMOTE (1 << 1) |
227 | 0 | #define BGP_EVPNES_EVI_INCONS_VTEP_LIST (1 << 2) |
228 | | |
229 | | /* memory used for adding the es_evi to es_evi->vpn->es_evi_rb_tree */ |
230 | | RB_ENTRY(bgp_evpn_es_evi) rb_node; |
231 | | /* memory used for linking the es_evi to |
232 | | * es_evi->vpn->local_es_evi_list |
233 | | */ |
234 | | struct listnode l2vni_listnode; |
235 | | /* memory used for linking the es_evi to |
236 | | * es_evi->es->es_evi_list |
237 | | */ |
238 | | struct listnode es_listnode; |
239 | | |
240 | | /* memory used for linking the es_evi to |
241 | | * es_evi->es_frag->es_evi_frag_list |
242 | | */ |
243 | | struct listnode es_frag_listnode; |
244 | | /* list of PEs (bgp_evpn_es_evi_vtep) attached to the ES for this VNI */ |
245 | | struct list *es_evi_vtep_list; |
246 | | |
247 | | struct bgp_evpn_es_vrf *es_vrf; |
248 | | }; |
249 | | |
250 | | /* PE attached to an ES for a VNI. This entry is created when an EAD-per-ES |
251 | | * or EAD-per-EVI Type1 route is imported into the VNI. |
252 | | */ |
253 | | struct bgp_evpn_es_evi_vtep { |
254 | | struct bgp_evpn_es_evi *es_evi; /* parent ES-EVI */ |
255 | | struct in_addr vtep_ip; |
256 | | |
257 | | uint32_t flags; |
258 | | /* Rxed an EAD-per-ES route from the PE */ |
259 | 0 | #define BGP_EVPN_EVI_VTEP_EAD_PER_ES (1 << 0) /* rxed EAD-per-ES */ |
260 | | /* Rxed an EAD-per-EVI route from the PE */ |
261 | 0 | #define BGP_EVPN_EVI_VTEP_EAD_PER_EVI (1 << 1) /* rxed EAD-per-EVI */ |
262 | | /* VTEP is active i.e. will result in the creation of an es-vtep */ |
263 | | #define BGP_EVPN_EVI_VTEP_ACTIVE (1 << 2) |
264 | 0 | #define BGP_EVPN_EVI_VTEP_EAD (BGP_EVPN_EVI_VTEP_EAD_PER_ES |\ |
265 | 0 | BGP_EVPN_EVI_VTEP_EAD_PER_EVI) |
266 | | |
267 | | /* memory used for adding the entry to es_evi->es_evi_vtep_list */ |
268 | | struct listnode es_evi_listnode; |
269 | | struct bgp_evpn_es_vtep *es_vtep; |
270 | | }; |
271 | | |
272 | | /* A nexthop is created when a path (imported from an EVPN type-2 route) |
273 | | * is added to the VRF route table using that nexthop. |
274 | | * It is added on first pi reference and removed on last pi deref. |
275 | | */ |
276 | | struct bgp_evpn_nh { |
277 | | /* backpointer to the VRF */ |
278 | | struct bgp *bgp_vrf; |
279 | | /* nexthop/VTEP IP */ |
280 | | struct ipaddr ip; |
281 | | /* description for easy logging */ |
282 | | char nh_str[INET6_ADDRSTRLEN]; |
283 | | struct ethaddr rmac; |
284 | | /* pi from which we are pulling the nh RMAC */ |
285 | | struct bgp_path_info *ref_pi; |
286 | | /* List of VRF paths using this nexthop */ |
287 | | struct list *pi_list; |
288 | | uint8_t flags; |
289 | 0 | #define BGP_EVPN_NH_READY_FOR_ZEBRA (1 << 0) |
290 | | }; |
291 | | |
292 | | /* multihoming information stored in bgp_master */ |
293 | 13 | #define bgp_mh_info (bm->mh_info) |
294 | | struct bgp_evpn_mh_info { |
295 | | /* RB tree of Ethernet segments (used for EVPN-MH) */ |
296 | | struct bgp_es_rb_head es_rb_tree; |
297 | | /* List of local ESs */ |
298 | | struct list *local_es_list; |
299 | | /* List of ESs with pending/periodic processing */ |
300 | | struct list *pend_es_list; |
301 | | /* periodic timer for running background consistency checks */ |
302 | | struct event *t_cons_check; |
303 | | |
304 | | /* config knobs for optimizing or interop */ |
305 | | /* Generate EAD-EVI routes even if the ES is oper-down. This can be |
306 | | * enabled as an optimization to avoid a storm of updates when an ES |
307 | | * link flaps. |
308 | | */ |
309 | | bool ead_evi_adv_for_down_links; |
310 | | /* Enable ES consistency checking */ |
311 | | bool consistency_checking; |
312 | | /* Use L3 NHGs for host routes in symmetric IRB */ |
313 | | bool host_routes_use_l3nhg; |
314 | | /* Some vendors are not generating the EAD-per-EVI route. This knob |
315 | | * can be turned off to activate a remote ES-PE when the EAD-per-ES |
316 | | * route is rxed i.e. not wait on the EAD-per-EVI route |
317 | | */ |
318 | | bool ead_evi_rx; |
319 | 1 | #define BGP_EVPN_MH_EAD_EVI_RX_DEF true |
320 | | /* Skip EAD-EVI advertisements by turning off this knob */ |
321 | | bool ead_evi_tx; |
322 | 1 | #define BGP_EVPN_MH_EAD_EVI_TX_DEF true |
323 | | /* If the Local ES is inactive we advertise the MAC-IP without the |
324 | | * L3 ecomm |
325 | | */ |
326 | | bool suppress_l3_ecomm_on_inactive_es; |
327 | | /* Setup EVPN PE nexthops and their RMAC in bgpd */ |
328 | | bool bgp_evpn_nh_setup; |
329 | | |
330 | | /* If global export-rts are configured that is used for sending |
331 | | * sending the ead-per-es route instead of the L2-VNI(s) RTs |
332 | | */ |
333 | | struct list *ead_es_export_rtl; |
334 | | |
335 | | /* Number of EVIs in an ES fragment - used of EAD-per-ES route |
336 | | * construction |
337 | | */ |
338 | | uint32_t evi_per_es_frag; |
339 | | }; |
340 | | |
341 | | /****************************************************************************/ |
342 | | static inline int bgp_evpn_is_es_local(struct bgp_evpn_es *es) |
343 | 0 | { |
344 | 0 | return CHECK_FLAG(es->flags, BGP_EVPNES_LOCAL) ? 1 : 0; |
345 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_is_es_local Unexecuted instantiation: bgp_evpn.c:bgp_evpn_is_es_local Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_is_es_local Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_is_es_local Unexecuted instantiation: bgp_route.c:bgp_evpn_is_es_local Unexecuted instantiation: bgp_vty.c:bgp_evpn_is_es_local Unexecuted instantiation: bgp_zebra.c:bgp_evpn_is_es_local Unexecuted instantiation: bgpd.c:bgp_evpn_is_es_local |
346 | | |
347 | | extern esi_t *zero_esi; |
348 | | static inline bool bgp_evpn_is_esi_valid(esi_t *esi) |
349 | 677 | { |
350 | 677 | return !!memcmp(esi, zero_esi, sizeof(esi_t)); |
351 | 677 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_is_esi_valid bgp_evpn.c:bgp_evpn_is_esi_valid Line | Count | Source | 349 | 677 | { | 350 | 677 | return !!memcmp(esi, zero_esi, sizeof(esi_t)); | 351 | 677 | } |
Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_is_esi_valid Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_is_esi_valid Unexecuted instantiation: bgp_route.c:bgp_evpn_is_esi_valid Unexecuted instantiation: bgp_vty.c:bgp_evpn_is_esi_valid Unexecuted instantiation: bgp_zebra.c:bgp_evpn_is_esi_valid Unexecuted instantiation: bgpd.c:bgp_evpn_is_esi_valid |
352 | | |
353 | | static inline esi_t *bgp_evpn_attr_get_esi(struct attr *attr) |
354 | 0 | { |
355 | 0 | return attr ? &attr->esi : zero_esi; |
356 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_get_esi Unexecuted instantiation: bgpd.c:bgp_evpn_attr_get_esi |
357 | | |
358 | | static inline bool bgp_evpn_attr_is_sync(struct attr *attr) |
359 | 0 | { |
360 | 0 | return attr ? !!(attr->es_flags & |
361 | 0 | (ATTR_ES_PEER_PROXY | ATTR_ES_PEER_ACTIVE)) : false; |
362 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_is_sync Unexecuted instantiation: bgpd.c:bgp_evpn_attr_is_sync |
363 | | |
364 | | static inline uint32_t bgp_evpn_attr_get_sync_seq(struct attr *attr) |
365 | 0 | { |
366 | 0 | return attr ? attr->mm_sync_seqnum : 0; |
367 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_get_sync_seq Unexecuted instantiation: bgpd.c:bgp_evpn_attr_get_sync_seq |
368 | | |
369 | | static inline bool bgp_evpn_attr_is_active_on_peer(struct attr *attr) |
370 | 0 | { |
371 | 0 | return attr ? |
372 | 0 | !!(attr->es_flags & ATTR_ES_PEER_ACTIVE) : false; |
373 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_is_active_on_peer Unexecuted instantiation: bgpd.c:bgp_evpn_attr_is_active_on_peer |
374 | | |
375 | | static inline bool bgp_evpn_attr_is_router_on_peer(struct attr *attr) |
376 | 0 | { |
377 | 0 | return attr ? |
378 | 0 | !!(attr->es_flags & ATTR_ES_PEER_ROUTER) : false; |
379 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_is_router_on_peer Unexecuted instantiation: bgpd.c:bgp_evpn_attr_is_router_on_peer |
380 | | |
381 | | static inline bool bgp_evpn_attr_is_proxy(struct attr *attr) |
382 | 0 | { |
383 | 0 | return attr ? !!(attr->es_flags & ATTR_ES_PROXY_ADVERT) : false; |
384 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_is_proxy Unexecuted instantiation: bgpd.c:bgp_evpn_attr_is_proxy |
385 | | |
386 | | static inline bool bgp_evpn_attr_is_local_es(struct attr *attr) |
387 | 0 | { |
388 | 0 | return attr ? !!(attr->es_flags & ATTR_ES_IS_LOCAL) : false; |
389 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_is_local_es Unexecuted instantiation: bgpd.c:bgp_evpn_attr_is_local_es |
390 | | |
391 | | static inline uint32_t bgp_evpn_attr_get_df_pref(struct attr *attr) |
392 | 0 | { |
393 | 0 | return (attr) ? attr->df_pref : 0; |
394 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgp_evpn.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgp_route.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgp_vty.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgp_zebra.c:bgp_evpn_attr_get_df_pref Unexecuted instantiation: bgpd.c:bgp_evpn_attr_get_df_pref |
395 | | |
396 | | static inline bool bgp_evpn_local_es_is_active(struct bgp_evpn_es *es) |
397 | 0 | { |
398 | 0 | return (es->flags & BGP_EVPNES_OPER_UP) |
399 | 0 | && !(es->flags & BGP_EVPNES_BYPASS); |
400 | 0 | } Unexecuted instantiation: bgp_main.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgp_evpn.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgp_evpn_mh.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgp_evpn_vty.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgp_route.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgp_vty.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgp_zebra.c:bgp_evpn_local_es_is_active Unexecuted instantiation: bgpd.c:bgp_evpn_local_es_is_active |
401 | | |
402 | | /****************************************************************************/ |
403 | | extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp, |
404 | | struct bgp_evpn_es *es, afi_t afi, safi_t safi, |
405 | | struct prefix_evpn *evp, struct bgp_path_info *pi, |
406 | | int install); |
407 | | extern void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn); |
408 | | extern int delete_global_ead_evi_routes(struct bgp *bgp, struct bgpevpn *vpn); |
409 | | extern int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, |
410 | | struct bgpevpn *vpn, afi_t afi, safi_t safi, |
411 | | struct bgp_dest *dest, struct attr *attr, |
412 | | struct bgp_path_info **ri, |
413 | | int *route_changed); |
414 | | int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi, |
415 | | struct attr *attr, uint8_t *pfx, int psize, |
416 | | uint32_t addpath_id); |
417 | | int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi, |
418 | | struct attr *attr, uint8_t *pfx, int psize, |
419 | | uint32_t addpath_id); |
420 | | extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, |
421 | | struct in_addr originator_ip, bool oper_up, |
422 | | uint16_t df_pref, bool bypass); |
423 | | extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi); |
424 | | extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni); |
425 | | extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni); |
426 | | extern int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, |
427 | | const struct prefix_evpn *p); |
428 | | extern int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, |
429 | | const struct prefix_evpn *p); |
430 | | extern void bgp_evpn_mh_init(void); |
431 | | extern void bgp_evpn_mh_finish(void); |
432 | | void bgp_evpn_vni_es_init(struct bgpevpn *vpn); |
433 | | void bgp_evpn_vni_es_cleanup(struct bgpevpn *vpn); |
434 | | void bgp_evpn_es_show_esi(struct vty *vty, esi_t *esi, bool uj); |
435 | | void bgp_evpn_es_show(struct vty *vty, bool uj, bool detail); |
436 | | void bgp_evpn_es_evi_show_vni(struct vty *vty, vni_t vni, |
437 | | bool uj, bool detail); |
438 | | void bgp_evpn_es_evi_show(struct vty *vty, bool uj, bool detail); |
439 | | struct bgp_evpn_es *bgp_evpn_es_find(const esi_t *esi); |
440 | | extern void bgp_evpn_vrf_es_init(struct bgp *bgp_vrf); |
441 | | extern bool bgp_evpn_is_esi_local_and_non_bypass(esi_t *esi); |
442 | | extern void bgp_evpn_es_vrf_deref(struct bgp_evpn_es_evi *es_evi); |
443 | | extern void bgp_evpn_es_vrf_ref(struct bgp_evpn_es_evi *es_evi, |
444 | | struct bgp *bgp_vrf); |
445 | | extern void bgp_evpn_path_mh_info_free(struct bgp_path_mh_info *mh_info); |
446 | | extern void bgp_evpn_path_es_link(struct bgp_path_info *pi, vni_t vni, |
447 | | esi_t *esi); |
448 | | extern bool bgp_evpn_path_es_use_nhg(struct bgp *bgp_vrf, |
449 | | struct bgp_path_info *pi, uint32_t *nhg_p); |
450 | | extern void bgp_evpn_es_vrf_show(struct vty *vty, bool uj, |
451 | | struct bgp_evpn_es *es); |
452 | | extern void bgp_evpn_es_vrf_show_esi(struct vty *vty, esi_t *esi, bool uj); |
453 | | extern void bgp_evpn_switch_ead_evi_rx(void); |
454 | | extern bool bgp_evpn_es_add_l3_ecomm_ok(esi_t *esi); |
455 | | extern void bgp_evpn_es_vrf_use_nhg(struct bgp *bgp_vrf, esi_t *esi, |
456 | | bool *use_l3nhg, bool *is_l3nhg_active, |
457 | | struct bgp_evpn_es_vrf **es_vrf_p); |
458 | | extern void bgp_evpn_nh_init(struct bgp *bgp_vrf); |
459 | | extern void bgp_evpn_nh_finish(struct bgp *bgp_vrf); |
460 | | extern void bgp_evpn_nh_show(struct vty *vty, bool uj); |
461 | | extern void bgp_evpn_path_nh_add(struct bgp *bgp_vrf, struct bgp_path_info *pi); |
462 | | extern void bgp_evpn_path_nh_del(struct bgp *bgp_vrf, struct bgp_path_info *pi); |
463 | | extern void bgp_evpn_mh_config_ead_export_rt(struct bgp *bgp, |
464 | | struct ecommunity *ecom, bool del); |
465 | | |
466 | | #endif /* _FRR_BGP_EVPN_MH_H */ |