Skip to content
Snippets Groups Projects
Commit 7e7875c4 authored by Anatoly Mirin's avatar Anatoly Mirin
Browse files

mcproxy: add max groups parameter

New max_groups parameter is intended to limit the maximum number
of group subscriptions per mcproxy instance.

Also the same parameter is written by mcastmngr to
'/proc/sys/net/ipv4/igmp_max_memberships', but this is not enough.
mcproxy must explicitly analyze this parameter to prevent MFC entries
from being added to mr_table and packet forwarding for extra groups.
parent 2cf04cfa
No related branches found
No related tags found
1 merge request!20mcproxy: add max groups parameter
--- a/mcproxy/include/parser/configuration.hpp
+++ b/mcproxy/include/parser/configuration.hpp
@@ -46,6 +46,7 @@ private:
int m_lmqi = -1; // Last member Query interval
int m_rv = -1; // robustness value
bool m_fastleave = true; // Fast leave
+ int m_max_groups = -1;
//<line number (for a better error message output), command>
std::vector<std::pair<unsigned int, std::string>> m_cmds;
@@ -70,6 +71,7 @@ public:
int get_last_member_query_interval() const;
int get_robustness_value() const;
bool get_fastleave() const;
+ int get_max_groups() const;
std::string to_string() const;
--- a/mcproxy/include/parser/parser.hpp
+++ b/mcproxy/include/parser/parser.hpp
@@ -39,7 +39,8 @@ enum parser_type {
PT_QRI,
PT_LMQI,
PT_RV,
- PT_FASTLEAVE
+ PT_FASTLEAVE,
+ PT_MAX_GROUPS
};
class parser
--- a/mcproxy/include/parser/token.hpp
+++ b/mcproxy/include/parser/token.hpp
@@ -64,7 +64,8 @@ enum token_type {
TT_QRI,
TT_LMQI,
TT_RV,
- TT_FASTLEAVE
+ TT_FASTLEAVE,
+ TT_MAX_GROUPS
};
std::string get_token_type_name(token_type tt);
--- a/mcproxy/include/proxy/querier.hpp
+++ b/mcproxy/include/proxy/querier.hpp
@@ -58,6 +58,8 @@ private:
//join all router groups or leave them
bool router_groups_function(bool subscribe) const;
+ // get max number of groups, taking into account router groups
+ unsigned int get_effective_max_groups() const;
bool send_general_query();
//
--- a/mcproxy/include/proxy/timers_values.hpp
+++ b/mcproxy/include/proxy/timers_values.hpp
@@ -36,6 +36,7 @@ struct timers_values_tank {
std::chrono::milliseconds last_listener_query_interval = std::chrono::milliseconds(1000);
unsigned int last_listener_query_count = robustness_variable;
std::chrono::milliseconds unsolicited_report_interval = std::chrono::milliseconds(1000);
+ unsigned int max_groups = 20;
};
static timers_values_tank default_timers_values_tank = timers_values_tank();
@@ -82,6 +83,7 @@ public:
std::chrono::milliseconds get_last_listener_query_time() const; //
std::chrono::milliseconds get_unsolicited_report_interval() const;
std::chrono::milliseconds get_older_host_present_interval() const; //
+ unsigned int get_max_groups() const;
void set_robustness_variable(unsigned int robustness_variable);
void set_query_interval(std::chrono::seconds query_interval);
@@ -91,6 +93,7 @@ public:
void set_last_listener_query_interval(std::chrono::milliseconds last_listener_query_interval);
void set_last_listener_query_count(unsigned int last_listener_query_count);
void set_unsolicited_report_interval(std::chrono::milliseconds unsolicited_report_interval);
+ void set_max_groups(unsigned int max_groups);
void reset_to_default_tank();
--- a/mcproxy/src/parser/configuration.cpp
+++ b/mcproxy/src/parser/configuration.cpp
@@ -166,6 +166,10 @@ void configuration::run_parser()
m_fastleave = (p.parse_get_pram_value())?true:false;
break;
}
+ case PT_MAX_GROUPS: {
+ m_max_groups = p.parse_get_pram_value();
+ break;
+ }
case PT_INSTANCE_DEFINITION: {
p.parse_instance_definition(m_inst_def_set);
break;
@@ -338,6 +342,11 @@ bool configuration::get_fastleave() cons
HC_LOG_TRACE("");
return m_fastleave;
}
+int configuration::get_max_groups() const
+{
+ HC_LOG_TRACE("");
+ return m_max_groups;
+}
const inst_def_set& configuration::get_inst_def_set() const
{
--- a/mcproxy/src/parser/parser.cpp
+++ b/mcproxy/src/parser/parser.cpp
@@ -50,6 +50,8 @@ parser_type parser::get_parser_type()
return PT_RV;
} else if (m_current_token.get_type() == TT_FASTLEAVE) {
return PT_FASTLEAVE;
+ } else if (m_current_token.get_type() == TT_MAX_GROUPS) {
+ return PT_MAX_GROUPS;
} else if (m_current_token.get_type() == TT_PINSTANCE) {
auto cmp_token = m_scanner.get_next_token(true, 1);
if (cmp_token.get_type() == TT_DOUBLE_DOT || cmp_token.get_type() == TT_LEFT_BRACKET) {
--- a/mcproxy/src/parser/scanner.cpp
+++ b/mcproxy/src/parser/scanner.cpp
@@ -200,6 +200,8 @@ token scanner::read_next_token()
return TT_RV;
} else if (cmp_str.compare("fastleave") == 0) {
return TT_FASTLEAVE;
+ } else if (cmp_str.compare("max_groups") == 0) {
+ return TT_MAX_GROUPS;
} else {
return token(TT_STRING, s.str());
}
--- a/mcproxy/src/proxy/proxy.cpp
+++ b/mcproxy/src/proxy/proxy.cpp
@@ -287,6 +287,12 @@ void proxy::start_proxy_instances()
std::cout << "fastleave :" <<m_configuration->get_fastleave() <<std::endl;
+ val = m_configuration->get_max_groups();
+ std::cout << "max_groups :" << val <<std::endl;
+ if ( val > 0 ) {
+ tv.set_max_groups(val);
+ }
+
pr_i->add_msg(std::make_shared<config_msg>(config_msg::ADD_DOWNSTREAM, if_index, d, tv));
}
--- a/mcproxy/src/proxy/querier.cpp
+++ b/mcproxy/src/proxy/querier.cpp
@@ -92,6 +92,42 @@ bool querier::router_groups_function(boo
}
return rc;
}
+
+unsigned int querier::get_effective_max_groups() const
+{
+ unsigned int max_groups = m_timers_values.get_max_groups();
+ if (max_groups == 0)
+ return 0;
+
+ if (is_IPv4(m_db.querier_version_mode)) {
+ auto router_group = m_db.group_info.find(addr_storage(IPV4_ALL_IGMP_ROUTERS_ADDR));
+ if (router_group != end(m_db.group_info)) {
+ max_groups++;
+ }
+ router_group = m_db.group_info.find(addr_storage(IPV4_IGMPV3_ADDR));
+ if (router_group != end(m_db.group_info)) {
+ max_groups++;
+ }
+ } else if (is_IPv6(m_db.querier_version_mode)) {
+ auto router_group = m_db.group_info.find(addr_storage(IPV6_ALL_NODE_LOCAL_ROUTER));
+ if (router_group != end(m_db.group_info)) {
+ max_groups++;
+ }
+ router_group = m_db.group_info.find(addr_storage(IPV6_ALL_SITE_LOCAL_ROUTER));
+ if (router_group != end(m_db.group_info)) {
+ max_groups++;
+ }
+ router_group = m_db.group_info.find(addr_storage(IPV6_ALL_MLDv2_CAPABLE_ROUTERS));
+ if (router_group != end(m_db.group_info)) {
+ max_groups++;
+ }
+ } else {
+ HC_LOG_ERROR("unknown ip version");
+ }
+
+ return max_groups;
+}
+
bool querier::send_general_query()
{
HC_LOG_TRACE("");
@@ -128,6 +164,18 @@ void querier::receive_record(const std::
auto db_info_it = m_db.group_info.find(gr->get_gaddr());
if (db_info_it == end(m_db.group_info)) {
+ unsigned int max_groups = m_timers_values.get_max_groups();
+ if ((max_groups > 0) && (m_db.group_info.size() >= max_groups))
+ {
+ max_groups = get_effective_max_groups();
+ if ((max_groups > 0) && (m_db.group_info.size() >= max_groups))
+ {
+ HC_LOG_ERROR("Max groups number exceeded (" << m_timers_values.get_max_groups() << "), " <<
+ "group record skipped: " << gr->get_gaddr());
+ return;
+ }
+ }
+
//add an empty neutral record to membership database
HC_LOG_DEBUG("gaddr not found");
db_info_it = m_db.group_info.insert(gaddr_pair(gr->get_gaddr(), gaddr_info(m_db.querier_version_mode))).first;
--- a/mcproxy/src/proxy/timers_values.cpp
+++ b/mcproxy/src/proxy/timers_values.cpp
@@ -248,6 +248,12 @@ std::chrono::milliseconds timers_values:
return (tank->robustness_variable * tank->query_interval) + tank->query_response_interval;
}
+unsigned int timers_values::get_max_groups() const
+{
+ HC_LOG_TRACE("");
+ return tank->max_groups;
+}
+
void timers_values::set_new_tank()
{
@@ -330,6 +336,12 @@ void timers_values::set_unsolicited_repo
tank->unsolicited_report_interval = unsolicited_report_interval;
}
+void timers_values::set_max_groups(unsigned int max_groups)
+{
+ HC_LOG_TRACE("");
+ set_new_tank();
+ tank->max_groups = max_groups;
+}
timers_values::~timers_values()
{
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment