vrrp: fix vrrp_garp_or_na_send()'s memory leak
[vpp.git] / src / plugins / igmp / igmp.c
index 61a9970..30f167d 100644 (file)
@@ -35,7 +35,6 @@
 
 igmp_main_t igmp_main;
 
-/* *INDENT-OFF* */
 /* General Query address */
 const static mfib_prefix_t mpfx_general_query = {
   .fp_proto = FIB_PROTOCOL_IP4,
@@ -57,7 +56,6 @@ const static mfib_prefix_t mpfx_report = {
     },
   },
 };
-/* *INDENT-ON* */
 
 /**
  * @brief igmp send query (igmp_timer_function_t)
@@ -142,12 +140,12 @@ igmp_listen (vlib_main_t * vm,
   /*
    * RFC 3376 Section 2
    " For a given combination of socket, interface, and multicast address,
-   only a single filter mode and source list can be in effect at any one
-   time.  However, either the filter mode or the source list, or both,
-   may be changed by subsequent IPMulticastListen requests that specify
-   the same socket, interface, and multicast address.  Each subsequent
-   request completely replaces any earlier request for the given socket,
-   interface and multicast address."
+   only a single filter mode and source list can be in effect at any one
+   time.  However, either the filter mode or the source list, or both,
+   may be changed by subsequent IPMulticastListen requests that specify
+   the same socket, interface, and multicast address.  Each subsequent
+   request completely replaces any earlier request for the given socket,
+   interface and multicast address."
    */
   int rv = 0;
   IGMP_DBG ("listen: (%U, %U) %U %U",
@@ -282,7 +280,7 @@ igmp_listen (vlib_main_t * vm,
          }
 
          if (0 == igmp_group_n_srcs (group, mode))
-           igmp_group_clear (group);
+           igmp_group_clear (&group);
 
          vec_free (added);
          vec_free (removed);
@@ -303,13 +301,6 @@ error:
   return (rv);
 }
 
-/** \brief igmp hardware interface link up down
-    @param vnm - vnet main
-    @param hw_if_index - interface hw_if_index
-    @param flags - hw interface flags
-
-    If an interface goes down, remove its (S,G)s.
-*/
 static walk_rc_t
 igmp_sw_if_down (vnet_main_t * vnm, u32 sw_if_index, void *ctx)
 {
@@ -325,6 +316,13 @@ igmp_sw_if_down (vnet_main_t * vnm, u32 sw_if_index, void *ctx)
   return (WALK_CONTINUE);
 }
 
+/** \brief igmp hardware interface link up down
+    @param vnm - vnet main
+    @param hw_if_index - interface hw_if_index
+    @param flags - hw interface flags
+
+    If an interface goes down, remove its (S,G)s.
+*/
 static clib_error_t *
 igmp_hw_interface_link_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
 {
@@ -345,16 +343,6 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
   IGMP_DBG ("%s:  %U", (enable ? "Enabled" : "Disabled"),
            format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index);
 
-  /* *INDENT-OFF* */
-  fib_route_path_t for_us_path =
-    {
-      .frp_proto = fib_proto_to_dpo (FIB_PROTOCOL_IP4),
-      .frp_addr = zero_addr,
-      .frp_sw_if_index = 0xffffffff,
-      .frp_fib_index = 0,
-      .frp_weight = 1,
-      .frp_flags = FIB_ROUTE_PATH_LOCAL,
-    };
   fib_route_path_t via_itf_path =
     {
       .frp_proto = fib_proto_to_dpo (FIB_PROTOCOL_IP4),
@@ -362,8 +350,18 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
       .frp_sw_if_index = sw_if_index,
       .frp_fib_index = 0,
       .frp_weight = 1,
+    .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
     };
-  /* *INDENT-ON* */
+  fib_route_path_t for_us_path = {
+    .frp_proto = fib_proto_to_dpo (FIB_PROTOCOL_IP4),
+    .frp_addr = zero_addr,
+    .frp_sw_if_index = 0xffffffff,
+    .frp_fib_index = 1,
+    .frp_weight = 0,
+    .frp_flags = FIB_ROUTE_PATH_LOCAL,
+    .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
+  };
+
   /* find configuration, if it doesn't exist, create new */
   config = igmp_config_lookup (sw_if_index);
   mfib_index = mfib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
@@ -375,7 +373,7 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
       vec_validate_init_empty (im->igmp_config_by_sw_if_index,
                               sw_if_index, ~0);
       pool_get (im->configs, config);
-      memset (config, 0, sizeof (igmp_config_t));
+      clib_memset (config, 0, sizeof (igmp_config_t));
       config->sw_if_index = sw_if_index;
       config->igmp_group_by_key =
        hash_create_mem (0, sizeof (igmp_key_t), sizeof (uword));
@@ -405,24 +403,20 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
        if (1 == im->n_configs_per_mfib_index[mfib_index])
          {
            /* first config in this FIB */
-           mfib_table_entry_path_update (mfib_index,
-                                         &mpfx_general_query,
+           mfib_table_lock (mfib_index, FIB_PROTOCOL_IP4, MFIB_SOURCE_IGMP);
+           mfib_table_entry_path_update (mfib_index, &mpfx_general_query,
                                          MFIB_SOURCE_IGMP,
-                                         &for_us_path,
-                                         MFIB_ITF_FLAG_FORWARD);
-           mfib_table_entry_path_update (mfib_index,
-                                         &mpfx_report,
+                                         MFIB_ENTRY_FLAG_NONE, &for_us_path);
+           mfib_table_entry_path_update (mfib_index, &mpfx_report,
                                          MFIB_SOURCE_IGMP,
-                                         &for_us_path,
-                                         MFIB_ITF_FLAG_FORWARD);
+                                         MFIB_ENTRY_FLAG_NONE, &for_us_path);
          }
-       mfib_table_entry_path_update (mfib_index,
-                                     &mpfx_general_query,
-                                     MFIB_SOURCE_IGMP,
-                                     &via_itf_path, MFIB_ITF_FLAG_ACCEPT);
+       mfib_table_entry_path_update (mfib_index, &mpfx_general_query,
+                                     MFIB_SOURCE_IGMP, MFIB_ENTRY_FLAG_NONE,
+                                     &via_itf_path);
        mfib_table_entry_path_update (mfib_index, &mpfx_report,
-                                     MFIB_SOURCE_IGMP, &via_itf_path,
-                                     MFIB_ITF_FLAG_ACCEPT);
+                                     MFIB_SOURCE_IGMP, MFIB_ENTRY_FLAG_NONE,
+                                     &via_itf_path);
       }
     }
   else if (config && !enable)
@@ -438,6 +432,7 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
          mfib_table_entry_path_remove (mfib_index,
                                        &mpfx_report,
                                        MFIB_SOURCE_IGMP, &for_us_path);
+         mfib_table_unlock (mfib_index, FIB_PROTOCOL_IP4, MFIB_SOURCE_IGMP);
        }
 
       mfib_table_entry_path_remove (mfib_index,
@@ -479,28 +474,25 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
 static clib_error_t *
 igmp_init (vlib_main_t * vm)
 {
-  clib_error_t *error;
   igmp_main_t *im = &igmp_main;
 
-  if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
-    return error;
-
   im->igmp_api_client_by_client_index = hash_create (0, sizeof (u32));
-
   im->logger = vlib_log_register_class ("igmp", 0);
 
   IGMP_DBG ("initialized");
 
-  return (error);
+  return (0);
 }
 
-VLIB_INIT_FUNCTION (igmp_init);
-/* *INDENT-OFF* */
-VLIB_PLUGIN_REGISTER () = {
+VLIB_INIT_FUNCTION (igmp_init) =
+{
+  .runs_after = VLIB_INITS("ip4_lookup_init"),
+};
+VLIB_PLUGIN_REGISTER () =
+{
   .version = VPP_BUILD_VER,
-  .description = "IGMP messaging",
+  .description = "Internet Group Management Protocol (IGMP)",
 };
-/* *INDENT-ON* */
 
 /*
  * fd.io coding-style-patch-verification: ON