]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_mplsvpn.h
*: fix code format accourding to checkpatch
[mirror_frr.git] / bgpd / bgp_mplsvpn.h
1 /* MPLS-VPN
2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GxNU Zebra.
5 *
6 * GNU Zebra 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 * GNU Zebra 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_MPLSVPN_H
22 #define _QUAGGA_BGP_MPLSVPN_H
23
24 #include "bgpd/bgp_route.h"
25 #include "bgpd/bgp_rd.h"
26 #include "bgpd/bgp_zebra.h"
27
28 #define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
29 #define MPLS_LABEL_IS_NULL(label) \
30 ((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \
31 || (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL \
32 || (label) == MPLS_LABEL_IMPLICIT_NULL)
33
34 #define BGP_VPNVX_HELP_STR \
35 "Address Family\n" \
36 "Address Family\n"
37
38 #define V4_HEADER \
39 " Network Next Hop Metric LocPrf Weight Path\n"
40 #define V4_HEADER_TAG " Network Next Hop In tag/Out tag\n"
41 #define V4_HEADER_OVERLAY \
42 " Network Next Hop EthTag Overlay Index RouterMac\n"
43
44 extern void bgp_mplsvpn_init(void);
45 extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
46 extern uint32_t decode_label(mpls_label_t *);
47 extern void encode_label(mpls_label_t, mpls_label_t *);
48
49 extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
50 int *index, afi_t *afi);
51 extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
52 enum bgp_show_type type, void *output_arg,
53 int tags, bool use_json);
54
55 extern void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
56 struct bgp_path_info *path_vrf);
57
58 extern void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
59 struct bgp_path_info *path_vrf);
60
61 extern void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn,
62 struct bgp *bgp_vrf, afi_t afi);
63
64 extern void vpn_leak_from_vrf_update_all(struct bgp *bgp_vpn,
65 struct bgp *bgp_vrf, afi_t afi);
66
67 extern void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, afi_t afi);
68
69 extern void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, struct bgp *bgp_vpn,
70 afi_t afi);
71
72 extern void vpn_leak_to_vrf_update(struct bgp *bgp_vpn,
73 struct bgp_path_info *path_vpn);
74
75 extern void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,
76 struct bgp_path_info *path_vpn);
77
78 extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
79 extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
80 extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
81 extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
82 extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
83 extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
84 extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
85 afi_t afi, safi_t safi);
86 void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
87 afi_t afi, safi_t safi);
88
89 static inline bool is_bgp_vrf_mplsvpn(struct bgp *bgp)
90 {
91 afi_t afi;
92
93 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
94 for (afi = 0; afi < AFI_MAX; ++afi) {
95 if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
96 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
97 || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
98 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT))
99 return true;
100 }
101 return false;
102 }
103
104 static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
105 const char **pmsg)
106 {
107 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
108 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
109
110 if (pmsg)
111 *pmsg = "source bgp instance neither vrf nor default";
112 return 0;
113 }
114
115 /* Is vrf configured to export to vpn? */
116 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
117 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
118 && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
119 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
120 if (pmsg)
121 *pmsg = "export not set";
122 return 0;
123 }
124
125 /* Is there an RT list set? */
126 if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
127 if (pmsg)
128 *pmsg = "rtlist tovpn not defined";
129 return 0;
130 }
131
132 /* Is there an RD set? */
133 if (!CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
134 BGP_VPN_POLICY_TOVPN_RD_SET)) {
135 if (pmsg)
136 *pmsg = "rd not defined";
137 return 0;
138 }
139
140 /* Is a route-map specified, but not defined? */
141 if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN] &&
142 !bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
143 if (pmsg)
144 *pmsg = "route-map tovpn named but not defined";
145 return 0;
146 }
147
148 /* Is there an "auto" export label that isn't allocated yet? */
149 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
150 BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
151 (bgp_vrf->vpn_policy[afi].tovpn_label == MPLS_LABEL_NONE)) {
152
153 if (pmsg)
154 *pmsg = "auto label not allocated";
155 return 0;
156 }
157
158 return 1;
159 }
160
161 static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi,
162 const char **pmsg)
163 {
164 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
165 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
166
167 if (pmsg)
168 *pmsg = "destination bgp instance neither vrf nor default";
169 return 0;
170 }
171
172 if (bgp_vrf->vrf_id == VRF_UNKNOWN) {
173 if (pmsg)
174 *pmsg = "destination bgp instance vrf is VRF_UNKNOWN";
175 return 0;
176 }
177
178 /* Is vrf configured to import from vpn? */
179 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
180 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)
181 && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
182 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
183 if (pmsg)
184 *pmsg = "import not set";
185 return 0;
186 }
187
188 /* Is there an RT list set? */
189 if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
190 if (pmsg)
191 *pmsg = "rtlist fromvpn not defined";
192 return 0;
193 }
194
195 /* Is a route-map specified, but not defined? */
196 if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN] &&
197 !bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
198 if (pmsg)
199 *pmsg = "route-map fromvpn named but not defined";
200 return 0;
201 }
202 return 1;
203 }
204
205 static inline void vpn_leak_prechange(vpn_policy_direction_t direction,
206 afi_t afi, struct bgp *bgp_vpn,
207 struct bgp *bgp_vrf)
208 {
209 /* Detect when default bgp instance is not (yet) defined by config */
210 if (!bgp_vpn)
211 return;
212
213 if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) &&
214 vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) {
215
216 vpn_leak_to_vrf_withdraw_all(bgp_vrf, afi);
217 }
218 if ((direction == BGP_VPN_POLICY_DIR_TOVPN) &&
219 vpn_leak_to_vpn_active(bgp_vrf, afi, NULL)) {
220
221 vpn_leak_from_vrf_withdraw_all(bgp_vpn, bgp_vrf, afi);
222 }
223 }
224
225 static inline void vpn_leak_postchange(vpn_policy_direction_t direction,
226 afi_t afi, struct bgp *bgp_vpn,
227 struct bgp *bgp_vrf)
228 {
229 /* Detect when default bgp instance is not (yet) defined by config */
230 if (!bgp_vpn)
231 return;
232
233 if (direction == BGP_VPN_POLICY_DIR_FROMVPN)
234 vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
235 if (direction == BGP_VPN_POLICY_DIR_TOVPN) {
236
237 if (bgp_vrf->vpn_policy[afi].tovpn_label !=
238 bgp_vrf->vpn_policy[afi]
239 .tovpn_zebra_vrf_label_last_sent) {
240 vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
241 }
242
243 if (!bgp_vrf->vpn_policy[afi].tovpn_sid)
244 ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
245
246 if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
247 bgp_vrf->vpn_policy[afi]
248 .tovpn_zebra_vrf_sid_last_sent)) {
249 vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
250 }
251
252 vpn_leak_from_vrf_update_all(bgp_vpn, bgp_vrf, afi);
253 }
254 }
255
256 /* Flag if the route is injectable into VPN. This would be either a
257 * non-imported route or a non-VPN imported route.
258 */
259 static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi)
260 {
261 struct bgp_path_info *parent_pi;
262 struct bgp_table *table;
263 struct bgp_dest *dest;
264
265 if (pi->sub_type != BGP_ROUTE_IMPORTED ||
266 !pi->extra ||
267 !pi->extra->parent)
268 return true;
269
270 parent_pi = (struct bgp_path_info *)pi->extra->parent;
271 dest = parent_pi->net;
272 if (!dest)
273 return true;
274 table = bgp_dest_table(dest);
275 if (table &&
276 (table->afi == AFI_IP || table->afi == AFI_IP6) &&
277 table->safi == SAFI_MPLS_VPN)
278 return false;
279 return true;
280 }
281
282 /* Flag if the route path's family is VPN. */
283 static inline bool is_pi_family_vpn(struct bgp_path_info *pi)
284 {
285 return (is_pi_family_matching(pi, AFI_IP, SAFI_MPLS_VPN) ||
286 is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN));
287 }
288
289 extern void vpn_policy_routemap_event(const char *rmap_name);
290
291 extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
292
293 extern void vpn_leak_postchange_all(void);
294 extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
295 bool is_config);
296 extern void bgp_vpn_leak_unimport(struct bgp *from_bgp);
297 extern void bgp_vpn_leak_export(struct bgp *from_bgp);
298
299 #endif /* _QUAGGA_BGP_MPLSVPN_H */