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>

Conflicts:
	zebra/rib.h

Conflicts:
	zebra/rib.h
	zebra/router-id.c
	zebra/zserv.h
This commit is contained in:
Feng Lu 2015-05-22 11:40:07 +02:00 committed by Vipin Kumar
parent 8f527c5e7e
commit c6ffe64543
6 changed files with 118 additions and 49 deletions

View file

@ -224,6 +224,7 @@ zebra_vrf_new (vrf_id_t vrf_id, void **info)
{ {
zvrf = zebra_vrf_alloc (vrf_id); zvrf = zebra_vrf_alloc (vrf_id);
*info = (void *)zvrf; *info = (void *)zvrf;
router_id_init (zvrf);
} }
return 0; return 0;
@ -360,7 +361,7 @@ main (int argc, char **argv)
rib_init (); rib_init ();
zebra_if_init (); zebra_if_init ();
zebra_debug_init (); zebra_debug_init ();
router_id_init(); router_id_cmd_init ();
zebra_vty_init (); zebra_vty_init ();
access_list_init (); access_list_init ();
prefix_list_init (); prefix_list_init ();

View file

@ -23,6 +23,7 @@
#ifndef _ZEBRA_RIB_H #ifndef _ZEBRA_RIB_H
#define _ZEBRA_RIB_H #define _ZEBRA_RIB_H
#include "linklist.h"
#include "prefix.h" #include "prefix.h"
#include "table.h" #include "table.h"
#include "queue.h" #include "queue.h"
@ -315,6 +316,15 @@ struct zebra_vrf
/* Routing tables off of main table for redistribute table */ /* Routing tables off of main table for redistribute table */
struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_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;
}; };
/* /*

View file

@ -36,16 +36,12 @@
#include "log.h" #include "log.h"
#include "table.h" #include "table.h"
#include "rib.h" #include "rib.h"
#include "vrf.h"
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/router-id.h" #include "zebra/router-id.h"
#include "zebra/redistribute.h" #include "zebra/redistribute.h"
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 */ /* master zebra server structure */
extern struct zebra_t zebrad; extern struct zebra_t zebrad;
@ -77,44 +73,55 @@ router_id_bad_address (struct connected *ifc)
} }
void void
router_id_get (struct prefix *p) router_id_get (struct prefix *p, vrf_id_t vrf_id)
{ {
struct listnode *node; struct listnode *node;
struct connected *c; struct connected *c;
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
p->u.prefix4.s_addr = 0; p->u.prefix4.s_addr = 0;
p->family = AF_INET; p->family = AF_INET;
p->prefixlen = 32; p->prefixlen = 32;
if (rid_user_assigned.u.prefix4.s_addr) if (zvrf->rid_user_assigned.u.prefix4.s_addr)
p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr; p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
else if (!list_isempty (rid_lo_sorted_list)) 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); c = listgetdata (node);
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; 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); c = listgetdata (node);
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
} }
} }
static void static void
router_id_set (struct prefix *p) router_id_set (struct prefix *p, vrf_id_t vrf_id)
{ {
struct prefix p2; struct prefix p2;
struct listnode *node; struct listnode *node;
struct zserv *client; 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)) 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 void
@ -125,28 +132,29 @@ router_id_add_address (struct connected *ifc)
struct prefix before; struct prefix before;
struct prefix after; struct prefix after;
struct zserv *client; struct zserv *client;
struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
if (router_id_bad_address (ifc)) if (router_id_bad_address (ifc))
return; return;
router_id_get (&before); router_id_get (&before, zvrf->vrf_id);
if (!strncmp (ifc->ifp->name, "lo", 2) if (!strncmp (ifc->ifp->name, "lo", 2)
|| !strncmp (ifc->ifp->name, "dummy", 5)) || !strncmp (ifc->ifp->name, "dummy", 5))
l = rid_lo_sorted_list; l = zvrf->rid_lo_sorted_list;
else else
l = rid_all_sorted_list; l = zvrf->rid_all_sorted_list;
if (!router_id_find_node (l, ifc)) if (!router_id_find_node (l, ifc))
listnode_add_sort (l, ifc); listnode_add_sort (l, ifc);
router_id_get (&after); router_id_get (&after, zvrf->vrf_id);
if (prefix_same (&before, &after)) if (prefix_same (&before, &after))
return; return;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) 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 void
@ -158,36 +166,51 @@ router_id_del_address (struct connected *ifc)
struct prefix before; struct prefix before;
struct listnode *node; struct listnode *node;
struct zserv *client; struct zserv *client;
struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
if (router_id_bad_address (ifc)) if (router_id_bad_address (ifc))
return; return;
router_id_get (&before); router_id_get (&before, zvrf->vrf_id);
if (!strncmp (ifc->ifp->name, "lo", 2) if (!strncmp (ifc->ifp->name, "lo", 2)
|| !strncmp (ifc->ifp->name, "dummy", 5)) || !strncmp (ifc->ifp->name, "dummy", 5))
l = rid_lo_sorted_list; l = zvrf->rid_lo_sorted_list;
else else
l = rid_all_sorted_list; l = zvrf->rid_all_sorted_list;
if ((c = router_id_find_node (l, ifc))) if ((c = router_id_find_node (l, ifc)))
listnode_delete (l, c); listnode_delete (l, c);
router_id_get (&after); router_id_get (&after, zvrf->vrf_id);
if (prefix_same (&before, &after)) if (prefix_same (&before, &after))
return; return;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) 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 void
router_id_write (struct vty *vty) router_id_write (struct vty *vty)
{ {
if (rid_user_assigned.u.prefix4.s_addr) struct zebra_vrf *zvrf;
vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4), vrf_iter_t iter;
VTY_NEWLINE);
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, DEFUN (router_id,
@ -197,6 +220,7 @@ DEFUN (router_id,
"IP address to use for router-id\n") "IP address to use for router-id\n")
{ {
struct prefix rid; struct prefix rid;
vrf_id_t vrf_id = VRF_DEFAULT;
rid.u.prefix4.s_addr = inet_addr (argv[0]); rid.u.prefix4.s_addr = inet_addr (argv[0]);
if (!rid.u.prefix4.s_addr) if (!rid.u.prefix4.s_addr)
@ -205,11 +229,21 @@ DEFUN (router_id,
rid.prefixlen = 32; rid.prefixlen = 32;
rid.family = AF_INET; 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; 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, DEFUN (no_router_id,
no_router_id_cmd, no_router_id_cmd,
"no router-id", "no router-id",
@ -217,16 +251,27 @@ DEFUN (no_router_id,
"Remove the manually configured router-id\n") "Remove the manually configured router-id\n")
{ {
struct prefix rid; struct prefix rid;
vrf_id_t vrf_id = VRF_DEFAULT;
rid.u.prefix4.s_addr = 0; rid.u.prefix4.s_addr = 0;
rid.prefixlen = 0; rid.prefixlen = 0;
rid.family = AF_INET; 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; 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 static int
router_id_cmp (void *a, void *b) router_id_cmp (void *a, void *b)
{ {
@ -237,18 +282,27 @@ router_id_cmp (void *a, void *b)
} }
void void
router_id_init (void) router_id_cmd_init (void)
{ {
install_element (CONFIG_NODE, &router_id_cmd); install_element (CONFIG_NODE, &router_id_cmd);
install_element (CONFIG_NODE, &no_router_id_cmd); install_element (CONFIG_NODE, &no_router_id_cmd);
install_element (CONFIG_NODE, &router_id_vrf_cmd);
memset (rid_all_sorted_list, 0, sizeof (_rid_all_sorted_list)); install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
memset (rid_lo_sorted_list, 0, sizeof (_rid_lo_sorted_list)); }
memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));
void
rid_all_sorted_list->cmp = router_id_cmp; router_id_init (struct zebra_vrf *zvrf)
rid_lo_sorted_list->cmp = router_id_cmp; {
zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
rid_user_assigned.family = AF_INET; zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
rid_user_assigned.prefixlen = 32;
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));
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;
} }

View file

@ -33,8 +33,9 @@
extern void router_id_add_address(struct connected *); extern void router_id_add_address(struct connected *);
extern void router_id_del_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_write(struct vty *);
extern void router_id_get(struct prefix *); extern void router_id_get(struct prefix *, vrf_id_t);
#endif #endif

View file

@ -948,7 +948,8 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int 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; struct stream *s;
int blen; int blen;
@ -1623,9 +1624,9 @@ zread_router_id_add (struct zserv *client, u_short length)
/* Router-id information is needed. */ /* Router-id information is needed. */
client->ridinfo = 1; 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. */ /* Unregister zebra server router-id information. */

View file

@ -151,7 +151,9 @@ extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *, u_
extern int zsend_interface_update (int, struct zserv *, struct interface *); extern int zsend_interface_update (int, struct zserv *, struct interface *);
extern int zsend_redistribute_route (int, struct zserv *, struct prefix *, extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
struct rib *); 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; extern pid_t pid;
extern void zserv_create_header(struct stream *s, uint16_t cmd); extern void zserv_create_header(struct stream *s, uint16_t cmd);