From f20bff25676e6f445d7415361c4903d1300f7f66 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 5 Jun 2018 01:50:04 +0000 Subject: [PATCH 1/2] [caclmgrd] Heuristically determine whether ACL is IPv4 or IPv6, use iptables/ip6tables accordingly --- files/image_config/caclmgrd/caclmgrd | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index dee85d2e26ed..d1d3e1319b73 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -11,6 +11,7 @@ # try: + import ipaddr as ipaddress import os import subprocess import sys @@ -113,12 +114,22 @@ class ControlPlaneAclManager(object): # Add iptables command to delete all non-default chains iptables_cmds.append("iptables -X") + # Add same set of commands for ip6tables + iptables_cmds.append("ip6tables -P INPUT ACCEPT") + iptables_cmds.append("ip6tables -P FORWARD ACCEPT") + iptables_cmds.append("ip6tables -P OUTPUT ACCEPT") + iptables_cmds.append("ip6tables -F") + iptables_cmds.append("ip6tables -X") + # Get current ACL tables and rules from Config DB self._tables_db_info = self.config_db.get_table(self.ACL_TABLE) self._rules_db_info = self.config_db.get_table(self.ACL_RULE) # Walk the ACL tables for (table_name, table_data) in self._tables_db_info.iteritems(): + + table_ip_version = None + # Ignore non-control-plane ACL tables if table_data["type"] != self.ACL_TABLE_TYPE_CTRLPLANE: continue @@ -152,10 +163,22 @@ class ControlPlaneAclManager(object): log_error("ACL rule does not contain PACKET_ACTION property") continue + # If we haven't determined the IP version for this ACL table yet, + # do it now. We determine heuristically based on whether the + # src IP is a v4 or v6 address. + if not table_ip_version: + if "SRC_IP" in rule_props and rule_props["SRC_IP"]: + ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0]) + if isinstance(ip_addr, ipaddress.IPv6Address): + table_ip_version = 6 + else: + table_ip_version = 4 + # Apply the rule to the default protocol(s) for this ACL service for ip_protocol in ip_protocols: for dst_port in dst_ports: - rule_cmd = "iptables -A INPUT -p {}".format(ip_protocol) + rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" + rule_cmd += " -A INPUT -p {}".format(ip_protocol) if "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) From 250155cfeb94a8ed41317dc2f6bafa87d7bb6894 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 5 Jun 2018 04:49:50 +0000 Subject: [PATCH 2/2] Check all rules in table until we find one with a SRC_IP --- files/image_config/caclmgrd/caclmgrd | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index d1d3e1319b73..0dc59766b3d5 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -155,6 +155,23 @@ class ControlPlaneAclManager(object): if rule_table_name == table_name: acl_rules[rule_props["PRIORITY"]] = rule_props + # If we haven't determined the IP version for this ACL table yet, + # try to do it now. We determine heuristically based on whether the + # src IP is an IPv4 or IPv6 address. + if not table_ip_version and "SRC_IP" in rule_props and rule_props["SRC_IP"]: + ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0]) + if isinstance(ip_addr, ipaddress.IPv6Address): + table_ip_version = 6 + elif isinstance(ip_addr, ipaddress.IPv4Address): + table_ip_version = 4 + + # If we were unable to determine whether this ACL table contains + # IPv4 or IPv6 rules, log a message and skip processing this table. + if not table_ip_version: + log_warning("Unable to determine if ACL table '{}' contains IPv4 or IPv6 rules. Skipping table..." + .format(table_name)) + continue + # For each ACL rule in this table (in descending order of priority) for priority in sorted(acl_rules.iterkeys(), reverse=True): rule_props = acl_rules[priority] @@ -163,17 +180,6 @@ class ControlPlaneAclManager(object): log_error("ACL rule does not contain PACKET_ACTION property") continue - # If we haven't determined the IP version for this ACL table yet, - # do it now. We determine heuristically based on whether the - # src IP is a v4 or v6 address. - if not table_ip_version: - if "SRC_IP" in rule_props and rule_props["SRC_IP"]: - ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0]) - if isinstance(ip_addr, ipaddress.IPv6Address): - table_ip_version = 6 - else: - table_ip_version = 4 - # Apply the rule to the default protocol(s) for this ACL service for ip_protocol in ip_protocols: for dst_port in dst_ports: