]>
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 | ||
31 | /* EVPN prefix lengths. */ | |
32 | #define EVPN_TYPE_2_ROUTE_PREFIXLEN 224 | |
33 | #define EVPN_TYPE_3_ROUTE_PREFIXLEN 224 | |
34 | ||
35 | /* EVPN route types. */ | |
d62a17ae | 36 | typedef enum { |
37 | BGP_EVPN_AD_ROUTE = 1, /* Ethernet Auto-Discovery (A-D) route */ | |
38 | BGP_EVPN_MAC_IP_ROUTE, /* MAC/IP Advertisement route */ | |
39 | BGP_EVPN_IMET_ROUTE, /* Inclusive Multicast Ethernet Tag route */ | |
40 | BGP_EVPN_ES_ROUTE, /* Ethernet Segment route */ | |
41 | BGP_EVPN_IP_PREFIX_ROUTE, /* IP Prefix route */ | |
a4168ebc | 42 | } bgp_evpn_route_type; |
43 | ||
44 | /* | |
45 | * Hash table of EVIs. Right now, the only type of EVI supported is with | |
46 | * VxLAN encapsulation, hence each EVI corresponds to a L2 VNI. | |
47 | * The VNIs are not "created" through BGP but through some other interface | |
48 | * on the system. This table stores VNIs that BGP comes to know as present | |
49 | * on the system (through interaction with zebra) as well as pre-configured | |
50 | * VNIs (which need to be defined in the system to become "live"). | |
51 | */ | |
d62a17ae | 52 | struct bgpevpn { |
53 | vni_t vni; | |
54 | u_int32_t flags; | |
a4168ebc | 55 | #define VNI_FLAG_CFGD 0x1 /* VNI is user configured */ |
56 | #define VNI_FLAG_LIVE 0x2 /* VNI is "live" */ | |
57 | #define VNI_FLAG_RD_CFGD 0x4 /* RD is user configured. */ | |
58 | #define VNI_FLAG_IMPRT_CFGD 0x8 /* Import RT is user configured */ | |
59 | #define VNI_FLAG_EXPRT_CFGD 0x10 /* Export RT is user configured */ | |
60 | ||
1a98c087 MK |
61 | /* Flag to indicate if we are advertising the g/w mac ip for this VNI*/ |
62 | u_int8_t advertise_gw_macip; | |
63 | ||
d62a17ae | 64 | /* Id for deriving the RD automatically for this VNI */ |
65 | u_int16_t rd_id; | |
a4168ebc | 66 | |
d62a17ae | 67 | /* RD for this VNI. */ |
68 | struct prefix_rd prd; | |
a4168ebc | 69 | |
d62a17ae | 70 | /* Route type 3 field */ |
71 | struct in_addr originator_ip; | |
a4168ebc | 72 | |
d62a17ae | 73 | /* Import and Export RTs. */ |
74 | struct list *import_rtl; | |
75 | struct list *export_rtl; | |
a4168ebc | 76 | |
d62a17ae | 77 | /* Route table for EVPN routes for this VNI. */ |
78 | struct bgp_table *route_table; | |
a4168ebc | 79 | |
d62a17ae | 80 | QOBJ_FIELDS |
a4168ebc | 81 | }; |
82 | ||
83 | DECLARE_QOBJ_TYPE(bgpevpn) | |
84 | ||
85 | /* Mapping of Import RT to VNIs. | |
86 | * The Import RTs of all VNIs are maintained in a hash table with each | |
87 | * RT linking to all VNIs that will import routes matching this RT. | |
88 | */ | |
d62a17ae | 89 | struct irt_node { |
90 | /* RT */ | |
91 | struct ecommunity_val rt; | |
a4168ebc | 92 | |
d62a17ae | 93 | /* List of VNIs importing routes matching this RT. */ |
94 | struct list *vnis; | |
a4168ebc | 95 | }; |
96 | ||
128ea8ab | 97 | #define RT_TYPE_IMPORT 1 |
98 | #define RT_TYPE_EXPORT 2 | |
99 | #define RT_TYPE_BOTH 3 | |
100 | ||
d62a17ae | 101 | static inline int is_vni_configured(struct bgpevpn *vpn) |
128ea8ab | 102 | { |
d62a17ae | 103 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD)); |
128ea8ab | 104 | } |
105 | ||
d62a17ae | 106 | static inline int is_vni_live(struct bgpevpn *vpn) |
128ea8ab | 107 | { |
d62a17ae | 108 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_LIVE)); |
128ea8ab | 109 | } |
110 | ||
d62a17ae | 111 | static inline int is_rd_configured(struct bgpevpn *vpn) |
128ea8ab | 112 | { |
d62a17ae | 113 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_RD_CFGD)); |
128ea8ab | 114 | } |
115 | ||
d62a17ae | 116 | static inline int bgp_evpn_rd_matches_existing(struct bgpevpn *vpn, |
117 | struct prefix_rd *prd) | |
128ea8ab | 118 | { |
d62a17ae | 119 | return (memcmp(&vpn->prd.val, prd->val, ECOMMUNITY_SIZE) == 0); |
128ea8ab | 120 | } |
121 | ||
d62a17ae | 122 | static inline int is_import_rt_configured(struct bgpevpn *vpn) |
128ea8ab | 123 | { |
d62a17ae | 124 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD)); |
128ea8ab | 125 | } |
126 | ||
d62a17ae | 127 | static inline int is_export_rt_configured(struct bgpevpn *vpn) |
128ea8ab | 128 | { |
d62a17ae | 129 | return (CHECK_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD)); |
128ea8ab | 130 | } |
131 | ||
d62a17ae | 132 | static inline int is_vni_param_configured(struct bgpevpn *vpn) |
128ea8ab | 133 | { |
d62a17ae | 134 | return (is_rd_configured(vpn) || is_import_rt_configured(vpn) |
135 | || is_export_rt_configured(vpn)); | |
128ea8ab | 136 | } |
137 | ||
d62a17ae | 138 | static inline void vni2label(vni_t vni, mpls_label_t *label) |
128ea8ab | 139 | { |
d62a17ae | 140 | u_char *tag = (u_char *)label; |
141 | tag[0] = (vni >> 16) & 0xFF; | |
142 | tag[1] = (vni >> 8) & 0xFF; | |
143 | tag[2] = vni & 0xFF; | |
128ea8ab | 144 | } |
145 | ||
d62a17ae | 146 | static inline vni_t label2vni(mpls_label_t *label) |
128ea8ab | 147 | { |
d62a17ae | 148 | u_char *tag = (u_char *)label; |
149 | vni_t vni; | |
128ea8ab | 150 | |
d62a17ae | 151 | vni = ((u_int32_t)*tag++ << 16); |
152 | vni |= (u_int32_t)*tag++ << 8; | |
153 | vni |= (u_int32_t)(*tag & 0xFF); | |
128ea8ab | 154 | |
d62a17ae | 155 | return vni; |
128ea8ab | 156 | } |
157 | ||
d62a17ae | 158 | static inline void encode_mac_mobility_extcomm(int static_mac, u_int32_t seq, |
159 | struct ecommunity_val *eval) | |
128ea8ab | 160 | { |
d62a17ae | 161 | memset(eval, 0, sizeof(*eval)); |
162 | eval->val[0] = ECOMMUNITY_ENCODE_EVPN; | |
163 | eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY; | |
164 | if (static_mac) | |
165 | eval->val[2] = ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY; | |
166 | eval->val[4] = (seq >> 24) & 0xff; | |
167 | eval->val[5] = (seq >> 16) & 0xff; | |
168 | eval->val[6] = (seq >> 8) & 0xff; | |
169 | eval->val[7] = seq & 0xff; | |
128ea8ab | 170 | } |
171 | ||
d62a17ae | 172 | static inline void build_evpn_type2_prefix(struct prefix_evpn *p, |
173 | struct ethaddr *mac, | |
174 | struct ipaddr *ip) | |
128ea8ab | 175 | { |
d62a17ae | 176 | memset(p, 0, sizeof(struct prefix_evpn)); |
177 | p->family = AF_ETHERNET; | |
178 | p->prefixlen = EVPN_TYPE_2_ROUTE_PREFIXLEN; | |
179 | p->prefix.route_type = BGP_EVPN_MAC_IP_ROUTE; | |
28328ea9 | 180 | memcpy(&p->prefix.mac.octet, mac->octet, ETH_ALEN); |
d62a17ae | 181 | p->prefix.ip.ipa_type = IPADDR_NONE; |
182 | if (ip) | |
183 | memcpy(&p->prefix.ip, ip, sizeof(*ip)); | |
128ea8ab | 184 | } |
185 | ||
d62a17ae | 186 | static inline void build_evpn_type3_prefix(struct prefix_evpn *p, |
187 | struct in_addr originator_ip) | |
128ea8ab | 188 | { |
d62a17ae | 189 | memset(p, 0, sizeof(struct prefix_evpn)); |
190 | p->family = AF_ETHERNET; | |
191 | p->prefixlen = EVPN_TYPE_3_ROUTE_PREFIXLEN; | |
192 | p->prefix.route_type = BGP_EVPN_IMET_ROUTE; | |
193 | p->prefix.ip.ipa_type = IPADDR_V4; | |
194 | p->prefix.ip.ipaddr_v4 = originator_ip; | |
128ea8ab | 195 | } |
196 | ||
197 | ||
d62a17ae | 198 | extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp, |
199 | struct bgpevpn *vpn); | |
200 | extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn, | |
201 | int withdraw); | |
202 | extern int bgp_evpn_install_routes(struct bgp *bgp, struct bgpevpn *vpn); | |
203 | extern int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn); | |
204 | extern void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn); | |
205 | extern void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, | |
206 | struct bgpevpn *vpn); | |
207 | extern void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, | |
208 | struct bgpevpn *vpn); | |
209 | extern void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, | |
210 | struct bgpevpn *vpn); | |
211 | extern void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn); | |
212 | extern struct bgpevpn *bgp_evpn_lookup_vni(struct bgp *bgp, vni_t vni); | |
213 | extern struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, | |
214 | struct in_addr originator_ip); | |
215 | extern void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn); | |
a4168ebc | 216 | #endif /* _BGP_EVPN_PRIVATE_H */ |