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