]>
git.proxmox.com Git - mirror_frr.git/blob - lib/vrf.c
3 * Copyright (C) 2014 6WIND S.A.
5 * This file is part of GNU Zebra.
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.
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.
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.
33 /* Identifier, same as the vector index */
42 /* Holding VRF hooks */
45 int (*vrf_new_hook
) (vrf_id_t
, void **);
46 int (*vrf_delete_hook
) (vrf_id_t
, void **);
50 struct route_table
*vrf_table
= NULL
;
52 /* Build the table key */
54 vrf_build_key (vrf_id_t vrf_id
, struct prefix
*p
)
57 p
->prefixlen
= IPV4_MAX_BITLEN
;
58 p
->u
.prefix4
.s_addr
= vrf_id
;
61 /* Get a VRF. If not found, create one. */
63 vrf_get (vrf_id_t vrf_id
)
66 struct route_node
*rn
;
69 vrf_build_key (vrf_id
, &p
);
70 rn
= route_node_get (vrf_table
, &p
);
73 vrf
= (struct vrf
*)rn
->info
;
74 route_unlock_node (rn
); /* get */
78 vrf
= XCALLOC (MTYPE_VRF
, sizeof (struct vrf
));
82 zlog_info ("VRF %u is created.", vrf_id
);
84 if (vrf_master
.vrf_new_hook
)
85 (*vrf_master
.vrf_new_hook
) (vrf_id
, &vrf
->info
);
90 /* Delete a VRF. This is called in vrf_terminate(). */
92 vrf_delete (struct vrf
*vrf
)
94 zlog_info ("VRF %u is to be deleted.", vrf
->vrf_id
);
96 if (vrf_master
.vrf_delete_hook
)
97 (*vrf_master
.vrf_delete_hook
) (vrf
->vrf_id
, &vrf
->info
);
100 XFREE (MTYPE_VRF_NAME
, vrf
->name
);
102 XFREE (MTYPE_VRF
, vrf
);
105 /* Look up a VRF by identifier. */
107 vrf_lookup (vrf_id_t vrf_id
)
110 struct route_node
*rn
;
111 struct vrf
*vrf
= NULL
;
113 vrf_build_key (vrf_id
, &p
);
114 rn
= route_node_lookup (vrf_table
, &p
);
117 vrf
= (struct vrf
*)rn
->info
;
118 route_unlock_node (rn
); /* lookup */
123 /* Add a VRF hook. Please add hooks before calling vrf_init(). */
125 vrf_add_hook (int type
, int (*func
)(vrf_id_t
, void **))
129 vrf_master
.vrf_new_hook
= func
;
131 case VRF_DELETE_HOOK
:
132 vrf_master
.vrf_delete_hook
= func
;
139 /* Return the iterator of the first VRF. */
143 struct route_node
*rn
;
145 for (rn
= route_top (vrf_table
); rn
; rn
= route_next (rn
))
148 route_unlock_node (rn
); /* top/next */
149 return (vrf_iter_t
)rn
;
151 return VRF_ITER_INVALID
;
154 /* Return the next VRF iterator to the given iterator. */
156 vrf_next (vrf_iter_t iter
)
158 struct route_node
*rn
= NULL
;
160 /* Lock it first because route_next() will unlock it. */
161 if (iter
!= VRF_ITER_INVALID
)
162 rn
= route_next (route_lock_node ((struct route_node
*)iter
));
164 for (; rn
; rn
= route_next (rn
))
167 route_unlock_node (rn
); /* next */
168 return (vrf_iter_t
)rn
;
170 return VRF_ITER_INVALID
;
173 /* Return the VRF iterator of the given VRF ID. If it does not exist,
174 * the iterator of the next existing VRF is returned. */
176 vrf_iterator (vrf_id_t vrf_id
)
179 struct route_node
*rn
;
181 vrf_build_key (vrf_id
, &p
);
182 rn
= route_node_get (vrf_table
, &p
);
185 /* OK, the VRF exists. */
186 route_unlock_node (rn
); /* get */
187 return (vrf_iter_t
)rn
;
190 /* Find the next VRF. */
191 for (rn
= route_next (rn
); rn
; rn
= route_next (rn
))
194 route_unlock_node (rn
); /* next */
195 return (vrf_iter_t
)rn
;
198 return VRF_ITER_INVALID
;
201 /* Obtain the VRF ID from the given VRF iterator. */
203 vrf_iter2id (vrf_iter_t iter
)
205 struct route_node
*rn
= (struct route_node
*) iter
;
206 return (rn
&& rn
->info
) ? ((struct vrf
*)rn
->info
)->vrf_id
: VRF_DEFAULT
;
209 /* Obtain the data pointer from the given VRF iterator. */
211 vrf_iter2info (vrf_iter_t iter
)
213 struct route_node
*rn
= (struct route_node
*) iter
;
214 return (rn
&& rn
->info
) ? ((struct vrf
*)rn
->info
)->info
: NULL
;
217 /* Get the data pointer of the specified VRF. If not found, create one. */
219 vrf_info_get (vrf_id_t vrf_id
)
221 struct vrf
*vrf
= vrf_get (vrf_id
);
225 /* Look up the data pointer of the specified VRF. */
227 vrf_info_lookup (vrf_id_t vrf_id
)
229 struct vrf
*vrf
= vrf_lookup (vrf_id
);
230 return vrf
? vrf
->info
: NULL
;
233 /* Initialize VRF module. */
237 struct vrf
*default_vrf
;
239 /* Allocate VRF table. */
240 vrf_table
= route_table_init ();
242 /* The default VRF always exists. */
243 default_vrf
= vrf_get (VRF_DEFAULT
);
246 zlog_err ("vrf_init: failed to create the default VRF!");
250 /* Set the default VRF name. */
251 default_vrf
->name
= XSTRDUP (MTYPE_VRF_NAME
, "Default-IP-Routing-Table");
254 /* Terminate VRF module. */
258 struct route_node
*rn
;
261 for (rn
= route_top (vrf_table
); rn
; rn
= route_next (rn
))
262 if ((vrf
= rn
->info
) != NULL
)
265 route_table_finish (vrf_table
);