summaryrefslogtreecommitdiffstats
path: root/src/plugins/igmp/igmp.h
diff options
context:
space:
mode:
authorJakub Grajciar <jgrajcia@cisco.com>2017-12-08 16:28:42 +0100
committerChris Luke <chris_luke@comcast.com>2018-03-19 15:53:19 +0000
commit7b867a8e491357058d37838091ed67a2e77bce2c (patch)
tree8f9373e4e41e930d0f20e90305168a1ab80dd714 /src/plugins/igmp/igmp.h
parent489cc829224407a51ca8d612c92bd78c30eaf660 (diff)
IGMP plugin
- host mode: igmp_listen - API to signal that the host has joined an (S,G) - route mode: igmp_enable - API to enable the reception of host IGMP messages igmp_event - API to report the host join/leave from an (S,G) Change-Id: Id180ec27dee617d33ab3088f5dcf6125d3aa9c8f Signed-off-by: Jakub Grajciar <jgrajcia@cisco.com>
Diffstat (limited to 'src/plugins/igmp/igmp.h')
-rw-r--r--src/plugins/igmp/igmp.h286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/plugins/igmp/igmp.h b/src/plugins/igmp/igmp.h
new file mode 100644
index 00000000000..c98cbd1dc0b
--- /dev/null
+++ b/src/plugins/igmp/igmp.h
@@ -0,0 +1,286 @@
+/*
+ *------------------------------------------------------------------
+ * 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.
+ *------------------------------------------------------------------
+ */
+
+#ifndef _IGMP_H_
+#define _IGMP_H_
+
+#include <vlib/vlib.h>
+#include <vnet/ip/ip.h>
+#include <vnet/ip/igmp_packet.h>
+#include <vnet/adj/adj_mcast.h>
+#include <igmp/igmp_format.h>
+
+#define IGMP_QUERY_TIMER (60)
+#define IGMP_SG_TIMER (3 * IGMP_QUERY_TIMER)
+#define IGMP_DEFAULT_ROBUSTNESS_VARIABLE (2)
+
+#define IGMP_DBG 1
+
+#if IGMP_DBG
+#define DBG(...) clib_warning(__VA_ARGS__)
+#else
+#define DBG(...)
+#endif /* IGMP_DBG */
+
+#define group_ptr(p, l) ((igmp_membership_group_v3_t *)((void*)p + l))
+
+enum
+{
+ IGMP_PROCESS_EVENT_UPDATE_TIMER = 1,
+} igmp_process_event_t;
+
+typedef enum
+{
+ IGMP_V1,
+ IGMP_V2,
+ IGMP_V3,
+} igmp_ver_t;
+
+struct igmp_config_t_;
+
+typedef struct igmp_config_t_ igmp_config_t;
+
+/* populate supplied bufefr with IGMP message */
+typedef void (create_msg_t) (vlib_buffer_t * b, igmp_config_t * config);
+
+typedef struct igmp_index_t_
+{
+ u32 config_index;
+ u32 sg_index;
+} igmp_index_t;
+
+typedef struct igmp_sg_key_t_
+{
+ ip46_address_t gaddr;
+ ip46_address_t saddr;
+} igmp_sg_key_t;
+
+typedef struct igmp_sg_t_
+{
+ ip46_address_t gaddr;
+ ip46_address_t saddr;
+
+ igmp_membership_group_v3_type_t group_type;
+
+ /* check if expired (S,G) timer is valid */
+ f64 exp_time;
+
+ igmp_sg_key_t *key;
+} igmp_sg_t;
+
+typedef struct igmp_config_t_
+{
+ u32 sw_if_index;
+
+ adj_index_t adj_index;
+
+ u8 cli_api_configured;
+
+ create_msg_t *next_create_msg;
+
+ igmp_ver_t igmp_ver;
+
+ 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_sg_by_key;
+
+ /* pool of (S,G)s per interface */
+ igmp_sg_t *sg;
+} igmp_config_t;
+
+struct igmp_timer_t_;
+
+typedef struct igmp_timer_t_ igmp_timer_t;
+
+typedef struct igmp_api_client_t_
+{
+ u32 client_index;
+ u32 pid;
+} igmp_api_client_t;
+
+typedef struct
+{
+ u8 *name;
+ igmp_type_t type;
+} igmp_type_info_t;
+
+typedef struct
+{
+ u8 *name;
+ igmp_membership_group_v3_type_t type;
+} igmp_report_type_info_t;
+
+typedef struct igmp_main_t_
+{
+ /** API message ID base */
+ u16 msg_id_base;
+
+ /* get api client by client_index */
+ uword *igmp_api_client_by_client_index;
+
+ /** pool of api clients registered for join/leave notifications */
+ igmp_api_client_t *api_clients;
+
+ /* get config index by config key */
+ uword *igmp_config_by_sw_if_index;
+
+ /** pool of igmp configurations */
+ igmp_config_t *configs;
+
+ /** buffer cache */
+ u32 **buffers;
+
+ /* next report/deletion */
+ igmp_index_t next_index;
+
+ /** pool of igmp timers */
+ igmp_timer_t *timers;
+
+ igmp_type_info_t *type_infos;
+ igmp_report_type_info_t *report_type_infos;
+
+ uword *type_info_by_type;
+ uword *report_type_info_by_report_type;
+
+} igmp_main_t;
+
+extern igmp_main_t igmp_main;
+
+typedef void (igmp_timer_function_t) (vlib_main_t * vm,
+ vlib_node_runtime_t * rt,
+ igmp_main_t * im, igmp_timer_t * timer);
+
+typedef struct igmp_timer_t_
+{
+ f64 exp_time;
+ igmp_timer_function_t *func;
+
+ u32 sw_if_index;
+ void *data;
+} igmp_timer_t;
+
+extern vlib_node_registration_t igmp_timer_process_node;
+extern vlib_node_registration_t igmp_input_node;
+extern vlib_node_registration_t igmp_parse_query_node;
+extern vlib_node_registration_t igmp_parse_report_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);
+
+void igmp_clear_config (igmp_config_t * config);
+
+void igmp_sort_timers (igmp_timer_t * timers);
+
+void igmp_create_int_timer (f64 time, u32 sw_if_index,
+ igmp_timer_function_t * func);
+void igmp_create_sg_timer (f64 time, u32 sw_if_index, igmp_sg_key_t * key,
+ igmp_timer_function_t * func);
+
+void igmp_send_query (vlib_main_t * vm, vlib_node_runtime_t * rt,
+ igmp_main_t * im, igmp_timer_t * timer);
+void igmp_query_resp_exp (vlib_main_t * vm, vlib_node_runtime_t * rt,
+ igmp_main_t * im, igmp_timer_t * timer);
+void igmp_send_report (vlib_main_t * vm, vlib_node_runtime_t * rt,
+ igmp_main_t * im, igmp_timer_t * timer);
+void igmp_send_state_changed (vlib_main_t * vm, vlib_node_runtime_t * rt,
+ igmp_main_t * im, igmp_timer_t * timer);
+void igmp_sg_exp (vlib_main_t * vm, vlib_node_runtime_t * rt,
+ igmp_main_t * im, igmp_timer_t * timer);
+
+static inline igmp_type_info_t *
+igmp_get_type_info (igmp_main_t * im, u32 type)
+{
+ uword *p;
+
+ p = hash_get (im->type_info_by_type, type);
+ return p ? vec_elt_at_index (im->type_infos, p[0]) : 0;
+}
+
+static inline igmp_report_type_info_t *
+igmp_get_report_type_info (igmp_main_t * im, u8 report_type)
+{
+ uword *p;
+
+ p = hash_get (im->report_type_info_by_report_type, report_type);
+ return p ? vec_elt_at_index (im->report_type_infos, p[0]) : 0;
+}
+
+void igmp_event (igmp_main_t * im, igmp_config_t * config, igmp_sg_t * sg);
+
+typedef enum
+{
+ IGMP_NEXT_IP4_REWRITE_MCAST_NODE,
+ IGMP_NEXT_IP6_REWRITE_MCAST_NODE,
+ IGMP_N_NEXT,
+} igmp_next_t;
+
+
+always_inline igmp_config_t *
+igmp_config_lookup (igmp_main_t * im, u32 sw_if_index)
+{
+ uword *p;
+ igmp_config_t *config = NULL;
+
+ p = hash_get_mem (im->igmp_config_by_sw_if_index, &sw_if_index);
+ if (p)
+ config = vec_elt_at_index (im->configs, p[0]);
+
+ return config;
+}
+
+always_inline igmp_sg_t *
+igmp_sg_lookup (igmp_config_t * config, igmp_sg_key_t * key)
+{
+ uword *p;
+ igmp_sg_t *sg = NULL;
+ if (!config)
+ return NULL;
+
+ p = hash_get_mem (config->igmp_sg_by_key, key);
+ if (p)
+ sg = vec_elt_at_index (config->sg, p[0]);
+
+ return sg;
+}
+
+always_inline igmp_api_client_t *
+igmp_api_client_lookup (igmp_main_t * im, u32 client_index)
+{
+ uword *p;
+ igmp_api_client_t *api_client = NULL;
+
+ p = hash_get_mem (im->igmp_api_client_by_client_index, &client_index);
+ if (p)
+ api_client = vec_elt_at_index (im->api_clients, p[0]);
+
+ return api_client;
+}
+
+#endif /* _IGMP_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */