X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fvrrp%2Fvrrp_api.c;h=e31e0a74c14da0a8032b1d081c71a678aa82bf9d;hb=4f30bc74577959efddfe4bc544cea4ec5c7019da;hp=3b9c256b263e16f9441f40fd1bdcc2d8163c8787;hpb=39e9428b90bc74d1bb15fc17759c8ef6ad712418;p=vpp.git diff --git a/src/plugins/vrrp/vrrp_api.c b/src/plugins/vrrp/vrrp_api.c index 3b9c256b263..e31e0a74c14 100644 --- a/src/plugins/vrrp/vrrp_api.c +++ b/src/plugins/vrrp/vrrp_api.c @@ -20,20 +20,124 @@ #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; 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)); @@ -102,13 +206,27 @@ 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); + 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) @@ -147,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); @@ -183,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); @@ -211,25 +313,24 @@ vl_api_vrrp_vr_dump_t_handler (vl_api_vrrp_vr_dump_t * mp) u32 sw_if_index; reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; 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; @@ -248,7 +349,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; @@ -312,14 +412,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); @@ -340,6 +440,8 @@ vl_api_vrrp_vr_peer_dump_t_handler (vl_api_vrrp_vr_peer_dump_t * mp) vrrp_vr_key_t vr_key; reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; vr_key.sw_if_index = ntohl (mp->sw_if_index); @@ -362,23 +464,20 @@ vl_api_vrrp_vr_peer_dump_t_handler (vl_api_vrrp_vr_peer_dump_t * mp) 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; @@ -456,6 +555,8 @@ vl_api_vrrp_vr_track_if_dump_t_handler (vl_api_vrrp_vr_track_if_dump_t * mp) vrrp_vr_t *vr; reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; if (!mp->dump_all) { @@ -465,18 +566,57 @@ vl_api_vrrp_vr_track_if_dump_t_handler (vl_api_vrrp_vr_track_if_dump_t * mp) 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 clib_error_t * @@ -490,7 +630,6 @@ vrrp_plugin_api_hookup (vlib_main_t * vm) return 0; } -/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON