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