#include <vrrp/vrrp.api_enum.h>
#include <vrrp/vrrp.api_types.h>
-#define REPLY_MSG_ID_BASE vmp->msg_id_base
+#define REPLY_MSG_ID_BASE vrrp_main.msg_id_base
#include <vlibapi/api_helper_macros.h>
/* API message handlers */
+static void
+vl_api_vrrp_vr_update_t_handler (vl_api_vrrp_vr_update_t *mp)
+{
+ vl_api_vrrp_vr_update_reply_t *rmp;
+ vrrp_vr_config_t vr_conf;
+ u32 api_flags;
+ u32 vrrp_index = INDEX_INVALID;
+ ip46_address_t *addrs = 0;
+ int rv;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ api_flags = htonl (mp->flags);
+
+ clib_memset (&vr_conf, 0, sizeof (vr_conf));
+
+ vr_conf.sw_if_index = ntohl (mp->sw_if_index);
+ vr_conf.vr_id = mp->vr_id;
+ vr_conf.priority = mp->priority;
+ vr_conf.adv_interval = ntohs (mp->interval);
+
+ if (api_flags & VRRP_API_VR_PREEMPT)
+ vr_conf.flags |= VRRP_VR_PREEMPT;
+
+ if (api_flags & VRRP_API_VR_ACCEPT)
+ vr_conf.flags |= VRRP_VR_ACCEPT;
+
+ if (api_flags & VRRP_API_VR_UNICAST)
+ vr_conf.flags |= VRRP_VR_UNICAST;
+
+ if (api_flags & VRRP_API_VR_IPV6)
+ vr_conf.flags |= VRRP_VR_IPV6;
+
+ int i;
+ for (i = 0; i < mp->n_addrs; i++)
+ {
+ ip46_address_t *addr;
+ void *src, *dst;
+ int len;
+
+ vec_add2 (addrs, addr, 1);
+
+ if (ntohl (mp->addrs[i].af) == ADDRESS_IP4)
+ {
+ src = &mp->addrs[i].un.ip4;
+ dst = &addr->ip4;
+ len = sizeof (addr->ip4);
+ }
+ else
+ {
+ src = &mp->addrs[i].un.ip6;
+ dst = &addr->ip6;
+ len = sizeof (addr->ip6);
+ }
+
+ clib_memcpy (dst, src, len);
+ }
+
+ vr_conf.vr_addrs = addrs;
+
+ if (vr_conf.priority == 0)
+ {
+ clib_warning ("VR priority must be > 0");
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ }
+ else if (vr_conf.adv_interval == 0)
+ {
+ clib_warning ("VR advertisement interval must be > 0");
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ }
+ else if (vr_conf.vr_id == 0)
+ {
+ clib_warning ("VR ID must be > 0");
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ }
+ else
+ {
+ vrrp_index = ntohl (mp->vrrp_index);
+ rv = vrrp_vr_update (&vrrp_index, &vr_conf);
+ }
+
+ vec_free (addrs);
+
+ BAD_SW_IF_INDEX_LABEL;
+ // clang-format off
+ REPLY_MACRO2 (VL_API_VRRP_VR_UPDATE_REPLY,
+ ({
+ rmp->vrrp_index = htonl (vrrp_index);
+ }));
+ // clang-format on
+}
+
+static void
+vl_api_vrrp_vr_del_t_handler (vl_api_vrrp_vr_del_t *mp)
+{
+ vl_api_vrrp_vr_del_reply_t *rmp;
+ int rv;
+
+ rv = vrrp_vr_del (ntohl (mp->vrrp_index));
+
+ REPLY_MACRO (VL_API_VRRP_VR_DEL_REPLY);
+}
+
static void
vl_api_vrrp_vr_add_del_t_handler (vl_api_vrrp_vr_add_del_t * mp)
{
- vrrp_main_t *vmp = &vrrp_main;
vl_api_vrrp_vr_add_del_reply_t *rmp;
vrrp_vr_config_t vr_conf;
u32 api_flags;
ip46_address_t *addrs = 0;
int rv;
+ VALIDATE_SW_IF_INDEX (mp);
+
api_flags = htonl (mp->flags);
clib_memset (&vr_conf, 0, sizeof (vr_conf));
rv = VNET_API_ERROR_INVALID_VALUE;
}
else
- rv = vrrp_vr_add_del (mp->is_add, &vr_conf);
+ rv = vrrp_vr_add_del (mp->is_add, &vr_conf, NULL);
vec_free (addrs);
+ BAD_SW_IF_INDEX_LABEL;
REPLY_MACRO (VL_API_VRRP_VR_ADD_DEL_REPLY);
}
+static vl_api_vrrp_vr_state_t
+vrrp_vr_state_encode (vrrp_vr_state_t vr_state)
+{
+ if (vr_state == VRRP_VR_STATE_BACKUP)
+ return VRRP_API_VR_STATE_BACKUP;
+ if (vr_state == VRRP_VR_STATE_MASTER)
+ return VRRP_API_VR_STATE_MASTER;
+ if (vr_state == VRRP_VR_STATE_INTF_DOWN)
+ return VRRP_API_VR_STATE_INTF_DOWN;
+
+ return VRRP_API_VR_STATE_INIT;
+}
+
static void
send_vrrp_vr_details (vrrp_vr_t * vr, vl_api_registration_t * reg,
u32 context)
mp->config.flags = htonl (api_flags);
/* runtime */
- switch (vr->runtime.state)
- {
- case VRRP_VR_STATE_INIT:
- mp->runtime.state = htonl (VRRP_API_VR_STATE_INIT);
- break;
- case VRRP_VR_STATE_BACKUP:
- mp->runtime.state = htonl (VRRP_API_VR_STATE_BACKUP);
- break;
- case VRRP_VR_STATE_MASTER:
- mp->runtime.state = htonl (VRRP_API_VR_STATE_MASTER);
- break;
- case VRRP_VR_STATE_INTF_DOWN:
- mp->runtime.state = htonl (VRRP_API_VR_STATE_INTF_DOWN);
- break;
- default:
- break;
- }
+ mp->runtime.state = htonl (vrrp_vr_state_encode (vr->runtime.state));
mp->runtime.master_adv_int = htons (vr->runtime.master_adv_int);
mp->runtime.skew = htons (vr->runtime.skew);
if (vrrp_vr_is_ipv6 (vr))
{
- api_addr->af = htonl (ADDRESS_IP6);
+ api_addr->af = ADDRESS_IP6;
dst = &api_addr->un.ip6;
src = &addr->ip6;
len = sizeof (addr->ip6);
}
else
{
- api_addr->af = htonl (ADDRESS_IP4);
+ api_addr->af = ADDRESS_IP4;
dst = &api_addr->un.ip4;
src = &addr->ip4;
len = sizeof (addr->ip4);
sw_if_index = htonl (mp->sw_if_index);
- /* *INDENT-OFF* */
- pool_foreach (vr, vmp->vrs, ({
+ pool_foreach (vr, vmp->vrs) {
if (sw_if_index && (sw_if_index != ~0) &&
(sw_if_index != vr->config.sw_if_index))
continue;
send_vrrp_vr_details (vr, reg, mp->context);
- }));
- /* *INDENT-ON* */
+ }
}
static void
vl_api_vrrp_vr_start_stop_t_handler (vl_api_vrrp_vr_start_stop_t * mp)
{
- vrrp_main_t *vmp = &vrrp_main;
vl_api_vrrp_vr_start_stop_reply_t *rmp;
vrrp_vr_key_t vr_key;
int rv;
static void
vl_api_vrrp_vr_set_peers_t_handler (vl_api_vrrp_vr_set_peers_t * mp)
{
- vrrp_main_t *vmp = &vrrp_main;
vl_api_vrrp_vr_set_peers_reply_t *rmp;
vrrp_vr_key_t vr_key;
ip46_address_t *peer_addrs = 0;
if (vrrp_vr_is_ipv6 (vr))
{
- api_addr->af = htonl (ADDRESS_IP6);
+ api_addr->af = ADDRESS_IP6;
dst = &api_addr->un.ip6;
src = &addr->ip6;
len = sizeof (addr->ip6);
}
else
{
- api_addr->af = htonl (ADDRESS_IP4);
+ api_addr->af = ADDRESS_IP4;
dst = &api_addr->un.ip4;
src = &addr->ip4;
len = sizeof (addr->ip4);
return;
}
- /* *INDENT-OFF* */
- pool_foreach (vr, vmp->vrs, ({
+ pool_foreach (vr, vmp->vrs) {
if (!vec_len (vr->config.peer_addrs))
continue;
send_vrrp_vr_details (vr, reg, mp->context);
- }));
- /* *INDENT-ON* */
+ }
}
static void
vl_api_vrrp_vr_track_if_add_del_t_handler
(vl_api_vrrp_vr_track_if_add_del_t * mp)
{
- vrrp_main_t *vmp = &vrrp_main;
vl_api_vrrp_vr_track_if_add_del_reply_t *rmp;
vrrp_vr_t *vr;
vrrp_vr_tracking_if_t *track_if, *track_ifs = 0;
return;
}
- /* *INDENT-OFF* */
- pool_foreach (vr, vmp->vrs, ({
+ pool_foreach (vr, vmp->vrs) {
if (!vec_len (vr->tracking.interfaces))
continue;
send_vrrp_vr_track_if_details (vr, reg, mp->context);
- }));
- /* *INDENT-ON* */
+ }
+}
+
+static void
+send_vrrp_vr_event (vpe_client_registration_t * reg,
+ vl_api_registration_t * vl_reg,
+ vrrp_vr_t * vr, vrrp_vr_state_t new_state)
+{
+ vrrp_main_t *vmp = &vrrp_main;
+ vl_api_vrrp_vr_event_t *mp;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = ntohs (VL_API_VRRP_VR_EVENT + vmp->msg_id_base);
+ mp->client_index = reg->client_index;
+ mp->pid = reg->client_pid;
+ mp->vr.sw_if_index = ntohl (vr->config.sw_if_index);
+ mp->vr.vr_id = vr->config.vr_id;
+ mp->vr.is_ipv6 = ((vr->config.flags & VRRP_VR_IPV6) != 0);
+
+ mp->old_state = htonl (vrrp_vr_state_encode (vr->runtime.state));
+ mp->new_state = htonl (vrrp_vr_state_encode (new_state));
+
+ vl_api_send_msg (vl_reg, (u8 *) mp);
+}
+
+void
+vrrp_vr_event (vrrp_vr_t * vr, vrrp_vr_state_t new_state)
+{
+ vpe_api_main_t *vam = &vpe_api_main;
+ vpe_client_registration_t *reg;
+ vl_api_registration_t *vl_reg;
+
+ pool_foreach (reg, vam->vrrp_vr_events_registrations)
+ {
+ vl_reg = vl_api_client_index_to_registration (reg->client_index);
+ if (vl_reg)
+ send_vrrp_vr_event (reg, vl_reg, vr, new_state);
+ }
}
+pub_sub_handler (vrrp_vr_events, VRRP_VR_EVENTS);
+
/* Set up the API message handling tables */
#include <vrrp/vrrp.api.c>
clib_error_t *
return 0;
}
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON