]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_vrf.c
lib: remove unused ns code
[mirror_frr.git] / zebra / zebra_vrf.c
CommitLineData
7c551956
DS
1/*
2 * Copyright (C) 2016 CumulusNetworks
3 * Donald Sharp
4 *
5 * This file is part of Quagga
6 *
7 * Quagga is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * Quagga is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22#include <zebra.h>
23
24#include "log.h"
25#include "linklist.h"
4a1ab8e4 26#include "memory.h"
7c551956
DS
27
28#include "zebra/debug.h"
29#include "zebra/zserv.h"
30#include "zebra/rib.h"
31#include "zebra/zebra_vrf.h"
32#include "zebra/router-id.h"
4a1ab8e4 33#include "zebra/zebra_memory.h"
28f6dde8 34#include "zebra/zebra_static.h"
7758e3f3 35#include "zebra/zebra_mpls.h"
7c551956
DS
36
37extern struct zebra_t zebrad;
871d39b3 38struct list *zvrf_list;
7c551956
DS
39
40/* VRF information update. */
41static void
42zebra_vrf_add_update (struct zebra_vrf *zvrf)
43{
44 struct listnode *node, *nnode;
45 struct zserv *client;
46
47 if (IS_ZEBRA_DEBUG_EVENT)
48 zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf->name);
49
50 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
51 zsend_vrf_add (client, zvrf);
52}
53
54static void
55zebra_vrf_delete_update (struct zebra_vrf *zvrf)
56{
57 struct listnode *node, *nnode;
58 struct zserv *client;
59
60 if (IS_ZEBRA_DEBUG_EVENT)
61 zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf->name);
62
63 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
64 zsend_vrf_delete (client, zvrf);
65}
66
67void
68zebra_vrf_update_all (struct zserv *client)
69{
70 struct vrf *vrf;
71 vrf_iter_t iter;
72
73 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
74 {
75 if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id)
76 zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id));
77 }
78}
79
80/* Callback upon creating a new VRF. */
81static int
82zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
83{
84 struct zebra_vrf *zvrf = *info;
85
3f6d6a5d
DS
86 if (IS_ZEBRA_DEBUG_EVENT)
87 zlog_info ("ZVRF %s with id %u", name, vrf_id);
7c551956
DS
88
89 if (! zvrf)
90 {
871d39b3
DS
91 zvrf = zebra_vrf_list_lookup_by_name (name);
92 if (!zvrf)
93 {
94 zvrf = zebra_vrf_alloc (vrf_id, name);
95 zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
96 *info = (void *)zvrf;
97 router_id_init (zvrf);
98 listnode_add_sort (zvrf_list, zvrf);
99 }
100 else
101 {
102 *info = (void *)zvrf;
103 router_id_init (zvrf);
104 }
7c551956
DS
105 }
106
34f8e6af
DS
107 if (zvrf->vrf_id == VRF_UNKNOWN)
108 zvrf->vrf_id = vrf_id;
109
7c551956
DS
110 return 0;
111}
112
fb148af4
DS
113/*
114 * Moving an interface amongst different vrf's
115 * causes the interface to get a new ifindex
116 * so we need to find static routes with
117 * the old ifindex and replace with new
118 * ifindex to insert back into the table
119 */
120void
121zebra_vrf_static_route_interface_fixup (struct interface *ifp)
122{
123 afi_t afi;
124 safi_t safi;
125 struct zebra_vrf *zvrf = zebra_vrf_lookup (ifp->vrf_id);
126 struct route_table *stable = NULL;
127 struct route_node *rn = NULL;
128 struct static_route *si = NULL;
129
130 if (!zvrf)
131 return;
132
133 for (afi = AFI_IP; afi < AFI_MAX; afi++)
134 {
135 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
136 {
137 stable = zvrf->stable[afi][safi];
138 if (stable)
139 for (rn = route_top (stable); rn; rn = route_next (rn))
140 {
141 if (rn->info)
142 {
143 si = rn->info;
144 if ((strcmp (si->ifname, ifp->name) == 0) &&
145 (si->ifindex != ifp->ifindex))
146 {
147 si->ifindex = ifp->ifindex;
148 static_install_route (afi, safi, &rn->p, si);
149 }
150 }
151 }
152 }
153 }
154
155}
156
7c551956
DS
157/* Callback upon enabling a VRF. */
158static int
159zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
160{
161 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
fb148af4
DS
162 struct route_table *stable = NULL;
163 struct route_node *rn = NULL;
164 struct static_route *si = NULL;
165 struct interface *ifp = NULL;
166 afi_t afi;
167 safi_t safi;
7c551956
DS
168
169 assert (zvrf);
170
171 zebra_vrf_add_update (zvrf);
172
fb148af4
DS
173 for (afi = AFI_IP; afi < AFI_MAX; afi++)
174 {
175 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
176 {
177 stable = zvrf->stable[afi][safi];
178 if (stable)
179 {
180 for (rn = route_top (stable); rn; rn = route_next (rn))
181 {
182 if (rn->info)
183 {
184 si = rn->info;
185 si->vrf_id = vrf_id;
186 if (si->ifindex)
187 {
188 ifp = if_lookup_by_name_vrf (si->ifname, si->vrf_id);
189 if (ifp)
190 si->ifindex = ifp->ifindex;
191 else
192 continue;
193 }
194 static_install_route (afi, safi, &rn->p, si);
195 }
196 }
197 }
198 }
199 }
7c551956
DS
200 return 0;
201}
202
203/* Callback upon disabling a VRF. */
204static int
205zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
206{
207 struct zebra_vrf *zvrf = (struct zebra_vrf *)(*info);
fb148af4
DS
208 struct route_table *stable = NULL;
209 struct route_node *rn = NULL;
210 afi_t afi;
211 safi_t safi;
7c551956
DS
212
213 if (IS_ZEBRA_DEBUG_KERNEL)
214 zlog_debug ("VRF %s id %u is now disabled.",
215 zvrf->name, zvrf->vrf_id);
216
fb148af4
DS
217 for (afi = AFI_IP; afi < AFI_MAX; afi++)
218 {
219 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
220 {
221 stable = zvrf->stable[afi][safi];
222 if (stable)
223 {
224 for (rn = route_top (stable); rn; rn = route_next (rn))
225 {
226 if (rn->info)
227 static_uninstall_route(afi, safi, &rn->p, rn->info);
228 }
229 }
230 }
231 }
7c551956
DS
232 return 0;
233}
234
235static int
236zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
237{
238 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
239
240 assert (zvrf);
241
242 zebra_vrf_delete_update (zvrf);
243
244 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
245 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
246
247 list_delete_all_node (zvrf->rid_all_sorted_list);
248 list_delete_all_node (zvrf->rid_lo_sorted_list);
249
871d39b3 250 zvrf->vrf_id = VRF_UNKNOWN;
7c551956 251
871d39b3 252 *info = NULL;
7c551956
DS
253 return 0;
254}
255
256/* Lookup the routing table in a VRF based on both VRF-Id and table-id.
257 * NOTE: Table-id is relevant only in the Default VRF.
258 */
259struct route_table *
260zebra_vrf_table_with_table_id (afi_t afi, safi_t safi,
261 vrf_id_t vrf_id, u_int32_t table_id)
262{
263 struct route_table *table = NULL;
264
265 if (afi >= AFI_MAX || safi >= SAFI_MAX)
266 return NULL;
267
268 if (vrf_id == VRF_DEFAULT)
269 {
270 if (table_id == RT_TABLE_MAIN ||
271 table_id == zebrad.rtm_table_default)
272 table = zebra_vrf_table (afi, safi, vrf_id);
273 else
274 table = zebra_vrf_other_route_table (afi, table_id, vrf_id);
275 }
276 else
277 table = zebra_vrf_table (afi, safi, vrf_id);
278
279 return table;
280}
281
282/*
283 * Create a routing table for the specific AFI/SAFI in the given VRF.
284 */
285static void
286zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
287{
288 rib_table_info_t *info;
289 struct route_table *table;
290
291 assert (!zvrf->table[afi][safi]);
292
293 table = route_table_init ();
294 zvrf->table[afi][safi] = table;
295
296 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
297 info->zvrf = zvrf;
298 info->afi = afi;
299 info->safi = safi;
300 table->info = info;
301}
302
303/* Allocate new zebra VRF. */
304struct zebra_vrf *
305zebra_vrf_alloc (vrf_id_t vrf_id, const char *name)
306{
307 struct zebra_vrf *zvrf;
308
309 zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
310
311 /* Allocate routing table and static table. */
312 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
313 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
314 zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
315 zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
316 zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
317 zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
318 zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
319 zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
320
321 zvrf->rnh_table[AFI_IP] = route_table_init();
322 zvrf->rnh_table[AFI_IP6] = route_table_init();
323
324 zvrf->import_check_table[AFI_IP] = route_table_init();
325 zvrf->import_check_table[AFI_IP6] = route_table_init();
326
327 /* Set VRF ID */
328 zvrf->vrf_id = vrf_id;
329
330 if (name)
331 {
332 strncpy (zvrf->name, name, strlen(name));
333 zvrf->name[strlen(name)] = '\0';
334 }
335
7758e3f3 336 zebra_mpls_init_tables (zvrf);
337
7c551956
DS
338 return zvrf;
339}
340
341/* Lookup VRF by identifier. */
342struct zebra_vrf *
343zebra_vrf_lookup (vrf_id_t vrf_id)
344{
345 return vrf_info_lookup (vrf_id);
346}
347
871d39b3
DS
348/* Lookup the zvrf in the zvrf_list. */
349struct zebra_vrf *
350zebra_vrf_list_lookup_by_name (const char *name)
351{
352 struct listnode *node;
353 struct zebra_vrf *zvrf;
354
a3d21ef3
DS
355 if (!name)
356 name = VRF_DEFAULT_NAME;
357
358 for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf))
359 {
360 if (strcmp(name, zvrf->name) == 0)
361 return zvrf;
362 }
871d39b3
DS
363 return NULL;
364}
365
7c551956
DS
366/* Lookup the routing table in an enabled VRF. */
367struct route_table *
368zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
369{
370 struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
371
372 if (!zvrf)
373 return NULL;
374
375 if (afi >= AFI_MAX || safi >= SAFI_MAX)
376 return NULL;
377
378 return zvrf->table[afi][safi];
379}
380
381/* Lookup the static routing table in a VRF. */
382struct route_table *
01bb6d57 383zebra_vrf_static_table (afi_t afi, safi_t safi, struct zebra_vrf *zvrf)
7c551956 384{
7c551956
DS
385 if (!zvrf)
386 return NULL;
387
388 if (afi >= AFI_MAX || safi >= SAFI_MAX)
389 return NULL;
390
391 return zvrf->stable[afi][safi];
392}
393
394struct route_table *
395zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
396{
397 struct zebra_vrf *zvrf;
398 rib_table_info_t *info;
399 struct route_table *table;
400
401 zvrf = vrf_info_lookup (vrf_id);
402 if (! zvrf)
403 return NULL;
404
405 if(afi >= AFI_MAX)
406 return NULL;
407
408 if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
409 return NULL;
410
411 if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default))
412 {
413 if (zvrf->other_table[afi][table_id] == NULL)
414 {
415 table = route_table_init();
416 info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
417 info->zvrf = zvrf;
418 info->afi = afi;
419 info->safi = SAFI_UNICAST;
420 table->info = info;
421 zvrf->other_table[afi][table_id] = table;
422 }
423
424 return (zvrf->other_table[afi][table_id]);
425 }
426
427 return zvrf->table[afi][SAFI_UNICAST];
428}
429
430/* Zebra VRF initialization. */
431void
432zebra_vrf_init (void)
433{
434 vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
435 vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
436 vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
437 vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
438
871d39b3
DS
439 zvrf_list = list_new ();
440
7c551956
DS
441 vrf_init ();
442}