]>
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 | |
37 | /* EVPN route types. */ | |
d62a17ae | 38 | typedef enum { |
39 | BGP_EVPN_AD_ROUTE = 1, /* Ethernet Auto-Discovery (A-D) route */ | |
40 | BGP_EVPN_MAC_IP_ROUTE, /* MAC/IP Advertisement route */ | |
41 | BGP_EVPN_IMET_ROUTE, /* Inclusive Multicast Ethernet Tag route */ | |
42 | BGP_EVPN_ES_ROUTE, /* Ethernet Segment route */ | |
43 | BGP_EVPN_IP_PREFIX_ROUTE, /* IP Prefix route */ | |
a4168ebc | 44 | } bgp_evpn_route_type; |
45 | ||
46 | /* | |
47 | * Hash table of EVIs. Right now, the only type of EVI supported is with | |
48 | * VxLAN encapsulation, hence each EVI corresponds to a L2 VNI. | |
49 | * The VNIs are not "created" through BGP but through some other interface | |
50 | * on the system. This table stores VNIs that BGP comes to know as present | |
51 | * on the system (through interaction with zebra) as well as pre-configured | |
52 | * VNIs (which need to be defined in the system to become "live"). | |
53 | */ | |
d62a17ae | 54 | struct bgpevpn { |
55 | vni_t vni; | |
29c53922 | 56 | vrf_id_t tenant_vrf_id; |
d7c0a89a | 57 | uint32_t flags; |
a4168ebc | 58 | #define VNI_FLAG_CFGD 0x1 /* VNI is user configured */ |
59 | #define VNI_FLAG_LIVE 0x2 /* VNI is "live" */ | |
60 | #define VNI_FLAG_RD_CFGD 0x4 /* RD is user configured. */ | |
61 | #define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */ | |
62 | #define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */ | |
c48d9f5f MK |
63 | #define VNI_FLAG_USE_TWO_LABELS 0x20 /* Attach both L2-VNI and L3-VNI if |
64 | needed for this VPN */ | |
a4168ebc | 65 | |
bc4606bd MK |
66 | struct bgp *bgp_vrf; /* back pointer to the vrf instance */ |
67 | ||
996c9314 LB |
68 | /* Flag to indicate if we are |
69 | * advertising the g/w mac ip for | |
70 | * this VNI*/ | |
d7c0a89a | 71 | uint8_t advertise_gw_macip; |
1a98c087 | 72 | |
d7c0a89a QY |
73 | /* Flag to indicate if we are |
74 | * advertising subnet for this VNI */ | |
75 | uint8_t advertise_subnet; | |
31310b25 | 76 | |
24864e44 CS |
77 | /* Flag to indicate if we are advertising the svi mac ip for this VNI*/ |
78 | uint8_t advertise_svi_macip; | |
79 | ||
d7c0a89a QY |
80 | /* Id for deriving the RD |
81 | * automatically for this VNI */ | |
82 | uint16_t rd_id; | |
a4168ebc | 83 | |
d7c0a89a QY |
84 | /* RD for this VNI. */ |
85 | struct prefix_rd prd; | |
a4168ebc | 86 | |
d7c0a89a QY |
87 | /* Route type 3 field */ |
88 | struct in_addr originator_ip; | |
a4168ebc | 89 | |
76d07c7a AK |
90 | /* PIM-SM MDT group for BUM flooding */ |
91 | struct in_addr mcast_grp; | |
92 | ||
d7c0a89a QY |
93 | /* Import and Export RTs. */ |
94 | struct list *import_rtl; | |
95 | struct list *export_rtl; | |
a4168ebc | 96 | |
d7c0a89a QY |
97 | /* Route table for EVPN routes for |
98 | * this VNI. */ | |
99 | struct bgp_table *route_table; | |
a4168ebc | 100 | |
d7c0a89a | 101 | QOBJ_FIELDS |
a4168ebc | 102 | }; |
103 | ||
104 | DECLARE_QOBJ_TYPE(bgpevpn) | |
105 | ||
50f74cf1 | 106 | struct evpnes { |
107 | ||
108 | /* Ethernet Segment Identifier */ | |
109 | esi_t esi; | |
110 | ||
111 | /* es flags */ | |
112 | uint16_t flags; | |
113 | #define EVPNES_LOCAL 0x01 | |
114 | #define EVPNES_REMOTE 0x02 | |
115 | ||
2bb9eff4 DS |
116 | /* |
117 | * Id for deriving the RD | |
118 | * automatically for this ESI | |
119 | */ | |
50f74cf1 | 120 | uint16_t rd_id; |
121 | ||
122 | /* RD for this VNI. */ | |
123 | struct prefix_rd prd; | |
124 | ||
125 | /* originator ip address */ | |
126 | struct ipaddr originator_ip; | |
127 | ||
128 | /* list of VTEPs in the same site */ | |
129 | struct list *vtep_list; | |
130 | ||
2bb9eff4 DS |
131 | /* |
132 | * Route table for EVPN routes for | |
133 | * this ESI. - type4 routes | |
134 | */ | |
50f74cf1 | 135 | struct bgp_table *route_table; |
136 | ||
137 | QOBJ_FIELDS | |
138 | }; | |
139 | ||
140 | DECLARE_QOBJ_TYPE(evpnes) | |
141 | ||
a4168ebc | 142 | /* Mapping of Import RT to VNIs. |
143 | * The Import RTs of all VNIs are maintained in a hash table with each | |
144 | * RT linking to all VNIs that will import routes matching this RT. | |
145 | */ | |
d62a17ae | 146 | struct irt_node { |
147 | /* RT */ | |
148 | struct ecommunity_val rt; | |
a4168ebc | 149 | |
d62a17ae | 150 | /* List of VNIs importing routes matching this RT. */ |
151 | struct list *vnis; | |
a4168ebc | 152 | }; |
153 | ||
10ebe1ab MK |
154 | /* Mapping of Import RT to VRFs. |
155 | * The Import RTs of all VRFss are maintained in a hash table with each | |
156 | * RT linking to all VRFs that will import routes matching this RT. | |
157 | */ | |
158 | struct vrf_irt_node { | |
159 | /* RT */ | |
160 | struct ecommunity_val rt; | |
161 | ||
162 | /* List of VNIs importing routes matching this RT. */ | |
163 | struct list *vrfs; | |
164 | }; | |
165 | ||
166 | ||
128ea8ab | 167 | #define RT_TYPE_IMPORT 1 |
168 | #define RT_TYPE_EXPORT 2 | |
169 | #define RT_TYPE_BOTH 3 | |
170 | ||
85c8d83b CS |
171 | #define EVPN_DAD_DEFAULT_TIME 180 /* secs */ |
172 | #define EVPN_DAD_DEFAULT_MAX_MOVES 5 /* default from RFC 7432 */ | |
173 | #define EVPN_DAD_DEFAULT_AUTO_RECOVERY_TIME 1800 /* secs */ | |
174 | ||
175 | struct bgp_evpn_info { | |
176 | /* enable disable dup detect */ | |
177 | bool dup_addr_detect; | |
178 | ||
179 | /* Detection time(M) */ | |
180 | int dad_time; | |
181 | /* Detection max moves(N) */ | |
182 | uint32_t dad_max_moves; | |
183 | /* Permanent freeze */ | |
184 | bool dad_freeze; | |
185 | /* Recovery time */ | |
186 | uint32_t dad_freeze_time; | |
24864e44 CS |
187 | |
188 | /* EVPN enable - advertise svi macip routes */ | |
189 | int advertise_svi_macip; | |
190 | ||
85c8d83b CS |
191 | }; |
192 | ||
676f83b9 | 193 | static inline int is_vrf_rd_configured(struct bgp *bgp_vrf) |
194 | { | |
996c9314 | 195 | return (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD)); |
676f83b9 | 196 | } |
197 | ||
198 | static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf, | |
199 | struct prefix_rd *prd) | |
200 | { | |
201 | return (memcmp(&bgp_vrf->vrf_prd.val, prd->val, ECOMMUNITY_SIZE) == 0); | |
202 | } | |
203 | ||
6d8c58b7 MK |
204 | static inline vni_t bgpevpn_get_l3vni(struct bgpevpn *vpn) |
205 | { | |
bc4606bd | 206 | return vpn->bgp_vrf ? vpn->bgp_vrf->l3vni : 0; |
6d8c58b7 MK |
207 | } |
208 | ||
209 | static inline void bgpevpn_get_rmac(struct bgpevpn *vpn, struct ethaddr *rmac) | |
210 | { | |
6d8c58b7 | 211 | memset(rmac, 0, sizeof(struct ethaddr)); |
bc4606bd | 212 | if (!vpn->bgp_vrf) |
6d8c58b7 | 213 | return; |
bc4606bd | 214 | memcpy(rmac, &vpn->bgp_vrf->rmac, sizeof(struct ethaddr)); |
6d8c58b7 MK |
215 | } |
216 | ||
217 | static inline struct list *bgpevpn_get_vrf_export_rtl(struct bgpevpn *vpn) | |
218 | { | |
bc4606bd | 219 | if (!vpn->bgp_vrf) |
6d8c58b7 MK |
220 | return NULL; |
221 | ||
bc4606bd | 222 | return vpn->bgp_vrf->vrf_export_rtl; |
6d8c58b7 MK |
223 | } |
224 | ||
225 | static inline struct list *bgpevpn_get_vrf_import_rtl(struct bgpevpn *vpn) | |
226 | { | |
bc4606bd | 227 | if (!vpn->bgp_vrf) |
6d8c58b7 MK |
228 | return NULL; |
229 | ||
bc4606bd | 230 | return vpn->bgp_vrf->vrf_import_rtl; |
6d8c58b7 MK |
231 | } |
232 | ||
6a8657d0 MK |
233 | static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn) |
234 | { | |
bc4606bd MK |
235 | /* bail if vpn is not associated to bgp_vrf */ |
236 | if (!vpn->bgp_vrf) | |
6a8657d0 | 237 | return; |
996c9314 | 238 | |
c48d9f5f | 239 | UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); |
bc4606bd | 240 | listnode_delete(vpn->bgp_vrf->l2vnis, vpn); |
996c9314 | 241 | |
bc4606bd | 242 | /* remove the backpointer to the vrf instance */ |
0c68e088 | 243 | bgp_unlock(vpn->bgp_vrf); |
bc4606bd | 244 | vpn->bgp_vrf = NULL; |
6a8657d0 MK |
245 | } |
246 | ||
247 | static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn) | |
248 | { | |
249 | struct bgp *bgp_vrf = NULL; | |
250 | ||
bc4606bd MK |
251 | /* bail if vpn is already associated to vrf */ |
252 | if (vpn->bgp_vrf) | |
253 | return; | |
254 | ||
6a8657d0 | 255 | bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id); |
c48d9f5f | 256 | if (!bgp_vrf) |
6a8657d0 | 257 | return; |
c48d9f5f | 258 | |
bc4606bd | 259 | /* associate the vpn to the bgp_vrf instance */ |
0c68e088 | 260 | vpn->bgp_vrf = bgp_lock(bgp_vrf); |
6a8657d0 | 261 | listnode_add_sort(bgp_vrf->l2vnis, vpn); |
83ea2eb0 | 262 | |
c48d9f5f | 263 | /* check if we are advertising two labels for this vpn */ |
996c9314 | 264 | if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY)) |
c48d9f5f | 265 | SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS); |
6a8657d0 MK |
266 | } |
267 | ||
d62a17ae | 268 | static inline int is_vni_configured(struct bgpevpn *vpn) |
128ea8ab | 269 | { |
d62a17ae | 270 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD)); |
128ea8ab | 271 | } |
272 | ||
d62a17ae | 273 | static inline int is_vni_live(struct bgpevpn *vpn) |
128ea8ab | 274 | { |
d62a17ae | 275 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE)); |
128ea8ab | 276 | } |
277 | ||
3d0b43d7 | 278 | static inline int is_l3vni_live(struct bgp *bgp_vrf) |
279 | { | |
280 | return (bgp_vrf->l3vni && bgp_vrf->l3vni_svi_ifindex); | |
281 | } | |
282 | ||
d62a17ae | 283 | static inline int is_rd_configured(struct bgpevpn *vpn) |
128ea8ab | 284 | { |
d62a17ae | 285 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD)); |
128ea8ab | 286 | } |
287 | ||
d62a17ae | 288 | static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn, |
289 | struct prefix_rd *prd) | |
128ea8ab | 290 | { |
d62a17ae | 291 | return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0); |
128ea8ab | 292 | } |
293 | ||
d62a17ae | 294 | static inline int is_import_rt_configured(struct bgpevpn *vpn) |
128ea8ab | 295 | { |
d62a17ae | 296 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD)); |
128ea8ab | 297 | } |
298 | ||
d62a17ae | 299 | static inline int is_export_rt_configured(struct bgpevpn *vpn) |
128ea8ab | 300 | { |
d62a17ae | 301 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD)); |
128ea8ab | 302 | } |
303 | ||
d62a17ae | 304 | static inline int is_vni_param_configured(struct bgpevpn *vpn) |
128ea8ab | 305 | { |
d62a17ae | 306 | return (is_rd_configured(vpn) || is_import_rt_configured(vpn) |
307 | || is_export_rt_configured(vpn)); | |
128ea8ab | 308 | } |
309 | ||
50f74cf1 | 310 | static inline void encode_es_rt_extcomm(struct ecommunity_val *eval, |
311 | struct ethaddr *mac) | |
312 | { | |
313 | memset(eval, 0, sizeof(struct ecommunity_val)); | |
314 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
315 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT; | |
316 | memcpy(&eval->val[2], mac, ETH_ALEN); | |
317 | } | |
318 | ||
bc59a672 MK |
319 | static inline void encode_rmac_extcomm(struct ecommunity_val *eval, |
320 | struct ethaddr *rmac) | |
321 | { | |
322 | memset(eval, 0, sizeof(*eval)); | |
323 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
324 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC; | |
325 | memcpy(&eval->val[2], rmac, ETH_ALEN); | |
326 | } | |
327 | ||
ead40654 MK |
328 | static inline void encode_default_gw_extcomm(struct ecommunity_val *eval) |
329 | { | |
330 | memset(eval, 0, sizeof(*eval)); | |
331 | eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE; | |
332 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DEF_GW; | |
333 | } | |
334 | ||
d7c0a89a | 335 | static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq, |
d62a17ae | 336 | struct ecommunity_val *eval) |
128ea8ab | 337 | { |
d62a17ae | 338 | memset(eval, 0, sizeof(*eval)); |
339 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
340 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY; | |
341 | if (static_mac) | |
342 | eval->val[2] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY; | |
343 | eval->val[4] = (seq >> 24) & 0xff; | |
344 | eval->val[5] = (seq >> 16) & 0xff; | |
345 | eval->val[6] = (seq >> 8) & 0xff; | |
346 | eval->val[7] = seq & 0xff; | |
128ea8ab | 347 | } |
348 | ||
68e33151 CS |
349 | static inline void encode_na_flag_extcomm(struct ecommunity_val *eval, |
350 | uint8_t na_flag) | |
351 | { | |
352 | memset(eval, 0, sizeof(*eval)); | |
353 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
354 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ND; | |
355 | if (na_flag) | |
356 | eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG; | |
357 | } | |
358 | ||
90264d64 MK |
359 | static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp, |
360 | struct prefix *ip) | |
361 | { | |
362 | memset(ip, 0, sizeof(struct prefix)); | |
3714a385 | 363 | if (is_evpn_prefix_ipaddr_v4(evp)) { |
90264d64 | 364 | ip->family = AF_INET; |
3714a385 | 365 | ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length; |
366 | memcpy(&(ip->u.prefix4), &(evp->prefix.prefix_addr.ip.ip), | |
90264d64 | 367 | IPV4_MAX_BYTELEN); |
3714a385 | 368 | } else if (is_evpn_prefix_ipaddr_v6(evp)) { |
90264d64 | 369 | ip->family = AF_INET6; |
3714a385 | 370 | ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length; |
371 | memcpy(&(ip->u.prefix6), &(evp->prefix.prefix_addr.ip.ip), | |
90264d64 MK |
372 | IPV6_MAX_BYTELEN); |
373 | } | |
374 | } | |
375 | ||
123214ef | 376 | static inline int is_evpn_prefix_default(const struct prefix *evp) |
6fb219da MK |
377 | { |
378 | if (evp->family != AF_EVPN) | |
379 | return 0; | |
380 | ||
3714a385 | 381 | return ((evp->u.prefix_evpn.prefix_addr.ip_prefix_length == 0) ? |
382 | 1 : 0); | |
6fb219da MK |
383 | } |
384 | ||
d3135ba3 | 385 | static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp, |
386 | struct prefix *ip) | |
387 | { | |
388 | memset(ip, 0, sizeof(struct prefix)); | |
3714a385 | 389 | if (is_evpn_prefix_ipaddr_v4(evp)) { |
d3135ba3 | 390 | ip->family = AF_INET; |
391 | ip->prefixlen = IPV4_MAX_BITLEN; | |
3714a385 | 392 | memcpy(&(ip->u.prefix4), &(evp->prefix.macip_addr.ip.ip), |
d3135ba3 | 393 | IPV4_MAX_BYTELEN); |
3714a385 | 394 | } else if (is_evpn_prefix_ipaddr_v6(evp)) { |
d3135ba3 | 395 | ip->family = AF_INET6; |
396 | ip->prefixlen = IPV6_MAX_BITLEN; | |
3714a385 | 397 | memcpy(&(ip->u.prefix6), &(evp->prefix.macip_addr.ip.ip), |
d3135ba3 | 398 | IPV6_MAX_BYTELEN); |
399 | } | |
400 | } | |
401 | ||
3714a385 | 402 | static inline void ip_prefix_from_evpn_prefix(struct prefix_evpn *evp, |
403 | struct prefix *ip) | |
404 | { | |
405 | if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) | |
406 | ip_prefix_from_type2_prefix(evp, ip); | |
407 | else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) | |
408 | ip_prefix_from_type5_prefix(evp, ip); | |
409 | } | |
410 | ||
d62a17ae | 411 | static inline void build_evpn_type2_prefix(struct prefix_evpn *p, |
412 | struct ethaddr *mac, | |
413 | struct ipaddr *ip) | |
128ea8ab | 414 | { |
d62a17ae | 415 | memset(p, 0, sizeof(struct prefix_evpn)); |
b03b8898 | 416 | p->family = AF_EVPN; |
50f74cf1 | 417 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; |
d62a17ae | 418 | p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE; |
3714a385 | 419 | memcpy(&p->prefix.macip_addr.mac.octet, mac->octet, ETH_ALEN); |
420 | p->prefix.macip_addr.ip.ipa_type = IPADDR_NONE; | |
d62a17ae | 421 | if (ip) |
3714a385 | 422 | memcpy(&p->prefix.macip_addr.ip, ip, sizeof(*ip)); |
128ea8ab | 423 | } |
424 | ||
342dd0c6 | 425 | static inline void build_type5_prefix_from_ip_prefix(struct prefix_evpn *evp, |
426 | struct prefix *ip_prefix) | |
427 | { | |
428 | struct ipaddr ip; | |
429 | ||
430 | memset(&ip, 0, sizeof(struct ipaddr)); | |
431 | if (ip_prefix->family == AF_INET) { | |
432 | ip.ipa_type = IPADDR_V4; | |
433 | memcpy(&ip.ipaddr_v4, &ip_prefix->u.prefix4, | |
434 | sizeof(struct in_addr)); | |
435 | } else { | |
436 | ip.ipa_type = IPADDR_V6; | |
437 | memcpy(&ip.ipaddr_v6, &ip_prefix->u.prefix6, | |
438 | sizeof(struct in6_addr)); | |
439 | } | |
440 | ||
441 | memset(evp, 0, sizeof(struct prefix_evpn)); | |
442 | evp->family = AF_EVPN; | |
50f74cf1 | 443 | evp->prefixlen = EVPN_ROUTE_PREFIXLEN; |
342dd0c6 | 444 | evp->prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE; |
3714a385 | 445 | evp->prefix.prefix_addr.ip_prefix_length = ip_prefix->prefixlen; |
446 | evp->prefix.prefix_addr.ip.ipa_type = ip.ipa_type; | |
447 | memcpy(&evp->prefix.prefix_addr.ip, &ip, sizeof(struct ipaddr)); | |
342dd0c6 | 448 | } |
449 | ||
d62a17ae | 450 | static inline void build_evpn_type3_prefix(struct prefix_evpn *p, |
451 | struct in_addr originator_ip) | |
128ea8ab | 452 | { |
d62a17ae | 453 | memset(p, 0, sizeof(struct prefix_evpn)); |
b03b8898 | 454 | p->family = AF_EVPN; |
50f74cf1 | 455 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; |
d62a17ae | 456 | p->prefix.route_type = BGP_EVPN_IMET_ROUTE; |
3714a385 | 457 | p->prefix.imet_addr.ip.ipa_type = IPADDR_V4; |
458 | p->prefix.imet_addr.ip.ipaddr_v4 = originator_ip; | |
128ea8ab | 459 | } |
460 | ||
50f74cf1 | 461 | static inline void build_evpn_type4_prefix(struct prefix_evpn *p, |
462 | esi_t *esi, | |
463 | struct in_addr originator_ip) | |
464 | { | |
465 | memset(p, 0, sizeof(struct prefix_evpn)); | |
466 | p->family = AF_EVPN; | |
467 | p->prefixlen = EVPN_ROUTE_PREFIXLEN; | |
468 | p->prefix.route_type = BGP_EVPN_ES_ROUTE; | |
469 | p->prefix.es_addr.ip_prefix_length = IPV4_MAX_BITLEN; | |
470 | p->prefix.es_addr.ip.ipa_type = IPADDR_V4; | |
471 | p->prefix.es_addr.ip.ipaddr_v4 = originator_ip; | |
472 | memcpy(&p->prefix.es_addr.esi, esi, sizeof(esi_t)); | |
473 | } | |
474 | ||
486456ca MK |
475 | static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi, |
476 | safi_t safi) | |
477 | { | |
478 | if (afi == AFI_IP && | |
479 | CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], | |
480 | BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4)) | |
481 | return 1; | |
482 | else if (afi == AFI_IP6 && | |
483 | CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN], | |
484 | BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6)) | |
485 | return 1; | |
486 | return 0; | |
487 | } | |
488 | ||
50f74cf1 | 489 | static inline void es_get_system_mac(esi_t *esi, |
490 | struct ethaddr *mac) | |
491 | { | |
2bb9eff4 DS |
492 | /* |
493 | * for type-1 and type-3 ESIs, | |
494 | * the system mac starts at val[1] | |
50f74cf1 | 495 | */ |
496 | memcpy(mac, &esi->val[1], ETH_ALEN); | |
497 | } | |
498 | ||
499 | static inline int is_es_local(struct evpnes *es) | |
500 | { | |
501 | return CHECK_FLAG(es->flags, EVPNES_LOCAL) ? 1 : 0; | |
502 | } | |
503 | ||
5fd9c12b KA |
504 | extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf, |
505 | afi_t afi, safi_t safi, | |
506 | bool add); | |
996c9314 | 507 | extern void evpn_rt_delete_auto(struct bgp *, vni_t, struct list *); |
523cafc4 | 508 | extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf, |
509 | struct ecommunity *ecomadd); | |
510 | extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf, | |
511 | struct ecommunity *ecomdel); | |
512 | extern void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf, | |
513 | struct ecommunity *ecomadd); | |
514 | extern void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf, | |
515 | struct ecommunity *ecomdel); | |
d62a17ae | 516 | extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp, |
517 | struct bgpevpn *vpn); | |
bf1061d8 | 518 | extern void bgp_evpn_handle_autort_change(struct bgp *bgp); |
676f83b9 | 519 | extern void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw); |
d62a17ae | 520 | extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn, |
521 | int withdraw); | |
522 | extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn); | |
523 | extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn); | |
523cafc4 | 524 | extern void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf); |
525 | extern void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf); | |
d62a17ae | 526 | extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn); |
527 | extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, | |
528 | struct bgpevpn *vpn); | |
529 | extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, | |
530 | struct bgpevpn *vpn); | |
531 | extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, | |
532 | struct bgpevpn *vpn); | |
533 | extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn); | |
676f83b9 | 534 | extern void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp); |
d62a17ae | 535 | extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni); |
536 | extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, | |
76d07c7a AK |
537 | struct in_addr originator_ip, |
538 | vrf_id_t tenant_vrf_id, | |
539 | struct in_addr mcast_grp); | |
d62a17ae | 540 | extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn); |
50f74cf1 | 541 | extern struct evpnes *bgp_evpn_lookup_es(struct bgp *bgp, esi_t *esi); |
542 | extern struct evpnes *bgp_evpn_es_new(struct bgp *bgp, esi_t *esi, | |
543 | struct ipaddr *originator_ip); | |
544 | extern void bgp_evpn_es_free(struct bgp *bgp, struct evpnes *es); | |
7df407ed | 545 | extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni); |
a4168ebc | 546 | #endif /* _BGP_EVPN_PRIVATE_H */ |