Line data Source code
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 :
31 : #define RT_ADDRSTRLEN 28
32 :
33 : /* EVPN prefix lengths. This represents the sizeof struct evpn_addr
34 : * in bits */
35 : #define EVPN_ROUTE_PREFIXLEN (sizeof(struct evpn_addr) * 8)
36 :
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 :
51 : RB_HEAD(bgp_es_evi_rb_head, bgp_evpn_es_evi);
52 0 : RB_PROTOTYPE(bgp_es_evi_rb_head, bgp_evpn_es_evi, rb_node,
53 : bgp_es_evi_rb_cmp);
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 : */
62 : struct bgpevpn {
63 : vni_t vni;
64 : vrf_id_t tenant_vrf_id;
65 : ifindex_t svi_ifindex;
66 : uint32_t flags;
67 : #define VNI_FLAG_CFGD 0x1 /* VNI is user configured */
68 : #define VNI_FLAG_LIVE 0x2 /* VNI is "live" */
69 : #define VNI_FLAG_RD_CFGD 0x4 /* RD is user configured. */
70 : #define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */
71 : #define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */
72 : #define VNI_FLAG_USE_TWO_LABELS 0x20 /* Attach both L2-VNI and L3-VNI if
73 : needed for this VPN */
74 :
75 : struct bgp *bgp_vrf; /* back pointer to the vrf instance */
76 :
77 : /* Flag to indicate if we are
78 : * advertising the g/w mac ip for
79 : * this VNI*/
80 : uint8_t advertise_gw_macip;
81 :
82 : /* Flag to indicate if we are
83 : * advertising subnet for this VNI */
84 : uint8_t advertise_subnet;
85 :
86 : /* Flag to indicate if we are advertising the svi mac ip for this VNI*/
87 : uint8_t advertise_svi_macip;
88 :
89 : /* Id for deriving the RD
90 : * automatically for this VNI */
91 : uint16_t rd_id;
92 :
93 : /* RD for this VNI. */
94 : struct prefix_rd prd;
95 :
96 : /* Route type 3 field */
97 : struct in_addr originator_ip;
98 :
99 : /* PIM-SM MDT group for BUM flooding */
100 : struct in_addr mcast_grp;
101 :
102 : /* Import and Export RTs. */
103 : struct list *import_rtl;
104 : struct list *export_rtl;
105 :
106 : /*
107 : * EVPN route that uses gateway IP overlay index as its nexthop
108 : * needs to do a recursive lookup.
109 : * A remote MAC/IP entry should be present for the gateway IP.
110 : * Maintain a hash of the addresses received via remote MAC/IP routes
111 : * for efficient gateway IP recursive lookup in this EVI
112 : */
113 : struct hash *remote_ip_hash;
114 :
115 : /* Route tables for EVPN routes for
116 : * this VNI. */
117 : struct bgp_table *ip_table;
118 : struct bgp_table *mac_table;
119 :
120 : /* RB tree of ES-EVIs */
121 : struct bgp_es_evi_rb_head es_evi_rb_tree;
122 :
123 : /* List of local ESs */
124 : struct list *local_es_evi_list;
125 :
126 : QOBJ_FIELDS;
127 : };
128 :
129 : DECLARE_QOBJ_TYPE(bgpevpn);
130 :
131 : /* Mapping of Import RT to VNIs.
132 : * The Import RTs of all VNIs are maintained in a hash table with each
133 : * RT linking to all VNIs that will import routes matching this RT.
134 : */
135 : struct irt_node {
136 : /* RT */
137 : struct ecommunity_val rt;
138 :
139 : /* List of VNIs importing routes matching this RT. */
140 : struct list *vnis;
141 : };
142 :
143 : /* Mapping of Import RT to VRFs.
144 : * The Import RTs of all VRFss are maintained in a hash table with each
145 : * RT linking to all VRFs that will import routes matching this RT.
146 : */
147 : struct vrf_irt_node {
148 : /* RT */
149 : struct ecommunity_val rt;
150 :
151 : /* List of VNIs importing routes matching this RT. */
152 : struct list *vrfs;
153 : };
154 :
155 :
156 : #define RT_TYPE_IMPORT 1
157 : #define RT_TYPE_EXPORT 2
158 : #define RT_TYPE_BOTH 3
159 :
160 : #define EVPN_DAD_DEFAULT_TIME 180 /* secs */
161 : #define EVPN_DAD_DEFAULT_MAX_MOVES 5 /* default from RFC 7432 */
162 : #define EVPN_DAD_DEFAULT_AUTO_RECOVERY_TIME 1800 /* secs */
163 :
164 : struct bgp_evpn_info {
165 : /* enable disable dup detect */
166 : bool dup_addr_detect;
167 :
168 : /* Detection time(M) */
169 : int dad_time;
170 : /* Detection max moves(N) */
171 : uint32_t dad_max_moves;
172 : /* Permanent freeze */
173 : bool dad_freeze;
174 : /* Recovery time */
175 : uint32_t dad_freeze_time;
176 :
177 : /* EVPN enable - advertise svi macip routes */
178 : int advertise_svi_macip;
179 :
180 : /* PIP feature knob */
181 : bool advertise_pip;
182 : /* PIP IP (sys ip) */
183 : struct in_addr pip_ip;
184 : struct in_addr pip_ip_static;
185 : /* PIP MAC (sys MAC) */
186 : struct ethaddr pip_rmac;
187 : struct ethaddr pip_rmac_static;
188 : struct ethaddr pip_rmac_zebra;
189 : bool is_anycast_mac;
190 : };
191 :
192 : /* This structure defines an entry in remote_ip_hash */
193 : struct evpn_remote_ip {
194 : struct ipaddr addr;
195 : struct list *macip_path_list;
196 : };
197 :
198 : /*
199 : * Wrapper struct for l3 RT's
200 : */
201 : struct vrf_route_target {
202 : /* flags based on config to determine how RTs are handled */
203 : uint8_t flags;
204 : #define BGP_VRF_RT_AUTO (1 << 0)
205 : #define BGP_VRF_RT_WILD (1 << 1)
206 :
207 : struct ecommunity *ecom;
208 : };
209 :
210 0 : static inline int is_vrf_rd_configured(struct bgp *bgp_vrf)
211 : {
212 0 : return (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_RD_CFGD));
213 : }
214 :
215 0 : static inline int bgp_evpn_vrf_rd_matches_existing(struct bgp *bgp_vrf,
216 : struct prefix_rd *prd)
217 : {
218 0 : return (memcmp(&bgp_vrf->vrf_prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
219 : }
220 :
221 0 : static inline vni_t bgpevpn_get_l3vni(struct bgpevpn *vpn)
222 : {
223 0 : return vpn->bgp_vrf ? vpn->bgp_vrf->l3vni : 0;
224 : }
225 :
226 : static inline void bgpevpn_get_rmac(struct bgpevpn *vpn, struct ethaddr *rmac)
227 : {
228 : memset(rmac, 0, sizeof(struct ethaddr));
229 : if (!vpn->bgp_vrf)
230 : return;
231 : memcpy(rmac, &vpn->bgp_vrf->rmac, sizeof(struct ethaddr));
232 : }
233 :
234 0 : static inline struct list *bgpevpn_get_vrf_export_rtl(struct bgpevpn *vpn)
235 : {
236 0 : if (!vpn->bgp_vrf)
237 : return NULL;
238 :
239 0 : return vpn->bgp_vrf->vrf_export_rtl;
240 : }
241 :
242 : static inline struct list *bgpevpn_get_vrf_import_rtl(struct bgpevpn *vpn)
243 : {
244 : if (!vpn->bgp_vrf)
245 : return NULL;
246 :
247 : return vpn->bgp_vrf->vrf_import_rtl;
248 : }
249 :
250 : extern void bgp_evpn_es_evi_vrf_ref(struct bgpevpn *vpn);
251 : extern void bgp_evpn_es_evi_vrf_deref(struct bgpevpn *vpn);
252 :
253 0 : static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn)
254 : {
255 : /* bail if vpn is not associated to bgp_vrf */
256 0 : if (!vpn->bgp_vrf)
257 : return;
258 :
259 0 : UNSET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
260 0 : listnode_delete(vpn->bgp_vrf->l2vnis, vpn);
261 :
262 0 : bgp_evpn_es_evi_vrf_deref(vpn);
263 :
264 : /* remove the backpointer to the vrf instance */
265 0 : bgp_unlock(vpn->bgp_vrf);
266 0 : vpn->bgp_vrf = NULL;
267 : }
268 :
269 0 : static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn)
270 : {
271 0 : struct bgp *bgp_vrf = NULL;
272 :
273 : /* bail if vpn is already associated to vrf */
274 0 : if (vpn->bgp_vrf)
275 : return;
276 :
277 0 : bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id);
278 0 : if (!bgp_vrf)
279 : return;
280 :
281 : /* associate the vpn to the bgp_vrf instance */
282 0 : vpn->bgp_vrf = bgp_lock(bgp_vrf);
283 0 : listnode_add_sort(bgp_vrf->l2vnis, vpn);
284 :
285 : /*
286 : * If L3VNI is configured,
287 : * check if we are advertising two labels for this vpn
288 : */
289 0 : if (bgp_vrf->l3vni &&
290 0 : !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY))
291 0 : SET_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS);
292 :
293 0 : bgp_evpn_es_evi_vrf_ref(vpn);
294 : }
295 :
296 0 : static inline int is_vni_configured(struct bgpevpn *vpn)
297 : {
298 0 : return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD));
299 : }
300 :
301 0 : static inline int is_vni_live(struct bgpevpn *vpn)
302 : {
303 0 : return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE));
304 : }
305 :
306 0 : static inline int is_l3vni_live(struct bgp *bgp_vrf)
307 : {
308 0 : return (bgp_vrf->l3vni && bgp_vrf->l3vni_svi_ifindex);
309 : }
310 :
311 0 : static inline int is_rd_configured(struct bgpevpn *vpn)
312 : {
313 0 : return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD));
314 : }
315 :
316 0 : static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn,
317 : struct prefix_rd *prd)
318 : {
319 0 : return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0);
320 : }
321 :
322 0 : static inline int is_import_rt_configured(struct bgpevpn *vpn)
323 : {
324 0 : return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD));
325 : }
326 :
327 0 : static inline int is_export_rt_configured(struct bgpevpn *vpn)
328 : {
329 0 : return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD));
330 : }
331 :
332 0 : static inline void encode_es_rt_extcomm(struct ecommunity_val *eval,
333 : struct ethaddr *mac)
334 : {
335 0 : memset(eval, 0, sizeof(struct ecommunity_val));
336 0 : eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
337 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT;
338 0 : memcpy(&eval->val[2], mac, ETH_ALEN);
339 0 : }
340 :
341 0 : static inline void encode_df_elect_extcomm(struct ecommunity_val *eval,
342 : uint16_t pref)
343 : {
344 0 : memset(eval, 0, sizeof(*eval));
345 0 : eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
346 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION;
347 0 : eval->val[2] = EVPN_MH_DF_ALG_PREF;
348 0 : eval->val[6] = (pref >> 8) & 0xff;
349 0 : eval->val[7] = pref & 0xff;
350 0 : }
351 :
352 0 : static inline void encode_esi_label_extcomm(struct ecommunity_val *eval,
353 : bool single_active)
354 : {
355 0 : memset(eval, 0, sizeof(struct ecommunity_val));
356 0 : eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
357 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL;
358 0 : if (single_active)
359 : eval->val[2] |= (1 << 0);
360 : }
361 :
362 0 : static inline void encode_rmac_extcomm(struct ecommunity_val *eval,
363 : struct ethaddr *rmac)
364 : {
365 0 : memset(eval, 0, sizeof(*eval));
366 0 : eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
367 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC;
368 0 : memcpy(&eval->val[2], rmac, ETH_ALEN);
369 0 : }
370 :
371 0 : static inline void encode_default_gw_extcomm(struct ecommunity_val *eval)
372 : {
373 0 : memset(eval, 0, sizeof(*eval));
374 0 : eval->val[0] = ECOMMUNITY_ENCODE_OPAQUE;
375 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DEF_GW;
376 : }
377 :
378 0 : static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq,
379 : struct ecommunity_val *eval)
380 : {
381 0 : memset(eval, 0, sizeof(*eval));
382 0 : eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
383 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY;
384 0 : if (static_mac)
385 0 : eval->val[2] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY;
386 0 : eval->val[4] = (seq >> 24) & 0xff;
387 0 : eval->val[5] = (seq >> 16) & 0xff;
388 0 : eval->val[6] = (seq >> 8) & 0xff;
389 0 : eval->val[7] = seq & 0xff;
390 0 : }
391 :
392 0 : static inline void encode_na_flag_extcomm(struct ecommunity_val *eval,
393 : uint8_t na_flag, bool proxy)
394 : {
395 0 : memset(eval, 0, sizeof(*eval));
396 0 : eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
397 0 : eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ND;
398 0 : if (na_flag)
399 0 : eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG;
400 0 : if (proxy)
401 0 : eval->val[2] |= ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG;
402 0 : }
403 :
404 0 : static inline void ip_prefix_from_type5_prefix(const struct prefix_evpn *evp,
405 : struct prefix *ip)
406 : {
407 0 : memset(ip, 0, sizeof(struct prefix));
408 0 : if (is_evpn_prefix_ipaddr_v4(evp)) {
409 0 : ip->family = AF_INET;
410 0 : ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length;
411 0 : memcpy(&(ip->u.prefix4), &(evp->prefix.prefix_addr.ip.ip),
412 : IPV4_MAX_BYTELEN);
413 0 : } else if (is_evpn_prefix_ipaddr_v6(evp)) {
414 0 : ip->family = AF_INET6;
415 0 : ip->prefixlen = evp->prefix.prefix_addr.ip_prefix_length;
416 0 : memcpy(&(ip->u.prefix6), &(evp->prefix.prefix_addr.ip.ip),
417 : IPV6_MAX_BYTELEN);
418 : }
419 0 : }
420 :
421 0 : static inline int is_evpn_prefix_default(const struct prefix *evp)
422 : {
423 0 : if (evp->family != AF_EVPN)
424 : return 0;
425 :
426 0 : return ((evp->u.prefix_evpn.prefix_addr.ip_prefix_length == 0) ?
427 0 : 1 : 0);
428 : }
429 :
430 0 : static inline void ip_prefix_from_type2_prefix(const struct prefix_evpn *evp,
431 : struct prefix *ip)
432 : {
433 0 : memset(ip, 0, sizeof(struct prefix));
434 0 : if (is_evpn_prefix_ipaddr_v4(evp)) {
435 0 : ip->family = AF_INET;
436 0 : ip->prefixlen = IPV4_MAX_BITLEN;
437 0 : memcpy(&(ip->u.prefix4), &(evp->prefix.macip_addr.ip.ip),
438 : IPV4_MAX_BYTELEN);
439 0 : } else if (is_evpn_prefix_ipaddr_v6(evp)) {
440 0 : ip->family = AF_INET6;
441 0 : ip->prefixlen = IPV6_MAX_BITLEN;
442 0 : memcpy(&(ip->u.prefix6), &(evp->prefix.macip_addr.ip.ip),
443 : IPV6_MAX_BYTELEN);
444 : }
445 0 : }
446 :
447 0 : static inline void ip_prefix_from_evpn_prefix(const struct prefix_evpn *evp,
448 : struct prefix *ip)
449 : {
450 0 : if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
451 0 : ip_prefix_from_type2_prefix(evp, ip);
452 0 : else if (evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE)
453 0 : ip_prefix_from_type5_prefix(evp, ip);
454 0 : }
455 :
456 0 : static inline void build_evpn_type2_prefix(struct prefix_evpn *p,
457 : struct ethaddr *mac,
458 : struct ipaddr *ip)
459 : {
460 0 : memset(p, 0, sizeof(struct prefix_evpn));
461 0 : p->family = AF_EVPN;
462 0 : p->prefixlen = EVPN_ROUTE_PREFIXLEN;
463 0 : p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE;
464 0 : memcpy(&p->prefix.macip_addr.mac.octet, mac->octet, ETH_ALEN);
465 0 : p->prefix.macip_addr.ip.ipa_type = IPADDR_NONE;
466 0 : memcpy(&p->prefix.macip_addr.ip, ip, sizeof(*ip));
467 0 : }
468 :
469 : static inline void
470 0 : build_type5_prefix_from_ip_prefix(struct prefix_evpn *evp,
471 : const struct prefix *ip_prefix)
472 : {
473 0 : struct ipaddr ip;
474 :
475 0 : memset(&ip, 0, sizeof(struct ipaddr));
476 0 : if (ip_prefix->family == AF_INET) {
477 0 : ip.ipa_type = IPADDR_V4;
478 0 : memcpy(&ip.ipaddr_v4, &ip_prefix->u.prefix4,
479 : sizeof(struct in_addr));
480 : } else {
481 0 : ip.ipa_type = IPADDR_V6;
482 0 : memcpy(&ip.ipaddr_v6, &ip_prefix->u.prefix6,
483 : sizeof(struct in6_addr));
484 : }
485 :
486 0 : memset(evp, 0, sizeof(struct prefix_evpn));
487 0 : evp->family = AF_EVPN;
488 0 : evp->prefixlen = EVPN_ROUTE_PREFIXLEN;
489 0 : evp->prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
490 0 : evp->prefix.prefix_addr.ip_prefix_length = ip_prefix->prefixlen;
491 0 : evp->prefix.prefix_addr.ip.ipa_type = ip.ipa_type;
492 0 : memcpy(&evp->prefix.prefix_addr.ip, &ip, sizeof(struct ipaddr));
493 0 : }
494 :
495 0 : static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
496 : struct in_addr originator_ip)
497 : {
498 0 : memset(p, 0, sizeof(struct prefix_evpn));
499 0 : p->family = AF_EVPN;
500 0 : p->prefixlen = EVPN_ROUTE_PREFIXLEN;
501 0 : p->prefix.route_type = BGP_EVPN_IMET_ROUTE;
502 0 : p->prefix.imet_addr.ip.ipa_type = IPADDR_V4;
503 0 : p->prefix.imet_addr.ip.ipaddr_v4 = originator_ip;
504 0 : }
505 :
506 0 : static inline void build_evpn_type4_prefix(struct prefix_evpn *p,
507 : esi_t *esi,
508 : struct in_addr originator_ip)
509 : {
510 0 : memset(p, 0, sizeof(struct prefix_evpn));
511 0 : p->family = AF_EVPN;
512 0 : p->prefixlen = EVPN_ROUTE_PREFIXLEN;
513 0 : p->prefix.route_type = BGP_EVPN_ES_ROUTE;
514 0 : p->prefix.es_addr.ip_prefix_length = IPV4_MAX_BITLEN;
515 0 : p->prefix.es_addr.ip.ipa_type = IPADDR_V4;
516 0 : p->prefix.es_addr.ip.ipaddr_v4 = originator_ip;
517 0 : memcpy(&p->prefix.es_addr.esi, esi, sizeof(esi_t));
518 0 : }
519 :
520 0 : static inline void build_evpn_type1_prefix(struct prefix_evpn *p,
521 : uint32_t eth_tag,
522 : esi_t *esi,
523 : struct in_addr originator_ip)
524 : {
525 0 : memset(p, 0, sizeof(struct prefix_evpn));
526 0 : p->family = AF_EVPN;
527 0 : p->prefixlen = EVPN_ROUTE_PREFIXLEN;
528 0 : p->prefix.route_type = BGP_EVPN_AD_ROUTE;
529 0 : p->prefix.ead_addr.eth_tag = eth_tag;
530 0 : p->prefix.ead_addr.ip.ipa_type = IPADDR_V4;
531 0 : p->prefix.ead_addr.ip.ipaddr_v4 = originator_ip;
532 0 : memcpy(&p->prefix.ead_addr.esi, esi, sizeof(esi_t));
533 0 : }
534 :
535 0 : static inline void evpn_type1_prefix_global_copy(struct prefix_evpn *global_p,
536 : const struct prefix_evpn *vni_p)
537 : {
538 0 : memcpy(global_p, vni_p, sizeof(*global_p));
539 0 : global_p->prefix.ead_addr.ip.ipa_type = 0;
540 0 : global_p->prefix.ead_addr.ip.ipaddr_v4.s_addr = INADDR_ANY;
541 0 : global_p->prefix.ead_addr.frag_id = 0;
542 : }
543 :
544 : /* EAD prefix in the global table doesn't include the VTEP-IP so
545 : * we need to create a different copy for the VNI
546 : */
547 : static inline struct prefix_evpn *
548 0 : evpn_type1_prefix_vni_ip_copy(struct prefix_evpn *vni_p,
549 : const struct prefix_evpn *global_p,
550 : struct in_addr originator_ip)
551 : {
552 0 : memcpy(vni_p, global_p, sizeof(*vni_p));
553 0 : vni_p->prefix.ead_addr.ip.ipa_type = IPADDR_V4;
554 0 : vni_p->prefix.ead_addr.ip.ipaddr_v4 = originator_ip;
555 :
556 0 : return vni_p;
557 : }
558 :
559 0 : static inline void evpn_type2_prefix_global_copy(
560 : struct prefix_evpn *global_p, const struct prefix_evpn *vni_p,
561 : const struct ethaddr *mac, const struct ipaddr *ip)
562 : {
563 0 : memcpy(global_p, vni_p, sizeof(*global_p));
564 :
565 0 : if (mac)
566 0 : global_p->prefix.macip_addr.mac = *mac;
567 :
568 0 : if (ip)
569 0 : global_p->prefix.macip_addr.ip = *ip;
570 0 : }
571 :
572 : static inline void
573 0 : evpn_type2_prefix_vni_ip_copy(struct prefix_evpn *vni_p,
574 : const struct prefix_evpn *global_p)
575 : {
576 0 : memcpy(vni_p, global_p, sizeof(*vni_p));
577 0 : memset(&vni_p->prefix.macip_addr.mac, 0, sizeof(struct ethaddr));
578 0 : }
579 :
580 : static inline void
581 0 : evpn_type2_prefix_vni_mac_copy(struct prefix_evpn *vni_p,
582 : const struct prefix_evpn *global_p)
583 : {
584 0 : memcpy(vni_p, global_p, sizeof(*vni_p));
585 0 : memset(&vni_p->prefix.macip_addr.ip, 0, sizeof(struct ipaddr));
586 0 : }
587 :
588 : /* Get MAC of path_info prefix */
589 : static inline struct ethaddr *
590 0 : evpn_type2_path_info_get_mac(const struct bgp_path_info *local_pi)
591 : {
592 0 : assert(local_pi->extra);
593 0 : return &local_pi->extra->vni_info.mac;
594 : }
595 :
596 : /* Get IP of path_info prefix */
597 : static inline struct ipaddr *
598 0 : evpn_type2_path_info_get_ip(const struct bgp_path_info *local_pi)
599 : {
600 0 : assert(local_pi->extra);
601 0 : return &local_pi->extra->vni_info.ip;
602 : }
603 :
604 : /* Set MAC of path_info prefix */
605 0 : static inline void evpn_type2_path_info_set_mac(struct bgp_path_info *local_pi,
606 : const struct ethaddr mac)
607 : {
608 0 : assert(local_pi->extra);
609 0 : local_pi->extra->vni_info.mac = mac;
610 0 : }
611 :
612 : /* Set IP of path_info prefix */
613 0 : static inline void evpn_type2_path_info_set_ip(struct bgp_path_info *local_pi,
614 : const struct ipaddr ip)
615 : {
616 0 : assert(local_pi->extra);
617 0 : local_pi->extra->vni_info.ip = ip;
618 0 : }
619 :
620 : /* Is the IP empty for the RT's dest? */
621 0 : static inline bool is_evpn_type2_dest_ipaddr_none(const struct bgp_dest *dest)
622 : {
623 0 : const struct prefix_evpn *evp =
624 0 : (const struct prefix_evpn *)bgp_dest_get_prefix(dest);
625 :
626 0 : assert(evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE);
627 0 : return is_evpn_prefix_ipaddr_none(evp);
628 : }
629 :
630 0 : static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi,
631 : safi_t safi)
632 : {
633 0 : if (afi == AFI_IP &&
634 0 : CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
635 : BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
636 : return 1;
637 0 : else if (afi == AFI_IP6 &&
638 0 : CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
639 : BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
640 0 : return 1;
641 : return 0;
642 : }
643 :
644 0 : static inline void es_get_system_mac(esi_t *esi,
645 : struct ethaddr *mac)
646 : {
647 : /*
648 : * for type-1 and type-3 ESIs,
649 : * the system mac starts at val[1]
650 : */
651 0 : memcpy(mac, &esi->val[1], ETH_ALEN);
652 : }
653 :
654 0 : static inline bool bgp_evpn_is_svi_macip_enabled(struct bgpevpn *vpn)
655 : {
656 0 : struct bgp *bgp_evpn = NULL;
657 :
658 0 : bgp_evpn = bgp_get_evpn();
659 :
660 0 : return (bgp_evpn->evpn_info->advertise_svi_macip ||
661 0 : vpn->advertise_svi_macip);
662 : }
663 :
664 0 : static inline bool bgp_evpn_is_path_local(struct bgp *bgp,
665 : struct bgp_path_info *pi)
666 : {
667 0 : return (pi->peer == bgp->peer_self
668 : && pi->type == ZEBRA_ROUTE_BGP
669 0 : && pi->sub_type == BGP_ROUTE_STATIC);
670 : }
671 :
672 : extern struct zclient *zclient;
673 :
674 : extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf,
675 : afi_t afi, safi_t safi,
676 : bool add);
677 : extern void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl,
678 : bool is_l3);
679 : extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
680 : struct ecommunity *ecomadd);
681 : extern void bgp_evpn_configure_export_auto_rt_for_vrf(struct bgp *bgp_vrf);
682 : extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
683 : struct ecommunity *ecomdel);
684 : extern void bgp_evpn_unconfigure_export_auto_rt_for_vrf(struct bgp *bgp_vrf);
685 : extern void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
686 : struct ecommunity *ecomadd,
687 : bool is_wildcard);
688 : extern void bgp_evpn_configure_import_auto_rt_for_vrf(struct bgp *bgp_vrf);
689 : extern void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
690 : struct ecommunity *ecomdel);
691 : extern void bgp_evpn_unconfigure_import_auto_rt_for_vrf(struct bgp *bgp_vrf);
692 : extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
693 : struct bgpevpn *vpn);
694 : extern void bgp_evpn_handle_autort_change(struct bgp *bgp);
695 : extern void bgp_evpn_handle_vrf_rd_change(struct bgp *bgp_vrf, int withdraw);
696 : extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
697 : int withdraw);
698 : extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn);
699 : extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn);
700 : extern void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf);
701 : extern void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf);
702 : extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn);
703 : extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp,
704 : struct bgpevpn *vpn);
705 : extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp,
706 : struct bgpevpn *vpn);
707 : extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp,
708 : struct bgpevpn *vpn);
709 : extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn);
710 : extern void bgp_evpn_derive_auto_rd_for_vrf(struct bgp *bgp);
711 : extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni);
712 : extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
713 : struct in_addr originator_ip,
714 : vrf_id_t tenant_vrf_id,
715 : struct in_addr mcast_grp,
716 : ifindex_t svi_ifindex);
717 : extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn);
718 : extern bool bgp_evpn_lookup_l3vni_l2vni_table(vni_t vni);
719 : extern int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn);
720 : extern void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi,
721 : struct bgp_dest *dest,
722 : struct bgp_path_info **pi);
723 : int vni_list_cmp(void *p1, void *p2);
724 : extern int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
725 : struct bgp_dest *dest);
726 : extern struct bgp_dest *
727 : bgp_evpn_global_node_get(struct bgp_table *table, afi_t afi, safi_t safi,
728 : const struct prefix_evpn *evp, struct prefix_rd *prd,
729 : const struct bgp_path_info *local_pi);
730 : extern struct bgp_dest *
731 : bgp_evpn_global_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi,
732 : const struct prefix_evpn *evp,
733 : struct prefix_rd *prd,
734 : const struct bgp_path_info *local_pi);
735 : extern struct bgp_dest *
736 : bgp_evpn_vni_ip_node_get(struct bgp_table *const table,
737 : const struct prefix_evpn *evp,
738 : const struct bgp_path_info *parent_pi);
739 : extern struct bgp_dest *
740 : bgp_evpn_vni_ip_node_lookup(const struct bgp_table *const table,
741 : const struct prefix_evpn *evp,
742 : const struct bgp_path_info *parent_pi);
743 : extern struct bgp_dest *
744 : bgp_evpn_vni_mac_node_get(struct bgp_table *const table,
745 : const struct prefix_evpn *evp,
746 : const struct bgp_path_info *parent_pi);
747 : extern struct bgp_dest *
748 : bgp_evpn_vni_mac_node_lookup(const struct bgp_table *const table,
749 : const struct prefix_evpn *evp,
750 : const struct bgp_path_info *parent_pi);
751 : extern struct bgp_dest *
752 : bgp_evpn_vni_node_get(struct bgpevpn *vpn, const struct prefix_evpn *p,
753 : const struct bgp_path_info *parent_pi);
754 : extern struct bgp_dest *
755 : bgp_evpn_vni_node_lookup(const struct bgpevpn *vpn, const struct prefix_evpn *p,
756 : const struct bgp_path_info *parent_pi);
757 :
758 : extern void bgp_evpn_import_route_in_vrfs(struct bgp_path_info *pi, int import);
759 : extern void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
760 : struct bgpevpn *vpn,
761 : struct bgp_node *rn,
762 : struct bgp_path_info *local_pi,
763 : const char *caller);
764 : extern int bgp_evpn_route_entry_install_if_vrf_match(struct bgp *bgp_vrf,
765 : struct bgp_path_info *pi,
766 : int install);
767 : extern void bgp_evpn_import_type2_route(struct bgp_path_info *pi, int import);
768 : extern void bgp_evpn_xxport_delete_ecomm(void *val);
769 : extern int bgp_evpn_route_target_cmp(struct ecommunity *ecom1,
770 : struct ecommunity *ecom2);
771 : #endif /* _BGP_EVPN_PRIVATE_H */
|