X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fvrrp%2Fvrrp_api.c;h=5eb0ffc6f20be9533031e3d061163cb58bc15874;hb=39c40fa349505b584472678318ef8548ab203aed;hp=9ef90203f32c270cfe16481a0e767c89d960f3df;hpb=bdfdc4a480260a874de9b828723b01f119b57fbe;p=vpp.git diff --git a/src/plugins/vrrp/vrrp_api.c b/src/plugins/vrrp/vrrp_api.c index 9ef90203f32..5eb0ffc6f20 100644 --- a/src/plugins/vrrp/vrrp_api.c +++ b/src/plugins/vrrp/vrrp_api.c @@ -20,14 +20,116 @@ #include #include -#define REPLY_MSG_ID_BASE vmp->msg_id_base +#define REPLY_MSG_ID_BASE vrrp_main.msg_id_base #include /* 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; @@ -104,7 +206,7 @@ vl_api_vrrp_vr_add_del_t_handler (vl_api_vrrp_vr_add_del_t * mp) 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); @@ -112,6 +214,19 @@ vl_api_vrrp_vr_add_del_t_handler (vl_api_vrrp_vr_add_del_t * mp) 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) @@ -150,23 +265,7 @@ send_vrrp_vr_details (vrrp_vr_t * vr, vl_api_registration_t * reg, 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); @@ -186,14 +285,14 @@ send_vrrp_vr_details (vrrp_vr_t * vr, vl_api_registration_t * reg, 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); @@ -220,21 +319,20 @@ vl_api_vrrp_vr_dump_t_handler (vl_api_vrrp_vr_dump_t * mp) 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; @@ -253,7 +351,6 @@ vl_api_vrrp_vr_start_stop_t_handler (vl_api_vrrp_vr_start_stop_t * mp) 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; @@ -317,14 +414,14 @@ send_vrrp_vr_peer_details (vrrp_vr_t * vr, vl_api_registration_t * reg, 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); @@ -370,14 +467,14 @@ vl_api_vrrp_vr_peer_dump_t_handler (vl_api_vrrp_vr_peer_dump_t * mp) } /* *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* */ } @@ -385,7 +482,6 @@ 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; @@ -475,17 +571,60 @@ vl_api_vrrp_vr_track_if_dump_t_handler (vl_api_vrrp_vr_track_if_dump_t * mp) } /* *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; + + /* *INDENT-OFF* */ + 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); + } + /* *INDENT-ON* */ +} + +pub_sub_handler (vrrp_vr_events, VRRP_VR_EVENTS); + /* Set up the API message handling tables */ #include clib_error_t *