mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 04:26:12 +00:00
lib, zebra: Abstract vrf.c to handle both vrf_id_t and char *name
Abstract vrf.c code to allow pass in a vrf name as well as to start the coding of how namespaces and vrf's will interact. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
90fb3e1389
commit
216b18efe1
310
lib/vrf.c
310
lib/vrf.c
@ -29,38 +29,102 @@
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
|
||||
#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
|
||||
|
||||
struct vrf
|
||||
{
|
||||
/* Identifier, same as the vector index */
|
||||
vrf_id_t vrf_id;
|
||||
/* Name */
|
||||
char *name;
|
||||
|
||||
/* Master list of interfaces belonging to this VRF */
|
||||
struct list *iflist;
|
||||
|
||||
/* 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 **);
|
||||
int (*vrf_enable_hook) (vrf_id_t, void **);
|
||||
int (*vrf_disable_hook) (vrf_id_t, void **);
|
||||
int (*vrf_new_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_delete_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_enable_hook) (vrf_id_t, const char *, void **);
|
||||
int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
|
||||
} vrf_master = {0,};
|
||||
|
||||
/* VRF table */
|
||||
struct route_table *vrf_table = NULL;
|
||||
|
||||
/* VRF is part of a list too to store it before its actually active */
|
||||
struct list *vrf_list;
|
||||
|
||||
static int vrf_is_enabled (struct vrf *vrf);
|
||||
static int vrf_enable (struct vrf *vrf);
|
||||
static void vrf_disable (struct vrf *vrf);
|
||||
|
||||
/* VRF list existance check by name. */
|
||||
struct vrf *
|
||||
vrf_list_lookup_by_name (const char *name)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct vrf *vrfp;
|
||||
|
||||
if (name)
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
|
||||
{
|
||||
if (strcmp(name, vrfp->name) == 0)
|
||||
return vrfp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct vrf *
|
||||
vrf_list_lookup_by_name_len (const char *name, size_t namelen)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct vrf *vrfp;
|
||||
|
||||
if (namelen > INTERFACE_NAMSIZ)
|
||||
return NULL;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrfp))
|
||||
{
|
||||
if (!memcmp(name, vrfp->name, namelen) && (vrfp->name[namelen] == '\0'))
|
||||
return vrfp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create new interface structure. */
|
||||
struct vrf *
|
||||
vrf_create (const char *name, size_t namelen)
|
||||
{
|
||||
struct vrf *vrfp;
|
||||
|
||||
vrfp = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
||||
|
||||
assert (name);
|
||||
assert (namelen <= VRF_NAMSIZ); /* Need space for '\0' at end. */
|
||||
strncpy (vrfp->name, name, namelen);
|
||||
vrfp->name[namelen] = '\0';
|
||||
if (vrf_list_lookup_by_name (vrfp->name) == NULL)
|
||||
listnode_add_sort (vrf_list, vrfp);
|
||||
else
|
||||
zlog_err("vrf_create(%s): corruption detected -- vrf with this "
|
||||
"name exists already with vrf-id %u!", vrfp->name, vrfp->vrf_id);
|
||||
|
||||
UNSET_FLAG(vrfp->status, ZEBRA_VRF_ACTIVE);
|
||||
|
||||
/* Pending: - Make sure this 0 vrf-id isnt taken as default vrf
|
||||
- See if calling the the new_hook here is ok, may need to make the attached callback re-entrant.
|
||||
if (vrf_master.vrf_new_hook)
|
||||
(*vrf_master.vrf_new_hook) (0, name, &vrfp->info);
|
||||
*/
|
||||
return vrfp;
|
||||
}
|
||||
|
||||
struct vrf *
|
||||
vrf_get_by_name_len (const char *name, size_t namelen)
|
||||
{
|
||||
struct vrf *vrfp;
|
||||
|
||||
return ((vrfp = vrf_list_lookup_by_name_len (name, namelen)) != NULL) ? vrfp :
|
||||
vrf_create (name, namelen);
|
||||
}
|
||||
|
||||
struct vrf *
|
||||
vrf_get_by_name (const char *name)
|
||||
{
|
||||
struct vrf *vrfp;
|
||||
|
||||
return ((vrfp = vrf_list_lookup_by_name (name)) != NULL) ? vrfp :
|
||||
vrf_create (name, strlen(name));
|
||||
}
|
||||
|
||||
/* Build the table key */
|
||||
static void
|
||||
@ -71,13 +135,16 @@ vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
|
||||
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)
|
||||
/* Get a VRF. If not found, create one.
|
||||
* Arg: name
|
||||
* Description: Please note that this routine can be called with just the name
|
||||
and 0 vrf-id */
|
||||
struct vrf *
|
||||
vrf_get (vrf_id_t vrf_id, const char *name)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
struct vrf *vrf;
|
||||
struct vrf *vrf = NULL;
|
||||
|
||||
vrf_build_key (vrf_id, &p);
|
||||
rn = route_node_get (vrf_table, &p);
|
||||
@ -85,26 +152,47 @@ vrf_get (vrf_id_t vrf_id)
|
||||
{
|
||||
vrf = (struct vrf *)rn->info;
|
||||
route_unlock_node (rn); /* get */
|
||||
return vrf;
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
strncpy (vrf->name, name, strlen(name));
|
||||
vrf->name[strlen(name)] = '\0';
|
||||
if (vrf_list_lookup_by_name (vrf->name) == NULL)
|
||||
listnode_add_sort (vrf_list, vrf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name)
|
||||
vrf = vrf_get_by_name(name);
|
||||
|
||||
if (!vrf)
|
||||
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
||||
|
||||
vrf->vrf_id = vrf_id;
|
||||
rn->info = vrf;
|
||||
vrf->node = rn;
|
||||
|
||||
/* Initialize interfaces. */
|
||||
if_init (vrf_id, &vrf->iflist);
|
||||
}
|
||||
|
||||
if (name)
|
||||
zlog_info ("VRF %s with id %u is created.", name, vrf_id);
|
||||
else
|
||||
zlog_info ("VRF %u is created.", vrf_id);
|
||||
|
||||
if (vrf_master.vrf_new_hook)
|
||||
(*vrf_master.vrf_new_hook) (vrf_id, &vrf->info);
|
||||
if (vrf_master.vrf_new_hook && name) {
|
||||
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
|
||||
|
||||
if (vrf->info)
|
||||
zlog_info ("zvrf is created.");
|
||||
}
|
||||
return vrf;
|
||||
}
|
||||
|
||||
/* Delete a VRF. This is called in vrf_terminate(). */
|
||||
static void
|
||||
void
|
||||
vrf_delete (struct vrf *vrf)
|
||||
{
|
||||
zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
|
||||
@ -113,18 +201,24 @@ vrf_delete (struct vrf *vrf)
|
||||
vrf_disable (vrf);
|
||||
|
||||
if (vrf_master.vrf_delete_hook)
|
||||
(*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
|
||||
(*vrf_master.vrf_delete_hook) (vrf->vrf_id, vrf->name, &vrf->info);
|
||||
|
||||
if (CHECK_FLAG (vrf->status, ZEBRA_VRF_ACTIVE))
|
||||
if_terminate (vrf->vrf_id, &vrf->iflist);
|
||||
|
||||
if (vrf->name)
|
||||
XFREE (MTYPE_VRF_NAME, vrf->name);
|
||||
if (vrf->node)
|
||||
{
|
||||
vrf->node->info = NULL;
|
||||
route_unlock_node(vrf->node);
|
||||
}
|
||||
|
||||
listnode_delete (vrf_list, vrf);
|
||||
|
||||
XFREE (MTYPE_VRF, vrf);
|
||||
}
|
||||
|
||||
/* Look up a VRF by identifier. */
|
||||
static struct vrf *
|
||||
struct vrf *
|
||||
vrf_lookup (vrf_id_t vrf_id)
|
||||
{
|
||||
struct prefix p;
|
||||
@ -149,7 +243,11 @@ vrf_lookup (vrf_id_t vrf_id)
|
||||
static int
|
||||
vrf_is_enabled (struct vrf *vrf)
|
||||
{
|
||||
return vrf && CHECK_FLAG (vrf->status, ZEBRA_VRF_ACTIVE);
|
||||
|
||||
/*Pending: figure out the real use of this routine.. it used to be..
|
||||
return vrf && vrf->vrf_id == VRF_DEFAULT;
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@ -159,21 +257,22 @@ vrf_is_enabled (struct vrf *vrf)
|
||||
*
|
||||
* RETURN: 1 - enabled successfully; otherwise, 0.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
vrf_enable (struct vrf *vrf)
|
||||
{
|
||||
/* Till now, only the default VRF can be enabled. */
|
||||
if (vrf->vrf_id == VRF_DEFAULT)
|
||||
{
|
||||
//Pending: see if VRF lib had a reason to leave it for default only
|
||||
// /* Till now, only the default VRF can be enabled. */
|
||||
// if (vrf->vrf_id == VRF_DEFAULT)
|
||||
// {
|
||||
zlog_info ("VRF %u is enabled.", vrf->vrf_id);
|
||||
|
||||
if (vrf_master.vrf_enable_hook)
|
||||
(*vrf_master.vrf_enable_hook) (vrf->vrf_id, &vrf->info);
|
||||
(*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// }
|
||||
|
||||
return 0;
|
||||
// return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -189,16 +288,17 @@ vrf_disable (struct vrf *vrf)
|
||||
zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
|
||||
|
||||
/* Till now, nothing to be done for the default VRF. */
|
||||
//Pending: see why this statement.
|
||||
|
||||
if (vrf_master.vrf_disable_hook)
|
||||
(*vrf_master.vrf_disable_hook) (vrf->vrf_id, &vrf->info);
|
||||
(*vrf_master.vrf_disable_hook) (vrf->vrf_id, vrf->name, &vrf->info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add a VRF hook. Please add hooks before calling vrf_init(). */
|
||||
void
|
||||
vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
|
||||
vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
|
||||
{
|
||||
switch (type) {
|
||||
case VRF_NEW_HOOK:
|
||||
@ -288,6 +388,13 @@ vrf_iter2id (vrf_iter_t iter)
|
||||
return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
|
||||
}
|
||||
|
||||
struct vrf *
|
||||
vrf_iter2vrf (vrf_iter_t iter)
|
||||
{
|
||||
struct route_node *rn = (struct route_node *) iter;
|
||||
return (rn && rn->info) ? (struct vrf *)rn->info : NULL;
|
||||
}
|
||||
|
||||
/* Obtain the data pointer from the given VRF iterator. */
|
||||
void *
|
||||
vrf_iter2info (vrf_iter_t iter)
|
||||
@ -304,11 +411,41 @@ vrf_iter2iflist (vrf_iter_t iter)
|
||||
return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
|
||||
}
|
||||
|
||||
/* Look up a VRF by name. */
|
||||
struct vrf *
|
||||
vrf_lookup_by_name (const char *name)
|
||||
{
|
||||
struct vrf *vrf = NULL;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
{
|
||||
vrf = vrf_iter2vrf (iter);
|
||||
if (vrf && !strcmp(vrf->name, name))
|
||||
break;
|
||||
}
|
||||
|
||||
return vrf;
|
||||
}
|
||||
|
||||
vrf_id_t
|
||||
vrf_name_to_id (const char *name)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT; //Pending: need a way to return invalid id/ routine not used.
|
||||
|
||||
vrf = vrf_lookup_by_name (name);
|
||||
if (vrf)
|
||||
vrf_id = vrf->vrf_id;
|
||||
|
||||
return vrf_id;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
struct vrf *vrf = vrf_get (vrf_id, NULL);
|
||||
return vrf->info;
|
||||
}
|
||||
|
||||
@ -332,7 +469,7 @@ vrf_iflist (vrf_id_t vrf_id)
|
||||
struct list *
|
||||
vrf_iflist_get (vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf * vrf = vrf_get (vrf_id);
|
||||
struct vrf * vrf = vrf_get (vrf_id, NULL);
|
||||
return vrf->iflist;
|
||||
}
|
||||
|
||||
@ -429,26 +566,92 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id)
|
||||
VRF_BITMAP_FLAG (offset)) ? 1 : 0;
|
||||
}
|
||||
|
||||
//Pending: See if combining the common parts with if_cmp_func() make sense.
|
||||
/* Compare interface names, returning an integer greater than, equal to, or
|
||||
* less than 0, (following the strcmp convention), according to the
|
||||
* relationship between vrfp1 and vrfp2. Interface names consist of an
|
||||
* alphabetic prefix and a numeric suffix. The primary sort key is
|
||||
* lexicographic by name, and then numeric by number. No number sorts
|
||||
* before all numbers. Examples: de0 < de1, de100 < fxp0 < xl0, devpty <
|
||||
* devpty0, de0 < del0
|
||||
*/
|
||||
int
|
||||
vrf_cmp_func (struct vrf *vrfp1, struct vrf *vrfp2)
|
||||
{
|
||||
unsigned int l1, l2;
|
||||
long int x1, x2;
|
||||
char *p1, *p2;
|
||||
int res;
|
||||
|
||||
p1 = vrfp1->name;
|
||||
p2 = vrfp2->name;
|
||||
|
||||
while (*p1 && *p2) {
|
||||
/* look up to any number */
|
||||
l1 = strcspn(p1, "0123456789");
|
||||
l2 = strcspn(p2, "0123456789");
|
||||
|
||||
/* name lengths are different -> compare names */
|
||||
if (l1 != l2)
|
||||
return (strcmp(p1, p2));
|
||||
|
||||
/* Note that this relies on all numbers being less than all letters, so
|
||||
* that de0 < del0.
|
||||
*/
|
||||
res = strncmp(p1, p2, l1);
|
||||
|
||||
/* names are different -> compare them */
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
/* with identical name part, go to numeric part */
|
||||
p1 += l1;
|
||||
p2 += l1;
|
||||
|
||||
if (!*p1)
|
||||
return -1;
|
||||
if (!*p2)
|
||||
return 1;
|
||||
|
||||
x1 = strtol(p1, &p1, 10);
|
||||
x2 = strtol(p2, &p2, 10);
|
||||
|
||||
/* let's compare numbers now */
|
||||
if (x1 < x2)
|
||||
return -1;
|
||||
if (x1 > x2)
|
||||
return 1;
|
||||
|
||||
/* numbers were equal, lets do it again..
|
||||
(it happens with name like "eth123.456:789") */
|
||||
}
|
||||
if (*p1)
|
||||
return 1;
|
||||
if (*p2)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize VRF module. */
|
||||
void
|
||||
vrf_init (void)
|
||||
{
|
||||
struct vrf *default_vrf;
|
||||
|
||||
vrf_list = list_new ();
|
||||
vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
|
||||
|
||||
/* Allocate VRF table. */
|
||||
vrf_table = route_table_init ();
|
||||
|
||||
/* The default VRF always exists. */
|
||||
default_vrf = vrf_get (VRF_DEFAULT);
|
||||
default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
|
||||
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, VRF_DEFAULT_NAME);
|
||||
|
||||
/* Enable the default VRF. */
|
||||
if (!vrf_enable (default_vrf))
|
||||
{
|
||||
@ -478,16 +681,7 @@ vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!vrf_is_enabled (vrf_lookup (vrf_id)))
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vrf_id == VRF_DEFAULT)
|
||||
ret = socket (domain, type, protocol);
|
||||
else
|
||||
errno = ENOSYS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
78
lib/vrf.h
78
lib/vrf.h
@ -25,15 +25,33 @@
|
||||
|
||||
#include "linklist.h"
|
||||
|
||||
/* The default NS ID */
|
||||
#define NS_DEFAULT 0
|
||||
|
||||
/* The default VRF ID */
|
||||
#define VRF_DEFAULT 0
|
||||
|
||||
/* Pending: May need to refine this. */
|
||||
#ifndef IFLA_VRF_MAX
|
||||
enum {
|
||||
IFLA_VRF_UNSPEC,
|
||||
IFLA_VRF_TABLE,
|
||||
__IFLA_VRF_MAX
|
||||
};
|
||||
|
||||
#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
|
||||
#endif
|
||||
|
||||
#define VRF_NAMSIZ 36
|
||||
|
||||
#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
|
||||
|
||||
/*
|
||||
* The command strings
|
||||
*/
|
||||
|
||||
#define VRF_CMD_STR "vrf <0-65535>"
|
||||
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF ID\n"
|
||||
#define VRF_CMD_STR "vrf NAME"
|
||||
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF name\n"
|
||||
|
||||
#define VRF_ALL_CMD_STR "vrf all"
|
||||
#define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n"
|
||||
@ -47,6 +65,30 @@
|
||||
#define VRF_ENABLE_HOOK 2 /* a VRF is ready to use */
|
||||
#define VRF_DISABLE_HOOK 3 /* a VRF is to be unusable */
|
||||
|
||||
struct vrf
|
||||
{
|
||||
/* Identifier, same as the vector index */
|
||||
vrf_id_t vrf_id;
|
||||
/* Name */
|
||||
|
||||
char name[VRF_NAMSIZ + 1];
|
||||
|
||||
/* Zebra internal VRF status */
|
||||
u_char status;
|
||||
#define ZEBRA_VRF_ACTIVE (1 << 0)
|
||||
|
||||
struct route_node *node;
|
||||
|
||||
/* Master list of interfaces belonging to this VRF */
|
||||
struct list *iflist;
|
||||
|
||||
/* User data */
|
||||
void *info;
|
||||
};
|
||||
|
||||
|
||||
extern struct list *vrf_list;
|
||||
|
||||
/*
|
||||
* Add a specific hook to VRF module.
|
||||
* @param1: hook type
|
||||
@ -55,7 +97,7 @@
|
||||
* - 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 **));
|
||||
extern void vrf_add_hook (int, int (*)(vrf_id_t, const char *, void **));
|
||||
|
||||
/*
|
||||
* VRF iteration
|
||||
@ -64,6 +106,35 @@ extern void vrf_add_hook (int, int (*)(vrf_id_t, void **));
|
||||
typedef void * vrf_iter_t;
|
||||
#define VRF_ITER_INVALID NULL /* invalid value of the iterator */
|
||||
|
||||
extern int vrf_cmp_func (struct vrf *, struct vrf *);
|
||||
extern struct vrf *vrf_lookup (vrf_id_t);
|
||||
extern struct vrf *vrf_lookup_by_name (const char *);
|
||||
extern struct vrf *vrf_list_lookup_by_name (const char *);
|
||||
extern struct vrf *vrf_list_lookup_by_name_len (const char *, size_t);
|
||||
extern struct vrf *vrf_get_by_name (const char *);
|
||||
extern struct vrf *vrf_get_by_name_len (const char *, size_t);
|
||||
extern struct vrf *vrf_get (vrf_id_t, const char *);
|
||||
extern struct vrf *vrf_create (const char *, size_t);
|
||||
extern void vrf_delete (struct vrf *);
|
||||
extern int vrf_enable (struct vrf *);
|
||||
extern vrf_id_t vrf_name_to_id (const char *);
|
||||
|
||||
#define VRF_GET_ID(V,NAME) \
|
||||
do { \
|
||||
struct vrf *vrf; \
|
||||
if (!(vrf = vrf_list_lookup_by_name(NAME))) \
|
||||
{ \
|
||||
vty_out (vty, "%% VRF %s not found%s", NAME, VTY_NEWLINE);\
|
||||
return CMD_WARNING; \
|
||||
} \
|
||||
if (!vrf->vrf_id) \
|
||||
{ \
|
||||
vty_out (vty, "%% VRF %s not active%s", NAME, VTY_NEWLINE);\
|
||||
return CMD_WARNING; \
|
||||
} \
|
||||
(V) = vrf->vrf_id; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* VRF iteration utilities. Example for the usage:
|
||||
*
|
||||
@ -88,6 +159,7 @@ extern vrf_iter_t vrf_iterator (vrf_id_t);
|
||||
* VRF iterator to properties
|
||||
*/
|
||||
extern vrf_id_t vrf_iter2id (vrf_iter_t);
|
||||
extern struct vrf *vrf_iter2vrf (vrf_iter_t);
|
||||
extern void *vrf_iter2info (vrf_iter_t);
|
||||
extern struct list *vrf_iter2iflist (vrf_iter_t);
|
||||
|
||||
|
@ -216,7 +216,7 @@ struct quagga_signal_t zebra_signals[] =
|
||||
|
||||
/* Callback upon creating a new VRF. */
|
||||
static int
|
||||
zebra_vrf_new (vrf_id_t vrf_id, void **info)
|
||||
zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = *info;
|
||||
|
||||
@ -232,7 +232,7 @@ zebra_vrf_new (vrf_id_t vrf_id, void **info)
|
||||
|
||||
/* Callback upon enabling a VRF. */
|
||||
static int
|
||||
zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||
zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||
|
||||
@ -250,7 +250,7 @@ zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||
|
||||
/* Callback upon disabling a VRF. */
|
||||
static int
|
||||
zebra_vrf_disable (vrf_id_t vrf_id, void **info)
|
||||
zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||
struct listnode *list_node;
|
||||
|
@ -204,7 +204,7 @@ struct quagga_signal_t zebra_signals[] =
|
||||
|
||||
/* Callback upon creating a new VRF. */
|
||||
static int
|
||||
zebra_vrf_new (vrf_id_t vrf_id, void **info)
|
||||
zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = *info;
|
||||
|
||||
@ -219,7 +219,7 @@ zebra_vrf_new (vrf_id_t vrf_id, void **info)
|
||||
|
||||
/* Callback upon enabling a VRF. */
|
||||
static int
|
||||
zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||
zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||
|
||||
@ -233,7 +233,7 @@ zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||
|
||||
/* Callback upon disabling a VRF. */
|
||||
static int
|
||||
zebra_vrf_disable (vrf_id_t vrf_id, void **info)
|
||||
zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||
struct listnode *list_node;
|
||||
|
Loading…
Reference in New Issue
Block a user