]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: maintain the router-id per VRF
authorFeng Lu <lu.feng@6wind.com>
Fri, 22 May 2015 09:40:07 +0000 (11:40 +0200)
committerVipin Kumar <vipin@cumulusnetworks.com>
Fri, 30 Oct 2015 07:19:15 +0000 (00:19 -0700)
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

zebra/main.c
zebra/rib.h
zebra/router-id.c
zebra/router-id.h
zebra/zserv.c
zebra/zserv.h

index 92a0c0b31be13b380c963eacbea81f232d138bc5..95a0e438e82d95a358756dabe7f7387998aa765b 100644 (file)
@@ -224,6 +224,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;
@@ -360,7 +361,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 ();
index b76231f8a9c90c663f89afca3b9550ca288f6a98..ddc6a49dcd0aa060665d369e94ed6bc79e5bf7c2 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _ZEBRA_RIB_H
 #define _ZEBRA_RIB_H
 
+#include "linklist.h"
 #include "prefix.h"
 #include "table.h"
 #include "queue.h"
@@ -315,6 +316,15 @@ struct zebra_vrf
 
   /* Routing tables off of main table for redistribute table */
   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;
 };
 
 /*
index a17cd9e57fd60695cc23e219ba7d787889897e1a..2b470c6dbe7c33fd10ac61a66e325024c08e9141 100644 (file)
 #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"
 
-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;
@@ -77,44 +73,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;
 
-  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
@@ -125,28 +132,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
@@ -158,36 +166,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,
@@ -197,6 +220,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)
@@ -205,11 +229,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",
@@ -217,16 +251,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)
 {
@@ -237,18 +282,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;
 }
index be12bf502965bb63d7c503183ede7b62ac694f3a..46d300eeac579b131aca7d27e96101579225f748 100644 (file)
@@ -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
index 052c797f8babb6a42c45ec5f39dc3b05870f26ed..7a5700210f3c80b310ca40c74404bc4df948f9b8 100644 (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. */
 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;
@@ -1623,9 +1624,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. */
index ace37152477545ac3e91232abda0f2a04a4461c7..29b3145672ca352dbf42c1dbf1c8e0258cb6bc61 100644 (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_redistribute_route (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;
 
 extern void zserv_create_header(struct stream *s, uint16_t cmd);