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>
This commit is contained in:

committed by
Chris Luke

parent
489cc82922
commit
7b867a8e49
@ -216,6 +216,7 @@ PLUGIN_ENABLED(dpdk)
|
||||
PLUGIN_ENABLED(flowprobe)
|
||||
PLUGIN_ENABLED(gbp)
|
||||
PLUGIN_ENABLED(gtpu)
|
||||
PLUGIN_ENABLED(igmp)
|
||||
PLUGIN_ENABLED(ila)
|
||||
PLUGIN_ENABLED(ioam)
|
||||
PLUGIN_ENABLED(ixge)
|
||||
|
@ -51,6 +51,10 @@ if ENABLE_GTPU_PLUGIN
|
||||
include gtpu.am
|
||||
endif
|
||||
|
||||
if ENABLE_IGMP_PLUGIN
|
||||
include igmp.am
|
||||
endif
|
||||
|
||||
if ENABLE_ILA_PLUGIN
|
||||
include ila.am
|
||||
endif
|
||||
|
31
src/plugins/igmp.am
Normal file
31
src/plugins/igmp.am
Normal file
@ -0,0 +1,31 @@
|
||||
# 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.
|
||||
|
||||
vppplugins_LTLIBRARIES += igmp_plugin.la
|
||||
|
||||
igmp_plugin_la_SOURCES = \
|
||||
igmp/igmp.c \
|
||||
igmp/cli.c \
|
||||
igmp/igmp_api.c \
|
||||
igmp/igmp_plugin.api.h \
|
||||
igmp/input.c \
|
||||
igmp/igmp_format.c
|
||||
|
||||
nobase_apiinclude_HEADERS += \
|
||||
igmp/igmp_all_api_h.h \
|
||||
igmp/igmp_msg_enum.h \
|
||||
igmp/igmp.api.h
|
||||
|
||||
API_FILES += igmp/igmp.api
|
||||
|
||||
# vi:syntax=automake
|
211
src/plugins/igmp/cli.c
Normal file
211
src/plugins/igmp/cli.c
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* 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 <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <vlib/vlib.h>
|
||||
#include <vlib/unix/unix.h>
|
||||
#include <vnet/ip/ip.h>
|
||||
#include <vnet/fib/fib_entry.h>
|
||||
#include <vnet/fib/fib_table.h>
|
||||
#include <vnet/mfib/mfib_table.h>
|
||||
|
||||
#include <igmp/igmp.h>
|
||||
|
||||
static clib_error_t *
|
||||
igmp_clear_interface_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
clib_error_t *error = NULL;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
u32 sw_if_index;
|
||||
|
||||
igmp_main_t *im = &igmp_main;
|
||||
igmp_config_t *config;
|
||||
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
{
|
||||
error =
|
||||
clib_error_return (0, "'help clear igmp' or 'clear igmp ?' for help");
|
||||
return error;
|
||||
}
|
||||
|
||||
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat
|
||||
(line_input, "int %U", unformat_vnet_sw_interface, vnm,
|
||||
&sw_if_index));
|
||||
else
|
||||
{
|
||||
error =
|
||||
clib_error_return (0, "unknown input '%U'", format_unformat_error,
|
||||
line_input);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
config = igmp_config_lookup (im, sw_if_index);
|
||||
if (config)
|
||||
igmp_clear_config (config);
|
||||
|
||||
done:
|
||||
unformat_free (line_input);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (igmp_clear_interface_command, static) = {
|
||||
.path = "clear igmp",
|
||||
.short_help = "clear igmp int <interface>",
|
||||
.function = igmp_clear_interface_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static clib_error_t *
|
||||
igmp_listen_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
unformat_input_t _line_input, *line_input = &_line_input;
|
||||
clib_error_t *error = NULL;
|
||||
u8 enable = 1;
|
||||
ip46_address_t saddr, gaddr;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
u32 sw_if_index;
|
||||
int rv;
|
||||
|
||||
if (!unformat_user (input, unformat_line_input, line_input))
|
||||
{
|
||||
error =
|
||||
clib_error_return (0,
|
||||
"'help igmp listen' or 'igmp listen ?' for help");
|
||||
return error;
|
||||
}
|
||||
|
||||
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (line_input, "enable"))
|
||||
enable = 1;
|
||||
else if (unformat (line_input, "disable"))
|
||||
enable = 0;
|
||||
else
|
||||
if (unformat
|
||||
(line_input, "int %U", unformat_vnet_sw_interface, vnm,
|
||||
&sw_if_index));
|
||||
else
|
||||
if (unformat (line_input, "saddr %U", unformat_ip46_address, &saddr));
|
||||
else
|
||||
if (unformat (line_input, "gaddr %U", unformat_ip46_address, &gaddr));
|
||||
else
|
||||
{
|
||||
error =
|
||||
clib_error_return (0, "unknown input '%U'", format_unformat_error,
|
||||
line_input);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ((vnet_sw_interface_get_flags (vnm, sw_if_index)
|
||||
&& VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
|
||||
{
|
||||
error = clib_error_return (0, "Interface is down");
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = igmp_listen (vm, enable, sw_if_index, saddr, gaddr,
|
||||
/* cli_api_listen */ 1);
|
||||
if (rv == -1)
|
||||
{
|
||||
if (enable)
|
||||
error =
|
||||
clib_error_return (0, "This igmp configuration already exists");
|
||||
else
|
||||
error =
|
||||
clib_error_return (0, "This igmp configuration does not nexist");
|
||||
}
|
||||
else if (rv == -2)
|
||||
error =
|
||||
clib_error_return (0,
|
||||
"Failed to add configuration, interface is in router mode");
|
||||
|
||||
done:
|
||||
unformat_free (line_input);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (igmp_listen_command, static) = {
|
||||
.path = "igmp listen",
|
||||
.short_help = "igmp listen [<enable|disable>] "
|
||||
"int <interface> saddr <ip4-address> gaddr <ip4-address>",
|
||||
.function = igmp_listen_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static clib_error_t *
|
||||
igmp_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
clib_error_t *error = NULL;
|
||||
igmp_main_t *im = &igmp_main;
|
||||
vnet_main_t *vnm = vnet_get_main ();
|
||||
igmp_config_t *config;
|
||||
igmp_sg_t *sg;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
pool_foreach (config, im->configs, (
|
||||
{
|
||||
vlib_cli_output (vm, "interface: %U", format_vnet_sw_if_index_name,
|
||||
vnm, config->sw_if_index);
|
||||
pool_foreach (sg, config->sg, (
|
||||
{
|
||||
vlib_cli_output (vm, "\t(S,G): %U:%U:%U", format_ip46_address,
|
||||
&sg->saddr, ip46_address_is_ip4 (&sg->saddr),
|
||||
format_ip46_address, &sg->gaddr, ip46_address_is_ip4
|
||||
(&sg->gaddr), format_igmp_report_type, sg->group_type);
|
||||
}));
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (igmp_show_command, static) = {
|
||||
.path = "show igmp config",
|
||||
.short_help = "show igmp config",
|
||||
.function = igmp_show_command_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
clib_error_t *
|
||||
igmp_cli_init (vlib_main_t * vm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
VLIB_INIT_FUNCTION (igmp_cli_init);
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
45
src/plugins/igmp/error.h
Normal file
45
src/plugins/igmp/error.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* 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_ERROR_H_
|
||||
#define _IGMP_ERROR_H_
|
||||
|
||||
#define foreach_igmp_error \
|
||||
_ (NONE, "valid igmp packets") \
|
||||
_ (UNSPECIFIED, "unspecified error") \
|
||||
_ (INVALID_PROTOCOL, "invalid ip4 protocol") \
|
||||
_ (BAD_CHECKSUM, "bad checksum") \
|
||||
_ (UNKNOWN_TYPE, "unknown igmp message type") \
|
||||
_ (CLI_API_CONFIG, "CLI/API configured (S,G)s on interface") \
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define _(sym,str) IGMP_ERROR_##sym,
|
||||
foreach_igmp_error
|
||||
#undef _
|
||||
IGMP_N_ERROR,
|
||||
} igmp_error_t;
|
||||
|
||||
#endif /* IGMP_ERROR_H */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
144
src/plugins/igmp/igmp.api
Normal file
144
src/plugins/igmp/igmp.api
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
option version = "1.0.0";
|
||||
|
||||
/** \brief
|
||||
Used by a 'host' to enable the recption/listening of packets for a specific
|
||||
multicast group
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param enable - if set, enable igmp messages on configuration
|
||||
@param sw_if_index - interface sw index
|
||||
@param saddr - source address
|
||||
@param gaddr - group address
|
||||
*/
|
||||
autoreply define igmp_listen
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
u8 enable;
|
||||
u32 sw_if_index;
|
||||
u8 saddr[4];
|
||||
u8 gaddr[4];
|
||||
};
|
||||
|
||||
/** \brief
|
||||
Used by a 'router' to enable the recption of IGMP packets and the
|
||||
construction of group state for hosts on the link
|
||||
multicast group
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param enable - if set, enable igmp messages on configuration
|
||||
@param sw_if_index - interface sw index
|
||||
*/
|
||||
autoreply define igmp_enable_disable
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
u8 enable;
|
||||
u32 sw_if_index;
|
||||
};
|
||||
|
||||
/** \brief dump (S,G)s from interface
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - interface sw index
|
||||
@param dump_all - get (S,G)s from all interfaces
|
||||
*/
|
||||
define igmp_dump
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
u32 sw_if_index;
|
||||
u8 dump_all;
|
||||
};
|
||||
|
||||
/** \brief igmp details
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - interface sw index
|
||||
@param saddr - source address
|
||||
@param gaddr - group address
|
||||
*/
|
||||
define igmp_details
|
||||
{
|
||||
u32 context;
|
||||
|
||||
u32 sw_if_index;
|
||||
u8 saddr[4];
|
||||
u8 gaddr[4];
|
||||
};
|
||||
|
||||
/** \brief remove all (S,G)s from an interface
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - interface sw index
|
||||
*/
|
||||
autoreply define igmp_clear_interface
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
u32 sw_if_index;
|
||||
};
|
||||
|
||||
/** \brief register for igmp events
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param pid - sender's pid
|
||||
@param enable - 1 enable, 0 disable igmp events
|
||||
*/
|
||||
autoreply define want_igmp_events
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
u32 enable;
|
||||
u32 pid;
|
||||
};
|
||||
|
||||
service {
|
||||
rpc want_igmp_events returns want_igmp_events_reply
|
||||
events igmp_event;
|
||||
};
|
||||
|
||||
/** \brief igmp event details
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - interface sw index
|
||||
@param saddr - source address
|
||||
@param gaddr - group address
|
||||
@param is_join - if set source is joining the group, else leaving
|
||||
*/
|
||||
define igmp_event
|
||||
{
|
||||
u32 context;
|
||||
|
||||
u32 sw_if_index;
|
||||
u8 saddr[4];
|
||||
u8 gaddr[4];
|
||||
u8 is_join;
|
||||
};
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
849
src/plugins/igmp/igmp.c
Normal file
849
src/plugins/igmp/igmp.c
Normal file
File diff suppressed because it is too large
Load Diff
35
src/plugins/igmp/igmp.def
Normal file
35
src/plugins/igmp/igmp.def
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* Copyright (c) 2018 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
igmp_type (0x11, membership_query)
|
||||
igmp_type (0x12, membership_report_v1)
|
||||
igmp_type (0x13, dvmrp)
|
||||
igmp_type (0x14, pim_v1)
|
||||
igmp_type (0x15, cisco_trace)
|
||||
igmp_type (0x16, membership_report_v2)
|
||||
igmp_type (0x17, leave_group_v2)
|
||||
igmp_type (0x1e, traceroute_response)
|
||||
igmp_type (0x1f, traceroute_request)
|
||||
igmp_type (0x22, membership_report_v3)
|
||||
igmp_type (0x30, router_advertisement)
|
||||
igmp_type (0x32, router_termination)
|
||||
igmp_report_type (1, mode_is_filter_include)
|
||||
igmp_report_type (2, mode_is_filter_exclude)
|
||||
igmp_report_type (3, change_to_filter_include)
|
||||
igmp_report_type (4, change_to_filter_exclude)
|
||||
igmp_report_type (5, allow_new_sources)
|
||||
igmp_report_type (6, block_old_sources)
|
286
src/plugins/igmp/igmp.h
Normal file
286
src/plugins/igmp/igmp.h
Normal file
@ -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:
|
||||
*/
|
26
src/plugins/igmp/igmp_all_api_h.h
Normal file
26
src/plugins/igmp/igmp_all_api_h.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* 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.api.h>
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
337
src/plugins/igmp/igmp_api.c
Normal file
337
src/plugins/igmp/igmp_api.c
Normal file
File diff suppressed because it is too large
Load Diff
159
src/plugins/igmp/igmp_format.c
Normal file
159
src/plugins/igmp/igmp_format.c
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* Copyright (c) 2018 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.h>
|
||||
#include <vnet/ip/ip.h>
|
||||
|
||||
u8 *
|
||||
format_igmp_type (u8 * s, va_list * args)
|
||||
{
|
||||
igmp_type_t type = va_arg (*args, igmp_type_t);
|
||||
igmp_main_t *im = &igmp_main;
|
||||
igmp_type_info_t *ti = igmp_get_type_info (im, type);
|
||||
|
||||
if (ti)
|
||||
return format (s, "%s", ti->name);
|
||||
else
|
||||
return format (s, "unknown %d", type);
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_igmp_report_type (u8 * s, va_list * args)
|
||||
{
|
||||
igmp_membership_group_v3_type_t report_type =
|
||||
va_arg (*args, igmp_membership_group_v3_type_t);
|
||||
igmp_main_t *im = &igmp_main;
|
||||
igmp_report_type_info_t *rti = igmp_get_report_type_info (im, report_type);
|
||||
|
||||
if (rti)
|
||||
return format (s, "%s", rti->name);
|
||||
else
|
||||
return format (s, "unknown %d", report_type);
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_igmp_header (u8 * s, va_list * args)
|
||||
{
|
||||
igmp_header_t *hdr = va_arg (*args, igmp_header_t *);
|
||||
u32 max_header_bytes = va_arg (*args, u32);
|
||||
u32 indent;
|
||||
|
||||
if (max_header_bytes < sizeof (hdr[0]))
|
||||
return format (s, "IGMP header truncated");
|
||||
|
||||
indent = format_get_indent (s);
|
||||
indent += 2;
|
||||
|
||||
s =
|
||||
format (s, "%U%U: code %u, checksum 0x%04x", format_white_space, indent,
|
||||
format_igmp_type, hdr->type, hdr->code,
|
||||
clib_net_to_host_u16 (hdr->checksum));
|
||||
return s;
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_igmp_report_v3 (u8 * s, va_list * args)
|
||||
{
|
||||
igmp_membership_report_v3_t *igmp =
|
||||
va_arg (*args, igmp_membership_report_v3_t *);
|
||||
u32 max_header_bytes = va_arg (*args, u32);
|
||||
igmp_membership_group_v3_t *group;
|
||||
|
||||
u32 len = sizeof (igmp_membership_report_v3_t);
|
||||
u32 indent;
|
||||
|
||||
if (max_header_bytes < sizeof (igmp[0]))
|
||||
return format (s, "IGMP report truncated");
|
||||
|
||||
indent = format_get_indent (s);
|
||||
indent += 2;
|
||||
|
||||
s =
|
||||
format (s, "%Un_groups %u", format_white_space, indent,
|
||||
clib_net_to_host_u16 (igmp->n_groups));
|
||||
indent += 2;
|
||||
int i, j = 0;
|
||||
for (i = 0; i < clib_net_to_host_u16 (igmp->n_groups); i++)
|
||||
{
|
||||
group = group_ptr (igmp, len);
|
||||
s =
|
||||
format (s, "\n%U%U: %U, sources %u", format_white_space, indent,
|
||||
format_igmp_report_type, group->type, format_ip4_address,
|
||||
&group->dst_address,
|
||||
clib_net_to_host_u16 (group->n_src_addresses));
|
||||
indent += 2;
|
||||
for (j = 0; j < clib_net_to_host_u16 (group->n_src_addresses); j++)
|
||||
{
|
||||
s =
|
||||
format (s, "\n%U%U", format_white_space, indent,
|
||||
format_ip4_address, &group->src_addresses[j]);
|
||||
}
|
||||
indent -= 2;
|
||||
len +=
|
||||
sizeof (igmp_membership_group_v3_t) +
|
||||
(sizeof (ip4_address_t) *
|
||||
clib_net_to_host_u16 (group->n_src_addresses));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
u8 *
|
||||
format_igmp_query_v3 (u8 * s, va_list * args)
|
||||
{
|
||||
igmp_membership_query_v3_t *igmp =
|
||||
va_arg (*args, igmp_membership_query_v3_t *);
|
||||
u32 max_header_bytes = va_arg (*args, u32);
|
||||
u32 indent;
|
||||
int i;
|
||||
|
||||
if (max_header_bytes < sizeof (igmp[0]))
|
||||
return format (s, "IGMP query truncated");
|
||||
|
||||
indent = format_get_indent (s);
|
||||
indent += 2;
|
||||
|
||||
ip4_address_t tmp;
|
||||
tmp.as_u32 = 0;
|
||||
|
||||
if ((!ip4_address_compare (&igmp->dst, &tmp))
|
||||
&& (igmp->n_src_addresses == 0))
|
||||
s = format (s, "%UGeneral Query", format_white_space, indent);
|
||||
else if (igmp->n_src_addresses == 0)
|
||||
s = format (s, "%UGroup-Specific Query: %U", format_white_space, indent,
|
||||
format_ip4_address, &igmp->dst);
|
||||
else
|
||||
{
|
||||
s =
|
||||
format (s, "%UGroup-and-Source-Specific Query: %U",
|
||||
format_white_space, indent, format_ip4_address, &igmp->dst);
|
||||
indent += 2;
|
||||
for (i = 0; i < clib_net_to_host_u16 (igmp->n_src_addresses); i++)
|
||||
{
|
||||
s = format (s, "\n%U%U", format_white_space, indent,
|
||||
format_ip4_address, &igmp->src_addresses[i]);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
39
src/plugins/igmp/igmp_format.h
Normal file
39
src/plugins/igmp/igmp_format.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* Copyright (c) 2018 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_FORMAT_H_
|
||||
#define _IGMP_FORMAT_H_
|
||||
|
||||
u8 *format_igmp_type (u8 * s, va_list * args);
|
||||
|
||||
u8 *format_igmp_report_type (u8 * s, va_list * args);
|
||||
|
||||
u8 *format_igmp_header (u8 * s, va_list * args);
|
||||
|
||||
u8 *format_igmp_report_v3 (u8 * s, va_list * args);
|
||||
|
||||
u8 *format_igmp_query_v3 (u8 * s, va_list * args);
|
||||
|
||||
#endif /* IGMP_FORMAT_H */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
39
src/plugins/igmp/igmp_msg_enum.h
Normal file
39
src/plugins/igmp/igmp_msg_enum.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*------------------------------------------------------------------
|
||||
* 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_MSG_ENUM_H_
|
||||
#define _IGMP_MSG_ENUM_H_
|
||||
|
||||
#include <vppinfra/byte_order.h>
|
||||
|
||||
#define vl_msg_id(n,h) n,
|
||||
typedef enum
|
||||
{
|
||||
#include <igmp/igmp_all_api_h.h>
|
||||
VL_MSG_FIRST_AVAILABLE,
|
||||
} vl_msg_id_t;
|
||||
#undef vl_msg_id
|
||||
|
||||
#endif /* IGMP_MSG_ENUM_H_ */
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
550
src/plugins/igmp/input.c
Normal file
550
src/plugins/igmp/input.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,8 @@
|
||||
#include <vnet/fib/fib_node_list.h>
|
||||
#include <vnet/fib/fib_urpf_list.h>
|
||||
|
||||
#include <vlib/unix/plugin.h>
|
||||
|
||||
/*
|
||||
* Add debugs for passing tests
|
||||
*/
|
||||
@ -827,7 +829,15 @@ fib_test_v4 (void)
|
||||
* table, and 4 path-lists in the v6 MFIB table
|
||||
*/
|
||||
#define ENBR (5+5+2)
|
||||
#define PNBR (5+5+6)
|
||||
|
||||
u32 PNBR = 5+5+2+4;
|
||||
|
||||
/*
|
||||
* if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
|
||||
*/
|
||||
if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
|
||||
PNBR += 2;
|
||||
|
||||
FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
|
||||
FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
|
||||
fib_path_list_pool_size());
|
||||
@ -4343,7 +4353,13 @@ fib_test_v6 (void)
|
||||
* All entries are special so no path-list sharing.
|
||||
*/
|
||||
#define ENPS (5+4)
|
||||
#define PNPS (5+4+4)
|
||||
u32 PNPS = (5+4+4);
|
||||
/*
|
||||
* if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
|
||||
*/
|
||||
if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
|
||||
PNPS += 2;
|
||||
|
||||
FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
|
||||
FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
|
||||
fib_path_list_pool_size());
|
||||
|
@ -83,6 +83,24 @@ typedef struct
|
||||
ip4_address_t dst;
|
||||
} igmp_message_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* type 0x11 (IGMPv3) */
|
||||
igmp_header_t header;
|
||||
|
||||
ip4_address_t dst;
|
||||
|
||||
/* Reserved, Suppress Router-Side Processing flag and
|
||||
Querier's Robustness Variable RRRRSQQQ. */
|
||||
u8 resv_s_qrv;
|
||||
|
||||
/* Querier's Query Interval Code */
|
||||
u8 qqi_code;
|
||||
|
||||
u16 n_src_addresses;
|
||||
ip4_address_t src_addresses[0];
|
||||
} igmp_membership_query_v3_t;
|
||||
|
||||
#define foreach_igmp_membership_group_v3_type \
|
||||
_ (1, mode_is_filter_include) \
|
||||
_ (2, mode_is_filter_exclude) \
|
||||
|
323
test/test_igmp.py
Normal file
323
test/test_igmp.py
Normal file
File diff suppressed because it is too large
Load Diff
39
test/vpp_igmp.py
Normal file
39
test/vpp_igmp.py
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
from vpp_object import VppObject
|
||||
|
||||
|
||||
class IgmpSG():
|
||||
def __init__(self, saddr, gaddr):
|
||||
self.saddr = saddr
|
||||
self.gaddr = gaddr
|
||||
|
||||
|
||||
class VppIgmpConfig(VppObject):
|
||||
def __init__(self, test, sw_if_index, sg=None):
|
||||
self._test = test
|
||||
self.sw_if_index = sw_if_index
|
||||
if isinstance(sg, list):
|
||||
self.sg_list = sg
|
||||
else:
|
||||
self.sg_list = []
|
||||
self.sg_list.append(sg)
|
||||
|
||||
def add_sg(self, sg):
|
||||
self.sg.append(sg)
|
||||
|
||||
def add_vpp_config(self):
|
||||
for e in self.sg_list:
|
||||
self._test.vapi.igmp_listen(
|
||||
1, self.sw_if_index, e.saddr, e.gaddr)
|
||||
|
||||
def remove_vpp_config(self):
|
||||
self._test.vapi.igmp_clear_interface(self.sw_if_index)
|
||||
|
||||
def __str__(self):
|
||||
return self.object_id()
|
||||
|
||||
def object_id(self):
|
||||
return "%s:%d" % (self.sg_list, self.sw_if_index)
|
||||
|
||||
def query_vpp_config(self):
|
||||
return self._test.vapi.igmp_dump()
|
@ -3291,3 +3291,39 @@ class VppPapiProvider(object):
|
||||
{'sw_if_index': sw_if_index,
|
||||
'input_source': input_source,
|
||||
'enable': enable})
|
||||
|
||||
def igmp_listen(self, enable, sw_if_index, saddr, gaddr):
|
||||
""" Listen for new (S,G) on specified interface
|
||||
|
||||
:param enable: add/del
|
||||
:param sw_if_index: interface sw index
|
||||
:param saddr: source ip4 addr
|
||||
:param gaddr: group ip4 addr
|
||||
"""
|
||||
return self.api(self.papi.igmp_listen,
|
||||
{'enable': enable,
|
||||
'sw_if_index': sw_if_index,
|
||||
'saddr': saddr,
|
||||
'gaddr': gaddr})
|
||||
|
||||
def igmp_dump(self, sw_if_index=None):
|
||||
""" Dump all (S,G) interface configurations """
|
||||
if sw_if_index is None:
|
||||
dump_all = 1
|
||||
sw_if_index = 0
|
||||
else:
|
||||
dump_all = 0
|
||||
return self.api(self.papi.igmp_dump, {'sw_if_index': sw_if_index,
|
||||
'dump_all': dump_all})
|
||||
|
||||
def igmp_clear_interface(self, sw_if_index):
|
||||
""" Remove all (S,G)s from specified interface
|
||||
doesn't send IGMP report!
|
||||
"""
|
||||
return self.api(
|
||||
self.papi.igmp_clear_interface, {
|
||||
'sw_if_index': sw_if_index})
|
||||
|
||||
def want_igmp_events(self, enable=1):
|
||||
return self.api(self.papi.want_igmp_events, {'enable': enable,
|
||||
'pid': os.getpid()})
|
||||
|
Reference in New Issue
Block a user