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;
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 =
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;
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;
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,
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)
*/
struct list *v6;
- /* Time between ADVERTISEMENTS (centiseconds) */
- int advint;
-
/* Whether this VRRP Router is currently the master */
bool is_master;
*/
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
*/
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;
#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,
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);
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
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);
}