diff --git a/neutron/agent/linux/iptables_firewall.py b/neutron/agent/linux/iptables_firewall.py index ad11abe499..8d112e819e 100644 --- a/neutron/agent/linux/iptables_firewall.py +++ b/neutron/agent/linux/iptables_firewall.py @@ -214,6 +214,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver): #Note(nati) allow dhcp or RA packet ipv4_rules += ['-p udp -m udp --sport 68 --dport 67 -j RETURN'] ipv6_rules += ['-p icmpv6 -j RETURN'] + ipv6_rules += ['-p udp -m udp --sport 546 --dport 547 -j RETURN'] mac_ipv4_pairs = [] mac_ipv6_pairs = [] @@ -236,9 +237,10 @@ class IptablesFirewallDriver(firewall.FirewallDriver): self._setup_spoof_filter_chain(port, self.iptables.ipv6['filter'], mac_ipv6_pairs, ipv6_rules) - def _drop_dhcp_rule(self): + def _drop_dhcp_rule(self, ipv4_rules, ipv6_rules): #Note(nati) Drop dhcp packet from VM - return ['-p udp -m udp --sport 67 --dport 68 -j DROP'] + ipv4_rules += ['-p udp -m udp --sport 67 --dport 68 -j DROP'] + ipv6_rules += ['-p udp -m udp --sport 547 --dport 546 -j DROP'] def _accept_inbound_icmpv6(self): # Allow multicast listener, neighbor solicitation and @@ -264,7 +266,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver): self._spoofing_rule(port, ipv4_iptables_rule, ipv6_iptables_rule) - ipv4_iptables_rule += self._drop_dhcp_rule() + self._drop_dhcp_rule(ipv4_iptables_rule, ipv6_iptables_rule) if direction == INGRESS_DIRECTION: ipv6_iptables_rule += self._accept_inbound_icmpv6() ipv4_iptables_rule += self._convert_sgr_to_iptables_rules( diff --git a/neutron/tests/unit/test_iptables_firewall.py b/neutron/tests/unit/test_iptables_firewall.py index 18c4fe4db3..06f490d554 100644 --- a/neutron/tests/unit/test_iptables_firewall.py +++ b/neutron/tests/unit/test_iptables_firewall.py @@ -801,14 +801,18 @@ class IptablesFirewallTestCase(base.BaseTestCase): ethertype = rule['ethertype'] prefix = FAKE_IP[ethertype] filter_inst = self.v4filter_inst - dhcp_rule = mock.call.add_rule( + dhcp_rule = [mock.call.add_rule( 'ofake_dev', - '-p udp -m udp --sport 68 --dport 67 -j RETURN') + '-p udp -m udp --sport 68 --dport 67 -j RETURN')] if ethertype == 'IPv6': filter_inst = self.v6filter_inst - dhcp_rule = mock.call.add_rule('ofake_dev', '-p icmpv6 -j RETURN') + dhcp_rule = [mock.call.add_rule('ofake_dev', + '-p icmpv6 -j RETURN'), + mock.call.add_rule('ofake_dev', '-p udp -m udp ' + '--sport 546 --dport 547 ' + '-j RETURN')] sg = [rule] port['security_group_rules'] = sg self.firewall.prepare_port_filter(port) @@ -860,13 +864,17 @@ class IptablesFirewallTestCase(base.BaseTestCase): 'sfake_dev', '-m mac --mac-source ff:ff:ff:ff:ff:ff -s %s -j RETURN' % prefix), - mock.call.add_rule('sfake_dev', '-j DROP'), - dhcp_rule, - mock.call.add_rule('ofake_dev', '-j $sfake_dev')] + mock.call.add_rule('sfake_dev', '-j DROP')] + calls += dhcp_rule + calls.append(mock.call.add_rule('ofake_dev', '-j $sfake_dev')) if ethertype == 'IPv4': calls.append(mock.call.add_rule( 'ofake_dev', '-p udp -m udp --sport 67 --dport 68 -j DROP')) + if ethertype == 'IPv6': + calls.append(mock.call.add_rule( + 'ofake_dev', + '-p udp -m udp --sport 547 --dport 546 -j DROP')) calls += [mock.call.add_rule( 'ofake_dev', '-m state --state INVALID -j DROP'), diff --git a/neutron/tests/unit/test_security_groups_rpc.py b/neutron/tests/unit/test_security_groups_rpc.py index 1a32051e49..5c72b2ccb4 100644 --- a/neutron/tests/unit/test_security_groups_rpc.py +++ b/neutron/tests/unit/test_security_groups_rpc.py @@ -1593,6 +1593,8 @@ IPTABLES_FILTER_V6_1 = """# Generated by iptables_manager [0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ %(physdev_is_bridged)s -j %(bn)s-o_port1 [0:0] -A %(bn)s-o_port1 -p icmpv6 -j RETURN +[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 546 --dport 547 -j RETURN +[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 547 --dport 546 -j DROP [0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP [0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN [0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback @@ -1643,6 +1645,8 @@ IPTABLES_FILTER_V6_2 = """# Generated by iptables_manager [0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port1 \ %(physdev_is_bridged)s -j %(bn)s-o_port1 [0:0] -A %(bn)s-o_port1 -p icmpv6 -j RETURN +[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 546 --dport 547 -j RETURN +[0:0] -A %(bn)s-o_port1 -p udp -m udp --sport 547 --dport 546 -j DROP [0:0] -A %(bn)s-o_port1 -m state --state INVALID -j DROP [0:0] -A %(bn)s-o_port1 -m state --state RELATED,ESTABLISHED -j RETURN [0:0] -A %(bn)s-o_port1 -j %(bn)s-sg-fallback @@ -1665,6 +1669,8 @@ IPTABLES_FILTER_V6_2 = """# Generated by iptables_manager [0:0] -A %(bn)s-INPUT %(physdev_mod)s --physdev-EGRESS tap_port2 \ %(physdev_is_bridged)s -j %(bn)s-o_port2 [0:0] -A %(bn)s-o_port2 -p icmpv6 -j RETURN +[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 546 --dport 547 -j RETURN +[0:0] -A %(bn)s-o_port2 -p udp -m udp --sport 547 --dport 546 -j DROP [0:0] -A %(bn)s-o_port2 -m state --state INVALID -j DROP [0:0] -A %(bn)s-o_port2 -m state --state RELATED,ESTABLISHED -j RETURN [0:0] -A %(bn)s-o_port2 -j %(bn)s-sg-fallback