diff options
author | Feng Lu <lu.feng@6wind.com> | 2015-05-22 11:40:07 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2015-06-02 07:48:34 +0200 |
commit | ac19a449261bf69e83827f4bb0c6e5526277b41b (patch) | |
tree | a93cc7cde55a9c0c65da4b09fc309b503807ffda | |
parent | 7aaf4ea990398335bd40b56cc9586ab6a7178a4f (diff) | |
download | quagga-ac19a449261bf69e83827f4bb0c6e5526277b41b.tar.bz2 quagga-ac19a449261bf69e83827f4bb0c6e5526277b41b.tar.xz |
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>
-rw-r--r-- | zebra/main.c | 3 | ||||
-rw-r--r-- | zebra/rib.h | 10 | ||||
-rw-r--r-- | zebra/router-id.c | 136 | ||||
-rw-r--r-- | zebra/router-id.h | 5 | ||||
-rw-r--r-- | zebra/zserv.c | 7 | ||||
-rw-r--r-- | zebra/zserv.h | 3 |
6 files changed, 114 insertions, 50 deletions
diff --git a/zebra/main.c b/zebra/main.c index a690c9a1..c7e3b68c 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -215,6 +215,7 @@ zebra_vrf_new (vrf_id_t vrf_id, void **info) { zvrf = zebra_vrf_alloc (vrf_id); *info = (void *)zvrf; + router_id_init (zvrf); } return 0; @@ -348,7 +349,7 @@ main (int argc, char **argv) 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 dcb307ef..06aa3535 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 @@ struct zebra_vrf /* 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 bfafc272..a4eb73ae 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 @@ router_id_bad_address (struct connected *ifc) } 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; + + 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); - rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr; + zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr; - router_id_get (&p2); + 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 @@ router_id_add_address (struct connected *ifc) 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 @@ router_id_del_address (struct connected *ifc) 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 @@ DEFUN (router_id, "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 @@ DEFUN (router_id, 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 @@ DEFUN (no_router_id, "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 @@ router_id_cmp (void *a, void *b) } 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); +} + +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; - 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)); + 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_all_sorted_list->cmp = router_id_cmp; - rid_lo_sorted_list->cmp = router_id_cmp; + zvrf->rid_all_sorted_list->cmp = router_id_cmp; + zvrf->rid_lo_sorted_list->cmp = router_id_cmp; - rid_user_assigned.family = AF_INET; - rid_user_assigned.prefixlen = 32; + 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 be12bf50..46d300ee 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 85f448c4..e17bb720 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -735,7 +735,8 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) /* 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 @@ zread_router_id_add (struct zserv *client, u_short length) /* 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 5e8bccac..eaa164b9 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -106,7 +106,8 @@ extern int zsend_interface_address (int, struct zserv *, struct interface *, 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; |