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