]>
Commit | Line | Data |
---|---|---|
a4168ebc | 1 | /* BGP EVPN internal definitions |
2 | * Copyright (C) 2017 Cumulus Networks, Inc. | |
3 | * | |
4 | * This file is part of FRR. | |
5 | * | |
6 | * FRR is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation; either version 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * FRR is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with FRR; see the file COPYING. If not, write to the Free | |
18 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 | * 02111-1307, USA. | |
20 | */ | |
21 | ||
22 | #ifndef _BGP_EVPN_PRIVATE_H | |
23 | #define _BGP_EVPN_PRIVATE_H | |
24 | ||
25 | #include "vxlan.h" | |
26 | #include "zebra.h" | |
27 | ||
28 | #include "bgpd/bgpd.h" | |
29 | #include "bgpd/bgp_ecommunity.h" | |
30 | ||
60466a63 | 31 | #define RT_ADDRSTRLEN 28 |
9c92b5f7 | 32 | |
2f04c4f0 AK |
33 | /* EVPN prefix lengths. This represents the sizeof struct evpn_addr |
34 | * in bits */ | |
35 | #define EVPN_ROUTE_PREFIXLEN (sizeof(struct evpn_addr) * 8) | |
a4168ebc | 36 | |
c44ab6f1 AK |
37 | /* EVPN route RD buffer length */ |
38 | #define BGP_EVPN_PREFIX_RD_LEN 100 | |
39 | ||
40 | /* packet sizes for EVPN routes */ | |
41 | /* Type-1 route should be 25 bytes | |
42 | * RD (8), ESI (10), eth-tag (4), vni (3) | |
43 | */ | |
44 | #define BGP_EVPN_TYPE1_PSIZE 25 | |
45 | /* Type-4 route should be either 23 or 35 bytes | |
46 | * RD (8), ESI (10), ip-len (1), ip (4 or 16) | |
47 | */ | |
48 | #define BGP_EVPN_TYPE4_V4_PSIZE 23 | |
49 | #define BGP_EVPN_TYPE4_V6_PSIZE 34 | |
50 | ||
c44ab6f1 AK |
51 | RB_HEAD(bgp_es_evi_rb_head, bgp_evpn_es_evi); |
52 | RB_PROTOTYPE(bgp_es_evi_rb_head, bgp_evpn_es_evi, rb_node, | |
53 | bgp_es_evi_rb_cmp); | |
a4168ebc | 54 | /* |
55 | * Hash table of EVIs. Right now, the only type of EVI supported is with | |
56 | * VxLAN encapsulation, hence each EVI corresponds to a L2 VNI. | |
57 | * The VNIs are not "created" through BGP but through some other interface | |
58 | * on the system. This table stores VNIs that BGP comes to know as present | |
59 | * on the system (through interaction with zebra) as well as pre-configured | |
60 | * VNIs (which need to be defined in the system to become "live"). | |
61 | */ | |
d62a17ae | 62 | struct bgpevpn { |
63 | vni_t vni; | |
29c53922 | 64 | vrf_id_t tenant_vrf_id; |
d7c0a89a | 65 | uint32_t flags; |
a4168ebc | 66 | #define VNI_FLAG_CFGD 0x1 /* VNI is user configured */ |
67 | #define VNI_FLAG_LIVE 0x2 /* VNI is "live" */ | |
68 | #define VNI_FLAG_RD_CFGD 0x4 /* RD is user configured. */ | |
69 | #define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */ | |
70 | #define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */ | |
c48d9f5f MK |
71 | #define VNI_FLAG_USE_TWO_LABELS 0x20 /* Attach both L2-VNI and L3-VNI if |
72 | needed for this VPN */ | |
a4168ebc | 73 | |
bc4606bd MK |
74 | struct bgp *bgp_vrf; /* back pointer to the vrf instance */ |
75 | ||
996c9314 LB |
76 | /* Flag to indicate if we are |
77 | * advertising the g/w mac ip for | |
78 | * this VNI*/ | |
d7c0a89a | 79 | uint8_t advertise_gw_macip; |
1a98c087 | 80 | |
d7c0a89a QY |
81 | /* Flag to indicate if we are |
82 | * advertising subnet for this VNI */ | |
83 | uint8_t advertise_subnet; | |
31310b25 | 84 | |
24864e44 CS |
85 | /* Flag to indicate if we are advertising the svi mac ip for this VNI*/ |
86 | uint8_t advertise_svi_macip; | |
87 | ||
d7c0a89a QY |
88 | /* Id for deriving the RD |
89 | * automatically for this VNI */ | |
90 | uint16_t rd_id; | |
a4168ebc | 91 | |
d7c0a89a QY |
92 | /* RD for this VNI. */ |
93 | struct prefix_rd prd; | |
a4168ebc | 94 | |
d7c0a89a QY |
95 | /* Route type 3 field */ |
96 | struct in_addr originator_ip; | |
a4168ebc | 97 | |
76d07c7a AK |
98 | /* PIM-SM MDT group for BUM flooding */ |
99 | struct in_addr mcast_grp; | |
100 | ||
d7c0a89a QY |
101 | /* Import and Export RTs. */ |
102 | struct list *import_rtl; | |
103 | struct list *export_rtl; | |
a4168ebc | 104 | |
d7c0a89a QY |
105 | /* Route table for EVPN routes for |
106 | * this VNI. */ | |
107 | struct bgp_table *route_table; | |
a4168ebc | 108 | |
c44ab6f1 AK |
109 | /* RB tree of ES-EVIs */ |
110 | struct bgp_es_evi_rb_head es_evi_rb_tree; | |
50f74cf1 | 111 | |
c44ab6f1 AK |
112 | /* List of local ESs */ |
113 | struct list *local_es_evi_list; | |
50f74cf1 | 114 | |
115 | QOBJ_FIELDS | |
116 | }; | |
117 | ||
c44ab6f1 | 118 | DECLARE_QOBJ_TYPE(bgpevpn) |
50f74cf1 | 119 | |
a4168ebc | 120 | /* Mapping of Import RT to VNIs. |
121 | * The Import RTs of all VNIs are maintained in a hash table with each | |
122 | * RT linking to all VNIs that will import routes matching this RT. | |
123 | */ | |
d62a17ae | 124 | struct irt_node { |
125 | /* RT */ | |
126 | struct ecommunity_val rt; | |
a4168ebc | 127 | |
d62a17ae | 128 | /* List of VNIs importing routes matching this RT. */ |
129 | struct list *vnis; | |
a4168ebc | 130 | }; |
131 | ||
10ebe1ab MK |
132 | /* Mapping of Import RT to VRFs. |
133 | * The Import RTs of all VRFss are maintained in a hash table with each | |
134 | * RT linking to all VRFs that will import routes matching this RT. | |
135 | */ | |
136 | struct vrf_irt_node { | |
137 | /* RT */ | |
138 | struct ecommunity_val rt; | |
139 | ||
140 | /* List of VNIs importing routes matching this RT. */ | |
141 | struct list *vrfs; | |
142 | }; | |
143 | ||
144 | ||
128ea8ab | 145 | #define RT_TYPE_IMPORT 1 |
146 | #define RT_TYPE_EXPORT 2 | |
147 | #define RT_TYPE_BOTH 3 | |
148 | ||
85c8d83b CS |
149 | #define EVPN_DAD_DEFAULT_TIME 180 /* secs */ |
150 | #define EVPN_DAD_DEFAULT_MAX_MOVES 5 /* default from RFC 7432 */ | |
151 | #define EVPN_DAD_DEFAULT_AUTO_RECOVERY_TIME 1800 /* secs */ | |
152 | ||
153 | struct bgp_evpn_info { | |
154 | /* enable disable dup detect */ | |
155 | bool dup_addr_detect; | |
156 | ||
157 | /* Detection time(M) */ | |
158 | int dad_time; | |
159 | /* Detection max moves(N) */ | |
160 | uint32_t dad_max_moves; | |
161 | /* Permanent freeze */ | |
162 | bool dad_freeze; | |
163 | /* Recovery time */ | |
164 | uint32_t dad_freeze_time; | |
24864e44 CS |
165 | |
166 | /* EVPN enable - advertise svi macip routes */ | |
167 | int advertise_svi_macip; | |
168 | ||
5394a276 CS |
169 | /* PIP feature knob */ |
170 | bool advertise_pip; | |
171 | /* PIP IP (sys ip) */ | |
172 | struct in_addr pip_ip; | |
173 | struct in_addr pip_ip_static; | |
174 | /* PIP MAC (sys MAC) */ | |
175 | struct ethaddr pip_rmac; | |
176 | struct ethaddr pip_rmac_static; | |
177 | struct ethaddr pip_rmac_zebra; | |
178 | bool is_anycast_mac; | |
85c8d83b CS |
179 | }; |
180 | ||
676f83b9 | 181 | static inline int is_vrf_rd_configured(struct bgp *bgp_vrf) |
182 | { | |
996c9314 | 183 | return (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD)); |
676f83b9 | 184 | } |
185 | ||
186 | static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf, | |
187 | struct prefix_rd *prd) | |
188 | { | |
189 | return (memcmp(&bgp_vrf->vrf_prd.val, prd->val, ECOMMUNITY_SIZE) == 0); | |
190 | } | |
191 | ||
6d8c58b7 MK |
192 | static inline vni_t bgpevpn_get_l3vni(struct bgpevpn *vpn) |
193 | { | |
bc4606bd | 194 | return vpn->bgp_vrf ? vpn->bgp_vrf->l3vni : 0; |
6d8c58b7 MK |
195 | } |
196 | ||
197 | static inline void bgpevpn_get_rmac(struct bgpevpn *vpn, struct ethaddr *rmac) | |
198 | { | |
6d8c58b7 | 199 | memset(rmac, 0, sizeof(struct ethaddr)); |
bc4606bd | 200 | if (!vpn->bgp_vrf) |
6d8c58b7 | 201 | return; |
bc4606bd | 202 | memcpy(rmac, &vpn->bgp_vrf->rmac, sizeof(struct ethaddr)); |
6d8c58b7 MK |
203 | } |
204 | ||
205 | static inline struct list *bgpevpn_get_vrf_export_rtl(struct bgpevpn *vpn) | |
206 | { | |
bc4606bd | 207 | if (!vpn->bgp_vrf) |
6d8c58b7 MK |
208 | return NULL; |
209 | ||
bc4606bd | 210 | return vpn->bgp_vrf->vrf_export_rtl; |
6d8c58b7 MK |
211 | } |
212 | ||
213 | static inline struct list *bgpevpn_get_vrf_import_rtl(struct bgpevpn *vpn) | |
214 | { | |
bc4606bd | 215 | if (!vpn->bgp_vrf) |
6d8c58b7 MK |
216 | return NULL; |
217 | ||
bc4606bd | 218 | return vpn->bgp_vrf->vrf_import_rtl; |
6d8c58b7 MK |
219 | } |
220 | ||
c589d847 AK |
221 | extern void bgp_evpn_es_evi_vrf_ref(struct bgpevpn *vpn); |
222 | extern void bgp_evpn_es_evi_vrf_deref(struct bgpevpn *vpn); | |
223 | ||
6a8657d0 MK |
224 | static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn) |
225 | { | |
bc4606bd MK |
226 | /* bail if vpn is not associated to bgp_vrf */ |
227 | if (!vpn->bgp_vrf) | |
6a8657d0 | 228 | return; |
996c9314 | 229 | |
c48d9f5f | 230 | UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); |
bc4606bd | 231 | listnode_delete(vpn->bgp_vrf->l2vnis, vpn); |
996c9314 | 232 | |
c589d847 AK |
233 | bgp_evpn_es_evi_vrf_deref(vpn); |
234 | ||
bc4606bd | 235 | /* remove the backpointer to the vrf instance */ |
0c68e088 | 236 | bgp_unlock(vpn->bgp_vrf); |
bc4606bd | 237 | vpn->bgp_vrf = NULL; |
6a8657d0 MK |
238 | } |
239 | ||
240 | static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn) | |
241 | { | |
242 | struct bgp *bgp_vrf = NULL; | |
243 | ||
bc4606bd MK |
244 | /* bail if vpn is already associated to vrf */ |
245 | if (vpn->bgp_vrf) | |
246 | return; | |
247 | ||
6a8657d0 | 248 | bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); |
c48d9f5f | 249 | if (!bgp_vrf) |
6a8657d0 | 250 | return; |
c48d9f5f | 251 | |
bc4606bd | 252 | /* associate the vpn to the bgp_vrf instance */ |
0c68e088 | 253 | vpn->bgp_vrf = bgp_lock(bgp_vrf); |
6a8657d0 | 254 | listnode_add_sort(bgp_vrf->l2vnis, vpn); |
83ea2eb0 | 255 | |
10f70510 AD |
256 | /* |
257 | * If L3VNI is configured, | |
258 | * check if we are advertising two labels for this vpn | |
259 | */ | |
260 | if (bgp_vrf->l3vni && | |
261 | !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) | |
c48d9f5f | 262 | SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); |
c589d847 AK |
263 | |
264 | bgp_evpn_es_evi_vrf_ref(vpn); | |
6a8657d0 MK |
265 | } |
266 | ||
d62a17ae | 267 | static inline int is_vni_configured(struct bgpevpn *vpn) |
128ea8ab | 268 | { |
d62a17ae | 269 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD)); |
128ea8ab | 270 | } |
271 | ||
d62a17ae | 272 | static inline int is_vni_live(struct bgpevpn *vpn) |
128ea8ab | 273 | { |
d62a17ae | 274 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE)); |
128ea8ab | 275 | } |
276 | ||
3d0b43d7 | 277 | static inline int is_l3vni_live(struct bgp *bgp_vrf) |
278 | { | |
279 | return (bgp_vrf->l3vni && bgp_vrf->l3vni_svi_ifindex); | |
280 | } | |
281 | ||
d62a17ae | 282 | static inline int is_rd_configured(struct bgpevpn *vpn) |
128ea8ab | 283 | { |
d62a17ae | 284 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD)); |
128ea8ab | 285 | } |
286 | ||
d62a17ae | 287 | static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn, |
288 | struct prefix_rd *prd) | |
128ea8ab | 289 | { |
d62a17ae | 290 | return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0); |
128ea8ab | 291 | } |
292 | ||
d62a17ae | 293 | static inline int is_import_rt_configured(struct bgpevpn *vpn) |
128ea8ab | 294 | { |
d62a17ae | 295 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD)); |
128ea8ab | 296 | } |
297 | ||
d62a17ae | 298 | static inline int is_export_rt_configured(struct bgpevpn *vpn) |
128ea8ab | 299 | { |
d62a17ae | 300 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD)); |
128ea8ab | 301 | } |
302 | ||
d62a17ae | 303 | static inline int is_vni_param_configured(struct bgpevpn *vpn) |
128ea8ab | 304 | { |
d62a17ae | 305 | return (is_rd_configured(vpn) || is_import_rt_configured(vpn) |
306 | || is_export_rt_configured(vpn)); | |
128ea8ab | 307 | } |
308 | ||
50f74cf1 | 309 | static inline void encode_es_rt_extcomm(struct ecommunity_val *eval, |
310 | struct ethaddr *mac) | |
311 | { | |
312 | memset(eval, 0, sizeof(struct ecommunity_val)); | |
313 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
314 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT; | |
315 | memcpy(&eval->val[2], mac, ETH_ALEN); | |
316 | } | |
317 | ||
74e2bd89 AK |
318 | static inline void encode_df_elect_extcomm(struct ecommunity_val *eval, |
319 | uint16_t pref) | |
320 | { | |
321 | memset(eval, 0, sizeof(*eval)); | |
322 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
323 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION; | |
324 | eval->val[2] = EVPN_MH_DF_ALG_PREF; | |
325 | eval->val[6] = (pref >> 8) & 0xff; | |
326 | eval->val[7] = pref & 0xff; | |
327 | } | |
328 | ||
c44ab6f1 AK |
329 | static inline void encode_esi_label_extcomm(struct ecommunity_val *eval, |
330 | bool single_active) | |
331 | { | |
332 | memset(eval, 0, sizeof(struct ecommunity_val)); | |
333 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
334 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL; | |
335 | if (single_active) | |
336 | eval->val[2] |= (1 << 0); | |
337 | } | |
338 | ||
bc59a672 MK |
339 | static inline void encode_rmac_extcomm(struct ecommunity_val *eval, |
340 | struct ethaddr *rmac) | |
341 | { | |
342 | memset(eval, 0, sizeof(*eval)); | |
343 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
344 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC; | |
345 | memcpy(&eval->val[2], rmac, ETH_ALEN); | |
346 | } | |
347 | ||
ead40654 MK |
348 | static inline void encode_default_gw_extcomm(struct ecommunity_val *eval) |
349 | { | |
350 | memset(eval, 0, sizeof(*eval)); | |
351 | eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE; | |
352 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DEF_GW; | |
353 | } | |
354 | ||
d7c0a89a | 355 | static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq, |
d62a17ae | 356 | struct ecommunity_val *eval) |
128ea8ab | 357 | { |
d62a17ae | 358 | memset(eval, 0, sizeof(*eval)); |
359 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
360 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY; | |
361 | if (static_mac) | |
362 | eval->val[2] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY; | |
363 | eval->val[4] = (seq >> 24) & 0xff; | |
364 | eval->val[5] = (seq >> 16) & 0xff; | |
365 | eval->val[6] = (seq >> 8) & 0xff; | |
366 | eval->val[7] = seq & 0xff; | |
128ea8ab | 367 | } |
368 | ||
68e33151 | 369 | static inline void encode_na_flag_extcomm(struct ecommunity_val *eval, |
9c7edc03 | 370 | uint8_t na_flag, bool proxy) |
68e33151 CS |
371 | { |
372 | memset(eval, 0, sizeof(*eval)); | |
373 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
374 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ND; | |
375 | if (na_flag) | |
376 | eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG; | |
9c7edc03 AK |
377 | if (proxy) |
378 | eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG; | |
68e33151 CS |
379 | } |
380 | ||
bd494ec5 | 381 | static inline void ip_prefix_from_type5_prefix(const struct prefix_evpn *evp, |
90264d64 MK |
382 | struct prefix *ip) |
383 | { | |
384 | memset(ip, 0, sizeof(struct prefix)); | |
3714a385 | 385 | if (is_evpn_prefix_ipaddr_v4(evp)) { |
90264d64 | 386 | ip->family = AF_INET; |
3714a385 | 387 | ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length; |
388 | memcpy(&(ip->u.prefix4), &(evp->prefix.prefix_addr.ip.ip), | |
90264d64 | 389 | IPV4_MAX_BYTELEN); |
3714a385 | 390 | } else if (is_evpn_prefix_ipaddr_v6(evp)) { |
90264d64 | 391 | ip->family = AF_INET6; |
3714a385 | 392 | ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length; |
393 | memcpy(&(ip->u.prefix6), &(evp->prefix.prefix_addr.ip.ip), | |
90264d64 MK |
394 | IPV6_MAX_BYTELEN); |
395 | } | |
396 | } | |
397 | ||
123214ef | 398 | static inline int is_evpn_prefix_default(const struct prefix *evp) |
6fb219da MK |
399 | { |
400 | if (evp->family != AF_EVPN) | |
401 | return 0; | |
402 | ||
3714a385 | 403 | return ((evp->u.prefix_evpn.prefix_addr.ip_prefix_length == 0) ? |
404 | 1 : 0); | |
6fb219da MK |
405 | } |
406 | ||
bd494ec5 | 407 | static inline void ip_prefix_from_type2_prefix(const struct prefix_evpn *evp, |
d3135ba3 | 408 | struct prefix *ip) |
409 | { | |
410 | memset(ip, 0, sizeof(struct prefix)); | |
3714a385 | 411 | if (is_evpn_prefix_ipaddr_v4(evp)) { |
d3135ba3 | 412 | ip->family = AF_INET; |
413 | ip->prefixlen = IPV4_MAX_BITLEN; | |
3714a385 | 414 | memcpy(&(ip->u.prefix4), &(evp->prefix.macip_addr.ip.ip), |
d3135ba3 | 415 | IPV4_MAX_BYTELEN); |
3714a385 | 416 | } else if (is_evpn_prefix_ipaddr_v6(evp)) { |
d3135ba3 | 417 | ip->family = AF_INET6; |
418 | ip->prefixlen = IPV6_MAX_BITLEN; | |
3714a385 | 419 | memcpy(&(ip->u.prefix6), &(evp->prefix.macip_addr.ip.ip), |
d3135ba3 | 420 | IPV6_MAX_BYTELEN); |
421 | } | |
422 | } | |
423 | ||
bd494ec5 | 424 | static inline void ip_prefix_from_evpn_prefix(const struct prefix_evpn *evp, |
3714a385 | 425 | struct prefix *ip) |
426 | { | |
427 | if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) | |
428 | ip_prefix_from_type2_prefix(evp, ip); | |
429 | else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) | |
430 | ip_prefix_from_type5_prefix(evp, ip); | |
431 | } | |
432 | ||
d62a17ae | 433 | static inline void build_evpn_type2_prefix(struct prefix_evpn *p, |
434 | struct ethaddr *mac, | |
435 | struct ipaddr *ip) | |
128ea8ab | 436 | { |
d62a17ae | 437 | memset(p, 0, sizeof(struct prefix_evpn)); |
b03b8898 | 438 | p->family = AF_EVPN; |
50f74cf1 | 439 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; |
d62a17ae | 440 | p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE; |
3714a385 | 441 | memcpy(&p->prefix.macip_addr.mac.octet, mac->octet, ETH_ALEN); |
442 | p->prefix.macip_addr.ip.ipa_type = IPADDR_NONE; | |
d62a17ae | 443 | if (ip) |
3714a385 | 444 | memcpy(&p->prefix.macip_addr.ip, ip, sizeof(*ip)); |
128ea8ab | 445 | } |
446 | ||
bd494ec5 DS |
447 | static inline void |
448 | build_type5_prefix_from_ip_prefix(struct prefix_evpn *evp, | |
449 | const struct prefix *ip_prefix) | |
342dd0c6 | 450 | { |
451 | struct ipaddr ip; | |
452 | ||
453 | memset(&ip, 0, sizeof(struct ipaddr)); | |
454 | if (ip_prefix->family == AF_INET) { | |
455 | ip.ipa_type = IPADDR_V4; | |
456 | memcpy(&ip.ipaddr_v4, &ip_prefix->u.prefix4, | |
457 | sizeof(struct in_addr)); | |
458 | } else { | |
459 | ip.ipa_type = IPADDR_V6; | |
460 | memcpy(&ip.ipaddr_v6, &ip_prefix->u.prefix6, | |
461 | sizeof(struct in6_addr)); | |
462 | } | |
463 | ||
464 | memset(evp, 0, sizeof(struct prefix_evpn)); | |
465 | evp->family = AF_EVPN; | |
50f74cf1 | 466 | evp->prefixlen = EVPN_ROUTE_PREFIXLEN; |
342dd0c6 | 467 | evp->prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE; |
3714a385 | 468 | evp->prefix.prefix_addr.ip_prefix_length = ip_prefix->prefixlen; |
469 | evp->prefix.prefix_addr.ip.ipa_type = ip.ipa_type; | |
470 | memcpy(&evp->prefix.prefix_addr.ip, &ip, sizeof(struct ipaddr)); | |
342dd0c6 | 471 | } |
472 | ||
d62a17ae | 473 | static inline void build_evpn_type3_prefix(struct prefix_evpn *p, |
474 | struct in_addr originator_ip) | |
128ea8ab | 475 | { |
d62a17ae | 476 | memset(p, 0, sizeof(struct prefix_evpn)); |
b03b8898 | 477 | p->family = AF_EVPN; |
50f74cf1 | 478 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; |
d62a17ae | 479 | p->prefix.route_type = BGP_EVPN_IMET_ROUTE; |
3714a385 | 480 | p->prefix.imet_addr.ip.ipa_type = IPADDR_V4; |
481 | p->prefix.imet_addr.ip.ipaddr_v4 = originator_ip; | |
128ea8ab | 482 | } |
483 | ||
50f74cf1 | 484 | static inline void build_evpn_type4_prefix(struct prefix_evpn *p, |
485 | esi_t *esi, | |
486 | struct in_addr originator_ip) | |
487 | { | |
488 | memset(p, 0, sizeof(struct prefix_evpn)); | |
489 | p->family = AF_EVPN; | |
490 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; | |
491 | p->prefix.route_type = BGP_EVPN_ES_ROUTE; | |
492 | p->prefix.es_addr.ip_prefix_length = IPV4_MAX_BITLEN; | |
493 | p->prefix.es_addr.ip.ipa_type = IPADDR_V4; | |
494 | p->prefix.es_addr.ip.ipaddr_v4 = originator_ip; | |
495 | memcpy(&p->prefix.es_addr.esi, esi, sizeof(esi_t)); | |
496 | } | |
497 | ||
c44ab6f1 AK |
498 | static inline void build_evpn_type1_prefix(struct prefix_evpn *p, |
499 | uint32_t eth_tag, | |
500 | esi_t *esi, | |
501 | struct in_addr originator_ip) | |
502 | { | |
503 | memset(p, 0, sizeof(struct prefix_evpn)); | |
504 | p->family = AF_EVPN; | |
505 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; | |
506 | p->prefix.route_type = BGP_EVPN_AD_ROUTE; | |
507 | p->prefix.ead_addr.eth_tag = eth_tag; | |
c44ab6f1 AK |
508 | p->prefix.ead_addr.ip.ipa_type = IPADDR_V4; |
509 | p->prefix.ead_addr.ip.ipaddr_v4 = originator_ip; | |
510 | memcpy(&p->prefix.ead_addr.esi, esi, sizeof(esi_t)); | |
511 | } | |
512 | ||
513 | static inline void evpn_type1_prefix_global_copy(struct prefix_evpn *global_p, | |
514 | const struct prefix_evpn *vni_p) | |
515 | { | |
516 | memcpy(global_p, vni_p, sizeof(*global_p)); | |
c44ab6f1 | 517 | global_p->prefix.ead_addr.ip.ipa_type = 0; |
3a6290bd | 518 | global_p->prefix.ead_addr.ip.ipaddr_v4.s_addr = INADDR_ANY; |
c44ab6f1 AK |
519 | } |
520 | ||
521 | /* EAD prefix in the global table doesn't include the VTEP-IP so | |
522 | * we need to create a different copy for the VNI | |
523 | */ | |
524 | static inline struct prefix_evpn *evpn_type1_prefix_vni_copy( | |
525 | struct prefix_evpn *vni_p, | |
526 | const struct prefix_evpn *global_p, | |
527 | struct in_addr originator_ip) | |
528 | { | |
529 | memcpy(vni_p, global_p, sizeof(*vni_p)); | |
c44ab6f1 AK |
530 | vni_p->prefix.ead_addr.ip.ipa_type = IPADDR_V4; |
531 | vni_p->prefix.ead_addr.ip.ipaddr_v4 = originator_ip; | |
532 | ||
533 | return vni_p; | |
534 | } | |
535 | ||
486456ca MK |
536 | static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi, |
537 | safi_t safi) | |
538 | { | |
539 | if (afi == AFI_IP && | |
540 | CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], | |
541 | BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4)) | |
542 | return 1; | |
543 | else if (afi == AFI_IP6 && | |
544 | CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], | |
545 | BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6)) | |
546 | return 1; | |
547 | return 0; | |
548 | } | |
549 | ||
50f74cf1 | 550 | static inline void es_get_system_mac(esi_t *esi, |
551 | struct ethaddr *mac) | |
552 | { | |
2bb9eff4 DS |
553 | /* |
554 | * for type-1 and type-3 ESIs, | |
555 | * the system mac starts at val[1] | |
50f74cf1 | 556 | */ |
557 | memcpy(mac, &esi->val[1], ETH_ALEN); | |
558 | } | |
559 | ||
0ca10580 CS |
560 | static inline bool bgp_evpn_is_svi_macip_enabled(struct bgpevpn *vpn) |
561 | { | |
562 | struct bgp *bgp_evpn = NULL; | |
563 | ||
564 | bgp_evpn = bgp_get_evpn(); | |
565 | ||
566 | return (bgp_evpn->evpn_info->advertise_svi_macip || | |
567 | vpn->advertise_svi_macip); | |
568 | } | |
569 | ||
9c7edc03 AK |
570 | static inline bool bgp_evpn_is_path_local(struct bgp *bgp, |
571 | struct bgp_path_info *pi) | |
572 | { | |
573 | return (pi->peer == bgp->peer_self | |
574 | && pi->type == ZEBRA_ROUTE_BGP | |
575 | && pi->sub_type == BGP_ROUTE_STATIC); | |
576 | } | |
577 | ||
c44ab6f1 AK |
578 | extern struct zclient *zclient; |
579 | ||
5fd9c12b KA |
580 | extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf, |
581 | afi_t afi, safi_t safi, | |
582 | bool add); | |
996c9314 | 583 | extern void evpn_rt_delete_auto(struct bgp *, vni_t, struct list *); |
523cafc4 | 584 | extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf, |
585 | struct ecommunity *ecomadd); | |
586 | extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf, | |
587 | struct ecommunity *ecomdel); | |
588 | extern void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf, | |
589 | struct ecommunity *ecomadd); | |
590 | extern void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf, | |
591 | struct ecommunity *ecomdel); | |
d62a17ae | 592 | extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp, |
593 | struct bgpevpn *vpn); | |
bf1061d8 | 594 | extern void bgp_evpn_handle_autort_change(struct bgp *bgp); |
676f83b9 | 595 | extern void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw); |
d62a17ae | 596 | extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn, |
597 | int withdraw); | |
598 | extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn); | |
599 | extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn); | |
523cafc4 | 600 | extern void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf); |
601 | extern void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf); | |
d62a17ae | 602 | extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn); |
603 | extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, | |
604 | struct bgpevpn *vpn); | |
605 | extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, | |
606 | struct bgpevpn *vpn); | |
607 | extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, | |
608 | struct bgpevpn *vpn); | |
609 | extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn); | |
676f83b9 | 610 | extern void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp); |
d62a17ae | 611 | extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni); |
612 | extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, | |
76d07c7a AK |
613 | struct in_addr originator_ip, |
614 | vrf_id_t tenant_vrf_id, | |
615 | struct in_addr mcast_grp); | |
d62a17ae | 616 | extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn); |
7df407ed | 617 | extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni); |
0ca10580 | 618 | extern int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn); |
185fb14a AK |
619 | extern void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi, |
620 | struct bgp_dest *dest, | |
621 | struct bgp_path_info **pi); | |
c44ab6f1 AK |
622 | int vni_list_cmp(void *p1, void *p2); |
623 | extern int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, | |
09319b4e DS |
624 | struct bgp_dest *dest); |
625 | extern struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table, | |
626 | afi_t afi, safi_t safi, | |
627 | const struct prefix_evpn *evp, | |
628 | struct prefix_rd *prd); | |
629 | extern struct bgp_dest * | |
630 | bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi, | |
631 | const struct prefix_evpn *evp, | |
632 | struct prefix_rd *prd); | |
26c03e43 AK |
633 | extern struct bgp_node *bgp_global_evpn_node_get(struct bgp_table *table, |
634 | afi_t afi, safi_t safi, | |
635 | const struct prefix_evpn *evp, | |
636 | struct prefix_rd *prd); | |
637 | extern struct bgp_node * | |
638 | bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi, | |
639 | const struct prefix_evpn *evp, | |
640 | struct prefix_rd *prd); | |
641 | extern void bgp_evpn_import_route_in_vrfs(struct bgp_path_info *pi, int import); | |
a4168ebc | 642 | #endif /* _BGP_EVPN_PRIVATE_H */ |