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