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