]> git.puffer.fish Git - matthieu/frr.git/commitdiff
vrrpd: config commands, enable ARP
authorQuentin Young <qlyoung@cumulusnetworks.com>
Tue, 4 Dec 2018 21:28:25 +0000 (21:28 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 17 May 2019 00:27:08 +0000 (00:27 +0000)
* Allow configuring priority
* Allow configuring IPv4 addresses
* Add show command for vrouters
* Fix hash comparison function
* Fix ARP packetization bugs
* Enable sending of gratuitous ARP

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

index 23f144a792aabe43f7fbfcafe586c17802a89bd5..fd0c62cb0d7b203f515319b9067d6df84714a4d2 100644 (file)
@@ -58,21 +58,7 @@ static void vrrp_mac_set(struct ethaddr *mac, bool v6, uint8_t vrid)
        mac->octet[5] = vrid;
 }
 
-/*
- * Sets advertisement_interval and master_adver_interval on a Virtual Router,
- * then recalculates and sets skew_time and master_down_interval based on these
- * values.
- *
- * vr
- *    Virtual Router to operate on
- *
- * advertisement_interval
- *    Advertisement_Interval to set
- *
- * master_adver_interval
- *    Master_Adver_Interval to set
- */
-static void vrrp_update_times(struct vrrp_vrouter *vr, uint16_t advertisement_interval,
+void vrrp_update_times(struct vrrp_vrouter *vr, uint16_t advertisement_interval,
                       uint16_t master_adver_interval)
 {
        vr->advertisement_interval = advertisement_interval;
@@ -83,6 +69,25 @@ static void vrrp_update_times(struct vrrp_vrouter *vr, uint16_t advertisement_in
        vr->master_down_interval /= 256;
 }
 
+void vrrp_update_priority(struct vrrp_vrouter *vr, uint8_t priority)
+{
+       if (vr->priority == priority)
+               return;
+
+       vr->priority = priority;
+       /* Timers depend on priority value, need to recalculate them */
+       vrrp_update_times(vr, vr->advertisement_interval,
+                         vr->master_adver_interval);
+}
+
+void vrrp_add_ip(struct vrrp_vrouter *vr, struct in_addr v4)
+{
+       struct in_addr *v4_ins = XCALLOC(MTYPE_TMP, sizeof(struct in_addr));
+
+       *v4_ins = v4;
+       listnode_add(vr->v4, v4_ins);
+}
+
 struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
 {
        struct vrrp_vrouter *vr =
@@ -93,7 +98,6 @@ struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
        vr->vrid = vrid;
        vr->v4 = list_new();
        vr->v6 = list_new();
-       vr->advint = VRRP_DEFAULT_ADVINT;
        vr->is_master = false;
        vr->priority = VRRP_DEFAULT_PRIORITY;
        vr->advertisement_interval = VRRP_DEFAULT_ADVINT;
@@ -111,6 +115,17 @@ struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
        return vr;
 }
 
+void vrrp_vrouter_destroy(struct vrrp_vrouter *vr)
+{
+       if (vr->sock >= 0)
+               close(vr->sock);
+       vr->ifp = NULL;
+       list_delete(&vr->v4);
+       list_delete(&vr->v6);
+       hash_release(vrrp_vrouters_hash, vr);
+       XFREE(MTYPE_TMP, vr);
+}
+
 struct vrrp_vrouter *vrrp_lookup(uint8_t vrid)
 {
        struct vrrp_vrouter vr;
@@ -302,7 +317,7 @@ static int vrrp_startup(struct vrrp_vrouter *vr)
 
        if (vr->priority == VRRP_PRIO_MASTER) {
                vrrp_send_advertisement(vr);
-               /* vrrp_garp_send(vr); */
+               vrrp_garp_send_all(vr);
 
                thread_add_timer_msec(master, vrrp_adver_timer_expire, vr,
                                      vr->advertisement_interval * 10,
@@ -360,7 +375,7 @@ 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;
+       return vr1->vrid == vr2->vrid;
 }
 
 void vrrp_init(void)
index f1b93b924218d1b302b8ef5e3de318620da2bfbe..240144d3b39eb155eb03fc99d56cee5110074545 100644 (file)
@@ -67,9 +67,6 @@ struct vrrp_vrouter {
         */
        struct list *v6;
 
-       /* Time between ADVERTISEMENTS (centiseconds) */
-       int advint;
-
        /* Whether this VRRP Router is currently the master */
        bool is_master;
 
@@ -151,6 +148,52 @@ void vrrp_init(void);
  */
 struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid);
 
+/*
+ * Destroy a VRRP Virtual Router.
+ */
+void vrrp_vrouter_destroy(struct vrrp_vrouter *vr);
+
+/*
+ * Sets advertisement_interval and master_adver_interval on a Virtual Router,
+ * then recalculates and sets skew_time and master_down_interval based on these
+ * values.
+ *
+ * vr
+ *    Virtual Router to operate on
+ *
+ * advertisement_interval
+ *    Advertisement_Interval to set
+ *
+ * master_adver_interval
+ *    Master_Adver_Interval to set
+ */
+void vrrp_update_times(struct vrrp_vrouter *vr, uint16_t advertisement_interval,
+                      uint16_t master_adver_interval);
+
+/*
+ * Change the priority of a VRRP Virtual Router.
+ *
+ * Recalculates timers using new priority.
+ *
+ * vr
+ *    Virtual Router to change priority of
+ *
+ * priority
+ *    New priority
+ */
+void vrrp_update_priority(struct vrrp_vrouter *vr, uint8_t priority);
+
+/*
+ * Add IPv4 address to a VRRP Virtual Router
+ *
+ * vr
+ *    Virtual Router to add IPv4 address to
+ *
+ * v4
+ *    Address to add
+ */
+void vrrp_add_ip(struct vrrp_vrouter *vr, struct in_addr v4);
+
 /*
  * Find VRRP Virtual Router by Virtual Router ID
  */
index a67af4e10472ab271349688fa0ca3a11d47afca3..f917c7ec3aa9392b76b772b6307f3cdf7a8a2376 100644 (file)
@@ -93,18 +93,18 @@ static ssize_t vrrp_build_garp(uint8_t *buf, struct interface *ifp,
        arph->ar_hln = ifp->hw_addr_len;
        arph->ar_pln = sizeof(struct in_addr);
        arph->ar_op = htons(ARPOP_REQUEST);
-       arp_ptr = (uint8_t *)(arph + sizeof(struct arphdr));
+       arp_ptr = (uint8_t *)(arph + 1);
        /* Source MAC: us */
        memcpy(arp_ptr, ifp->hw_addr, ifp->hw_addr_len);
        arp_ptr += ifp->hw_addr_len;
        /* Source IP: us */
-       memcpy(arp_ptr, &v4, sizeof(struct in_addr));
+       memcpy(arp_ptr, v4, sizeof(struct in_addr));
        arp_ptr += sizeof(struct in_addr);
        /* Dest MAC: broadcast */
        memset(arp_ptr, 0xFF, ETH_ALEN);
        arp_ptr += ifp->hw_addr_len;
        /* Dest IP: us */
-       memcpy(arp_ptr, &v4, sizeof(struct in_addr));
+       memcpy(arp_ptr, v4, sizeof(struct in_addr));
        arp_ptr += sizeof(struct in_addr);
 
        return arp_ptr - buf;
index f30aadd626afe40fe7276bed5432c8c4c65e1cff..6c7fc5f1947962377ce557b165a9744f97de9bf7 100644 (file)
 #include "command.h"
 #include "vty.h"
 #include "if.h"
+#include "termtable.h"
+#include "prefix.h"
 
 #include "vrrp.h"
 #include "vrrp_vty.h"
 #include "vrrp_memory.h"
-//#ifndef VTYSH_EXTRACT_PL
-//#include "vrrp/vrrp_vty_clippy.c"
-//#endif
+#ifndef VTYSH_EXTRACT_PL
+#include "vrrpd/vrrp_vty_clippy.c"
+#endif
 
 
 #define VRRP_STR "Virtual Router Redundancy Protocol\n"
 #define VRRP_VRID_STR "Virtual Router ID\n"
+#define VRRP_PRIORITY_STR "Virtual Router Priority\n"
+#define VRRP_IP_STR "Virtual Router IPv4 address\n"
+
+#define VROUTER_GET_VTY(_vty, _vrid, _vr)                                      \
+       do {                                                                   \
+               _vr = vrrp_lookup(_vrid);                                      \
+               if (!_vr) {                                                    \
+                       vty_out(_vty,                                          \
+                               "%% Please configure VRRP instance %u\n",      \
+                               (unsigned int)_vrid);                          \
+                       return CMD_WARNING_CONFIG_FAILED;                      \
+               }                                                              \
+       } while (0);
 
 DEFUN_NOSH (show_debugging_vrrpd,
            show_debugging_vrrpd_cmd,
@@ -46,19 +61,14 @@ DEFUN_NOSH (show_debugging_vrrpd,
        return CMD_SUCCESS;
 }
 
-DEFUN(vrrp_vrid,
+DEFPY(vrrp_vrid,
       vrrp_vrid_cmd,
-      "[no] vrrp (1-255)",
+      "[no] vrrp (1-255)$vrid",
       NO_STR
       VRRP_STR
       VRRP_VRID_STR)
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
-       int idx = 0;
-       uint8_t vrid;
-
-       argv_find(argv, argc, "(1-255)", &idx);
-       vrid = strtoul(argv[idx]->arg, NULL, 10);
 
        struct vrrp_vrouter *vr = vrrp_vrouter_create(ifp, vrid);
        int ret = vrrp_event(vr, VRRP_EVENT_STARTUP);
@@ -70,6 +80,107 @@ DEFUN(vrrp_vrid,
        return CMD_SUCCESS;
 }
 
+DEFPY(vrrp_priority,
+      vrrp_priority_cmd,
+      "[no] vrrp (1-255)$vrid priority (1-254)",
+      NO_STR
+      VRRP_STR
+      VRRP_VRID_STR
+      VRRP_PRIORITY_STR
+      "Priority value\n")
+{
+       struct vrrp_vrouter *vr;
+
+       VROUTER_GET_VTY(vty, vrid, vr);
+       vrrp_update_priority(vr, priority);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(vrrp_ip,
+      vrrp_ip_cmd,
+      "[no] vrrp (1-255)$vrid ip A.B.C.D$ip",
+      NO_STR
+      VRRP_STR
+      VRRP_VRID_STR
+      "Add IP address\n"
+      VRRP_IP_STR)
+{
+       struct vrrp_vrouter *vr;
+
+       VROUTER_GET_VTY(vty, vrid, vr);
+       vrrp_add_ip(vr, ip);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(vrrp_vrid_show,
+      vrrp_vrid_show_cmd,
+      "show vrrp [(1-255)$vrid]",
+      SHOW_STR
+      VRRP_STR
+      VRRP_VRID_STR)
+{
+       struct vrrp_vrouter *vr;
+       char ethstr[ETHER_ADDR_STRLEN];
+       char ipstr[INET_ADDRSTRLEN];
+       const char *stastr;
+
+       VROUTER_GET_VTY(vty, vrid, vr);
+
+       switch (vr->fsm.state) {
+       case VRRP_STATE_INITIALIZE:
+               stastr = "Initialize";
+               break;
+       case VRRP_STATE_MASTER:
+               stastr = "Master";
+               break;
+       case VRRP_STATE_BACKUP:
+               stastr = "Backup";
+               break;
+       }
+
+       struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+
+       ttable_add_row(tt, "%s|%" PRIu32, "Virtual Router ID", vr->vrid);
+       prefix_mac2str(&vr->vr_mac_v4, ethstr, sizeof(ethstr));
+       ttable_add_row(tt, "%s|%s", "Virtual MAC", ethstr);
+       ttable_add_row(tt, "%s|%s", "Status", stastr);
+       ttable_add_row(tt, "%s|%" PRIu8, "Priority", vr->priority);
+       ttable_add_row(tt, "%s|%s", "Preempt Mode",
+                      vr->preempt_mode ? "Yes" : "No");
+       ttable_add_row(tt, "%s|%s", "Accept Mode",
+                      vr->accept_mode ? "Yes" : "No");
+       ttable_add_row(tt, "%s|%" PRIu16, "Advertisement Interval",
+                      vr->advertisement_interval);
+       ttable_add_row(tt, "%s|%" PRIu16, "Master Advertisement Interval",
+                      vr->master_adver_interval);
+       ttable_add_row(tt, "%s|%" PRIu16, "Skew Time", vr->skew_time);
+       ttable_add_row(tt, "%s|%" PRIu16, "Master Down Interval",
+                      vr->master_down_interval);
+       ttable_add_row(tt, "%s|%u", "IPv4 Addresses", vr->v4->count);
+
+       char *table = ttable_dump(tt, "\n");
+       vty_out(vty, "\n%s\n", table);
+       XFREE(MTYPE_TMP, table);
+       ttable_del(tt);
+
+       /* Dump IPv4 Addresses */
+       if (vr->v4->count) {
+               vty_out(vty, " IPv4 Addresses\n");
+               vty_out(vty, " --------------\n");
+               struct listnode *ln;
+               struct in_addr *v4;
+               for (ALL_LIST_ELEMENTS_RO(vr->v4, ln, v4)) {
+                       inet_ntop(AF_INET, v4, ipstr, sizeof(ipstr));
+                       vty_out(vty, " %s\n", ipstr);
+               }
+               vty_out(vty, "\n");
+       }
+
+       return CMD_SUCCESS;
+}
+
 static struct cmd_node interface_node = {
        INTERFACE_NODE,
        "%s(config-if)# ", 1
@@ -80,5 +191,8 @@ void vrrp_vty_init(void)
        install_node(&interface_node, NULL);
        if_cmd_init();
        install_element(VIEW_NODE, &show_debugging_vrrpd_cmd);
+       install_element(VIEW_NODE, &vrrp_vrid_show_cmd);
        install_element(INTERFACE_NODE, &vrrp_vrid_cmd);
+       install_element(INTERFACE_NODE, &vrrp_priority_cmd);
+       install_element(INTERFACE_NODE, &vrrp_ip_cmd);
 }