1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
/* E-VPN header for packet handling
* Copyright (C) 2016 6WIND
*
* This file is part of FRRouting.
*
* FRRouting is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* FRRouting is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _QUAGGA_BGP_EVPN_H
#define _QUAGGA_BGP_EVPN_H
#include "vxlan.h"
#include "bgpd.h"
#define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
#define EVPN_AUTORT_VXLAN 0x10000000
#define EVPN_ENABLED(bgp) (bgp)->advertise_all_vni
static inline int is_evpn_enabled(void)
{
struct bgp *bgp = NULL;
bgp = bgp_get_evpn();
return bgp ? EVPN_ENABLED(bgp) : 0;
}
static inline void vni2label(vni_t vni, mpls_label_t *label)
{
uint8_t *tag = (uint8_t *)label;
tag[0] = (vni >> 16) & 0xFF;
tag[1] = (vni >> 8) & 0xFF;
tag[2] = vni & 0xFF;
}
static inline vni_t label2vni(mpls_label_t *label)
{
uint8_t *tag = (uint8_t *)label;
vni_t vni;
vni = ((uint32_t)*tag++ << 16);
vni |= (uint32_t)*tag++ << 8;
vni |= (uint32_t)(*tag & 0xFF);
return vni;
}
static inline int advertise_type5_routes(struct bgp *bgp_vrf,
afi_t afi)
{
if (!bgp_vrf->l3vni)
return 0;
if ((afi == AFI_IP)
&& ((CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV4_UNICAST))
|| (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP))))
return 1;
if ((afi == AFI_IP6)
&& ((CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV6_UNICAST))
|| (CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))))
return 1;
return 0;
}
/* Flag if the route's parent is a EVPN route. */
static inline struct bgp_path_info *
get_route_parent_evpn(struct bgp_path_info *ri)
{
struct bgp_path_info *parent_ri;
/* If not imported (or doesn't have a parent), bail. */
if (ri->sub_type != BGP_ROUTE_IMPORTED ||
!ri->extra ||
!ri->extra->parent)
return NULL;
/* Determine parent recursively */
for (parent_ri = ri->extra->parent;
parent_ri->extra && parent_ri->extra->parent;
parent_ri = parent_ri->extra->parent)
;
return parent_ri;
}
/* Flag if the route's parent is a EVPN route. */
static inline int is_route_parent_evpn(struct bgp_path_info *ri)
{
struct bgp_path_info *parent_ri;
struct bgp_table *table;
struct bgp_dest *dest;
parent_ri = get_route_parent_evpn(ri);
if (!parent_ri)
return 0;
/* See if of family L2VPN/EVPN */
dest = parent_ri->net;
if (!dest)
return 0;
table = bgp_dest_table(dest);
if (table &&
table->afi == AFI_L2VPN &&
table->safi == SAFI_EVPN)
return 1;
return 0;
}
/* Flag if the route path's family is EVPN. */
static inline bool is_pi_family_evpn(struct bgp_path_info *pi)
{
return is_pi_family_matching(pi, AFI_L2VPN, SAFI_EVPN);
}
/* Flag if the route is injectable into EVPN. This would be either a
* non-imported route or a non-EVPN imported route.
*/
static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi)
{
struct bgp_path_info *parent_pi;
struct bgp_table *table;
struct bgp_dest *dest;
if (pi->sub_type != BGP_ROUTE_IMPORTED ||
!pi->extra ||
!pi->extra->parent)
return true;
parent_pi = (struct bgp_path_info *)pi->extra->parent;
dest = parent_pi->net;
if (!dest)
return true;
table = bgp_dest_table(dest);
if (table &&
table->afi == AFI_L2VPN &&
table->safi == SAFI_EVPN)
return false;
return true;
}
static inline bool evpn_resolve_overlay_index(void)
{
struct bgp *bgp = NULL;
bgp = bgp_get_evpn();
return bgp ? bgp->resolve_overlay_index : false;
}
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
const struct prefix *p,
struct attr *src_attr, afi_t afi,
safi_t safi);
extern void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf,
const struct prefix *p, afi_t afi,
safi_t safi);
extern void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi,
safi_t safi);
extern void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
safi_t safi);
extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf);
extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
extern char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels,
char *buf, int len);
extern void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json);
extern void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p,
const struct prefix_rd *prd,
mpls_label_t *label, uint32_t num_labels,
struct attr *attr, bool addpath_capable,
uint32_t addpath_tx_id);
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
struct bgp_nlri *packet, int withdraw);
extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
const struct prefix *p,
struct bgp_path_info *ri);
extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
const struct prefix *p,
struct bgp_path_info *ri);
extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
struct ethaddr *mac, struct ipaddr *ip,
int state);
extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
struct ethaddr *mac, struct ipaddr *ip,
uint8_t flags, uint32_t seq, esi_t *esi);
extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id,
struct ethaddr *rmac,
struct ethaddr *vrr_rmac,
struct in_addr originator_ip, int filter,
ifindex_t svi_ifindex, bool is_anycast_mac);
extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id);
extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip,
vrf_id_t tenant_vrf_id,
struct in_addr mcast_grp,
ifindex_t svi_ifindex);
extern void bgp_evpn_flood_control_change(struct bgp *bgp);
extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
extern void bgp_evpn_cleanup(struct bgp *bgp);
extern void bgp_evpn_init(struct bgp *bgp);
extern int bgp_evpn_get_type5_prefixlen(const struct prefix *pfx);
extern bool bgp_evpn_is_prefix_nht_supported(const struct prefix *pfx);
extern void update_advertise_vrf_routes(struct bgp *bgp_vrf);
extern void bgp_evpn_show_remote_ip_hash(struct hash_bucket *bucket,
void *args);
extern void bgp_evpn_show_vni_svi_hash(struct hash_bucket *bucket, void *args);
extern bool bgp_evpn_is_gateway_ip_resolved(struct bgp_nexthop_cache *bnc);
extern void
bgp_evpn_handle_resolve_overlay_index_set(struct hash_bucket *bucket,
void *arg);
extern void
bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket,
void *arg);
#endif /* _QUAGGA_BGP_EVPN_H */
|