]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.h
Merge pull request #11598 from patrasar/pim_get_instance
[mirror_frr.git] / bgpd / bgp_mplsvpn.h
CommitLineData
718e3744 1/* MPLS-VPN
896014f4
DL
2 * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
8557760c 4 * This file is part of GxNU Zebra.
896014f4
DL
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 */
718e3744 20
00d252cb 21#ifndef _QUAGGA_BGP_MPLSVPN_H
22#define _QUAGGA_BGP_MPLSVPN_H
23
ea7cd161 24#include "bgpd/bgp_attr.h"
4f280b15 25#include "bgpd/bgp_route.h"
8557760c 26#include "bgpd/bgp_rd.h"
ddb5b488 27#include "bgpd/bgp_zebra.h"
718e3744 28
d62a17ae 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)
65efcfce 34
d62a17ae 35#define BGP_VPNVX_HELP_STR \
36 "Address Family\n" \
37 "Address Family\n"
d6902373 38
d62a17ae 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"
96ade3ed 44
d62a17ae 45extern void bgp_mplsvpn_init(void);
46extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
d7c0a89a 47extern uint32_t decode_label(mpls_label_t *);
9bedbb1e 48extern void encode_label(mpls_label_t, mpls_label_t *);
00d252cb 49
d62a17ae 50extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
51 int *index, afi_t *afi);
52extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
53 enum bgp_show_type type, void *output_arg,
9f049418 54 int tags, bool use_json);
d6902373 55
02212dee 56extern void vpn_leak_from_vrf_update(struct bgp *to_bgp, struct bgp *from_bgp,
40381db7 57 struct bgp_path_info *path_vrf);
ddb5b488 58
02212dee 59extern void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, struct bgp *from_bgp,
40381db7 60 struct bgp_path_info *path_vrf);
ddb5b488 61
02212dee
LS
62extern void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp,
63 struct bgp *from_bgp, afi_t afi);
ddb5b488 64
02212dee
LS
65extern void vpn_leak_from_vrf_update_all(struct bgp *to_bgp,
66 struct bgp *from_bgp, afi_t afi);
ddb5b488 67
02212dee 68extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
ddb5b488 69
02212dee 70extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
ddb5b488
PZ
71 afi_t afi);
72
02212dee 73extern void vpn_leak_to_vrf_update(struct bgp *from_bgp,
40381db7 74 struct bgp_path_info *path_vpn);
ddb5b488 75
02212dee 76extern void vpn_leak_to_vrf_withdraw(struct bgp *from_bgp,
40381db7 77 struct bgp_path_info *path_vpn);
ddb5b488
PZ
78
79extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
80extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
b72c9e14
HS
81extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
82extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
e70e9f8e 83extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
b72c9e14 84extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
a45cd34e
RS
85extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
86 uint8_t size);
1d4e8b0d 87extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 88 afi_t afi, safi_t safi);
1d4e8b0d 89void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 90 afi_t afi, safi_t safi);
ddb5b488 91
2fceba1f
PR
92static 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
ddb5b488
PZ
107static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
108 const char **pmsg)
109{
d555f3e9
PZ
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
ddb5b488
PZ
118 /* Is vrf configured to export to vpn? */
119 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
12a844a5
DS
120 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
121 && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
122 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
ddb5b488
PZ
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 }
e70e9f8e 142
d92a55df
PZ
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
e70e9f8e
PZ
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
ddb5b488
PZ
161 return 1;
162}
163
164static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi,
b9c7bc5a 165 const char **pmsg)
ddb5b488 166{
ddb5b488 167 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
d555f3e9 168 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
ddb5b488
PZ
169
170 if (pmsg)
171 *pmsg = "destination bgp instance neither vrf nor default";
172 return 0;
173 }
174
e504cf3b
DS
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
b9c7bc5a
PZ
181 /* Is vrf configured to import from vpn? */
182 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
12a844a5
DS
183 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)
184 && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
185 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
ddb5b488 186 if (pmsg)
b9c7bc5a 187 *pmsg = "import not set";
ddb5b488
PZ
188 return 0;
189 }
d92a55df
PZ
190
191 /* Is there an RT list set? */
ddb5b488
PZ
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 }
d92a55df
PZ
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 }
ddb5b488
PZ
205 return 1;
206}
207
9c2fd3fe 208static inline void vpn_leak_prechange(enum vpn_policy_direction direction,
ddb5b488
PZ
209 afi_t afi, struct bgp *bgp_vpn,
210 struct bgp *bgp_vrf)
211{
3bd70bf8
PZ
212 /* Detect when default bgp instance is not (yet) defined by config */
213 if (!bgp_vpn)
214 return;
215
d555f3e9
PZ
216 if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) &&
217 vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) {
218
ddb5b488 219 vpn_leak_to_vrf_withdraw_all(bgp_vrf, afi);
d555f3e9
PZ
220 }
221 if ((direction == BGP_VPN_POLICY_DIR_TOVPN) &&
222 vpn_leak_to_vpn_active(bgp_vrf, afi, NULL)) {
223
ddb5b488 224 vpn_leak_from_vrf_withdraw_all(bgp_vpn, bgp_vrf, afi);
d555f3e9 225 }
ddb5b488
PZ
226}
227
9c2fd3fe 228static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
ddb5b488
PZ
229 afi_t afi, struct bgp *bgp_vpn,
230 struct bgp *bgp_vrf)
231{
3bd70bf8
PZ
232 /* Detect when default bgp instance is not (yet) defined by config */
233 if (!bgp_vpn)
234 return;
235
ddb5b488
PZ
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
d555f3e9
PZ
240 if (bgp_vrf->vpn_policy[afi].tovpn_label !=
241 bgp_vrf->vpn_policy[afi]
ddb5b488
PZ
242 .tovpn_zebra_vrf_label_last_sent) {
243 vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
244 }
245
b72c9e14
HS
246 if (!bgp_vrf->vpn_policy[afi].tovpn_sid)
247 ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
248
d79ff732
HS
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
b72c9e14 253 if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
7de4c885
HS
254 bgp_vrf->vpn_policy[afi]
255 .tovpn_zebra_vrf_sid_last_sent)) {
b72c9e14
HS
256 vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
257 }
258
ddb5b488
PZ
259 vpn_leak_from_vrf_update_all(bgp_vpn, bgp_vrf, afi);
260 }
ddb5b488
PZ
261}
262
12d6100c 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 */
266static 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;
9bcb3eef 270 struct bgp_dest *dest;
12d6100c 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;
9bcb3eef
DS
278 dest = parent_pi->net;
279 if (!dest)
12d6100c 280 return true;
9bcb3eef 281 table = bgp_dest_table(dest);
12d6100c 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
9544ddb2 289/* Flag if the route path's family is VPN. */
290static 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
ddb5b488
PZ
296extern void vpn_policy_routemap_event(const char *rmap_name);
297
301ad80a
PG
298extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
299
3bd70bf8 300extern void vpn_leak_postchange_all(void);
e65fe398
MS
301extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
302 bool is_config);
ff8a8a7a 303extern void bgp_vpn_leak_unimport(struct bgp *from_bgp);
48381346 304extern void bgp_vpn_leak_export(struct bgp *from_bgp);
3bd70bf8 305
00d252cb 306#endif /* _QUAGGA_BGP_MPLSVPN_H */