zebra: maintain the router-id per VRF
A router may need different identifier among the VRFs. So move the
maintenance of router-id per VRF.
* rib.h:
Move the previous global variables in router-id.c into the
"struct zebra_vrf":
- struct list _rid_all_sorted_list/*rid_all_sorted_list
- struct list _rid_lo_sorted_list/*rid_lo_sorted_list
- struct prefix rid_user_assigned
* router-id.c/router-id.h:
A new parameter "vrf_id" is added to all the router-id APIs.
Their operations are done only within the specified VRF.
A new command "router-id A.B.C.D vrf N" is added to allow
manual router-id for any VRF.
The old router_id_init() function is splitted into two:
- router_id_cmd_init(): it only installs the commands
- router_id_init(): this new one initializes the variables for
a specified VRF
* zebra_rib.c: Add new functions zebra_vrf_get/lookup() called
from router-id.c.
* main.c: Replace router_id_init() with router_id_cmd_init() and
call the new router_id_init() in zebra_vrf_new().
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>
diff --git a/zebra/main.c b/zebra/main.c
index a690c9a..c7e3b68 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -215,6 +215,7 @@
{
zvrf = zebra_vrf_alloc (vrf_id);
*info = (void *)zvrf;
+ router_id_init (zvrf);
}
return 0;
@@ -348,7 +349,7 @@
rib_init ();
zebra_if_init ();
zebra_debug_init ();
- router_id_init();
+ router_id_cmd_init ();
zebra_vty_init ();
access_list_init ();
prefix_list_init ();
diff --git a/zebra/rib.h b/zebra/rib.h
index dcb307e..06aa353 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -23,6 +23,7 @@
#ifndef _ZEBRA_RIB_H
#define _ZEBRA_RIB_H
+#include "linklist.h"
#include "prefix.h"
#include "table.h"
#include "queue.h"
@@ -351,6 +352,15 @@
/* Static route configuration. */
struct route_table *stable[AFI_MAX][SAFI_MAX];
+
+ /* 2nd pointer type used primarily to quell a warning on
+ * ALL_LIST_ELEMENTS_RO
+ */
+ struct list _rid_all_sorted_list;
+ struct list _rid_lo_sorted_list;
+ struct list *rid_all_sorted_list;
+ struct list *rid_lo_sorted_list;
+ struct prefix rid_user_assigned;
};
/*
diff --git a/zebra/router-id.c b/zebra/router-id.c
index bfafc27..a4eb73a 100644
--- a/zebra/router-id.c
+++ b/zebra/router-id.c
@@ -36,20 +36,12 @@
#include "log.h"
#include "table.h"
#include "rib.h"
+#include "vrf.h"
#include "zebra/zserv.h"
#include "zebra/router-id.h"
#include "zebra/redistribute.h"
-/* 2nd pointer type used primarily to quell a warning on
- * ALL_LIST_ELEMENTS_RO
- */
-static struct list _rid_all_sorted_list;
-static struct list _rid_lo_sorted_list;
-static struct list *rid_all_sorted_list = &_rid_all_sorted_list;
-static struct list *rid_lo_sorted_list = &_rid_lo_sorted_list;
-static struct prefix rid_user_assigned;
-
/* master zebra server structure */
extern struct zebra_t zebrad;
@@ -80,44 +72,55 @@
}
void
-router_id_get (struct prefix *p)
+router_id_get (struct prefix *p, vrf_id_t vrf_id)
{
struct listnode *node;
struct connected *c;
+ struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
p->u.prefix4.s_addr = 0;
p->family = AF_INET;
p->prefixlen = 32;
- if (rid_user_assigned.u.prefix4.s_addr)
- p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
- else if (!list_isempty (rid_lo_sorted_list))
+ if (zvrf->rid_user_assigned.u.prefix4.s_addr)
+ p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
+ else if (!list_isempty (zvrf->rid_lo_sorted_list))
{
- node = listtail (rid_lo_sorted_list);
+ node = listtail (zvrf->rid_lo_sorted_list);
c = listgetdata (node);
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
}
- else if (!list_isempty (rid_all_sorted_list))
+ else if (!list_isempty (zvrf->rid_all_sorted_list))
{
- node = listtail (rid_all_sorted_list);
+ node = listtail (zvrf->rid_all_sorted_list);
c = listgetdata (node);
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
}
}
static void
-router_id_set (struct prefix *p)
+router_id_set (struct prefix *p, vrf_id_t vrf_id)
{
struct prefix p2;
struct listnode *node;
struct zserv *client;
+ struct zebra_vrf *zvrf;
- rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
+ if (p->u.prefix4.s_addr == 0) /* unset */
+ {
+ zvrf = vrf_info_lookup (vrf_id);
+ if (! zvrf)
+ return;
+ }
+ else /* set */
+ zvrf = vrf_info_get (vrf_id);
- router_id_get (&p2);
+ zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
+
+ router_id_get (&p2, vrf_id);
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
- zsend_router_id_update (client, &p2);
+ zsend_router_id_update (client, &p2, vrf_id);
}
void
@@ -128,28 +131,29 @@
struct prefix before;
struct prefix after;
struct zserv *client;
+ struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
if (router_id_bad_address (ifc))
return;
- router_id_get (&before);
+ router_id_get (&before, zvrf->vrf_id);
if (!strncmp (ifc->ifp->name, "lo", 2)
|| !strncmp (ifc->ifp->name, "dummy", 5))
- l = rid_lo_sorted_list;
+ l = zvrf->rid_lo_sorted_list;
else
- l = rid_all_sorted_list;
+ l = zvrf->rid_all_sorted_list;
if (!router_id_find_node (l, ifc))
listnode_add_sort (l, ifc);
- router_id_get (&after);
+ router_id_get (&after, zvrf->vrf_id);
if (prefix_same (&before, &after))
return;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
- zsend_router_id_update (client, &after);
+ zsend_router_id_update (client, &after, zvrf->vrf_id);
}
void
@@ -161,36 +165,51 @@
struct prefix before;
struct listnode *node;
struct zserv *client;
+ struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
if (router_id_bad_address (ifc))
return;
- router_id_get (&before);
+ router_id_get (&before, zvrf->vrf_id);
if (!strncmp (ifc->ifp->name, "lo", 2)
|| !strncmp (ifc->ifp->name, "dummy", 5))
- l = rid_lo_sorted_list;
+ l = zvrf->rid_lo_sorted_list;
else
- l = rid_all_sorted_list;
+ l = zvrf->rid_all_sorted_list;
if ((c = router_id_find_node (l, ifc)))
listnode_delete (l, c);
- router_id_get (&after);
+ router_id_get (&after, zvrf->vrf_id);
if (prefix_same (&before, &after))
return;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
- zsend_router_id_update (client, &after);
+ zsend_router_id_update (client, &after, zvrf->vrf_id);
}
void
router_id_write (struct vty *vty)
{
- if (rid_user_assigned.u.prefix4.s_addr)
- vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
- VTY_NEWLINE);
+ struct zebra_vrf *zvrf;
+ vrf_iter_t iter;
+
+ for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+ if ((zvrf = vrf_iter2info (iter)) != NULL)
+ if (zvrf->rid_user_assigned.u.prefix4.s_addr)
+ {
+ if (zvrf->vrf_id == VRF_DEFAULT)
+ vty_out (vty, "router-id %s%s",
+ inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
+ VTY_NEWLINE);
+ else
+ vty_out (vty, "router-id %s vrf %u%s",
+ inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
+ zvrf->vrf_id,
+ VTY_NEWLINE);
+ }
}
DEFUN (router_id,
@@ -200,6 +219,7 @@
"IP address to use for router-id\n")
{
struct prefix rid;
+ vrf_id_t vrf_id = VRF_DEFAULT;
rid.u.prefix4.s_addr = inet_addr (argv[0]);
if (!rid.u.prefix4.s_addr)
@@ -208,11 +228,21 @@
rid.prefixlen = 32;
rid.family = AF_INET;
- router_id_set (&rid);
+ if (argc > 1)
+ VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
+
+ router_id_set (&rid, vrf_id);
return CMD_SUCCESS;
}
+ALIAS (router_id,
+ router_id_vrf_cmd,
+ "router-id A.B.C.D " VRF_CMD_STR,
+ "Manually set the router-id\n"
+ "IP address to use for router-id\n"
+ VRF_CMD_HELP_STR)
+
DEFUN (no_router_id,
no_router_id_cmd,
"no router-id",
@@ -220,16 +250,27 @@
"Remove the manually configured router-id\n")
{
struct prefix rid;
+ vrf_id_t vrf_id = VRF_DEFAULT;
rid.u.prefix4.s_addr = 0;
rid.prefixlen = 0;
rid.family = AF_INET;
- router_id_set (&rid);
+ if (argc > 0)
+ VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
+
+ router_id_set (&rid, vrf_id);
return CMD_SUCCESS;
}
+ALIAS (no_router_id,
+ no_router_id_vrf_cmd,
+ "no router-id " VRF_CMD_STR,
+ NO_STR
+ "Remove the manually configured router-id\n"
+ VRF_CMD_HELP_STR)
+
static int
router_id_cmp (void *a, void *b)
{
@@ -240,18 +281,27 @@
}
void
-router_id_init (void)
+router_id_cmd_init (void)
{
install_element (CONFIG_NODE, &router_id_cmd);
install_element (CONFIG_NODE, &no_router_id_cmd);
+ install_element (CONFIG_NODE, &router_id_vrf_cmd);
+ install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
+}
- memset (rid_all_sorted_list, 0, sizeof (*rid_all_sorted_list));
- memset (rid_lo_sorted_list, 0, sizeof (*rid_lo_sorted_list));
- memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));
+void
+router_id_init (struct zebra_vrf *zvrf)
+{
+ zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
+ zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
- rid_all_sorted_list->cmp = router_id_cmp;
- rid_lo_sorted_list->cmp = router_id_cmp;
+ memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list));
+ memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list));
+ memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned));
- rid_user_assigned.family = AF_INET;
- rid_user_assigned.prefixlen = 32;
+ zvrf->rid_all_sorted_list->cmp = router_id_cmp;
+ zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
+
+ zvrf->rid_user_assigned.family = AF_INET;
+ zvrf->rid_user_assigned.prefixlen = 32;
}
diff --git a/zebra/router-id.h b/zebra/router-id.h
index be12bf5..46d300e 100644
--- a/zebra/router-id.h
+++ b/zebra/router-id.h
@@ -33,8 +33,9 @@
extern void router_id_add_address(struct connected *);
extern void router_id_del_address(struct connected *);
-extern void router_id_init(void);
+extern void router_id_init(struct zebra_vrf *);
+extern void router_id_cmd_init(void);
extern void router_id_write(struct vty *);
-extern void router_id_get(struct prefix *);
+extern void router_id_get(struct prefix *, vrf_id_t);
#endif
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 85f448c..e17bb72 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -735,7 +735,8 @@
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int
-zsend_router_id_update (struct zserv *client, struct prefix *p)
+zsend_router_id_update (struct zserv *client, struct prefix *p,
+ vrf_id_t vrf_id)
{
struct stream *s;
int blen;
@@ -1181,9 +1182,9 @@
/* Router-id information is needed. */
client->ridinfo = 1;
- router_id_get (&p);
+ router_id_get (&p, VRF_DEFAULT);
- return zsend_router_id_update (client,&p);
+ return zsend_router_id_update (client, &p, VRF_DEFAULT);
}
/* Unregister zebra server router-id information. */
diff --git a/zebra/zserv.h b/zebra/zserv.h
index 5e8bcca..eaa164b 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -106,7 +106,8 @@
extern int zsend_interface_update (int, struct zserv *, struct interface *);
extern int zsend_route_multipath (int, struct zserv *, struct prefix *,
struct rib *);
-extern int zsend_router_id_update(struct zserv *, struct prefix *);
+extern int zsend_router_id_update (struct zserv *, struct prefix *,
+ vrf_id_t);
extern pid_t pid;