blob: 51f9e3795b8bda58a07f5c92f5e7a0795a7f0eac [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
32struct vrf
33{
34 /* Identifier, same as the vector index */
35 vrf_id_t vrf_id;
36 /* Name */
37 char *name;
38
39 /* User data */
40 void *info;
41};
42
43/* Holding VRF hooks */
44struct vrf_master
45{
46 int (*vrf_new_hook) (vrf_id_t, void **);
47 int (*vrf_delete_hook) (vrf_id_t, void **);
48} vrf_master = {0,};
49
50/* VRF table */
51struct route_table *vrf_table = NULL;
52
53/* Build the table key */
54static void
55vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
56{
57 p->family = AF_INET;
58 p->prefixlen = IPV4_MAX_BITLEN;
59 p->u.prefix4.s_addr = vrf_id;
60}
61
62/* Get a VRF. If not found, create one. */
63static struct vrf *
64vrf_get (vrf_id_t vrf_id)
65{
66 struct prefix p;
67 struct route_node *rn;
68 struct vrf *vrf;
69
70 vrf_build_key (vrf_id, &p);
71 rn = route_node_get (vrf_table, &p);
72 if (rn->info)
73 {
74 vrf = (struct vrf *)rn->info;
75 route_unlock_node (rn); /* get */
76 return vrf;
77 }
78
79 vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
80 vrf->vrf_id = vrf_id;
81 rn->info = vrf;
82
83 zlog_info ("VRF %u is created.", vrf_id);
84
85 if (vrf_master.vrf_new_hook)
86 (*vrf_master.vrf_new_hook) (vrf_id, &vrf->info);
87
88 return vrf;
89}
90
91/* Delete a VRF. This is called in vrf_terminate(). */
92static void
93vrf_delete (struct vrf *vrf)
94{
95 zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
96
97 if (vrf_master.vrf_delete_hook)
98 (*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
99
100 if (vrf->name)
101 XFREE (MTYPE_VRF_NAME, vrf->name);
102
103 XFREE (MTYPE_VRF, vrf);
104}
105
106/* Look up a VRF by identifier. */
107static struct vrf *
108vrf_lookup (vrf_id_t vrf_id)
109{
110 struct prefix p;
111 struct route_node *rn;
112 struct vrf *vrf = NULL;
113
114 vrf_build_key (vrf_id, &p);
115 rn = route_node_lookup (vrf_table, &p);
116 if (rn)
117 {
118 vrf = (struct vrf *)rn->info;
119 route_unlock_node (rn); /* lookup */
120 }
121 return vrf;
122}
123
124/* Add a VRF hook. Please add hooks before calling vrf_init(). */
125void
126vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
127{
128 switch (type) {
129 case VRF_NEW_HOOK:
130 vrf_master.vrf_new_hook = func;
131 break;
132 case VRF_DELETE_HOOK:
133 vrf_master.vrf_delete_hook = func;
134 break;
135 default:
136 break;
137 }
138}
139
140/* Return the iterator of the first VRF. */
141vrf_iter_t
142vrf_first (void)
143{
144 struct route_node *rn;
145
146 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
147 if (rn->info)
148 {
149 route_unlock_node (rn); /* top/next */
150 return (vrf_iter_t)rn;
151 }
152 return VRF_ITER_INVALID;
153}
154
155/* Return the next VRF iterator to the given iterator. */
156vrf_iter_t
157vrf_next (vrf_iter_t iter)
158{
159 struct route_node *rn = NULL;
160
161 /* Lock it first because route_next() will unlock it. */
162 if (iter != VRF_ITER_INVALID)
163 rn = route_next (route_lock_node ((struct route_node *)iter));
164
165 for (; rn; rn = route_next (rn))
166 if (rn->info)
167 {
168 route_unlock_node (rn); /* next */
169 return (vrf_iter_t)rn;
170 }
171 return VRF_ITER_INVALID;
172}
173
174/* Return the VRF iterator of the given VRF ID. If it does not exist,
175 * the iterator of the next existing VRF is returned. */
176vrf_iter_t
177vrf_iterator (vrf_id_t vrf_id)
178{
179 struct prefix p;
180 struct route_node *rn;
181
182 vrf_build_key (vrf_id, &p);
183 rn = route_node_get (vrf_table, &p);
184 if (rn->info)
185 {
186 /* OK, the VRF exists. */
187 route_unlock_node (rn); /* get */
188 return (vrf_iter_t)rn;
189 }
190
191 /* Find the next VRF. */
192 for (rn = route_next (rn); rn; rn = route_next (rn))
193 if (rn->info)
194 {
195 route_unlock_node (rn); /* next */
196 return (vrf_iter_t)rn;
197 }
198
199 return VRF_ITER_INVALID;
200}
201
202/* Obtain the VRF ID from the given VRF iterator. */
203vrf_id_t
204vrf_iter2id (vrf_iter_t iter)
205{
206 struct route_node *rn = (struct route_node *) iter;
207 return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
208}
209
210/* Obtain the data pointer from the given VRF iterator. */
211void *
212vrf_iter2info (vrf_iter_t iter)
213{
214 struct route_node *rn = (struct route_node *) iter;
215 return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
216}
217
218/* Get the data pointer of the specified VRF. If not found, create one. */
219void *
220vrf_info_get (vrf_id_t vrf_id)
221{
222 struct vrf *vrf = vrf_get (vrf_id);
223 return vrf->info;
224}
225
226/* Look up the data pointer of the specified VRF. */
227void *
228vrf_info_lookup (vrf_id_t vrf_id)
229{
230 struct vrf *vrf = vrf_lookup (vrf_id);
231 return vrf ? vrf->info : NULL;
232}
233
234/* Initialize VRF module. */
235void
236vrf_init (void)
237{
238 struct vrf *default_vrf;
239
240 /* Allocate VRF table. */
241 vrf_table = route_table_init ();
242
243 /* The default VRF always exists. */
244 default_vrf = vrf_get (VRF_DEFAULT);
245 if (!default_vrf)
246 {
247 zlog_err ("vrf_init: failed to create the default VRF!");
248 exit (1);
249 }
250
251 /* Set the default VRF name. */
252 default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, "Default-IP-Routing-Table");
Feng Lu126215c2015-05-22 11:39:58 +0200253
254 if_init ();
Feng Lu41f44a22015-05-22 11:39:56 +0200255}
256
257/* Terminate VRF module. */
258void
259vrf_terminate (void)
260{
261 struct route_node *rn;
262 struct vrf *vrf;
263
264 for (rn = route_top (vrf_table); rn; rn = route_next (rn))
265 if ((vrf = rn->info) != NULL)
266 vrf_delete (vrf);
267
268 route_table_finish (vrf_table);
269 vrf_table = NULL;
Feng Lu126215c2015-05-22 11:39:58 +0200270
271 if_terminate ();
Feng Lu41f44a22015-05-22 11:39:56 +0200272}
273