19034270 IPv6 filter rules are not properly handled
authorGirish Moodalbail <Girish.Moodalbail@oracle.COM>
Thu, 26 Jun 2014 19:18:52 -0700
changeset 1977 12e9c20eef5a
parent 1976 850795cfd6d3
child 1978 e9a8064da9fd
19034270 IPv6 filter rules are not properly handled
components/openstack/neutron/files/agent/evs_l3_agent.py
components/openstack/neutron/files/agent/solaris/net_lib.py
components/openstack/neutron/files/neutron-l3-agent
--- a/components/openstack/neutron/files/agent/evs_l3_agent.py	Thu Jun 26 16:27:27 2014 -0700
+++ b/components/openstack/neutron/files/agent/evs_l3_agent.py	Thu Jun 26 19:18:52 2014 -0700
@@ -306,7 +306,8 @@
         # now setup the IPF rule
         rules = ['block in quick on %s from %s to pool/%d' %
                  (internal_dlname, subnet_cidr, new_ippool_name)]
-        ri.ipfilters_manager.add_ipf_rules(rules)
+        ipversion = netaddr.IPNetwork(subnet_cidr).version
+        ri.ipfilters_manager.add_ipf_rules(rules, ipversion)
 
     def internal_network_removed(self, ri, port):
         internal_dlname = self.get_internal_device_name(port['id'])
@@ -318,7 +319,8 @@
         ippool_name = self._get_ippool_name(port['mac_address'])
         rules = ['block in quick on %s from %s to pool/%d' %
                  (internal_dlname, port['subnet']['cidr'], ippool_name)]
-        ri.ipfilters_manager.remove_ipf_rules(rules)
+        ipversion = netaddr.IPNetwork(port['subnet']['cidr']).version
+        ri.ipfilters_manager.remove_ipf_rules(rules, ipversion)
         # remove the ippool
         ri.ipfilters_manager.remove_ippool(ippool_name, None)
         for internal_port in ri.internal_ports:
--- a/components/openstack/neutron/files/agent/solaris/net_lib.py	Thu Jun 26 16:27:27 2014 -0700
+++ b/components/openstack/neutron/files/agent/solaris/net_lib.py	Thu Jun 26 19:18:52 2014 -0700
@@ -262,9 +262,11 @@
 class IPfilterCommand(CommandBase):
     '''Wrapper around Solaris ipf(1m) command'''
 
-    def split_rules(self, rules):
+    def _split_rules(self, rules, version):
         # assumes that rules are inbound!
         cmd = ['/usr/sbin/ipfstat', '-i']
+        if version == 6:
+            cmd.insert(1, '-6')
         stdout = self.execute_with_pfexec(cmd)
         existing_rules = []
         non_existing_rules = []
@@ -276,20 +278,20 @@
 
         return existing_rules, non_existing_rules
 
-    def add_rules(self, rules, version='4'):
-        rules = self.split_rules(rules)[1]
+    def add_rules(self, rules, version=4):
+        rules = self._split_rules(rules, version)[1]
         process_input = '\n'.join(rules)
         cmd = ['/usr/sbin/ipf', '-f', '-']
-        if version == '6':
-            cmd.append('-6')
+        if version == 6:
+            cmd.insert(1, '-6')
         return self.execute_with_pfexec(cmd, process_input=process_input)
 
-    def remove_rules(self, rules, version='4'):
-        rules = self.split_rules(rules)[0]
+    def remove_rules(self, rules, version=4):
+        rules = self._split_rules(rules, version)[0]
         process_input = '\n'.join(rules)
         cmd = ['/usr/sbin/ipf', '-r', '-f', '-']
-        if version == '6':
-            cmd.append('-6')
+        if version == 6:
+            cmd.insert(1, '-6')
         return self.execute_with_pfexec(cmd, process_input=process_input)
 
 
--- a/components/openstack/neutron/files/neutron-l3-agent	Thu Jun 26 16:27:27 2014 -0700
+++ b/components/openstack/neutron/files/neutron-l3-agent	Thu Jun 26 19:18:52 2014 -0700
@@ -61,6 +61,50 @@
     smf_include.smf_subprocess(cmd)
 
 
+def remove_ipfilter_rules(version):
+    # remove IP Filter rules added by neutron-l3-agent
+    cmd = ["/usr/bin/pfexec", "/usr/sbin/ipfstat", "-io"]
+    if version == 6:
+        cmd.insert(2, "-6")
+    p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+    output, error = p.communicate()
+    if p.returncode != 0:
+        print "failed to retrieve IP Filter rules"
+        return smf_include.SMF_EXIT_ERR_FATAL
+
+    ipfilters = output.splitlines()
+    # L3 agent IP Filter rules are of the form
+    # block in quick on l3i64cbb496_a_0 from ... to pool/15417332
+    prog = re.compile('on l3i[0-9A-Fa-f\_]{10}_0')
+    ippool_names = []
+    for ipf in ipfilters:
+        if not prog.search(ipf):
+            continue
+        # capture the IP pool name
+        ippool_names.append(ipf.split('pool/')[1])
+
+        try:
+            # remove the IP Filter rule
+            p = Popen(["echo", ipf], stdout=PIPE)
+            cmd = ["/usr/bin/pfexec", "/usr/sbin/ipf", "-r", "-f", "-"]
+            if version == 6:
+                cmd.insert(2, "-6")
+            check_call(cmd, stdin=p.stdout)
+        except CalledProcessError as err:
+            print "failed to remove IP Filter rule %s: %s" % (ipf, err)
+            return smf_include.SMF_EXIT_ERR_FATAL
+
+    # remove IP Pools added by neutron-l3-agent
+    for ippool_name in ippool_names:
+        try:
+            check_call(["/usr/bin/pfexec", "/usr/sbin/ippool", "-R",
+                        "-m", ippool_name, "-t", "tree"])
+        except CalledProcessError as err:
+            print "failed to remove IP Pool %s: %s" % (ippool_name, err)
+            return smf_include.SMF_EXIT_ERR_FATAL
+    return smf_include.SMF_EXIT_OK
+
+
 def stop():
     try:
         # first kill the SMF contract
@@ -95,42 +139,15 @@
             print "failed to remove datalinks used by L3 agent: %s" % (err)
             return smf_include.SMF_EXIT_ERR_FATAL
 
-    # remove IP Filter rules added by neutron-l3-agent
-    cmd = ["/usr/bin/pfexec", "/usr/sbin/ipfstat", "-io"]
-    p = Popen(cmd, stdout=PIPE, stderr=PIPE)
-    output, error = p.communicate()
-    if p.returncode != 0:
-        print "failed to retrieve IP Filter rules"
-        return smf_include.SMF_EXIT_ERR_FATAL
+    # remove IPv4 Filter rules added by neutron-l3-agent
+    rv = remove_ipfilter_rules(4)
+    if rv != smf_include.SMF_EXIT_OK:
+        return rv
 
-    ipfilters = output.splitlines()
-    # L3 agent IP Filter rules are of the form
-    # block in quick on l3i64cbb496_a_0 from ... to pool/15417332
-    prog = re.compile('on l3i[0-9A-Fa-f\_]{10}_0')
-    ippool_names = []
-    for ipf in ipfilters:
-        if not prog.search(ipf):
-            continue
-        # capture the IP pool name
-        ippool_names.append(ipf.split('pool/')[1])
-
-        try:
-            # remove the IP Filter rule
-            p = Popen(["echo", ipf], stdout=PIPE)
-            check_call(["/usr/bin/pfexec", "/usr/sbin/ipf", "-r", "-f", "-"],
-                       stdin=p.stdout)
-        except CalledProcessError as err:
-            print "failed to remove IP Filter rule %s: %s" % (ipf, err)
-            return smf_include.SMF_EXIT_ERR_FATAL
-
-    # remove IP Pools added by neutron-l3-agent
-    for ippool_name in ippool_names:
-        try:
-            check_call(["/usr/bin/pfexec", "/usr/sbin/ippool", "-R",
-                        "-m", ippool_name, "-t", "tree"])
-        except CalledProcessError as err:
-            print "failed to remove IP Pool %s: %s" % (ippool_name, err)
-            return smf_include.SMF_EXIT_ERR_FATAL
+    # remove IPv6 Filter rules added by neutron-l3-agent
+    rv = remove_ipfilter_rules(6)
+    if rv != smf_include.SMF_EXIT_OK:
+        return rv
 
     # remove IP NAT rules added by neutron-l3-agent
     cmd = ["/usr/bin/pfexec", "/usr/sbin/ipnat", "-lR"]