]> git.puffer.fish Git - matthieu/frr.git/commitdiff
vrrpd: same VRID, different interface
authorQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 29 Jan 2019 20:51:35 +0000 (20:51 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 17 May 2019 00:27:08 +0000 (00:27 +0000)
Identify VRRP instances by the 2-tuple (ifp, vrid) instead of by VRID,
allowing the same instance to be configured on different interfaces.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
vrrpd/vrrp.c
vrrpd/vrrp.h
vrrpd/vrrp_vty.c

index 08517c79d11606ff53a36e32bfc123e1a2dbc09d..682c85adb5b8e8829c6917877c7dab0a33d08b11 100644 (file)
@@ -305,7 +305,7 @@ static void vrrp_router_destroy(struct vrrp_router *r)
 
 struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
 {
-       struct vrrp_vrouter *vr = vrrp_lookup(vrid);
+       struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
 
        if (vr)
                return vr;
@@ -332,15 +332,15 @@ void vrrp_vrouter_destroy(struct vrrp_vrouter *vr)
 {
        vrrp_router_destroy(vr->v4);
        vrrp_router_destroy(vr->v6);
-       vr->ifp = NULL;
        hash_release(vrrp_vrouters_hash, vr);
        XFREE(MTYPE_TMP, vr);
 }
 
-struct vrrp_vrouter *vrrp_lookup(uint8_t vrid)
+struct vrrp_vrouter *vrrp_lookup(struct interface *ifp, uint8_t vrid)
 {
        struct vrrp_vrouter vr;
        vr.vrid = vrid;
+       vr.ifp = ifp;
 
        return hash_lookup(vrrp_vrouters_hash, &vr);
 }
@@ -1173,7 +1173,11 @@ static unsigned int vrrp_hash_key(void *arg)
 {
        struct vrrp_vrouter *vr = arg;
 
-       return vr->vrid;
+       char key[IFNAMSIZ + 64];
+       snprintf(key, sizeof(key), "%d%s%u", vr->ifp->ifindex, vr->ifp->name,
+                vr->vrid);
+
+       return string_hash_make(key);
 }
 
 static bool vrrp_hash_cmp(const void *arg1, const void *arg2)
@@ -1181,7 +1185,12 @@ static bool vrrp_hash_cmp(const void *arg1, const void *arg2)
        const struct vrrp_vrouter *vr1 = arg1;
        const struct vrrp_vrouter *vr2 = arg2;
 
-       return vr1->vrid == vr2->vrid;
+       if (vr1->ifp != vr2->ifp)
+               return 0;
+       if (vr1->vrid != vr2->vrid)
+               return 0;
+
+       return 1;
 }
 
 void vrrp_init(void)
index d060b95dfab2a4167d7254bb5de6dea0cdb0f109..e8535cb6918e7d620458bd9c3efdc196530da032 100644 (file)
@@ -333,6 +333,6 @@ int vrrp_event(struct vrrp_router *r, int event);
 /*
  * Find VRRP Virtual Router by Virtual Router ID
  */
-struct vrrp_vrouter *vrrp_lookup(uint8_t vrid);
+struct vrrp_vrouter *vrrp_lookup(struct interface *ifp, uint8_t vrid);
 
 #endif /* __VRRP_H__ */
index ff8f1e68e696b8b07893a367a1acd2dad0fc818d..ca2ef1842a65298e4b57e2939a8a3858384ad43c 100644 (file)
@@ -40,9 +40,9 @@
 #define VRRP_ADVINT_STR "Virtual Router Advertisement Interval\n"
 #define VRRP_IP_STR "Virtual Router IPv4 address\n"
 
-#define VROUTER_GET_VTY(_vty, _vrid, _vr)                                      \
+#define VROUTER_GET_VTY(_vty, _ifp, _vrid, _vr)                                \
        do {                                                                   \
-               _vr = vrrp_lookup(_vrid);                                      \
+               _vr = vrrp_lookup(_ifp, _vrid);                                \
                if (!_vr) {                                                    \
                        vty_out(_vty,                                          \
                                "%% Please configure VRRP instance %u\n",      \
@@ -72,7 +72,7 @@ DEFPY(vrrp_vrid,
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
 
-       struct vrrp_vrouter *vr = vrrp_lookup(vrid);
+       struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
 
        if (no && vr)
                vrrp_vrouter_destroy(vr);
@@ -97,13 +97,15 @@ DEFPY(vrrp_priority,
       VRRP_PRIORITY_STR
       "Priority value")
 {
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+
        struct vrrp_vrouter *vr;
        struct vrrp_router *r;
        bool nr[2] = { false, false };
        int ret = CMD_SUCCESS;
        uint8_t newprio = no ? VRRP_DEFAULT_PRIORITY : priority;
 
-       VROUTER_GET_VTY(vty, vrid, vr);
+       VROUTER_GET_VTY(vty, ifp, vrid, vr);
 
        r = vr->v4;
        for (int i = 0; i < 2; i++) {
@@ -141,10 +143,12 @@ DEFPY(vrrp_advertisement_interval,
       NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR
       "Advertisement interval in centiseconds")
 {
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+
        struct vrrp_vrouter *vr;
        uint16_t newadvint = no ? VRRP_DEFAULT_ADVINT : advertisement_interval;
 
-       VROUTER_GET_VTY(vty, vrid, vr);
+       VROUTER_GET_VTY(vty, ifp, vrid, vr);
        vrrp_set_advertisement_interval(vr, newadvint);
 
        return CMD_SUCCESS;
@@ -159,10 +163,12 @@ DEFPY(vrrp_ip,
       "Add IPv4 address\n"
       VRRP_IP_STR)
 {
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+
        struct vrrp_vrouter *vr;
        int ret;
 
-       VROUTER_GET_VTY(vty, vrid, vr);
+       VROUTER_GET_VTY(vty, ifp, vrid, vr);
        vrrp_add_ipv4(vr, ip);
 
        if (vr->v4->fsm.state == VRRP_STATE_INITIALIZE) {
@@ -189,10 +195,12 @@ DEFPY(vrrp_ip6,
       "Add IPv6 address\n"
       VRRP_IP_STR)
 {
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+
        struct vrrp_vrouter *vr;
        int ret;
 
-       VROUTER_GET_VTY(vty, vrid, vr);
+       VROUTER_GET_VTY(vty, ifp, vrid, vr);
        vrrp_add_ipv6(vr, ipv6);
 
        if (vr->v6->fsm.state == VRRP_STATE_INITIALIZE) {
@@ -287,26 +295,28 @@ static void vrrp_show(struct vty *vty, struct vrrp_vrouter *vr)
 
 DEFPY(vrrp_vrid_show,
       vrrp_vrid_show_cmd,
-      "show vrrp [(1-255)$vrid]",
+      "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid]",
       SHOW_STR
       VRRP_STR
+      INTERFACE_STR
+      "Only show VRRP instances on this interface\n"
       VRRP_VRID_STR)
 {
        struct vrrp_vrouter *vr;
+       struct listnode *ln;
+       struct list *ll = hash_to_list(vrrp_vrouters_hash);
 
-       if (vrid) {
-               VROUTER_GET_VTY(vty, vrid, vr);
-               vrrp_show(vty, vr);
-       } else {
-               struct list *ll = hash_to_list(vrrp_vrouters_hash);
-               struct listnode *ln;
-
-               for (ALL_LIST_ELEMENTS_RO(ll, ln, vr))
-                       vrrp_show(vty, vr);
+       for (ALL_LIST_ELEMENTS_RO(ll, ln, vr)) {
+               if (ifn && !strmatch(ifn, vr->ifp->name))
+                       continue;
+               if (vrid && vrid != vr->vrid)
+                       continue;
 
-               list_delete_and_null(&ll);
+               vrrp_show(vty, vr);
        }
 
+       list_delete(&ll);
+
        return CMD_SUCCESS;
 }