LCOV - code coverage report
Current view: top level - plugins/vrrp - vrrp_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 50 300 16.7 %
Date: 2023-10-26 01:39:38 Functions: 6 19 31.6 %

          Line data    Source code
       1             : /*
       2             :  * vrrp.c - vpp vrrp plug-in
       3             :  *
       4             :  * Copyright 2019-2020 Rubicon Communications, LLC (Netgate)
       5             :  *
       6             :  * SPDX-License-Identifier: Apache-2.0
       7             :  *
       8             :  */
       9             : 
      10             : #include <vnet/vnet.h>
      11             : #include <vnet/plugin/plugin.h>
      12             : #include <vrrp/vrrp.h>
      13             : 
      14             : #include <vlibapi/api.h>
      15             : #include <vlibmemory/api.h>
      16             : #include <vpp/app/version.h>
      17             : 
      18             : /* define message IDs */
      19             : #include <vnet/format_fns.h>
      20             : #include <vrrp/vrrp.api_enum.h>
      21             : #include <vrrp/vrrp.api_types.h>
      22             : 
      23             : #define REPLY_MSG_ID_BASE vrrp_main.msg_id_base
      24             : #include <vlibapi/api_helper_macros.h>
      25             : 
      26             : /* API message handlers */
      27             : static void
      28           0 : vl_api_vrrp_vr_update_t_handler (vl_api_vrrp_vr_update_t *mp)
      29             : {
      30             :   vl_api_vrrp_vr_update_reply_t *rmp;
      31             :   vrrp_vr_config_t vr_conf;
      32             :   u32 api_flags;
      33           0 :   u32 vrrp_index = INDEX_INVALID;
      34           0 :   ip46_address_t *addrs = 0;
      35             :   int rv;
      36             : 
      37           0 :   VALIDATE_SW_IF_INDEX (mp);
      38             : 
      39           0 :   api_flags = htonl (mp->flags);
      40             : 
      41           0 :   clib_memset (&vr_conf, 0, sizeof (vr_conf));
      42             : 
      43           0 :   vr_conf.sw_if_index = ntohl (mp->sw_if_index);
      44           0 :   vr_conf.vr_id = mp->vr_id;
      45           0 :   vr_conf.priority = mp->priority;
      46           0 :   vr_conf.adv_interval = ntohs (mp->interval);
      47             : 
      48           0 :   if (api_flags & VRRP_API_VR_PREEMPT)
      49           0 :     vr_conf.flags |= VRRP_VR_PREEMPT;
      50             : 
      51           0 :   if (api_flags & VRRP_API_VR_ACCEPT)
      52           0 :     vr_conf.flags |= VRRP_VR_ACCEPT;
      53             : 
      54           0 :   if (api_flags & VRRP_API_VR_UNICAST)
      55           0 :     vr_conf.flags |= VRRP_VR_UNICAST;
      56             : 
      57           0 :   if (api_flags & VRRP_API_VR_IPV6)
      58           0 :     vr_conf.flags |= VRRP_VR_IPV6;
      59             : 
      60             :   int i;
      61           0 :   for (i = 0; i < mp->n_addrs; i++)
      62             :     {
      63             :       ip46_address_t *addr;
      64             :       void *src, *dst;
      65             :       int len;
      66             : 
      67           0 :       vec_add2 (addrs, addr, 1);
      68             : 
      69           0 :       if (ntohl (mp->addrs[i].af) == ADDRESS_IP4)
      70             :         {
      71           0 :           src = &mp->addrs[i].un.ip4;
      72           0 :           dst = &addr->ip4;
      73           0 :           len = sizeof (addr->ip4);
      74             :         }
      75             :       else
      76             :         {
      77           0 :           src = &mp->addrs[i].un.ip6;
      78           0 :           dst = &addr->ip6;
      79           0 :           len = sizeof (addr->ip6);
      80             :         }
      81             : 
      82           0 :       clib_memcpy (dst, src, len);
      83             :     }
      84             : 
      85           0 :   vr_conf.vr_addrs = addrs;
      86             : 
      87           0 :   if (vr_conf.priority == 0)
      88             :     {
      89           0 :       clib_warning ("VR priority must be > 0");
      90           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
      91             :     }
      92           0 :   else if (vr_conf.adv_interval == 0)
      93             :     {
      94           0 :       clib_warning ("VR advertisement interval must be > 0");
      95           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
      96             :     }
      97           0 :   else if (vr_conf.vr_id == 0)
      98             :     {
      99           0 :       clib_warning ("VR ID must be > 0");
     100           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
     101             :     }
     102             :   else
     103             :     {
     104           0 :       vrrp_index = ntohl (mp->vrrp_index);
     105           0 :       rv = vrrp_vr_update (&vrrp_index, &vr_conf);
     106             :     }
     107             : 
     108           0 :   vec_free (addrs);
     109             : 
     110           0 :   BAD_SW_IF_INDEX_LABEL;
     111             :   // clang-format off
     112           0 :   REPLY_MACRO2 (VL_API_VRRP_VR_UPDATE_REPLY,
     113             :   ({
     114             :     rmp->vrrp_index = htonl (vrrp_index);
     115             :   }));
     116             :   // clang-format on
     117             : }
     118             : 
     119             : static void
     120           0 : vl_api_vrrp_vr_del_t_handler (vl_api_vrrp_vr_del_t *mp)
     121             : {
     122             :   vl_api_vrrp_vr_del_reply_t *rmp;
     123             :   int rv;
     124             : 
     125           0 :   rv = vrrp_vr_del (ntohl (mp->vrrp_index));
     126             : 
     127           0 :   REPLY_MACRO (VL_API_VRRP_VR_DEL_REPLY);
     128             : }
     129             : 
     130             : static void
     131           4 : vl_api_vrrp_vr_add_del_t_handler (vl_api_vrrp_vr_add_del_t * mp)
     132             : {
     133             :   vl_api_vrrp_vr_add_del_reply_t *rmp;
     134             :   vrrp_vr_config_t vr_conf;
     135             :   u32 api_flags;
     136           4 :   ip46_address_t *addrs = 0;
     137             :   int rv;
     138             : 
     139           4 :   VALIDATE_SW_IF_INDEX (mp);
     140             : 
     141           4 :   api_flags = htonl (mp->flags);
     142             : 
     143           4 :   clib_memset (&vr_conf, 0, sizeof (vr_conf));
     144             : 
     145           4 :   vr_conf.sw_if_index = ntohl (mp->sw_if_index);
     146           4 :   vr_conf.vr_id = mp->vr_id;
     147           4 :   vr_conf.priority = mp->priority;
     148           4 :   vr_conf.adv_interval = ntohs (mp->interval);
     149             : 
     150           4 :   if (api_flags & VRRP_API_VR_PREEMPT)
     151           4 :     vr_conf.flags |= VRRP_VR_PREEMPT;
     152             : 
     153           4 :   if (api_flags & VRRP_API_VR_ACCEPT)
     154           0 :     vr_conf.flags |= VRRP_VR_ACCEPT;
     155             : 
     156           4 :   if (api_flags & VRRP_API_VR_UNICAST)
     157           0 :     vr_conf.flags |= VRRP_VR_UNICAST;
     158             : 
     159           4 :   if (api_flags & VRRP_API_VR_IPV6)
     160           2 :     vr_conf.flags |= VRRP_VR_IPV6;
     161             : 
     162           4 :   if (mp->is_add)
     163             :     {
     164             :       int i;
     165             : 
     166           4 :       for (i = 0; i < mp->n_addrs; i++)
     167             :         {
     168             :           ip46_address_t *addr;
     169             :           void *src, *dst;
     170             :           int len;
     171             : 
     172           2 :           vec_add2 (addrs, addr, 1);
     173             : 
     174           2 :           if (ntohl (mp->addrs[i].af) == ADDRESS_IP4)
     175             :             {
     176           1 :               src = &mp->addrs[i].un.ip4;
     177           1 :               dst = &addr->ip4;
     178           1 :               len = sizeof (addr->ip4);
     179             :             }
     180             :           else
     181             :             {
     182           1 :               src = &mp->addrs[i].un.ip6;
     183           1 :               dst = &addr->ip6;
     184           1 :               len = sizeof (addr->ip6);
     185             :             }
     186             : 
     187           2 :           clib_memcpy (dst, src, len);
     188             :         }
     189             : 
     190           2 :       vr_conf.vr_addrs = addrs;
     191             :     }
     192             : 
     193           4 :   if (vr_conf.priority == 0)
     194             :     {
     195           0 :       clib_warning ("VR priority must be > 0");
     196           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
     197             :     }
     198           4 :   else if (vr_conf.adv_interval == 0)
     199             :     {
     200           0 :       clib_warning ("VR advertisement interval must be > 0");
     201           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
     202             :     }
     203           4 :   else if (vr_conf.vr_id == 0)
     204             :     {
     205           0 :       clib_warning ("VR ID must be > 0");
     206           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
     207             :     }
     208             :   else
     209           4 :     rv = vrrp_vr_add_del (mp->is_add, &vr_conf, NULL);
     210             : 
     211           4 :   vec_free (addrs);
     212             : 
     213           4 :   BAD_SW_IF_INDEX_LABEL;
     214           4 :   REPLY_MACRO (VL_API_VRRP_VR_ADD_DEL_REPLY);
     215             : }
     216             : 
     217             : static vl_api_vrrp_vr_state_t
     218           0 : vrrp_vr_state_encode (vrrp_vr_state_t vr_state)
     219             : {
     220           0 :   if (vr_state == VRRP_VR_STATE_BACKUP)
     221           0 :     return VRRP_API_VR_STATE_BACKUP;
     222           0 :   if (vr_state == VRRP_VR_STATE_MASTER)
     223           0 :     return VRRP_API_VR_STATE_MASTER;
     224           0 :   if (vr_state == VRRP_VR_STATE_INTF_DOWN)
     225           0 :     return VRRP_API_VR_STATE_INTF_DOWN;
     226             : 
     227           0 :   return VRRP_API_VR_STATE_INIT;
     228             : }
     229             : 
     230             : static void
     231           0 : send_vrrp_vr_details (vrrp_vr_t * vr, vl_api_registration_t * reg,
     232             :                       u32 context)
     233             : {
     234           0 :   vrrp_main_t *vmp = &vrrp_main;
     235             :   vl_api_vrrp_vr_details_t *mp;
     236             :   int n_addrs, msg_size;
     237             :   ip46_address_t *addr;
     238             :   vl_api_address_t *api_addr;
     239           0 :   u32 api_flags = 0;
     240             : 
     241           0 :   n_addrs = vec_len (vr->config.vr_addrs);
     242           0 :   msg_size = sizeof (*mp) + n_addrs * sizeof (*api_addr);
     243           0 :   mp = vl_msg_api_alloc (msg_size);
     244           0 :   if (!mp)
     245           0 :     return;
     246           0 :   clib_memset (mp, 0, msg_size);
     247           0 :   mp->_vl_msg_id = htons (VL_API_VRRP_VR_DETAILS + vmp->msg_id_base);
     248           0 :   mp->context = context;
     249             : 
     250             :   /* config */
     251           0 :   mp->config.sw_if_index = htonl (vr->config.sw_if_index);
     252           0 :   mp->config.vr_id = vr->config.vr_id;
     253           0 :   mp->config.priority = vr->config.priority;
     254           0 :   mp->config.interval = htons (vr->config.adv_interval);
     255             : 
     256           0 :   if (vr->config.flags & VRRP_VR_PREEMPT)
     257           0 :     api_flags |= VRRP_API_VR_PREEMPT;
     258           0 :   if (vr->config.flags & VRRP_VR_ACCEPT)
     259           0 :     api_flags |= VRRP_API_VR_ACCEPT;
     260           0 :   if (vrrp_vr_is_unicast (vr))
     261           0 :     api_flags |= VRRP_API_VR_UNICAST;
     262           0 :   if (vrrp_vr_is_ipv6 (vr))
     263           0 :     api_flags |= VRRP_API_VR_IPV6;
     264             : 
     265           0 :   mp->config.flags = htonl (api_flags);
     266             : 
     267             :   /* runtime */
     268           0 :   mp->runtime.state = htonl (vrrp_vr_state_encode (vr->runtime.state));
     269             : 
     270           0 :   mp->runtime.master_adv_int = htons (vr->runtime.master_adv_int);
     271           0 :   mp->runtime.skew = htons (vr->runtime.skew);
     272           0 :   mp->runtime.master_down_int = htons (vr->runtime.master_down_int);
     273           0 :   clib_memcpy (&mp->runtime.mac, &vr->runtime.mac, sizeof (vr->runtime.mac));
     274             : 
     275           0 :   mp->runtime.tracking.interfaces_dec = htonl (vr->tracking.interfaces_dec);
     276           0 :   mp->runtime.tracking.priority = vrrp_vr_priority (vr);
     277             : 
     278             :   /* addrs */
     279           0 :   mp->n_addrs = vec_len (vr->config.vr_addrs);
     280           0 :   api_addr = mp->addrs;
     281           0 :   vec_foreach (addr, vr->config.vr_addrs)
     282             :   {
     283             :     void *src, *dst;
     284             :     size_t len;
     285             : 
     286           0 :     if (vrrp_vr_is_ipv6 (vr))
     287             :       {
     288           0 :         api_addr->af = ADDRESS_IP6;
     289           0 :         dst = &api_addr->un.ip6;
     290           0 :         src = &addr->ip6;
     291           0 :         len = sizeof (addr->ip6);
     292             :       }
     293             :     else
     294             :       {
     295           0 :         api_addr->af = ADDRESS_IP4;
     296           0 :         dst = &api_addr->un.ip4;
     297           0 :         src = &addr->ip4;
     298           0 :         len = sizeof (addr->ip4);
     299             :       }
     300           0 :     clib_memcpy (dst, src, len);
     301           0 :     api_addr++;
     302             :   }
     303             : 
     304           0 :   vl_api_send_msg (reg, (u8 *) mp);
     305             : }
     306             : 
     307             : static void
     308           0 : vl_api_vrrp_vr_dump_t_handler (vl_api_vrrp_vr_dump_t * mp)
     309             : {
     310           0 :   vrrp_main_t *vmp = &vrrp_main;
     311             :   vl_api_registration_t *reg;
     312             :   vrrp_vr_t *vr;
     313             :   u32 sw_if_index;
     314             : 
     315           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     316           0 :   if (!reg)
     317           0 :     return;
     318             : 
     319           0 :   sw_if_index = htonl (mp->sw_if_index);
     320             : 
     321             :   /* *INDENT-OFF* */
     322           0 :   pool_foreach (vr, vmp->vrs)  {
     323             : 
     324           0 :     if (sw_if_index && (sw_if_index != ~0) &&
     325           0 :         (sw_if_index != vr->config.sw_if_index))
     326           0 :       continue;
     327             : 
     328           0 :     send_vrrp_vr_details (vr, reg, mp->context);
     329             :   }
     330             :   /* *INDENT-ON* */
     331             : }
     332             : 
     333             : static void
     334           4 : vl_api_vrrp_vr_start_stop_t_handler (vl_api_vrrp_vr_start_stop_t * mp)
     335             : {
     336             :   vl_api_vrrp_vr_start_stop_reply_t *rmp;
     337             :   vrrp_vr_key_t vr_key;
     338             :   int rv;
     339             : 
     340           4 :   clib_memset (&vr_key, 0, sizeof (vr_key));
     341             : 
     342           4 :   vr_key.sw_if_index = ntohl (mp->sw_if_index);
     343           4 :   vr_key.vr_id = mp->vr_id;
     344           4 :   vr_key.is_ipv6 = (mp->is_ipv6 != 0);
     345             : 
     346           4 :   rv = vrrp_vr_start_stop ((mp->is_start != 0), &vr_key);
     347             : 
     348           4 :   REPLY_MACRO (VL_API_VRRP_VR_START_STOP_REPLY);
     349             : }
     350             : 
     351             : static void
     352           0 : vl_api_vrrp_vr_set_peers_t_handler (vl_api_vrrp_vr_set_peers_t * mp)
     353             : {
     354             :   vl_api_vrrp_vr_set_peers_reply_t *rmp;
     355             :   vrrp_vr_key_t vr_key;
     356           0 :   ip46_address_t *peer_addrs = 0;
     357             :   int i;
     358             :   int rv;
     359             : 
     360           0 :   clib_memset (&vr_key, 0, sizeof (vr_key));
     361             : 
     362           0 :   vr_key.sw_if_index = ntohl (mp->sw_if_index);
     363           0 :   vr_key.vr_id = mp->vr_id;
     364           0 :   vr_key.is_ipv6 = (mp->is_ipv6 != 0);
     365             : 
     366           0 :   for (i = 0; i < mp->n_addrs; i++)
     367             :     {
     368             :       ip46_address_t *peer;
     369             : 
     370           0 :       vec_add2 (peer_addrs, peer, 1);
     371             : 
     372           0 :       if (mp->is_ipv6)
     373           0 :         clib_memcpy (&peer->ip6, mp->addrs[i].un.ip6, 16);
     374             :       else
     375           0 :         clib_memcpy (&peer->ip4, mp->addrs[i].un.ip4, 4);
     376             :     }
     377             : 
     378           0 :   rv = vrrp_vr_set_peers (&vr_key, peer_addrs);
     379             : 
     380           0 :   vec_free (peer_addrs);
     381           0 :   REPLY_MACRO (VL_API_VRRP_VR_SET_PEERS_REPLY);
     382             : }
     383             : 
     384             : static void
     385           0 : send_vrrp_vr_peer_details (vrrp_vr_t * vr, vl_api_registration_t * reg,
     386             :                            u32 context)
     387             : {
     388           0 :   vrrp_main_t *vmp = &vrrp_main;
     389             :   vl_api_vrrp_vr_peer_details_t *mp;
     390             :   int n_addrs, msg_size;
     391             :   ip46_address_t *addr;
     392             :   vl_api_address_t *api_addr;
     393             : 
     394           0 :   n_addrs = vec_len (vr->config.peer_addrs);
     395           0 :   msg_size = sizeof (*mp) + n_addrs * sizeof (*api_addr);
     396           0 :   mp = vl_msg_api_alloc (msg_size);
     397           0 :   if (!mp)
     398           0 :     return;
     399           0 :   clib_memset (mp, 0, msg_size);
     400           0 :   mp->_vl_msg_id = htons (VL_API_VRRP_VR_PEER_DETAILS + vmp->msg_id_base);
     401           0 :   mp->context = context;
     402             : 
     403           0 :   mp->sw_if_index = htonl (vr->config.sw_if_index);
     404           0 :   mp->vr_id = vr->config.vr_id;
     405           0 :   mp->is_ipv6 = vrrp_vr_is_ipv6 (vr);
     406             : 
     407             :   /* addrs */
     408           0 :   mp->n_peer_addrs = n_addrs;
     409           0 :   api_addr = mp->peer_addrs;
     410           0 :   vec_foreach (addr, vr->config.peer_addrs)
     411             :   {
     412             :     void *src, *dst;
     413             :     size_t len;
     414             : 
     415           0 :     if (vrrp_vr_is_ipv6 (vr))
     416             :       {
     417           0 :         api_addr->af = ADDRESS_IP6;
     418           0 :         dst = &api_addr->un.ip6;
     419           0 :         src = &addr->ip6;
     420           0 :         len = sizeof (addr->ip6);
     421             :       }
     422             :     else
     423             :       {
     424           0 :         api_addr->af = ADDRESS_IP4;
     425           0 :         dst = &api_addr->un.ip4;
     426           0 :         src = &addr->ip4;
     427           0 :         len = sizeof (addr->ip4);
     428             :       }
     429           0 :     clib_memcpy (dst, src, len);
     430           0 :     api_addr++;
     431             :   }
     432             : 
     433           0 :   vl_api_send_msg (reg, (u8 *) mp);
     434             : }
     435             : 
     436             : static void
     437           0 : vl_api_vrrp_vr_peer_dump_t_handler (vl_api_vrrp_vr_peer_dump_t * mp)
     438             : {
     439           0 :   vrrp_main_t *vmp = &vrrp_main;
     440             :   vl_api_registration_t *reg;
     441             :   vrrp_vr_t *vr;
     442             :   vrrp_vr_key_t vr_key;
     443             : 
     444           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     445           0 :   if (!reg)
     446           0 :     return;
     447             : 
     448           0 :   vr_key.sw_if_index = ntohl (mp->sw_if_index);
     449             : 
     450           0 :   if (vr_key.sw_if_index && (vr_key.sw_if_index != ~0))
     451             :     {
     452             :       uword *p;
     453           0 :       u32 vr_index = ~0;
     454             : 
     455           0 :       vr_key.vr_id = mp->vr_id;
     456           0 :       vr_key.is_ipv6 = mp->is_ipv6;
     457             : 
     458           0 :       p = mhash_get (&vmp->vr_index_by_key, &vr_key);
     459           0 :       if (!p)
     460           0 :         return;
     461             : 
     462           0 :       vr_index = p[0];
     463           0 :       vr = pool_elt_at_index (vmp->vrs, vr_index);
     464           0 :       send_vrrp_vr_peer_details (vr, reg, mp->context);
     465             : 
     466           0 :       return;
     467             :     }
     468             : 
     469             :   /* *INDENT-OFF* */
     470           0 :   pool_foreach (vr, vmp->vrs)  {
     471             : 
     472           0 :     if (!vec_len (vr->config.peer_addrs))
     473           0 :       continue;
     474             : 
     475           0 :     send_vrrp_vr_details (vr, reg, mp->context);
     476             : 
     477             :   }
     478             :   /* *INDENT-ON* */
     479             : }
     480             : 
     481             : static void
     482           0 :   vl_api_vrrp_vr_track_if_add_del_t_handler
     483             :   (vl_api_vrrp_vr_track_if_add_del_t * mp)
     484             : {
     485             :   vl_api_vrrp_vr_track_if_add_del_reply_t *rmp;
     486             :   vrrp_vr_t *vr;
     487           0 :   vrrp_vr_tracking_if_t *track_if, *track_ifs = 0;
     488           0 :   int rv = 0, i;
     489             : 
     490             :   /* lookup VR and return error if it does not exist */
     491             :   vr =
     492           0 :     vrrp_vr_lookup (ntohl (mp->sw_if_index), mp->vr_id, (mp->is_ipv6 != 0));
     493           0 :   if (!vr)
     494             :     {
     495           0 :       rv = VNET_API_ERROR_INVALID_VALUE;
     496           0 :       goto done;
     497             :     }
     498             : 
     499           0 :   for (i = 0; i < mp->n_ifs; i++)
     500             :     {
     501           0 :       vl_api_vrrp_vr_track_if_t *api_track_if = &mp->ifs[i];
     502             : 
     503           0 :       vec_add2 (track_ifs, track_if, 1);
     504           0 :       track_if->sw_if_index = ntohl (api_track_if->sw_if_index);
     505           0 :       track_if->priority = api_track_if->priority;
     506             :     }
     507             : 
     508           0 :   rv = vrrp_vr_tracking_ifs_add_del (vr, track_ifs, mp->is_add != 0);
     509             : 
     510           0 : done:
     511           0 :   vec_free (track_ifs);
     512           0 :   REPLY_MACRO (VL_API_VRRP_VR_TRACK_IF_ADD_DEL_REPLY);
     513             : }
     514             : 
     515             : static void
     516           0 : send_vrrp_vr_track_if_details (vrrp_vr_t * vr, vl_api_registration_t * reg,
     517             :                                u32 context)
     518             : {
     519           0 :   vrrp_main_t *vmp = &vrrp_main;
     520             :   vl_api_vrrp_vr_track_if_details_t *mp;
     521             :   int n_ifs, msg_size;
     522             :   vl_api_vrrp_vr_track_if_t *api_track_if;
     523             :   vrrp_vr_tracking_if_t *track_if;
     524             : 
     525           0 :   if (!vr)
     526           0 :     return;
     527             : 
     528           0 :   n_ifs = vec_len (vr->tracking.interfaces);
     529           0 :   msg_size = sizeof (*mp) + n_ifs * sizeof (*api_track_if);
     530           0 :   mp = vl_msg_api_alloc (msg_size);
     531           0 :   if (!mp)
     532           0 :     return;
     533           0 :   clib_memset (mp, 0, msg_size);
     534           0 :   mp->_vl_msg_id = htons (VL_API_VRRP_VR_TRACK_IF_DETAILS + vmp->msg_id_base);
     535           0 :   mp->context = context;
     536             : 
     537           0 :   mp->sw_if_index = htonl (vr->config.sw_if_index);
     538           0 :   mp->vr_id = vr->config.vr_id;
     539           0 :   mp->is_ipv6 = vrrp_vr_is_ipv6 (vr);
     540             : 
     541             :   /* tracked interfaces */
     542           0 :   mp->n_ifs = n_ifs;
     543           0 :   api_track_if = mp->ifs;
     544           0 :   vec_foreach (track_if, vr->tracking.interfaces)
     545             :   {
     546           0 :     api_track_if->sw_if_index = htonl (track_if->sw_if_index);
     547           0 :     api_track_if->priority = track_if->priority;
     548           0 :     api_track_if += 1;
     549             :   }
     550             : 
     551           0 :   vl_api_send_msg (reg, (u8 *) mp);
     552             : }
     553             : 
     554             : static void
     555           0 : vl_api_vrrp_vr_track_if_dump_t_handler (vl_api_vrrp_vr_track_if_dump_t * mp)
     556             : {
     557           0 :   vrrp_main_t *vmp = &vrrp_main;
     558             :   vl_api_registration_t *reg;
     559             :   vrrp_vr_t *vr;
     560             : 
     561           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     562           0 :   if (!reg)
     563           0 :     return;
     564             : 
     565           0 :   if (!mp->dump_all)
     566             :     {
     567           0 :       vr = vrrp_vr_lookup (ntohl (mp->sw_if_index), mp->vr_id, mp->is_ipv6);
     568           0 :       send_vrrp_vr_track_if_details (vr, reg, mp->context);
     569             : 
     570           0 :       return;
     571             :     }
     572             : 
     573             :   /* *INDENT-OFF* */
     574           0 :   pool_foreach (vr, vmp->vrs)  {
     575             : 
     576           0 :     if (!vec_len (vr->tracking.interfaces))
     577           0 :       continue;
     578             : 
     579           0 :     send_vrrp_vr_track_if_details (vr, reg, mp->context);
     580             : 
     581             :   }
     582             :   /* *INDENT-ON* */
     583             : }
     584             : 
     585             : static void
     586           0 : send_vrrp_vr_event (vpe_client_registration_t * reg,
     587             :                     vl_api_registration_t * vl_reg,
     588             :                     vrrp_vr_t * vr, vrrp_vr_state_t new_state)
     589             : {
     590           0 :   vrrp_main_t *vmp = &vrrp_main;
     591             :   vl_api_vrrp_vr_event_t *mp;
     592             : 
     593           0 :   mp = vl_msg_api_alloc (sizeof (*mp));
     594             : 
     595           0 :   clib_memset (mp, 0, sizeof (*mp));
     596           0 :   mp->_vl_msg_id = ntohs (VL_API_VRRP_VR_EVENT + vmp->msg_id_base);
     597           0 :   mp->client_index = reg->client_index;
     598           0 :   mp->pid = reg->client_pid;
     599           0 :   mp->vr.sw_if_index = ntohl (vr->config.sw_if_index);
     600           0 :   mp->vr.vr_id = vr->config.vr_id;
     601           0 :   mp->vr.is_ipv6 = ((vr->config.flags & VRRP_VR_IPV6) != 0);
     602             : 
     603           0 :   mp->old_state = htonl (vrrp_vr_state_encode (vr->runtime.state));
     604           0 :   mp->new_state = htonl (vrrp_vr_state_encode (new_state));
     605             : 
     606           0 :   vl_api_send_msg (vl_reg, (u8 *) mp);
     607           0 : }
     608             : 
     609             : void
     610           4 : vrrp_vr_event (vrrp_vr_t * vr, vrrp_vr_state_t new_state)
     611             : {
     612           4 :   vpe_api_main_t *vam = &vpe_api_main;
     613             :   vpe_client_registration_t *reg;
     614             :   vl_api_registration_t *vl_reg;
     615             : 
     616             :   /* *INDENT-OFF* */
     617           4 :   pool_foreach (reg, vam->vrrp_vr_events_registrations)
     618             :    {
     619           0 :     vl_reg = vl_api_client_index_to_registration (reg->client_index);
     620           0 :     if (vl_reg)
     621           0 :       send_vrrp_vr_event (reg, vl_reg, vr, new_state);
     622             :   }
     623             :   /* *INDENT-ON* */
     624           4 : }
     625             : 
     626        1816 : pub_sub_handler (vrrp_vr_events, VRRP_VR_EVENTS);
     627             : 
     628             : /* Set up the API message handling tables */
     629             : #include <vrrp/vrrp.api.c>
     630             : clib_error_t *
     631         575 : vrrp_plugin_api_hookup (vlib_main_t * vm)
     632             : {
     633         575 :   vrrp_main_t *vmp = &vrrp_main;
     634             : 
     635             :   /* Ask for a correctly-sized block of API message decode slots */
     636         575 :   vmp->msg_id_base = setup_message_id_table ();
     637             : 
     638         575 :   return 0;
     639             : }
     640             : 
     641             : /* *INDENT-ON* */
     642             : 
     643             : /*
     644             :  * fd.io coding-style-patch-verification: ON
     645             :  *
     646             :  * Local Variables:
     647             :  * eval: (c-set-style "gnu")
     648             :  * End:
     649             :  */

Generated by: LCOV version 1.14