igmp: bugfix and minor improvements 75/13275/3
authorJakub Grajciar <jgrajcia@cisco.com>
Thu, 28 Jun 2018 10:27:52 +0000 (12:27 +0200)
committerDamjan Marion <dmarion@me.com>
Fri, 29 Jun 2018 10:00:17 +0000 (10:00 +0000)
Change-Id: I8d284117a668dc55c06a6d68fe358a3d7e26c738
Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
src/plugins/igmp/cli.c
src/plugins/igmp/igmp.c
src/plugins/igmp/igmp.h
src/plugins/igmp/igmp_api.c
src/plugins/igmp/input.c

index 6ed5c5e..42f5932 100644 (file)
@@ -129,7 +129,7 @@ igmp_listen_command_fn (vlib_main_t * vm, unformat_input_t * input,
     }
 
   rv = igmp_listen (vm, enable, sw_if_index, saddr, gaddr,
-                   /* cli_api_listen */ 1);
+                   IGMP_CONFIG_FLAG_CLI_API_CONFIGURED);
   if (rv == -1)
     {
       if (enable)
index 15f6317..71c91b0 100644 (file)
@@ -402,65 +402,43 @@ igmp_send_msg (vlib_main_t * vm, vlib_node_runtime_t * node,
               igmp_main_t * im, igmp_config_t * config, igmp_group_t * group,
               u8 is_report)
 {
-  u32 thread_index = vlib_get_thread_index ();
-  u32 *to_next;
-  u32 next_index = IGMP_NEXT_IP4_REWRITE_MCAST_NODE;
+  u32 *to_next = 0;
+  u32 next_index = ip4_rewrite_node.index;
 
-  u32 n_free_bufs = vec_len (im->buffers[thread_index]);
-  if (PREDICT_FALSE (n_free_bufs < 1))
-    {
-      vec_validate (im->buffers[thread_index], 1 + n_free_bufs - 1);
-      n_free_bufs +=
-       vlib_buffer_alloc (vm, &im->buffers[thread_index][n_free_bufs], 1);
-      _vec_len (im->buffers[thread_index]) = n_free_bufs;
-    }
+  u32 bi = 0;
+  vlib_buffer_alloc (vm, &bi, 1);
 
-  u32 n_left_to_next;
-  u32 next0 = next_index;
-  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+  vlib_buffer_t *b = vlib_get_buffer (vm, bi);
+  vlib_buffer_free_list_t *fl = vlib_buffer_get_free_list (vm,
+                                                          VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
+  vlib_buffer_init_for_free_list (b, fl);
 
-  if (n_left_to_next > 0)
-    {
-      vlib_buffer_t *b = 0;
-      u32 bi = 0;
+  b->current_data = 0;
+  b->current_length = 0;
 
-      if (n_free_bufs)
-       {
-         u32 last_buf = vec_len (im->buffers[thread_index]) - 1;
-         bi = im->buffers[thread_index][last_buf];
-         b = vlib_get_buffer (vm, bi);
-         _vec_len (im->buffers[thread_index]) = last_buf;
-         n_free_bufs--;
-         if (PREDICT_FALSE (n_free_bufs == 0))
-           {
-             n_free_bufs += vlib_buffer_alloc (vm,
-                                               &im->buffers[thread_index]
-                                               [n_free_bufs], 1);
-             _vec_len (im->buffers[thread_index]) = n_free_bufs;
-           }
+  igmp_create_ip4 (b, config, group, is_report);
 
-         b->current_data = 0;
-         b->current_length = 0;
+  b->current_data = 0;
 
-         igmp_create_ip4 (b, config, group, is_report);
+  b->total_length_not_including_first_buffer = 0;
+  b->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
+  vnet_buffer (b)->sw_if_index[VLIB_RX] = (u32) ~ 0;
+  vnet_buffer (b)->ip.adj_index[VLIB_TX] = config->adj_index;
 
-         b->current_data = 0;
+  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
 
-         b->total_length_not_including_first_buffer = 0;
-         b->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
-         vnet_buffer (b)->sw_if_index[VLIB_RX] = (u32) ~ 0;
-         vnet_buffer (b)->ip.adj_index[VLIB_TX] = config->adj_index;
-         b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
-       }
 
-      to_next[0] = bi;
-      to_next += 1;
-      n_left_to_next -= 1;
+  vlib_frame_t *f = vlib_get_frame_to_node (vm, next_index);
+  to_next = vlib_frame_vector_args (f);
+  to_next[0] = bi;
 
-      vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
-                                      n_left_to_next, bi, next0);
-    }
-  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+  f->n_vectors = 1;
+
+  vlib_buffer_t *c = vlib_buffer_copy (vm, b);
+  to_next += 1;
+  to_next[0] = vlib_get_buffer_index (vm, c);
+
+  vlib_put_frame_to_node (vm, next_index, f);
 }
 
 void
@@ -736,8 +714,7 @@ VLIB_REGISTER_NODE (igmp_timer_process_node) =
 
 int
 igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
-            ip46_address_t saddr, ip46_address_t gaddr,
-            u8 cli_api_configured)
+            ip46_address_t saddr, ip46_address_t gaddr, u8 flags)
 {
   igmp_main_t *im = &igmp_main;
   igmp_config_t *config;
@@ -747,7 +724,7 @@ igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
   igmp_key_t gkey;
 
   igmp_membership_group_v3_type_t group_type =
-    (cli_api_configured) ?
+    (flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED) ?
     IGMP_MEMBERSHIP_GROUP_change_to_filter_include :
     IGMP_MEMBERSHIP_GROUP_mode_is_filter_include;
   int rv = 0;
@@ -769,13 +746,12 @@ igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
          config->sw_if_index = sw_if_index;
          config->igmp_group_by_key =
            hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
-         config->cli_api_configured = cli_api_configured;
          /* use IGMPv3 by default */
          config->igmp_ver = IGMP_V3;
          config->robustness_var = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
-         config->flags |= IGMP_CONFIG_FLAG_QUERY_RESP_RECVED;
+         config->flags |= IGMP_CONFIG_FLAG_QUERY_RESP_RECVED | flags;
 
-         if (!cli_api_configured)
+         if ((flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED) == 0)
            {
              /* create qery timer */
              igmp_create_int_timer (vlib_time_now (vm) + IGMP_QUERY_TIMER,
@@ -787,7 +763,8 @@ igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
          hash_set (im->igmp_config_by_sw_if_index,
                    config->sw_if_index, config - im->configs);
        }
-      else if (config->cli_api_configured != cli_api_configured)
+      else if ((config->flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED & flags)
+              == 0)
        {
          rv = -2;
          goto error;
@@ -805,7 +782,7 @@ igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
            hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
          group->n_srcs = 0;
          group->type = gkey.group_type;
-         if (cli_api_configured)
+         if (flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED)
            {
              /* create state-changed report timer with zero timeout */
              igmp_create_group_timer (0, sw_if_index, group->key,
@@ -825,7 +802,7 @@ igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
          src->key = clib_mem_alloc (sizeof (igmp_key_t));
          clib_memcpy (src->key, &skey, sizeof (igmp_key_t));
          clib_memcpy (&src->addr, &saddr, sizeof (ip46_address_t));
-         if (!cli_api_configured)
+         if ((flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED) == 0)
            {
              /* arm source timer (after expiration remove (S,G)) */
              igmp_event (im, config, group, src);
@@ -899,7 +876,7 @@ igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
                    }
 
                  /* notify all registered api clients */
-                 if (!cli_api_configured)
+                 if ((flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED) == 0)
                    igmp_event (im, config, new_group, new_src);
                  else
                    igmp_create_group_timer (0, sw_if_index, new_group->key,
@@ -975,14 +952,11 @@ igmp_init (vlib_main_t * vm)
 {
   clib_error_t *error;
   igmp_main_t *im = &igmp_main;
-  vlib_thread_main_t *tm = vlib_get_thread_main ();
   int i;
   if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
     return error;
   im->igmp_config_by_sw_if_index = hash_create (0, sizeof (u32));
   im->igmp_api_client_by_client_index = hash_create (0, sizeof (u32));
-  vec_validate_aligned (im->buffers, tm->n_vlib_mains - 1,
-                       CLIB_CACHE_LINE_BYTES);
   ip4_register_protocol (IP_PROTOCOL_IGMP, igmp_input_node.index);
   igmp_type_info_t *ti;
   igmp_report_type_info_t *rti;
index 4f197d9..b8759ff 100644 (file)
 /** General Query address - 224.0.0.1 */
 #define IGMP_GENERAL_QUERY_ADDRESS             (0xE0000001)
 /** Membership Report address - 224.0.0.22 */
-#define IGMP_MEMBERSHIP_REPORT_ADDRESS (0xE0000016)
+#define IGMP_MEMBERSHIP_REPORT_ADDRESS         (0xE0000016)
 
 /** helper macro to get igmp mebership group from pointer plus offset */
 #define group_ptr(p, l) ((igmp_membership_group_v3_t *)((char*)p + l))
 
+#define foreach_igmp_config_flag \
+ _(0, QUERY_RESP_RECVED, "query_response_received")    \
+ _(1, CAN_SEND_REPORT, "can_send_report")              \
+ _(2, CLI_API_CONFIGURED, "cli/api")
+
+typedef enum
+{
+#define _(a,b,c) IGMP_CONFIG_FLAG_##b = (1 << a),
+  foreach_igmp_config_flag
+#undef _
+} igmp_config_flag_t;
+
 enum
 {
   IGMP_PROCESS_EVENT_UPDATE_TIMER = 1,
@@ -133,7 +145,6 @@ typedef struct igmp_group_t_
 /** \brief igmp configuration
     @param sw_if_index - interface sw_if_index
     @param adj_index - adjacency index
-    @param cli_api_configured - if zero, an igmp report was received
     @param next_create_msg - specify next igmp message
     @param igmp_ver - igmp version
     @param robustness_var - robustness variable
@@ -147,8 +158,6 @@ typedef struct igmp_config_t_
 
   adj_index_t adj_index;
 
-  u8 cli_api_configured;
-
   create_msg_t *next_create_msg;
 
   igmp_ver_t igmp_ver;
@@ -156,8 +165,6 @@ typedef struct igmp_config_t_
   u8 robustness_var;
 
   u8 flags;
-#define IGMP_CONFIG_FLAG_QUERY_RESP_RECVED     (1 << 0)
-#define IGMP_CONFIG_FLAG_CAN_SEND_REPORT       (1 << 1)
 
   uword *igmp_group_by_key;
 
@@ -207,8 +214,6 @@ typedef struct igmp_main_t_
 
   igmp_config_t *configs;
 
-  u32 **buffers;
-
   igmp_timer_t *timers;
 
   igmp_type_info_t *type_infos;
@@ -256,15 +261,14 @@ extern vlib_node_registration_t igmp_parse_report_node;
     @param sw_if_index - interface sw_if_index
     @param saddr - source address
     @param gaddr - group address
-    @param cli_api_configured - if zero, an igmp report has been received on interface
+    @param flags - igmp configuration flags
 
     Add/del (S,G) on an interface. If user configured,
     send a status change report from the interface.
     If a report was received on interface notify registered api clients.
 */
 int igmp_listen (vlib_main_t * vm, u8 enable, u32 sw_if_index,
-                ip46_address_t saddr, ip46_address_t gaddr,
-                u8 cli_api_configured);
+                ip46_address_t saddr, ip46_address_t gaddr, u8 flags);
 
 /** \brief igmp clear config
     @param config - igmp configuration
index fc5ce1b..d283a0f 100644 (file)
@@ -79,7 +79,9 @@ vl_api_igmp_listen_t_handler (vl_api_igmp_listen_t * mp)
   clib_memcpy (&saddr.ip4.as_u8, mp->saddr, sizeof (u8) * 4);
   clib_memcpy (&gaddr.ip4.as_u8, mp->gaddr, sizeof (u8) * 4);
 
-  rv = igmp_listen (vm, mp->enable, ntohl (mp->sw_if_index), saddr, gaddr, 1);
+  rv =
+    igmp_listen (vm, mp->enable, ntohl (mp->sw_if_index), saddr, gaddr,
+                IGMP_CONFIG_FLAG_CLI_API_CONFIGURED);
 
 done:;
   unix_shared_memory_queue_t *q =
index 4322f50..829317d 100644 (file)
@@ -410,7 +410,7 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
          if (config)
            {
              config->flags |= IGMP_CONFIG_FLAG_QUERY_RESP_RECVED;
-             if (config->cli_api_configured)
+             if (config->flags & IGMP_CONFIG_FLAG_CLI_API_CONFIGURED)
                {
                  IGMP_DBG ("Interface %u has (S,G)s configured by CLI/API",
                            sw_if_index);
@@ -452,6 +452,10 @@ igmp_parse_report (vlib_main_t * vm, vlib_node_runtime_t * node,
                          src_addr++;
                        }
                    }
+                 else
+                   {
+                     j = clib_net_to_host_u16 (igmp_group->n_src_addresses);
+                   }
                }
              else if (igmp_group->type ==
                       IGMP_MEMBERSHIP_GROUP_mode_is_filter_exclude)