1 /* E-VPN header for packet handling
2  * Copyright (C) 2016 6WIND
3  *
4  * This file is part of FRRouting.
5  *
6  * FRRouting 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  * FRRouting 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 along
17  * with this program; see the file COPYING; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef _QUAGGA_BGP_EVPN_H
22 #define _QUAGGA_BGP_EVPN_H
23 
24 #include "vxlan.h"
25 #include "bgpd.h"
26 
27 #define EVPN_ROUTE_STRLEN 200 /* Must be >> MAC + IPv6 strings. */
28 #define EVPN_AUTORT_VXLAN 0x10000000
29 
30 #define EVPN_ENABLED(bgp)  (bgp)->advertise_all_vni
is_evpn_enabled(void)31 static inline int is_evpn_enabled(void)
32 {
33 	struct bgp *bgp = NULL;
34 
35 	bgp = bgp_get_evpn();
36 	return bgp ? EVPN_ENABLED(bgp) : 0;
37 }
38 
vni2label(vni_t vni,mpls_label_t * label)39 static inline void vni2label(vni_t vni, mpls_label_t *label)
40 {
41 	uint8_t *tag = (uint8_t *)label;
42 
43 	tag[0] = (vni >> 16) & 0xFF;
44 	tag[1] = (vni >> 8) & 0xFF;
45 	tag[2] = vni & 0xFF;
46 }
47 
label2vni(mpls_label_t * label)48 static inline vni_t label2vni(mpls_label_t *label)
49 {
50 	uint8_t *tag = (uint8_t *)label;
51 	vni_t vni;
52 
53 	vni = ((uint32_t)*tag++ << 16);
54 	vni |= (uint32_t)*tag++ << 8;
55 	vni |= (uint32_t)(*tag & 0xFF);
56 
57 	return vni;
58 }
59 
advertise_type5_routes(struct bgp * bgp_vrf,afi_t afi)60 static inline int advertise_type5_routes(struct bgp *bgp_vrf,
61 					 afi_t afi)
62 {
63 	if (!bgp_vrf->l3vni)
64 		return 0;
65 
66 	if (afi == AFI_IP &&
67 	    CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
68 		       BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST))
69 		return 1;
70 
71 	if (afi == AFI_IP6 &&
72 	    CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
73 		       BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
74 		return 1;
75 
76 	return 0;
77 }
78 
79 /* Flag if the route's parent is a EVPN route. */
is_route_parent_evpn(struct bgp_path_info * ri)80 static inline int is_route_parent_evpn(struct bgp_path_info *ri)
81 {
82 	struct bgp_path_info *parent_ri;
83 	struct bgp_table *table;
84 	struct bgp_dest *dest;
85 
86 	/* If not imported (or doesn't have a parent), bail. */
87 	if (ri->sub_type != BGP_ROUTE_IMPORTED ||
88 	    !ri->extra ||
89 	    !ri->extra->parent)
90 		return 0;
91 
92 	/* Determine parent recursively */
93 	for (parent_ri = ri->extra->parent;
94 	     parent_ri->extra && parent_ri->extra->parent;
95 	     parent_ri = parent_ri->extra->parent)
96 		;
97 
98 	/* See if of family L2VPN/EVPN */
99 	dest = parent_ri->net;
100 	if (!dest)
101 		return 0;
102 	table = bgp_dest_table(dest);
103 	if (table &&
104 	    table->afi == AFI_L2VPN &&
105 	    table->safi == SAFI_EVPN)
106 		return 1;
107 	return 0;
108 }
109 
110 /* Flag if the route path's family is EVPN. */
is_pi_family_evpn(struct bgp_path_info * pi)111 static inline bool is_pi_family_evpn(struct bgp_path_info *pi)
112 {
113 	return is_pi_family_matching(pi, AFI_L2VPN, SAFI_EVPN);
114 }
115 
116 /* Flag if the route is injectable into EVPN. This would be either a
117  * non-imported route or a non-EVPN imported route.
118  */
is_route_injectable_into_evpn(struct bgp_path_info * pi)119 static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi)
120 {
121 	struct bgp_path_info *parent_pi;
122 	struct bgp_table *table;
123 	struct bgp_dest *dest;
124 
125 	if (pi->sub_type != BGP_ROUTE_IMPORTED ||
126 	    !pi->extra ||
127 	    !pi->extra->parent)
128 		return true;
129 
130 	parent_pi = (struct bgp_path_info *)pi->extra->parent;
131 	dest = parent_pi->net;
132 	if (!dest)
133 		return true;
134 	table = bgp_dest_table(dest);
135 	if (table &&
136 	    table->afi == AFI_L2VPN &&
137 	    table->safi == SAFI_EVPN)
138 		return false;
139 	return true;
140 }
141 
142 extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
143 					   const struct prefix *p,
144 					   struct attr *src_attr, afi_t afi,
145 					   safi_t safi);
146 extern void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf,
147 					  const struct prefix *p, afi_t afi,
148 					  safi_t safi);
149 extern void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi,
150 					   safi_t safi);
151 extern void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
152 					    safi_t safi);
153 extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf);
154 extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
155 extern char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels,
156 				char *buf, int len);
157 extern char *bgp_evpn_route2str(const struct prefix_evpn *p, char *buf,
158 				int len);
159 extern void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json);
160 extern void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p,
161 				   const struct prefix_rd *prd,
162 				   mpls_label_t *label, uint32_t num_labels,
163 				   struct attr *attr, int addpath_encode,
164 				   uint32_t addpath_tx_id);
165 extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
166 			       struct bgp_nlri *packet, int withdraw);
167 extern int bgp_evpn_import_route(struct bgp *bgp, afi_t afi, safi_t safi,
168 				 const struct prefix *p,
169 				 struct bgp_path_info *ri);
170 extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
171 				   const struct prefix *p,
172 				   struct bgp_path_info *ri);
173 extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
174 extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
175 				    struct ethaddr *mac, struct ipaddr *ip,
176 					int state);
177 extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
178 				    struct ethaddr *mac, struct ipaddr *ip,
179 				    uint8_t flags, uint32_t seq, esi_t *esi);
180 extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id,
181 				    struct ethaddr *rmac,
182 				    struct ethaddr *vrr_rmac,
183 				    struct in_addr originator_ip, int filter,
184 				    ifindex_t svi_ifindex, bool is_anycast_mac);
185 extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id);
186 extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
187 extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
188 				  struct in_addr originator_ip,
189 				  vrf_id_t tenant_vrf_id,
190 				  struct in_addr mcast_grp);
191 extern void bgp_evpn_flood_control_change(struct bgp *bgp);
192 extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
193 extern void bgp_evpn_cleanup(struct bgp *bgp);
194 extern void bgp_evpn_init(struct bgp *bgp);
195 extern int bgp_evpn_get_type5_prefixlen(const struct prefix *pfx);
196 extern bool bgp_evpn_is_prefix_nht_supported(const struct prefix *pfx);
197 extern void update_advertise_vrf_routes(struct bgp *bgp_vrf);
198 
199 #endif /* _QUAGGA_BGP_EVPN_H */
200