blob: d11a98264cc0108fcbb97a8269a80dc8c447602f [file] [log] [blame]
Feng Lu41f44a22015-05-22 11:39:56 +02001/*
2 * VRF functions.
3 * Copyright (C) 2014 6WIND S.A.
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
11 *
12 * GNU Zebra 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
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
Feng Lu126215c2015-05-22 11:39:58 +020025#include "if.h"
Feng Lu41f44a22015-05-22 11:39:56 +020026#include "vrf.h"
27#include "prefix.h"
28#include "table.h"
29#include "log.h"
30#include "memory.h"
31
Feng Lufb2bfc12015-05-22 11:40:08 +020032#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
33
Feng Lu41f44a22015-05-22 11:39:56 +020034struct vrf
35{
36 /* Identifier, same as the vector index */
37 vrf_id_t vrf_id;
38 /* Name */
39 char *name;
40
Feng Lu5a5702f2015-05-22 11:39:59 +020041 /* Master list of interfaces belonging to this VRF */
42 struct list *iflist;
43
Feng Lu41f44a22015-05-22 11:39:56 +020044 /* User data */
45 void *info;
46};
47
48/* Holding VRF hooks */
49struct vrf_master
50{
51 int (*vrf_new_hook) (vrf_id_t, void **);
52 int (*vrf_delete_hook) (vrf_id_t, void **);
Feng Lufb2bfc12015-05-22 11:40:08 +020053 int (*vrf_enable_hook) (vrf_id_t, void **);
54 int (*vrf_disable_hook) (vrf_id_t, void **);
Feng Lu41f44a22015-05-22 11:39:56 +020055} vrf_master = {0,};
56
57/* VRF table */
58struct route_table *vrf_table = NULL;
59
Feng Lufb2bfc12015-05-22 11:40:08 +020060static int vrf_is_enabled (struct vrf *vrf);
61static int vrf_enable (struct vrf *vrf);
62static void vrf_disable (struct vrf *vrf);
63
64
Feng Lu41f44a22015-05-22 11:39:56 +020065/* Build the table key */
66static void
67vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
68{
69 p->family = AF_INET;
70 p->prefixlen = IPV4_MAX_BITLEN;
71 p->u.prefix4.s_addr = vrf_id;
72}
73
74/* Get a VRF. If not found, create one. */
75static struct vrf *
76vrf_get (vrf_id_t vrf_id)
77{
78 struct prefix p;
79 struct route_node *rn;
80 struct vrf *vrf;
81
82 vrf_build_key (vrf_id, &p);
83 rn = route_node_get (vrf_table, &p);
84 if (rn->info)
85 {
86 vrf = (struct vrf *)rn->info;
87 route_unlock_node (rn); /* get */
88 return vrf;
89 }
90
91 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
92 vrf->vrf_id = vrf_id;
93 rn->info = vrf;
94
Feng Lu5a5702f2015-05-22 11:39:59 +020095 /* Initialize interfaces. */
96 if_init (vrf_id, &vrf->iflist);
97
Feng Lu41f44a22015-05-22 11:39:56 +020098 zlog_info ("VRF %u is created.", vrf_id);
99
100 if (vrf_master.vrf_new_hook)
101 (*vrf_master.vrf_new_hook) (vrf_id, &vrf->info);
102
103 return vrf;
104}
105
106/* Delete a VRF. This is called in vrf_terminate(). */
107static void
108vrf_delete (struct vrf *vrf)
109{
110 zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
111
Feng Lufb2bfc12015-05-22 11:40:08 +0200112 if (vrf_is_enabled (vrf))
113 vrf_disable (vrf);
114
Feng Lu41f44a22015-05-22 11:39:56 +0200115 if (vrf_master.vrf_delete_hook)
116 (*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
117
Feng Lu5a5702f2015-05-22 11:39:59 +0200118 if_terminate (vrf->vrf_id, &vrf->iflist);
119
Feng Lu41f44a22015-05-22 11:39:56 +0200120 if (vrf->name)
121 XFREE (MTYPE_VRF_NAME, vrf->name);
122
123 XFREE (MTYPE_VRF, vrf);
124}
125
126/* Look up a VRF by identifier. */
127static struct vrf *
128vrf_lookup (vrf_id_t vrf_id)
129{
130 struct prefix p;
131 struct route_node *rn;
132 struct vrf *vrf = NULL;
133
134 vrf_build_key (vrf_id, &p);
135 rn = route_node_lookup (vrf_table, &p);
136 if (rn)
137 {
138 vrf = (struct vrf *)rn->info;
139 route_unlock_node (rn); /* lookup */
140 }
141 return vrf;
142}
143
Feng Lufb2bfc12015-05-22 11:40:08 +0200144/*
145 * Check whether the VRF is enabled - that is, whether the VRF
146 * is ready to allocate resources. Currently there's only one
147 * type of resource: socket.
148 */
149static int
150vrf_is_enabled (struct vrf *vrf)
151{
152 return vrf && vrf->vrf_id == VRF_DEFAULT;
153}
154
155/*
156 * Enable a VRF - that is, let the VRF be ready to use.
157 * The VRF_ENABLE_HOOK callback will be called to inform
158 * that they can allocate resources in this VRF.
159 *
160 * RETURN: 1 - enabled successfully; otherwise, 0.
161 */
162static int
163vrf_enable (struct vrf *vrf)
164{
165 /* Till now, only the default VRF can be enabled. */
166 if (vrf->vrf_id == VRF_DEFAULT)
167 {
168 zlog_info ("VRF %u is enabled.", vrf->vrf_id);
169
170 if (vrf_master.vrf_enable_hook)
171 (*vrf_master.vrf_enable_hook) (vrf->vrf_id, &vrf->info);
172
173 return 1;
174 }
175
176 return 0;
177}
178
179/*
180 * Disable a VRF - that is, let the VRF be unusable.
181 * The VRF_DELETE_HOOK callback will be called to inform
182 * that they must release the resources in the VRF.
183 */
184static void
185vrf_disable (struct vrf *vrf)
186{
187 if (vrf_is_enabled (vrf))
188 {
189 zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
190
191 /* Till now, nothing to be done for the default VRF. */
192
193 if (vrf_master.vrf_disable_hook)
194 (*vrf_master.vrf_disable_hook) (vrf->vrf_id, &vrf->info);
195 }
196}
197
198
Feng Lu41f44a22015-05-22 11:39:56 +0200199/* Add a VRF hook. Please add hooks before calling vrf_init(). */
200void
201vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
202{
203 switch (type) {
204 case VRF_NEW_HOOK:
205 vrf_master.vrf_new_hook = func;
206 break;
207 case VRF_DELETE_HOOK:
208 vrf_master.vrf_delete_hook = func;
209 break;
Feng Lufb2bfc12015-05-22 11:40:08 +0200210 case VRF_ENABLE_HOOK:
211 vrf_master.vrf_enable_hook = func;
212 break;
213 case VRF_DISABLE_HOOK:
214 vrf_master.vrf_disable_hook = func;
215 break;
Feng Lu41f44a22015-05-22 11:39:56 +0200216 default:
217 break;
218 }
219}
220
221/* Return the iterator of the first VRF. */
222vrf_iter_t
223vrf_first (void)
224{
225 struct route_node *rn;
226
227 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
228 if (rn->info)
229 {
230 route_unlock_node (rn); /* top/next */
231 return (vrf_iter_t)rn;
232 }
233 return VRF_ITER_INVALID;
234}
235
236/* Return the next VRF iterator to the given iterator. */
237vrf_iter_t
238vrf_next (vrf_iter_t iter)
239{
240 struct route_node *rn = NULL;
241
242 /* Lock it first because route_next() will unlock it. */
243 if (iter != VRF_ITER_INVALID)
244 rn = route_next (route_lock_node ((struct route_node *)iter));
245
246 for (; rn; rn = route_next (rn))
247 if (rn->info)
248 {
249 route_unlock_node (rn); /* next */
250 return (vrf_iter_t)rn;
251 }
252 return VRF_ITER_INVALID;
253}
254
255/* Return the VRF iterator of the given VRF ID. If it does not exist,
256 * the iterator of the next existing VRF is returned. */
257vrf_iter_t
258vrf_iterator (vrf_id_t vrf_id)
259{
260 struct prefix p;
261 struct route_node *rn;
262
263 vrf_build_key (vrf_id, &p);
264 rn = route_node_get (vrf_table, &p);
265 if (rn->info)
266 {
267 /* OK, the VRF exists. */
268 route_unlock_node (rn); /* get */
269 return (vrf_iter_t)rn;
270 }
271
272 /* Find the next VRF. */
273 for (rn = route_next (rn); rn; rn = route_next (rn))
274 if (rn->info)
275 {
276 route_unlock_node (rn); /* next */
277 return (vrf_iter_t)rn;
278 }
279
280 return VRF_ITER_INVALID;
281}
282
283/* Obtain the VRF ID from the given VRF iterator. */
284vrf_id_t
285vrf_iter2id (vrf_iter_t iter)
286{
287 struct route_node *rn = (struct route_node *) iter;
288 return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
289}
290
291/* Obtain the data pointer from the given VRF iterator. */
292void *
293vrf_iter2info (vrf_iter_t iter)
294{
295 struct route_node *rn = (struct route_node *) iter;
296 return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
297}
298
Feng Lu5a5702f2015-05-22 11:39:59 +0200299/* Obtain the interface list from the given VRF iterator. */
300struct list *
301vrf_iter2iflist (vrf_iter_t iter)
302{
303 struct route_node *rn = (struct route_node *) iter;
304 return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
305}
306
Feng Lu41f44a22015-05-22 11:39:56 +0200307/* Get the data pointer of the specified VRF. If not found, create one. */
308void *
309vrf_info_get (vrf_id_t vrf_id)
310{
311 struct vrf *vrf = vrf_get (vrf_id);
312 return vrf->info;
313}
314
315/* Look up the data pointer of the specified VRF. */
316void *
317vrf_info_lookup (vrf_id_t vrf_id)
318{
319 struct vrf *vrf = vrf_lookup (vrf_id);
320 return vrf ? vrf->info : NULL;
321}
322
Feng Lu5a5702f2015-05-22 11:39:59 +0200323/* Look up the interface list in a VRF. */
324struct list *
325vrf_iflist (vrf_id_t vrf_id)
326{
327 struct vrf * vrf = vrf_lookup (vrf_id);
328 return vrf ? vrf->iflist : NULL;
329}
330
331/* Get the interface list of the specified VRF. Create one if not find. */
332struct list *
333vrf_iflist_get (vrf_id_t vrf_id)
334{
335 struct vrf * vrf = vrf_get (vrf_id);
336 return vrf->iflist;
337}
338
Feng Lu41f44a22015-05-22 11:39:56 +0200339/* Initialize VRF module. */
340void
341vrf_init (void)
342{
343 struct vrf *default_vrf;
344
345 /* Allocate VRF table. */
346 vrf_table = route_table_init ();
347
348 /* The default VRF always exists. */
349 default_vrf = vrf_get (VRF_DEFAULT);
350 if (!default_vrf)
351 {
352 zlog_err ("vrf_init: failed to create the default VRF!");
353 exit (1);
354 }
355
356 /* Set the default VRF name. */
Feng Lufb2bfc12015-05-22 11:40:08 +0200357 default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, VRF_DEFAULT_NAME);
358
359 /* Enable the default VRF. */
360 if (!vrf_enable (default_vrf))
361 {
362 zlog_err ("vrf_init: failed to enable the default VRF!");
363 exit (1);
364 }
Feng Lu41f44a22015-05-22 11:39:56 +0200365}
366
367/* Terminate VRF module. */
368void
369vrf_terminate (void)
370{
371 struct route_node *rn;
372 struct vrf *vrf;
373
374 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
375 if ((vrf = rn->info) != NULL)
376 vrf_delete (vrf);
377
378 route_table_finish (vrf_table);
379 vrf_table = NULL;
Feng Lu41f44a22015-05-22 11:39:56 +0200380}
381
Feng Lufb2bfc12015-05-22 11:40:08 +0200382/* Create a socket for the VRF. */
383int
384vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
385{
386 int ret = -1;
387
388 if (!vrf_is_enabled (vrf_lookup (vrf_id)))
389 {
390 errno = ENOSYS;
391 return -1;
392 }
393
394 if (vrf_id == VRF_DEFAULT)
395 ret = socket (domain, type, protocol);
396 else
397 errno = ENOSYS;
398
399 return ret;
400}
401