From: Quentin Young Date: Tue, 29 Jan 2019 20:51:35 +0000 (+0000) Subject: vrrpd: same VRID, different interface X-Git-Tag: base_7.2~330^2~113 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=4f0b6b451a92fef15408320adaaacc71bc783a1e;p=mirror%2Ffrr.git vrrpd: same VRID, different interface 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 --- diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index 08517c79d1..682c85adb5 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -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) diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h index d060b95dfa..e8535cb691 100644 --- a/vrrpd/vrrp.h +++ b/vrrpd/vrrp.h @@ -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__ */ diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index ff8f1e68e6..ca2ef1842a 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -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; }