diff options
author | Feng Lu <lu.feng@6wind.com> | 2015-05-22 11:39:56 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2015-06-02 06:58:12 +0200 |
commit | 41f44a23e86a65a5cad7e5e8cafd7e935f153232 (patch) | |
tree | 1fcffa568b188ae66e5f18df09f6960522dfe564 /lib | |
parent | 395828eea809e8b2b8c5824d3639cefedd7aa9f0 (diff) | |
download | quagga-41f44a23e86a65a5cad7e5e8cafd7e935f153232.tar.bz2 quagga-41f44a23e86a65a5cad7e5e8cafd7e935f153232.tar.xz |
lib, zebra: move "struct vrf" to be a lib module
Previously "struct vrf" is defined locally in zebra. Now it is moved
to be a lib module.
This is the first step to support multi-VRF in quagga. The
implementation is splitted into small patches for the purpose of
easy review.
* lib:
"struct vrf" with basic members is defined in vrf.c. The member
"void *info" is for user data.
Some basic functions are defined in vrf.c for adding/deleting/
looking up a VRF, scanning the VRF table and initializing the
VRF module.
The type "vrf_id_t" is defined specificly for VRF ID.
* zebra:
The previous "struct vrf" is re-defined as "struct zebra_vrf";
and previous "vrf" variables are renamed to "zvrf".
The previous "struct vrf" related functions are removed from
zbera_rib.c. New functions are defined to maintain the new
"struct zebra_vrf".
The names vrf_xxx are reserved for the functions in VRF module.
So:
- the previous vrf_table() are renamed to zebra_vrf_table();
- the previous vrf_static_table() are renamed to
zebra_vrf_static_table().
The main logic is not changed.
BTW: Add a statement to zebra_snmp.c telling that the SNMP is
running only for the MIBs in the default VRF.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Vincent JARDIN <vincent.jardin@6wind.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/memtypes.c | 5 | ||||
-rw-r--r-- | lib/vrf.c | 268 | ||||
-rw-r--r-- | lib/vrf.h | 96 | ||||
-rw-r--r-- | lib/zebra.h | 3 |
5 files changed, 372 insertions, 4 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index fc023123..ac51fc62 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -13,7 +13,7 @@ libzebra_la_SOURCES = \ sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \ filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \ - sigevent.c pqueue.c jhash.c memtypes.c workqueue.c + sigevent.c pqueue.c jhash.c memtypes.c workqueue.c vrf.c BUILT_SOURCES = memtypes.h route_types.h gitversion.h @@ -28,7 +28,7 @@ pkginclude_HEADERS = \ str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \ plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \ privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ - workqueue.h route_types.h libospf.h + workqueue.h route_types.h libospf.h vrf.h noinst_HEADERS = \ plist_int.h diff --git a/lib/memtypes.c b/lib/memtypes.c index 1a0c11fe..3e599f67 100644 --- a/lib/memtypes.c +++ b/lib/memtypes.c @@ -69,14 +69,15 @@ struct memory_list memory_list_lib[] = { MTYPE_PQUEUE, "Priority queue" }, { MTYPE_PQUEUE_DATA, "Priority queue data" }, { MTYPE_HOST, "Host config" }, + { MTYPE_VRF, "VRF" }, + { MTYPE_VRF_NAME, "VRF name" }, { -1, NULL }, }; struct memory_list memory_list_zebra[] = { { MTYPE_RTADV_PREFIX, "Router Advertisement Prefix" }, - { MTYPE_VRF, "VRF" }, - { MTYPE_VRF_NAME, "VRF name" }, + { MTYPE_ZEBRA_VRF, "ZEBRA VRF" }, { MTYPE_NEXTHOP, "Nexthop" }, { MTYPE_RIB, "RIB" }, { MTYPE_RIB_QUEUE, "RIB process work queue" }, diff --git a/lib/vrf.c b/lib/vrf.c new file mode 100644 index 00000000..3ccbb996 --- /dev/null +++ b/lib/vrf.c @@ -0,0 +1,268 @@ +/* + * VRF functions. + * Copyright (C) 2014 6WIND S.A. + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <zebra.h> + +#include "vrf.h" +#include "prefix.h" +#include "table.h" +#include "log.h" +#include "memory.h" + +struct vrf +{ + /* Identifier, same as the vector index */ + vrf_id_t vrf_id; + /* Name */ + char *name; + + /* User data */ + void *info; +}; + +/* Holding VRF hooks */ +struct vrf_master +{ + int (*vrf_new_hook) (vrf_id_t, void **); + int (*vrf_delete_hook) (vrf_id_t, void **); +} vrf_master = {0,}; + +/* VRF table */ +struct route_table *vrf_table = NULL; + +/* Build the table key */ +static void +vrf_build_key (vrf_id_t vrf_id, struct prefix *p) +{ + p->family = AF_INET; + p->prefixlen = IPV4_MAX_BITLEN; + p->u.prefix4.s_addr = vrf_id; +} + +/* Get a VRF. If not found, create one. */ +static struct vrf * +vrf_get (vrf_id_t vrf_id) +{ + struct prefix p; + struct route_node *rn; + struct vrf *vrf; + + vrf_build_key (vrf_id, &p); + rn = route_node_get (vrf_table, &p); + if (rn->info) + { + vrf = (struct vrf *)rn->info; + route_unlock_node (rn); /* get */ + return vrf; + } + + vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); + vrf->vrf_id = vrf_id; + rn->info = vrf; + + zlog_info ("VRF %u is created.", vrf_id); + + if (vrf_master.vrf_new_hook) + (*vrf_master.vrf_new_hook) (vrf_id, &vrf->info); + + return vrf; +} + +/* Delete a VRF. This is called in vrf_terminate(). */ +static void +vrf_delete (struct vrf *vrf) +{ + zlog_info ("VRF %u is to be deleted.", vrf->vrf_id); + + if (vrf_master.vrf_delete_hook) + (*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info); + + if (vrf->name) + XFREE (MTYPE_VRF_NAME, vrf->name); + + XFREE (MTYPE_VRF, vrf); +} + +/* Look up a VRF by identifier. */ +static struct vrf * +vrf_lookup (vrf_id_t vrf_id) +{ + struct prefix p; + struct route_node *rn; + struct vrf *vrf = NULL; + + vrf_build_key (vrf_id, &p); + rn = route_node_lookup (vrf_table, &p); + if (rn) + { + vrf = (struct vrf *)rn->info; + route_unlock_node (rn); /* lookup */ + } + return vrf; +} + +/* Add a VRF hook. Please add hooks before calling vrf_init(). */ +void +vrf_add_hook (int type, int (*func)(vrf_id_t, void **)) +{ + switch (type) { + case VRF_NEW_HOOK: + vrf_master.vrf_new_hook = func; + break; + case VRF_DELETE_HOOK: + vrf_master.vrf_delete_hook = func; + break; + default: + break; + } +} + +/* Return the iterator of the first VRF. */ +vrf_iter_t +vrf_first (void) +{ + struct route_node *rn; + + for (rn = route_top (vrf_table); rn; rn = route_next (rn)) + if (rn->info) + { + route_unlock_node (rn); /* top/next */ + return (vrf_iter_t)rn; + } + return VRF_ITER_INVALID; +} + +/* Return the next VRF iterator to the given iterator. */ +vrf_iter_t +vrf_next (vrf_iter_t iter) +{ + struct route_node *rn = NULL; + + /* Lock it first because route_next() will unlock it. */ + if (iter != VRF_ITER_INVALID) + rn = route_next (route_lock_node ((struct route_node *)iter)); + + for (; rn; rn = route_next (rn)) + if (rn->info) + { + route_unlock_node (rn); /* next */ + return (vrf_iter_t)rn; + } + return VRF_ITER_INVALID; +} + +/* Return the VRF iterator of the given VRF ID. If it does not exist, + * the iterator of the next existing VRF is returned. */ +vrf_iter_t +vrf_iterator (vrf_id_t vrf_id) +{ + struct prefix p; + struct route_node *rn; + + vrf_build_key (vrf_id, &p); + rn = route_node_get (vrf_table, &p); + if (rn->info) + { + /* OK, the VRF exists. */ + route_unlock_node (rn); /* get */ + return (vrf_iter_t)rn; + } + + /* Find the next VRF. */ + for (rn = route_next (rn); rn; rn = route_next (rn)) + if (rn->info) + { + route_unlock_node (rn); /* next */ + return (vrf_iter_t)rn; + } + + return VRF_ITER_INVALID; +} + +/* Obtain the VRF ID from the given VRF iterator. */ +vrf_id_t +vrf_iter2id (vrf_iter_t iter) +{ + struct route_node *rn = (struct route_node *) iter; + return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT; +} + +/* Obtain the data pointer from the given VRF iterator. */ +void * +vrf_iter2info (vrf_iter_t iter) +{ + struct route_node *rn = (struct route_node *) iter; + return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL; +} + +/* Get the data pointer of the specified VRF. If not found, create one. */ +void * +vrf_info_get (vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_get (vrf_id); + return vrf->info; +} + +/* Look up the data pointer of the specified VRF. */ +void * +vrf_info_lookup (vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_lookup (vrf_id); + return vrf ? vrf->info : NULL; +} + +/* Initialize VRF module. */ +void +vrf_init (void) +{ + struct vrf *default_vrf; + + /* Allocate VRF table. */ + vrf_table = route_table_init (); + + /* The default VRF always exists. */ + default_vrf = vrf_get (VRF_DEFAULT); + if (!default_vrf) + { + zlog_err ("vrf_init: failed to create the default VRF!"); + exit (1); + } + + /* Set the default VRF name. */ + default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, "Default-IP-Routing-Table"); +} + +/* Terminate VRF module. */ +void +vrf_terminate (void) +{ + struct route_node *rn; + struct vrf *vrf; + + for (rn = route_top (vrf_table); rn; rn = route_next (rn)) + if ((vrf = rn->info) != NULL) + vrf_delete (vrf); + + route_table_finish (vrf_table); + vrf_table = NULL; +} + diff --git a/lib/vrf.h b/lib/vrf.h new file mode 100644 index 00000000..7e050994 --- /dev/null +++ b/lib/vrf.h @@ -0,0 +1,96 @@ +/* + * VRF related header. + * Copyright (C) 2014 6WIND S.A. + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ZEBRA_VRF_H +#define _ZEBRA_VRF_H + +/* The default VRF ID */ +#define VRF_DEFAULT 0 + +/* + * VRF hooks + */ + +#define VRF_NEW_HOOK 0 /* a new VRF is just created */ +#define VRF_DELETE_HOOK 1 /* a VRF is to be deleted */ + +/* + * Add a specific hook to VRF module. + * @param1: hook type + * @param2: the callback function + * - param 1: the VRF ID + * - param 2: the address of the user data pointer (the user data + * can be stored in or freed from there) + */ +extern void vrf_add_hook (int, int (*)(vrf_id_t, void **)); + +/* + * VRF iteration + */ + +typedef void * vrf_iter_t; +#define VRF_ITER_INVALID NULL /* invalid value of the iterator */ + +/* + * VRF iteration utilities. Example for the usage: + * + * vrf_iter_t iter = vrf_first(); + * for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + * + * or + * + * vrf_iter_t iter = vrf_iterator (<a given VRF ID>); + * for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + */ + +/* Return the iterator of the first VRF. */ +extern vrf_iter_t vrf_first (void); +/* Return the next VRF iterator to the given iterator. */ +extern vrf_iter_t vrf_next (vrf_iter_t); +/* Return the VRF iterator of the given VRF ID. If it does not exist, + * the iterator of the next existing VRF is returned. */ +extern vrf_iter_t vrf_iterator (vrf_id_t); + +/* + * VRF iterator to properties + */ +extern vrf_id_t vrf_iter2id (vrf_iter_t); +extern void *vrf_iter2info (vrf_iter_t); + +/* + * Utilities to obtain the user data + */ + +/* Get the data pointer of the specified VRF. If not found, create one. */ +extern void *vrf_info_get (vrf_id_t); +/* Look up the data pointer of the specified VRF. */ +extern void *vrf_info_lookup (vrf_id_t); + +/* + * VRF initializer/destructor + */ +/* Please add hooks before calling vrf_init(). */ +extern void vrf_init (void); +extern void vrf_terminate (void); + +#endif /*_ZEBRA_VRF_H*/ + diff --git a/lib/zebra.h b/lib/zebra.h index a5ed20e4..e88a6293 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -522,6 +522,9 @@ typedef u_int8_t safi_t; typedef u_int16_t zebra_size_t; typedef u_int16_t zebra_command_t; +/* VRF ID type. */ +typedef u_int16_t vrf_id_t; + /* FIFO -- first in first out structure and macros. */ struct fifo { |