]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_mplsvpn.h
doc: add doc for "sid vpn per-vrf export" command
[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"
a486300b 28#include "bgpd/bgp_vty.h"
718e3744 29
d62a17ae 30#define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
31#define MPLS_LABEL_IS_NULL(label) \
32 ((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \
33 || (label) == MPLS_LABEL_IPV6_EXPLICIT_NULL \
34 || (label) == MPLS_LABEL_IMPLICIT_NULL)
65efcfce 35
00e6edb9 36#define BGP_VPNVX_HELP_STR BGP_AF_STR BGP_AF_STR
d6902373 37
d62a17ae 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"
96ade3ed 43
c4ab9fd9
RS
44#define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH 20
45
d62a17ae 46extern void bgp_mplsvpn_init(void);
47extern int bgp_nlri_parse_vpn(struct peer *, struct attr *, struct bgp_nlri *);
d7c0a89a 48extern uint32_t decode_label(mpls_label_t *);
9bedbb1e 49extern void encode_label(mpls_label_t, mpls_label_t *);
00d252cb 50
d62a17ae 51extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
52 int *index, afi_t *afi);
53extern int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
54 enum bgp_show_type type, void *output_arg,
9f049418 55 int tags, bool use_json);
d6902373 56
02212dee 57extern void vpn_leak_from_vrf_update(struct bgp *to_bgp, struct bgp *from_bgp,
40381db7 58 struct bgp_path_info *path_vrf);
ddb5b488 59
02212dee 60extern void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, struct bgp *from_bgp,
40381db7 61 struct bgp_path_info *path_vrf);
ddb5b488 62
02212dee
LS
63extern void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp,
64 struct bgp *from_bgp, afi_t afi);
ddb5b488 65
02212dee
LS
66extern void vpn_leak_from_vrf_update_all(struct bgp *to_bgp,
67 struct bgp *from_bgp, afi_t afi);
ddb5b488 68
02212dee 69extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
ddb5b488 70
02212dee 71extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
ddb5b488
PZ
72 afi_t afi);
73
a486300b 74extern bool vpn_leak_to_vrf_update(struct bgp *from_bgp,
46dbf9d0
DA
75 struct bgp_path_info *path_vpn,
76 struct prefix_rd *prd);
ddb5b488 77
02212dee 78extern void vpn_leak_to_vrf_withdraw(struct bgp *from_bgp,
40381db7 79 struct bgp_path_info *path_vpn);
ddb5b488
PZ
80
81extern void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi);
82extern void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi);
b72c9e14 83extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
527588aa
CS
84extern void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi);
85extern void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp);
b72c9e14 86extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
527588aa
CS
87extern void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi);
88extern void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp);
e70e9f8e 89extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
b72c9e14 90extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
527588aa
CS
91extern void ensure_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
92 afi_t afi);
93extern void ensure_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
a45cd34e
RS
94extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
95 uint8_t size);
1d4e8b0d 96extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 97 afi_t afi, safi_t safi);
1d4e8b0d 98void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
44338987 99 afi_t afi, safi_t safi);
ddb5b488 100
2fceba1f
PR
101static inline bool is_bgp_vrf_mplsvpn(struct bgp *bgp)
102{
103 afi_t afi;
104
105 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
106 for (afi = 0; afi < AFI_MAX; ++afi) {
107 if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
108 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
109 || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
110 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT))
111 return true;
112 }
113 return false;
114}
115
ddb5b488
PZ
116static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
117 const char **pmsg)
118{
d555f3e9
PZ
119 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
120 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
121
122 if (pmsg)
123 *pmsg = "source bgp instance neither vrf nor default";
124 return 0;
125 }
126
ddb5b488
PZ
127 /* Is vrf configured to export to vpn? */
128 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
12a844a5
DS
129 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
130 && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
131 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
ddb5b488
PZ
132 if (pmsg)
133 *pmsg = "export not set";
134 return 0;
135 }
136
137 /* Is there an RT list set? */
138 if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
139 if (pmsg)
140 *pmsg = "rtlist tovpn not defined";
141 return 0;
142 }
143
144 /* Is there an RD set? */
145 if (!CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
146 BGP_VPN_POLICY_TOVPN_RD_SET)) {
147 if (pmsg)
148 *pmsg = "rd not defined";
149 return 0;
150 }
e70e9f8e 151
d92a55df
PZ
152 /* Is a route-map specified, but not defined? */
153 if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN] &&
154 !bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]) {
155 if (pmsg)
156 *pmsg = "route-map tovpn named but not defined";
157 return 0;
158 }
159
e70e9f8e
PZ
160 /* Is there an "auto" export label that isn't allocated yet? */
161 if (CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
162 BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
163 (bgp_vrf->vpn_policy[afi].tovpn_label == MPLS_LABEL_NONE)) {
164
165 if (pmsg)
166 *pmsg = "auto label not allocated";
167 return 0;
168 }
169
ddb5b488
PZ
170 return 1;
171}
172
173static inline int vpn_leak_from_vpn_active(struct bgp *bgp_vrf, afi_t afi,
b9c7bc5a 174 const char **pmsg)
ddb5b488 175{
ddb5b488 176 if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
d555f3e9 177 && bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
ddb5b488
PZ
178
179 if (pmsg)
180 *pmsg = "destination bgp instance neither vrf nor default";
181 return 0;
182 }
183
e504cf3b
DS
184 if (bgp_vrf->vrf_id == VRF_UNKNOWN) {
185 if (pmsg)
186 *pmsg = "destination bgp instance vrf is VRF_UNKNOWN";
187 return 0;
188 }
189
b9c7bc5a
PZ
190 /* Is vrf configured to import from vpn? */
191 if (!CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
12a844a5
DS
192 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)
193 && !CHECK_FLAG(bgp_vrf->af_flags[afi][SAFI_UNICAST],
194 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
ddb5b488 195 if (pmsg)
b9c7bc5a 196 *pmsg = "import not set";
ddb5b488
PZ
197 return 0;
198 }
d92a55df
PZ
199
200 /* Is there an RT list set? */
ddb5b488
PZ
201 if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
202 if (pmsg)
203 *pmsg = "rtlist fromvpn not defined";
204 return 0;
205 }
d92a55df
PZ
206
207 /* Is a route-map specified, but not defined? */
208 if (bgp_vrf->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN] &&
209 !bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_FROMVPN]) {
210 if (pmsg)
211 *pmsg = "route-map fromvpn named but not defined";
212 return 0;
213 }
ddb5b488
PZ
214 return 1;
215}
216
9c2fd3fe 217static inline void vpn_leak_prechange(enum vpn_policy_direction direction,
ddb5b488
PZ
218 afi_t afi, struct bgp *bgp_vpn,
219 struct bgp *bgp_vrf)
220{
3bd70bf8
PZ
221 /* Detect when default bgp instance is not (yet) defined by config */
222 if (!bgp_vpn)
223 return;
224
d555f3e9
PZ
225 if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) &&
226 vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) {
227
ddb5b488 228 vpn_leak_to_vrf_withdraw_all(bgp_vrf, afi);
d555f3e9
PZ
229 }
230 if ((direction == BGP_VPN_POLICY_DIR_TOVPN) &&
231 vpn_leak_to_vpn_active(bgp_vrf, afi, NULL)) {
232
ddb5b488 233 vpn_leak_from_vrf_withdraw_all(bgp_vpn, bgp_vrf, afi);
d555f3e9 234 }
ddb5b488
PZ
235}
236
9c2fd3fe 237static inline void vpn_leak_postchange(enum vpn_policy_direction direction,
ddb5b488
PZ
238 afi_t afi, struct bgp *bgp_vpn,
239 struct bgp *bgp_vrf)
240{
3bd70bf8
PZ
241 /* Detect when default bgp instance is not (yet) defined by config */
242 if (!bgp_vpn)
243 return;
244
a486300b
PG
245 if (direction == BGP_VPN_POLICY_DIR_FROMVPN) {
246 /* trigger a flush to re-sync with ADJ-RIB-in */
247 if (!CHECK_FLAG(bgp_vpn->af_flags[afi][SAFI_MPLS_VPN],
248 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL))
249 bgp_clear_soft_in(bgp_vpn, afi, SAFI_MPLS_VPN);
250 else
251 vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
252 }
ddb5b488
PZ
253 if (direction == BGP_VPN_POLICY_DIR_TOVPN) {
254
d555f3e9
PZ
255 if (bgp_vrf->vpn_policy[afi].tovpn_label !=
256 bgp_vrf->vpn_policy[afi]
ddb5b488
PZ
257 .tovpn_zebra_vrf_label_last_sent) {
258 vpn_leak_zebra_vrf_label_update(bgp_vrf, afi);
259 }
260
527588aa 261 if (!bgp_vrf->vpn_policy[afi].tovpn_sid && !bgp_vrf->tovpn_sid)
b72c9e14
HS
262 ensure_vrf_tovpn_sid(bgp_vpn, bgp_vrf, afi);
263
527588aa
CS
264 if ((!bgp_vrf->vpn_policy[afi].tovpn_sid &&
265 bgp_vrf->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent) ||
266 (!bgp_vrf->tovpn_sid &&
267 bgp_vrf->tovpn_zebra_vrf_sid_last_sent))
d79ff732
HS
268 vpn_leak_zebra_vrf_sid_withdraw(bgp_vrf, afi);
269
527588aa
CS
270 if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
271 if (sid_diff(bgp_vrf->vpn_policy[afi].tovpn_sid,
272 bgp_vrf->vpn_policy[afi]
273 .tovpn_zebra_vrf_sid_last_sent)) {
274 vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
275 }
276 } else if (bgp_vrf->tovpn_sid) {
277 if (sid_diff(bgp_vrf->tovpn_sid,
278 bgp_vrf->tovpn_zebra_vrf_sid_last_sent)) {
279 vpn_leak_zebra_vrf_sid_update(bgp_vrf, afi);
280 }
b72c9e14
HS
281 }
282
ddb5b488
PZ
283 vpn_leak_from_vrf_update_all(bgp_vpn, bgp_vrf, afi);
284 }
ddb5b488
PZ
285}
286
12d6100c 287/* Flag if the route is injectable into VPN. This would be either a
288 * non-imported route or a non-VPN imported route.
289 */
290static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi)
291{
292 struct bgp_path_info *parent_pi;
293 struct bgp_table *table;
9bcb3eef 294 struct bgp_dest *dest;
12d6100c 295
296 if (pi->sub_type != BGP_ROUTE_IMPORTED ||
297 !pi->extra ||
298 !pi->extra->parent)
299 return true;
300
301 parent_pi = (struct bgp_path_info *)pi->extra->parent;
9bcb3eef
DS
302 dest = parent_pi->net;
303 if (!dest)
12d6100c 304 return true;
9bcb3eef 305 table = bgp_dest_table(dest);
12d6100c 306 if (table &&
307 (table->afi == AFI_IP || table->afi == AFI_IP6) &&
308 table->safi == SAFI_MPLS_VPN)
309 return false;
310 return true;
311}
312
9544ddb2 313/* Flag if the route path's family is VPN. */
314static inline bool is_pi_family_vpn(struct bgp_path_info *pi)
315{
316 return (is_pi_family_matching(pi, AFI_IP, SAFI_MPLS_VPN) ||
317 is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN));
318}
319
ddb5b488
PZ
320extern void vpn_policy_routemap_event(const char *rmap_name);
321
301ad80a
PG
322extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
323
3bd70bf8 324extern void vpn_leak_postchange_all(void);
e65fe398
MS
325extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
326 bool is_config);
ff8a8a7a 327extern void bgp_vpn_leak_unimport(struct bgp *from_bgp);
48381346 328extern void bgp_vpn_leak_export(struct bgp *from_bgp);
3bd70bf8 329
00d252cb 330#endif /* _QUAGGA_BGP_MPLSVPN_H */