From b7892b16b25c34edd9da6b4901b08a58c9725046 Mon Sep 17 00:00:00 2001 From: jufeng Date: Tue, 13 Jun 2017 15:13:53 +0800 Subject: [PATCH] ovsfw: fix allowed_address_pairs MAC issue Current ovsfw implementation does not take care of the different MACs in allowed_address_pairs with the VM's MAC. This patch use the following method to fix this issue: 1. Do not check dl_src in table=72 because table=71 has checked dl_src for Egress. 2. Add all allowed MACs in table=0 and table=73 for Ingress. 3. Do not check dl_dst in table=82 because this check has done in table=0 and table=73. 4. Delete allowed MACs in table=0 and table=73 when needed. Change-Id: Iad59096f0c9855ebfd4a0d5b447e73b443d66c1d Closes-Bug: #1697593 --- .../internals/openvswitch_firewall.rst | 70 +++++++++------ .../linux/openvswitch_firewall/firewall.py | 89 ++++++++++--------- .../agent/linux/openvswitch_firewall/rules.py | 2 - .../tests/functional/agent/test_firewall.py | 31 +++++++ .../openvswitch_firewall/test_firewall.py | 6 +- .../linux/openvswitch_firewall/test_rules.py | 6 -- 6 files changed, 122 insertions(+), 82 deletions(-) diff --git a/doc/source/contributor/internals/openvswitch_firewall.rst b/doc/source/contributor/internals/openvswitch_firewall.rst index 1c38692e330..6d8fc91bade 100644 --- a/doc/source/contributor/internals/openvswitch_firewall.rst +++ b/doc/source/contributor/internals/openvswitch_firewall.rst @@ -129,12 +129,14 @@ the second security group. Ports have following attributes: - ip address: 192.168.0.1 - mac address: fa:16:3e:a4:22:10 - security group 1: can send icmp packets out + - allowed address pair: 10.0.0.1/32, fa:16:3e:8c:84:13 Port 2 - plugged to the port 2 in OVS bridge - ip address: 192.168.0.2 - mac address: fa:16:3e:24:57:c7 - security group 2: can receive icmp packets from security group 1 + - allowed address pair: 10.1.0.0/24, fa:16:3e:8c:84:14 ``table 0`` contains a low priority rule to continue packets processing in ``table 60`` aka TRANSIENT table. ``table 0`` is left for use to other @@ -152,7 +154,9 @@ connections into separate conntrack zones. table=60, priority=100,in_port=1 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71) table=60, priority=100,in_port=2 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,71) table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81) + table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:8c:84:13 actions=load:0x1->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81) table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81) + table=60, priority=90,dl_vlan=0x284,dl_dst=fa:16:3e:8c:84:14 actions=load:0x2->NXM_NX_REG5[],load:0x284->NXM_NX_REG6[],resubmit(,81) table=60, priority=0 actions=NORMAL Following ``table 71`` implements arp spoofing protection, ip spoofing @@ -185,7 +189,9 @@ Following rules implement arp spoofing protection :: table=71, priority=95,arp,reg5=0x1,in_port=1,dl_src=fa:16:3e:a4:22:10,arp_spa=192.168.0.1 actions=NORMAL + table=71, priority=95,arp,reg5=0x1,in_port=1,dl_src=fa:16:3e:8c:84:13,arp_spa=10.0.0.1 actions=NORMAL table=71, priority=95,arp,reg5=0x2,in_port=2,dl_src=fa:16:3e:24:57:c7,arp_spa=192.168.0.2 actions=NORMAL + table=71, priority=95,arp,reg5=0x2,in_port=2,dl_src=fa:16:3e:8c:84:14,arp_spa=10.1.0.0/24 actions=NORMAL DHCP and DHCPv6 traffic is allowed to instance but DHCP servers are blocked on instances. @@ -207,7 +213,9 @@ combinations. All other packets are dropped. :: table=71, priority=65,ct_state=-trk,ip,reg5=0x1,in_port=1,dl_src=fa:16:3e:a4:22:10,nw_src=192.168.0.1 actions=ct(table=72,zone=NXM_NX_REG6[0..15]) + table=71, priority=65,ct_state=-trk,ip,reg5=0x1,in_port=1,dl_src=fa:16:3e:8c:84:13,nw_src=10.0.0.1 actions=ct(table=72,zone=NXM_NX_REG6[0..15]) table=71, priority=65,ct_state=-trk,ip,reg5=0x2,in_port=2,dl_src=fa:16:3e:24:57:c7,nw_src=192.168.0.2 actions=ct(table=72,zone=NXM_NX_REG6[0..15]) + table=71, priority=65,ct_state=-trk,ip,reg5=0x2,in_port=2,dl_src=fa:16:3e:8c:84:14,nw_src=10.1.0.0/24 actions=ct(table=72,zone=NXM_NX_REG6[0..15]) table=71, priority=65,ct_state=-trk,ipv6,reg5=0x1,in_port=1,dl_src=fa:16:3e:a4:22:10,ipv6_src=fe80::f816:3eff:fea4:2210 actions=ct(table=72,zone=NXM_NX_REG6[0..15]) table=71, priority=65,ct_state=-trk,ipv6,reg5=0x2,in_port=2,dl_src=fa:16:3e:24:57:c7,ipv6_src=fe80::f816:3eff:fe24:57c7 actions=ct(table=72,zone=NXM_NX_REG6[0..15]) table=71, priority=10,ct_state=-trk,reg5=0x1,in_port=1 actions=drop @@ -226,8 +234,8 @@ In case below we allow all icmp egress traffic. :: - table=72, priority=70,ct_state=+est-rel-rpl,icmp,reg5=0x1,dl_src=fa:16:3e:a4:22:10 actions=resubmit(,73) - table=72, priority=70,ct_state=+new-est,icmp,reg5=0x1,dl_src=fa:16:3e:a4:22:10 actions=resubmit(,73) + table=72, priority=70,ct_state=+est-rel-rpl,icmp,reg5=0x1, actions=resubmit(,73) + table=72, priority=70,ct_state=+new-est,icmp,reg5=0x1, actions=resubmit(,73) table=72, priority=50,ct_state=+inv+trk actions=drop @@ -270,7 +278,9 @@ remaining egress connections are sent to normal switching. :: table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:a4:22:10 actions=load:0x1->NXM_NX_REG5[],resubmit(,81) + table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:8c:84:13 actions=load:0x1->NXM_NX_REG5[],resubmit(,81) table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:24:57:c7 actions=load:0x2->NXM_NX_REG5[],resubmit(,81) + table=73, priority=100,reg6=0x284,dl_dst=fa:16:3e:8c:84:14 actions=load:0x2->NXM_NX_REG5[],resubmit(,81) table=73, priority=90,ct_state=+new-est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15]),NORMAL table=73, priority=90,ct_state=+new-est,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15]),NORMAL table=73, priority=80,reg5=0x1 actions=NORMAL @@ -284,18 +294,18 @@ port. Not tracked packets are sent to obtain conntrack information. :: - table=81, priority=100,arp,reg5=0x1,dl_dst=fa:16:3e:a4:22:10 actions=strip_vlan,output:1 - table=81, priority=100,arp,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=strip_vlan,output:2 - table=81, priority=100,icmp6,reg5=0x1,dl_dst=fa:16:3e:a4:22:10,icmp_type=130 actions=strip_vlan,output:1 - table=81, priority=100,icmp6,reg5=0x1,dl_dst=fa:16:3e:a4:22:10,icmp_type=131 actions=strip_vlan,output:1 - table=81, priority=100,icmp6,reg5=0x1,dl_dst=fa:16:3e:a4:22:10,icmp_type=132 actions=strip_vlan,output:1 - table=81, priority=100,icmp6,reg5=0x1,dl_dst=fa:16:3e:a4:22:10,icmp_type=135 actions=strip_vlan,output:1 - table=81, priority=100,icmp6,reg5=0x1,dl_dst=fa:16:3e:a4:22:10,icmp_type=136 actions=strip_vlan,output:1 - table=81, priority=100,icmp6,reg5=0x2,dl_dst=fa:16:3e:24:57:c7,icmp_type=130 actions=strip_vlan,output:2 - table=81, priority=100,icmp6,reg5=0x2,dl_dst=fa:16:3e:24:57:c7,icmp_type=131 actions=strip_vlan,output:2 - table=81, priority=100,icmp6,reg5=0x2,dl_dst=fa:16:3e:24:57:c7,icmp_type=132 actions=strip_vlan,output:2 - table=81, priority=100,icmp6,reg5=0x2,dl_dst=fa:16:3e:24:57:c7,icmp_type=135 actions=strip_vlan,output:2 - table=81, priority=100,icmp6,reg5=0x2,dl_dst=fa:16:3e:24:57:c7,icmp_type=136 actions=strip_vlan,output:2 + table=81, priority=100,arp,reg5=0x1 actions=strip_vlan,output:1 + table=81, priority=100,arp,reg5=0x2 actions=strip_vlan,output:2 + table=81, priority=100,icmp6,reg5=0x1,icmp_type=130 actions=strip_vlan,output:1 + table=81, priority=100,icmp6,reg5=0x1,icmp_type=131 actions=strip_vlan,output:1 + table=81, priority=100,icmp6,reg5=0x1,icmp_type=132 actions=strip_vlan,output:1 + table=81, priority=100,icmp6,reg5=0x1,icmp_type=135 actions=strip_vlan,output:1 + table=81, priority=100,icmp6,reg5=0x1,icmp_type=136 actions=strip_vlan,output:1 + table=81, priority=100,icmp6,reg5=0x2,icmp_type=130 actions=strip_vlan,output:2 + table=81, priority=100,icmp6,reg5=0x2,icmp_type=131 actions=strip_vlan,output:2 + table=81, priority=100,icmp6,reg5=0x2,icmp_type=132 actions=strip_vlan,output:2 + table=81, priority=100,icmp6,reg5=0x2,icmp_type=135 actions=strip_vlan,output:2 + table=81, priority=100,icmp6,reg5=0x2,icmp_type=136 actions=strip_vlan,output:2 table=81, priority=95,udp,reg5=0x1,tp_src=67,tp_dst=68 actions=strip_vlan,output:1 table=81, priority=95,udp6,reg5=0x1,tp_src=547,tp_dst=546 actions=strip_vlan,output:1 table=81, priority=95,udp,reg5=0x2,tp_src=67,tp_dst=68 actions=strip_vlan,output:2 @@ -304,25 +314,27 @@ port. Not tracked packets are sent to obtain conntrack information. table=81, priority=90,ct_state=-trk,ipv6,reg5=0x1 actions=ct(table=82,zone=NXM_NX_REG6[0..15]) table=81, priority=90,ct_state=-trk,ip,reg5=0x2 actions=ct(table=82,zone=NXM_NX_REG6[0..15]) table=81, priority=90,ct_state=-trk,ipv6,reg5=0x2 actions=ct(table=82,zone=NXM_NX_REG6[0..15]) - table=81, priority=80,ct_state=+trk,reg5=0x1,dl_dst=fa:16:3e:a4:22:10 actions=resubmit(,82) - table=81, priority=80,ct_state=+trk,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=resubmit(,82) + table=81, priority=80,ct_state=+trk,reg5=0x1 actions=resubmit(,82) + table=81, priority=80,ct_state=+trk,reg5=0x2 actions=resubmit(,82) table=81, priority=0 actions=drop Similarly to ``table 72``, ``table 82`` accepts established and related connections. In this case we allow all icmp traffic coming from -``security group 1`` which is in this case only ``port 1`` with ip address -``192.168.0.1``. The first two rules match on the ip address, and the -next two rules match on the icmp protocol and the destination mac address. +``security group 1`` which is in this case only ``port 1``. +The first two rules match on the ip packets, and the +next two rules match on the icmp protocol. These four rules define conjunction flows. :: - table=82, priority=70,ct_state=+est-rel-rpl,ip,reg6=0xfff,nw_src=192.168.0.1 actions=conjunction(2147352552,1/2) - table=82, priority=70,ct_state=+new-est,ip,reg6=0xfff,nw_src=192.168.0.1 actions=conjunction(2147352553,1/2) - table=82, priority=70,ct_state=+est-rel-rpl,icmp,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=conjunction(2147352552,2/2) - table=82, priority=70,ct_state=+new-est,icmp,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=conjunction(2147352553,2/2) - table=82, priority=70,conj_id=2147352552,ct_state=+est-rel-rpl,ip,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=strip_vlan,output:2 - table=82, priority=70,conj_id=2147352553,ct_state=+new-est,ip,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=ct(commit,zone=NXM_NX_REG6[0..15]),strip_vlan,output:2 + table=82, priority=70,ct_state=+est-rel-rpl,ip,reg6=0x284,nw_src=192.168.0.1 actions=conjunction(2147352552,1/2) + table=82, priority=70,ct_state=+est-rel-rpl,ip,reg6=0x284,nw_src=10.0.0.1 actions=conjunction(2147352552,1/2) + table=82, priority=70,ct_state=+new-est,ip,reg6=0x284,nw_src=192.168.0.1 actions=conjunction(2147352553,1/2) + table=82, priority=70,ct_state=+new-est,ip,reg6=0x284,nw_src=10.0.0.1 actions=conjunction(2147352553,1/2) + table=82, priority=70,ct_state=+est-rel-rpl,icmp,reg5=0x2 actions=conjunction(2147352552,2/2) + table=82, priority=70,ct_state=+new-est,icmp,reg5=0x2 actions=conjunction(2147352553,2/2) + table=82, priority=70,conj_id=2147352552,ct_state=+est-rel-rpl,ip,reg5=0x2 actions=strip_vlan,output:2 + table=82, priority=70,conj_id=2147352553,ct_state=+new-est,ip,reg5=0x2 actions=ct(commit,zone=NXM_NX_REG6[0..15]),strip_vlan,output:2 table=82, priority=50,ct_state=+inv+trk actions=drop The mechanism for dropping connections that are not allowed anymore is the @@ -332,10 +344,10 @@ same as in ``table 72``. table=82, priority=50,ct_mark=0x1,reg5=0x1 actions=drop table=82, priority=50,ct_mark=0x1,reg5=0x2 actions=drop - table=82, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x1,dl_dst=fa:16:3e:a4:22:10 actions=strip_vlan,output:1 - table=82, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=strip_vlan,output:2 - table=82, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x1,dl_dst=fa:16:3e:a4:22:10 actions=strip_vlan,output:1 - table=82, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x2,dl_dst=fa:16:3e:24:57:c7 actions=strip_vlan,output:2 + table=82, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x1 actions=strip_vlan,output:1 + table=82, priority=50,ct_state=+est-rel+rpl,ct_zone=644,ct_mark=0,reg5=0x2 actions=strip_vlan,output:2 + table=82, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x1 actions=strip_vlan,output:1 + table=82, priority=50,ct_state=-new-est+rel-inv,ct_zone=644,ct_mark=0,reg5=0x2 actions=strip_vlan,output:2 table=82, priority=40,ct_state=-est,reg5=0x1 actions=drop table=82, priority=40,ct_state=+est,reg5=0x1 actions=ct(commit,zone=NXM_NX_REG6[0..15],exec(load:0x1->NXM_NX_CT_MARK[])) table=82, priority=40,ct_state=-est,reg5=0x2 actions=drop diff --git a/neutron/agent/linux/openvswitch_firewall/firewall.py b/neutron/agent/linux/openvswitch_firewall/firewall.py index 71eebe24dfb..8817751ba0a 100644 --- a/neutron/agent/linux/openvswitch_firewall/firewall.py +++ b/neutron/agent/linux/openvswitch_firewall/firewall.py @@ -113,6 +113,13 @@ class OFPort(object): return {(aap['mac_address'], aap['ip_address']) for aap in aap_dict if netaddr.IPNetwork(aap['ip_address']).version == version} + @property + def all_allowed_macs(self): + macs = {item[0] for item in self.allowed_pairs_v4.union( + self.allowed_pairs_v6)} + macs.add(self.mac) + return macs + @property def ipv4_addresses(self): return [ip_addr for ip_addr in self.fixed_ips @@ -450,12 +457,15 @@ class OVSFirewallDriver(firewall.FirewallDriver): self._initialize_egress_no_port_security(port['device']) return old_of_port = self.get_ofport(port) - of_port = self.get_or_create_ofport(port) + # Make sure delete old allow_address_pair MACs because + # allow_address_pair MACs will be updated in + # self.get_or_create_ofport(port) if old_of_port: LOG.error(_LE("Initializing port %s that was already " "initialized."), port['device']) self.delete_all_port_flows(old_of_port) + of_port = self.get_or_create_ofport(port) self.initialize_port_flows(of_port) self.add_flows_from_rules(of_port) @@ -571,21 +581,22 @@ class OVSFirewallDriver(firewall.FirewallDriver): ovs_consts.BASE_EGRESS_TABLE) ) - # Identify ingress flows after egress filtering - self._add_flow( - table=ovs_consts.TRANSIENT_TABLE, - priority=90, - dl_dst=port.mac, - dl_vlan='0x%x' % port.vlan_tag, - actions='set_field:{:d}->reg{:d},' - 'set_field:{:d}->reg{:d},' - 'strip_vlan,resubmit(,{:d})'.format( - port.ofport, - ovsfw_consts.REG_PORT, - port.vlan_tag, - ovsfw_consts.REG_NET, - ovs_consts.BASE_INGRESS_TABLE), - ) + # Identify ingress flows + for mac_addr in port.all_allowed_macs: + self._add_flow( + table=ovs_consts.TRANSIENT_TABLE, + priority=90, + dl_dst=mac_addr, + dl_vlan='0x%x' % port.vlan_tag, + actions='set_field:{:d}->reg{:d},' + 'set_field:{:d}->reg{:d},' + 'strip_vlan,resubmit(,{:d})'.format( + port.ofport, + ovsfw_consts.REG_PORT, + port.vlan_tag, + ovsfw_consts.REG_NET, + ovs_consts.BASE_INGRESS_TABLE), + ) self._initialize_egress(port) self._initialize_ingress(port) @@ -753,16 +764,17 @@ class OVSFirewallDriver(firewall.FirewallDriver): # Fill in accept_or_ingress table by checking that traffic is ingress # and if not, accept it - self._add_flow( - table=ovs_consts.ACCEPT_OR_INGRESS_TABLE, - priority=100, - dl_dst=port.mac, - reg_net=port.vlan_tag, - actions='set_field:{:d}->reg{:d},resubmit(,{:d})'.format( - port.ofport, - ovsfw_consts.REG_PORT, - ovs_consts.BASE_INGRESS_TABLE), - ) + for mac_addr in port.all_allowed_macs: + self._add_flow( + table=ovs_consts.ACCEPT_OR_INGRESS_TABLE, + priority=100, + dl_dst=mac_addr, + reg_net=port.vlan_tag, + actions='set_field:{:d}->reg{:d},resubmit(,{:d})'.format( + port.ofport, + ovsfw_consts.REG_PORT, + ovs_consts.BASE_INGRESS_TABLE), + ) for ethertype in [constants.ETHERTYPE_IP, constants.ETHERTYPE_IPV6]: self._add_flow( table=ovs_consts.ACCEPT_OR_INGRESS_TABLE, @@ -836,7 +848,6 @@ class OVSFirewallDriver(firewall.FirewallDriver): table=ovs_consts.BASE_INGRESS_TABLE, priority=100, reg_port=port.ofport, - dl_dst=port.mac, dl_type=constants.ETHERTYPE_IPV6, nw_proto=lib_const.PROTO_NUM_IPV6_ICMP, icmp_type=icmp_type, @@ -850,7 +861,6 @@ class OVSFirewallDriver(firewall.FirewallDriver): priority=100, dl_type=constants.ETHERTYPE_ARP, reg_port=port.ofport, - dl_dst=port.mac, actions='output:{:d}'.format(port.ofport), ) self._initialize_ingress_ipv6_icmp(port) @@ -887,7 +897,6 @@ class OVSFirewallDriver(firewall.FirewallDriver): ct_state=ovsfw_consts.OF_STATE_TRACKED, priority=80, reg_port=port.ofport, - dl_dst=port.mac, actions='resubmit(,{:d})'.format(ovs_consts.RULES_INGRESS_TABLE) ) @@ -914,7 +923,6 @@ class OVSFirewallDriver(firewall.FirewallDriver): self._add_flow( table=ovs_consts.RULES_INGRESS_TABLE, priority=50, - dl_dst=port.mac, reg_port=port.ofport, ct_state=state, ct_mark=ovsfw_consts.CT_MARK_NORMAL, @@ -995,18 +1003,17 @@ class OVSFirewallDriver(firewall.FirewallDriver): def delete_all_port_flows(self, port): """Delete all flows for given port""" - self._strict_delete_flow( - priority=90, - table=ovs_consts.TRANSIENT_TABLE, - dl_dst=port.mac, - dl_vlan=port.vlan_tag) - self._strict_delete_flow( - priority=100, - table=ovs_consts.TRANSIENT_TABLE, - in_port=port.ofport) + for mac_addr in port.all_allowed_macs: + self._strict_delete_flow(priority=90, + table=ovs_consts.TRANSIENT_TABLE, + dl_dst=mac_addr, + dl_vlan=port.vlan_tag) + self._delete_flows(table=ovs_consts.ACCEPT_OR_INGRESS_TABLE, + dl_dst=mac_addr, reg_net=port.vlan_tag) + self._strict_delete_flow(priority=100, + table=ovs_consts.TRANSIENT_TABLE, + in_port=port.ofport) self._delete_flows(reg_port=port.ofport) - self._delete_flows(table=ovs_consts.ACCEPT_OR_INGRESS_TABLE, - dl_dst=port.mac, reg_net=port.vlan_tag) def delete_flows_for_ip_addresses( self, ip_addresses, direction, ethertype, vlan_tag): diff --git a/neutron/agent/linux/openvswitch_firewall/rules.py b/neutron/agent/linux/openvswitch_firewall/rules.py index 65d2470d286..2f5e87002ef 100644 --- a/neutron/agent/linux/openvswitch_firewall/rules.py +++ b/neutron/agent/linux/openvswitch_firewall/rules.py @@ -77,11 +77,9 @@ def populate_flow_common(direction, flow_template, port): """Initialize common flow fields.""" if direction == firewall.INGRESS_DIRECTION: flow_template['table'] = ovs_consts.RULES_INGRESS_TABLE - flow_template['dl_dst'] = port.mac flow_template['actions'] = "output:{:d}".format(port.ofport) elif direction == firewall.EGRESS_DIRECTION: flow_template['table'] = ovs_consts.RULES_EGRESS_TABLE - flow_template['dl_src'] = port.mac # Traffic can be both ingress and egress, check that no ingress rules # should be applied flow_template['actions'] = 'resubmit(,{:d})'.format( diff --git a/neutron/tests/functional/agent/test_firewall.py b/neutron/tests/functional/agent/test_firewall.py index aa8d8707d3e..bc7b17ba4b0 100644 --- a/neutron/tests/functional/agent/test_firewall.py +++ b/neutron/tests/functional/agent/test_firewall.py @@ -398,20 +398,51 @@ class FirewallTestCase(BaseFirewallTestCase): port_mac = self.tester.vm_mac_address allowed_ip = netaddr.IPAddress(self.tester.vm_ip_address) + 1 not_allowed_ip = "%s/24" % (allowed_ip + 1) + allowed_mac = 'fa:16:3e:8c:84:13' + not_allowed_mac = 'fa:16:3e:8c:84:14' self.src_port_desc['allowed_address_pairs'] = [ {'mac_address': port_mac, + 'ip_address': "%s/32" % allowed_ip}, + {'mac_address': allowed_mac, 'ip_address': "%s/32" % allowed_ip}] allowed_ip = "%s/24" % allowed_ip self.firewall.update_port_filter(self.src_port_desc) self.tester.assert_connection(protocol=self.tester.ICMP, direction=self.tester.INGRESS) + self.tester.assert_connection(protocol=self.tester.ICMP, + direction=self.tester.EGRESS) self.tester.vm_ip_cidr = allowed_ip self.tester.assert_connection(protocol=self.tester.ICMP, direction=self.tester.INGRESS) + self.tester.assert_connection(protocol=self.tester.ICMP, + direction=self.tester.EGRESS) self.tester.vm_ip_cidr = not_allowed_ip self.tester.assert_no_connection(protocol=self.tester.ICMP, direction=self.tester.INGRESS) + self.tester.assert_no_connection(protocol=self.tester.ICMP, + direction=self.tester.EGRESS) + self.tester.vm_mac_address = allowed_mac + self.tester.vm_ip_cidr = allowed_ip + self.tester.flush_arp_tables() + self.tester.assert_connection(protocol=self.tester.ICMP, + direction=self.tester.INGRESS) + self.tester.assert_connection(protocol=self.tester.ICMP, + direction=self.tester.EGRESS) + self.tester.vm_mac_address = allowed_mac + self.tester.vm_ip_cidr = not_allowed_ip + self.tester.flush_arp_tables() + self.tester.assert_no_connection(protocol=self.tester.ICMP, + direction=self.tester.INGRESS) + self.tester.assert_no_connection(protocol=self.tester.ICMP, + direction=self.tester.EGRESS) + self.tester.vm_mac_address = not_allowed_mac + self.tester.vm_ip_cidr = allowed_ip + self.tester.flush_arp_tables() + self.tester.assert_no_connection(protocol=self.tester.ICMP, + direction=self.tester.INGRESS) + self.tester.assert_no_connection(protocol=self.tester.ICMP, + direction=self.tester.EGRESS) def test_arp_is_allowed(self): self.tester.assert_connection(protocol=self.tester.ARP, diff --git a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py index 153965a5d00..6c6cebc2eac 100644 --- a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py +++ b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py @@ -459,7 +459,8 @@ class TestOVSFirewallDriver(base.BaseTestCase): def test_prepare_port_filter(self): port_dict = {'device': 'port-id', - 'security_groups': [1]} + 'security_groups': [1], + 'fixed_ips': ["10.0.0.1"]} self._prepare_security_group() self.firewall.prepare_port_filter(port_dict) exp_egress_classifier = mock.call( @@ -482,7 +483,6 @@ class TestOVSFirewallDriver(base.BaseTestCase): filter_rule = mock.call( actions='ct(commit,zone=NXM_NX_REG6[0..15]),' 'output:{:d}'.format(self.port_ofport), - dl_dst=self.port_mac, dl_type="0x{:04x}".format(n_const.ETHERTYPE_IP), nw_proto=constants.PROTO_NUM_TCP, priority=70, @@ -528,7 +528,6 @@ class TestOVSFirewallDriver(base.BaseTestCase): filter_rules = [mock.call( actions='resubmit(,{:d})'.format( ovs_consts.ACCEPT_OR_INGRESS_TABLE), - dl_src=self.port_mac, dl_type="0x{:04x}".format(n_const.ETHERTYPE_IP), nw_proto=constants.PROTO_NUM_UDP, priority=70, @@ -538,7 +537,6 @@ class TestOVSFirewallDriver(base.BaseTestCase): mock.call( actions='conjunction({:d},2/2)'.format(conj_id), ct_state=ovsfw_consts.OF_STATE_ESTABLISHED_NOT_REPLY, - dl_src=mock.ANY, dl_type=mock.ANY, nw_proto=6, priority=70, reg5=self.port_ofport, diff --git a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py index 65d97144a2b..4acfead28bb 100644 --- a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py +++ b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_rules.py @@ -186,7 +186,6 @@ class TestCreateProtocolFlows(base.BaseTestCase): rule = {'protocol': constants.PROTO_NAME_TCP} expected_flows = [{ 'table': ovs_consts.RULES_INGRESS_TABLE, - 'dl_dst': self.port.mac, 'actions': 'output:1', 'nw_proto': constants.PROTO_NUM_TCP, }] @@ -197,7 +196,6 @@ class TestCreateProtocolFlows(base.BaseTestCase): rule = {'protocol': constants.PROTO_NAME_TCP} expected_flows = [{ 'table': ovs_consts.RULES_EGRESS_TABLE, - 'dl_src': self.port.mac, 'actions': 'resubmit(,{:d})'.format( ovs_consts.ACCEPT_OR_INGRESS_TABLE), 'nw_proto': constants.PROTO_NUM_TCP, @@ -209,7 +207,6 @@ class TestCreateProtocolFlows(base.BaseTestCase): rule = {} expected_flows = [{ 'table': ovs_consts.RULES_EGRESS_TABLE, - 'dl_src': self.port.mac, 'actions': 'resubmit(,{:d})'.format( ovs_consts.ACCEPT_OR_INGRESS_TABLE), }] @@ -221,7 +218,6 @@ class TestCreateProtocolFlows(base.BaseTestCase): 'protocol': constants.PROTO_NAME_ICMP} expected_flows = [{ 'table': ovs_consts.RULES_EGRESS_TABLE, - 'dl_src': self.port.mac, 'actions': 'resubmit(,{:d})'.format( ovs_consts.ACCEPT_OR_INGRESS_TABLE), 'nw_proto': constants.PROTO_NUM_IPV6_ICMP, @@ -236,7 +232,6 @@ class TestCreateProtocolFlows(base.BaseTestCase): 'port_range_max': 23} expected_flows = [{ 'table': ovs_consts.RULES_EGRESS_TABLE, - 'dl_src': self.port.mac, 'actions': 'resubmit(,{:d})'.format( ovs_consts.ACCEPT_OR_INGRESS_TABLE), 'nw_proto': constants.PROTO_NUM_TCP, @@ -353,7 +348,6 @@ class TestCreateConjFlows(base.BaseTestCase): conj_id = 1234 expected_template = { 'table': ovs_consts.RULES_INGRESS_TABLE, - 'dl_dst': port.mac, 'dl_type': n_const.ETHERTYPE_IPV6, 'priority': 70, 'conj_id': conj_id,