aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/igmp/igmp_ssm_range.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2018-06-07 23:48:20 -0700
committerFlorin Coras <florin.coras@gmail.com>2018-07-09 21:10:53 +0000
commit947ea6222dad1ef04595c34273e9231395aef443 (patch)
tree8990854b2901ff8cc2241b9abfc99b0b4b54d517 /src/plugins/igmp/igmp_ssm_range.c
parentdd47ecadcf63772a6037a1bb3715772d80e87f51 (diff)
IGMP improvements
- Enable/Disable an interface for IGMP - improve logging - refactor common code - no orphaned timers - IGMP state changes in main thread only - Large groups split over multiple state-change reports - SSM range configuration API. - more tests Change-Id: If5674f1044e7e97274a711f47807c9ba689d7b9a Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/plugins/igmp/igmp_ssm_range.c')
-rw-r--r--src/plugins/igmp/igmp_ssm_range.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/plugins/igmp/igmp_ssm_range.c b/src/plugins/igmp/igmp_ssm_range.c
new file mode 100644
index 00000000000..3d12712d3db
--- /dev/null
+++ b/src/plugins/igmp/igmp_ssm_range.c
@@ -0,0 +1,162 @@
+/*
+ *------------------------------------------------------------------
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *------------------------------------------------------------------
+ */
+
+#include <igmp/igmp_ssm_range.h>
+
+typedef struct igmp_group_prefix_t
+{
+ fib_prefix_t igp_prefix;
+ igmp_group_prefix_type_t igp_type;
+} igmp_group_prefix_t;
+
+static igmp_group_prefix_t *igmp_group_prefixs;
+
+u8 *
+format_igmp_group_prefix_type (u8 * s, va_list * args)
+{
+ igmp_group_prefix_type_t type = va_arg (*args, int);
+
+ switch (type)
+ {
+#define _(n,f) case IGMP_GROUP_PREFIX_TYPE_##f: return (format (s, "%s", #f));
+ foreach_igmp_group_prefix_type
+#undef _
+ }
+ return format (s, "unknown:%d", type);
+}
+
+static int
+igmp_group_prefix_cmp (const igmp_group_prefix_t * gp1,
+ const fib_prefix_t * p)
+{
+ return (fib_prefix_cmp (&gp1->igp_prefix, p));
+}
+
+void
+igmp_group_prefix_set (const fib_prefix_t * pfx,
+ igmp_group_prefix_type_t type)
+{
+ u32 pos;
+
+ pos =
+ vec_search_with_function (igmp_group_prefixs, pfx, igmp_group_prefix_cmp);
+
+ if ((~0 == pos) && (IGMP_GROUP_PREFIX_TYPE_SSM == type))
+ {
+ igmp_group_prefix_t gp = {
+ .igp_prefix = *pfx,
+ .igp_type = type,
+ };
+
+ vec_add1 (igmp_group_prefixs, gp);
+ }
+ if ((~0 != pos) && (IGMP_GROUP_PREFIX_TYPE_ASM == type))
+ {
+ vec_del1 (igmp_group_prefixs, pos);
+ }
+}
+
+static void
+igmp_ssm_range_populate (void)
+{
+ igmp_group_prefix_t *ssm_default;
+
+ vec_add2 (igmp_group_prefixs, ssm_default, 1);
+
+ ssm_default->igp_prefix.fp_addr.ip4.as_u32 = IGMP_SSM_DEFAULT;
+ ssm_default->igp_prefix.fp_proto = FIB_PROTOCOL_IP4;
+ ssm_default->igp_prefix.fp_len = 8;
+ ssm_default->igp_type = IGMP_GROUP_PREFIX_TYPE_SSM;
+}
+
+igmp_group_prefix_type_t
+igmp_group_prefix_get_type (const ip46_address_t * gaddr)
+{
+ igmp_group_prefix_t *igp;
+
+ vec_foreach (igp, igmp_group_prefixs)
+ {
+ if (ip4_destination_matches_route (&ip4_main,
+ &gaddr->ip4,
+ &igp->igp_prefix.fp_addr.ip4,
+ igp->igp_prefix.fp_len))
+ return (IGMP_GROUP_PREFIX_TYPE_SSM);
+ }
+
+ return (IGMP_GROUP_PREFIX_TYPE_ASM);
+}
+
+void
+igmp_ssm_range_walk (igmp_ssm_range_walk_t fn, void *ctx)
+{
+ igmp_group_prefix_t *igp;
+
+ vec_foreach (igp, igmp_group_prefixs)
+ {
+ if (WALK_STOP == fn (&igp->igp_prefix, igp->igp_type, ctx))
+ break;
+ }
+}
+
+static clib_error_t *
+igmp_ssm_range_show (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+ igmp_group_prefix_t *igp;
+
+ vec_foreach (igp, igmp_group_prefixs)
+ {
+ vlib_cli_output (vm, "%U => %U",
+ format_fib_prefix, &igp->igp_prefix,
+ format_igmp_group_prefix_type, igp->igp_type);
+ }
+ return (NULL);
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (igmp_show_timers_command, static) = {
+ .path = "show igmp ssm-ranges",
+ .short_help = "show igmp ssm-ranges",
+ .function = igmp_ssm_range_show,
+};
+/* *INDENT-ON* */
+
+static clib_error_t *
+igmp_ssm_range_init (vlib_main_t * vm)
+{
+ clib_error_t *error;
+
+ if ((error = vlib_call_init_function (vm, igmp_init)))
+ return error;
+
+ igmp_ssm_range_populate ();
+
+ IGMP_DBG ("ssm-range-initialized");
+
+ return (error);
+}
+
+VLIB_INIT_FUNCTION (igmp_ssm_range_init);
+
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */