fib: fib api updates
[vpp.git] / src / plugins / igmp / igmp.c
index 85ba35c..1e9f647 100644 (file)
@@ -142,12 +142,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",
@@ -346,15 +346,6 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode)
            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,7 +353,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,
     };
+  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,
+  };
+
   /* *INDENT-ON* */
   /* find configuration, if it doesn't exist, create new */
   config = igmp_config_lookup (sw_if_index);
@@ -375,12 +377,13 @@ 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));
       config->robustness_var = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
       config->mode = mode;
+      config->proxy_device_id = ~0;
 
       for (ii = 0; ii < IGMP_CONFIG_N_TIMERS; ii++)
        config->timers[ii] = IGMP_TIMER_ID_INVALID;
@@ -404,24 +407,19 @@ 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_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_SOURCE_IGMP, &for_us_path);
            mfib_table_entry_path_update (mfib_index,
                                          &mpfx_report,
-                                         MFIB_SOURCE_IGMP,
-                                         &for_us_path,
-                                         MFIB_ITF_FLAG_FORWARD);
+                                         MFIB_SOURCE_IGMP, &for_us_path);
          }
        mfib_table_entry_path_update (mfib_index,
                                      &mpfx_general_query,
-                                     MFIB_SOURCE_IGMP,
-                                     &via_itf_path, MFIB_ITF_FLAG_ACCEPT);
+                                     MFIB_SOURCE_IGMP, &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, &via_itf_path);
       }
     }
   else if (config && !enable)
@@ -437,6 +435,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,
@@ -445,6 +444,18 @@ 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, &via_itf_path);
+
+      /*
+       * remove interface from proxy device
+       * if this device is upstream, delete proxy device
+       */
+      if (config->mode == IGMP_MODE_ROUTER)
+       igmp_proxy_device_add_del_interface (config->proxy_device_id,
+                                            config->sw_if_index, 0);
+      else if (config->mode == IGMP_MODE_HOST)
+       igmp_proxy_device_add_del (config->proxy_device_id,
+                                  config->sw_if_index, 0);
+
       igmp_clear_config (config);
       im->igmp_config_by_sw_if_index[config->sw_if_index] = ~0;
       hash_free (config->igmp_group_by_key);
@@ -466,26 +477,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* */