Merge "Make DVR router support FLAT network for ovs-agent"
This commit is contained in:
commit
792f4efce9
@ -771,32 +771,47 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
return {id_: port.neutron_port_dict
|
return {id_: port.neutron_port_dict
|
||||||
for id_, port in self.sg_port_map.ports.items()}
|
for id_, port in self.sg_port_map.ports.items()}
|
||||||
|
|
||||||
def install_vlan_direct_flow(self, mac, segment_id, ofport, local_vlan):
|
def install_physical_direct_flow(self, mac, segment_id,
|
||||||
# If the port segment_id is not None/0, the
|
ofport, local_vlan, network_type):
|
||||||
# port's network type must be VLAN type.
|
actions = ('set_field:{:d}->reg{:d},'
|
||||||
if segment_id:
|
'set_field:{:d}->reg{:d},').format(
|
||||||
|
ofport,
|
||||||
|
ovsfw_consts.REG_PORT,
|
||||||
|
# This always needs the local vlan.
|
||||||
|
local_vlan,
|
||||||
|
ovsfw_consts.REG_NET)
|
||||||
|
if network_type == lib_const.TYPE_VLAN:
|
||||||
|
actions += 'strip_vlan,resubmit(,{:d})'.format(
|
||||||
|
ovs_consts.BASE_INGRESS_TABLE)
|
||||||
self._add_flow(
|
self._add_flow(
|
||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
priority=90,
|
priority=90,
|
||||||
dl_dst=mac,
|
dl_dst=mac,
|
||||||
dl_vlan='0x%x' % segment_id,
|
dl_vlan='0x%x' % segment_id,
|
||||||
actions='set_field:{:d}->reg{:d},'
|
actions=actions)
|
||||||
'set_field:{:d}->reg{:d},'
|
elif network_type == lib_const.TYPE_FLAT:
|
||||||
'strip_vlan,resubmit(,{:d})'.format(
|
# If the port belong to flat network, we need match vlan_tci and
|
||||||
ofport,
|
# needn't pop vlan
|
||||||
ovsfw_consts.REG_PORT,
|
actions += 'resubmit(,{:d})'.format(
|
||||||
# This always needs the local vlan.
|
ovs_consts.BASE_INGRESS_TABLE)
|
||||||
local_vlan,
|
self._add_flow(
|
||||||
ovsfw_consts.REG_NET,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
ovs_consts.BASE_INGRESS_TABLE)
|
priority=90,
|
||||||
)
|
dl_dst=mac,
|
||||||
|
vlan_tci=ovs_consts.FLAT_VLAN_TCI,
|
||||||
|
actions=actions)
|
||||||
|
|
||||||
def delete_vlan_direct_flow(self, mac, segment_id):
|
def delete_physical_direct_flow(self, mac, segment_id):
|
||||||
if segment_id:
|
if segment_id:
|
||||||
self._strict_delete_flow(priority=90,
|
self._strict_delete_flow(priority=90,
|
||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
dl_dst=mac,
|
dl_dst=mac,
|
||||||
dl_vlan=segment_id)
|
dl_vlan=segment_id)
|
||||||
|
else:
|
||||||
|
self._strict_delete_flow(priority=90,
|
||||||
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
|
dl_dst=mac,
|
||||||
|
vlan_tci=ovs_consts.FLAT_VLAN_TCI)
|
||||||
|
|
||||||
def initialize_port_flows(self, port):
|
def initialize_port_flows(self, port):
|
||||||
"""Set base flows for port
|
"""Set base flows for port
|
||||||
@ -821,8 +836,9 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
|
|
||||||
# Identify ingress flows
|
# Identify ingress flows
|
||||||
for mac_addr in port.all_allowed_macs:
|
for mac_addr in port.all_allowed_macs:
|
||||||
self.install_vlan_direct_flow(
|
self.install_physical_direct_flow(
|
||||||
mac_addr, port.segment_id, port.ofport, port.vlan_tag)
|
mac_addr, port.segment_id, port.ofport,
|
||||||
|
port.vlan_tag, port.network_type)
|
||||||
|
|
||||||
self._add_flow(
|
self._add_flow(
|
||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
@ -1406,7 +1422,7 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||||||
table=ovs_consts.TRANSIENT_TABLE,
|
table=ovs_consts.TRANSIENT_TABLE,
|
||||||
dl_dst=mac_addr,
|
dl_dst=mac_addr,
|
||||||
dl_vlan=port.vlan_tag)
|
dl_vlan=port.vlan_tag)
|
||||||
self.delete_vlan_direct_flow(mac_addr, port.segment_id)
|
self.delete_physical_direct_flow(mac_addr, port.segment_id)
|
||||||
self._delete_flows(table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
self._delete_flows(table=ovs_consts.ACCEPT_OR_INGRESS_TABLE,
|
||||||
dl_dst=mac_addr, reg_net=port.vlan_tag)
|
dl_dst=mac_addr, reg_net=port.vlan_tag)
|
||||||
|
|
||||||
|
@ -12,9 +12,6 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
FLAT_VLAN_ID = -1
|
|
||||||
LOCAL_VLAN_ID = -2
|
|
||||||
|
|
||||||
# Supported VXLAN features
|
# Supported VXLAN features
|
||||||
VXLAN_NONE = 'not_supported'
|
VXLAN_NONE = 'not_supported'
|
||||||
VXLAN_MCAST = 'multicast_flooding'
|
VXLAN_MCAST = 'multicast_flooding'
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
from neutron_lib import constants as p_const
|
from neutron_lib import constants as p_const
|
||||||
|
|
||||||
|
|
||||||
# Special vlan_id value in ovs_vlan_allocations table indicating flat network
|
# Special vlan_tci value indicating flat network
|
||||||
FLAT_VLAN_ID = -1
|
FLAT_VLAN_TCI = '0x0000/0x1fff'
|
||||||
|
|
||||||
# Topic for tunnel notifications between the plugin and agent
|
# Topic for tunnel notifications between the plugin and agent
|
||||||
TUNNEL = 'tunnel'
|
TUNNEL = 'tunnel'
|
||||||
@ -41,11 +41,14 @@ TUNNEL_NETWORK_TYPES = [p_const.TYPE_GRE, p_const.TYPE_VXLAN,
|
|||||||
|
|
||||||
LOCAL_SWITCHING = 0
|
LOCAL_SWITCHING = 0
|
||||||
|
|
||||||
|
# The pyhsical network types of support DVR router
|
||||||
|
DVR_PHYSICAL_NETWORK_TYPES = [p_const.TYPE_VLAN, p_const.TYPE_FLAT]
|
||||||
|
|
||||||
# Various tables for DVR use of integration bridge flows
|
# Various tables for DVR use of integration bridge flows
|
||||||
DVR_TO_SRC_MAC = 1
|
DVR_TO_SRC_MAC = 1
|
||||||
DVR_TO_SRC_MAC_VLAN = 2
|
DVR_TO_SRC_MAC_PHYSICAL = 2
|
||||||
ARP_DVR_MAC_TO_DST_MAC = 3
|
ARP_DVR_MAC_TO_DST_MAC = 3
|
||||||
ARP_DVR_MAC_TO_DST_MAC_VLAN = 4
|
ARP_DVR_MAC_TO_DST_MAC_PHYSICAL = 4
|
||||||
CANARY_TABLE = 23
|
CANARY_TABLE = 23
|
||||||
|
|
||||||
# Table for ARP poison/spoofing prevention rules
|
# Table for ARP poison/spoofing prevention rules
|
||||||
@ -82,7 +85,7 @@ ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE = 94
|
|||||||
INT_BR_ALL_TABLES = (
|
INT_BR_ALL_TABLES = (
|
||||||
LOCAL_SWITCHING,
|
LOCAL_SWITCHING,
|
||||||
DVR_TO_SRC_MAC,
|
DVR_TO_SRC_MAC,
|
||||||
DVR_TO_SRC_MAC_VLAN,
|
DVR_TO_SRC_MAC_PHYSICAL,
|
||||||
CANARY_TABLE,
|
CANARY_TABLE,
|
||||||
ARP_SPOOF_TABLE,
|
ARP_SPOOF_TABLE,
|
||||||
MAC_SPOOF_TABLE,
|
MAC_SPOOF_TABLE,
|
||||||
@ -128,15 +131,15 @@ TUN_BR_ALL_TABLES = (
|
|||||||
# --- Physical Bridges (phys_brs)
|
# --- Physical Bridges (phys_brs)
|
||||||
|
|
||||||
# Various tables for DVR use of physical bridge flows
|
# Various tables for DVR use of physical bridge flows
|
||||||
DVR_PROCESS_VLAN = 1
|
DVR_PROCESS_PHYSICAL = 1
|
||||||
LOCAL_VLAN_TRANSLATION = 2
|
LOCAL_VLAN_TRANSLATION = 2
|
||||||
DVR_NOT_LEARN_VLAN = 3
|
DVR_NOT_LEARN_PHYSICAL = 3
|
||||||
|
|
||||||
PHY_BR_ALL_TABLES = (
|
PHY_BR_ALL_TABLES = (
|
||||||
LOCAL_SWITCHING,
|
LOCAL_SWITCHING,
|
||||||
DVR_PROCESS_VLAN,
|
DVR_PROCESS_PHYSICAL,
|
||||||
LOCAL_VLAN_TRANSLATION,
|
LOCAL_VLAN_TRANSLATION,
|
||||||
DVR_NOT_LEARN_VLAN)
|
DVR_NOT_LEARN_PHYSICAL)
|
||||||
|
|
||||||
# --- end of OpenFlow table IDs
|
# --- end of OpenFlow table IDs
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
from neutron_lib import constants as p_const
|
|
||||||
from os_ken.lib.packet import ether_types
|
from os_ken.lib.packet import ether_types
|
||||||
from os_ken.lib.packet import icmpv6
|
from os_ken.lib.packet import icmpv6
|
||||||
from os_ken.lib.packet import in_proto
|
from os_ken.lib.packet import in_proto
|
||||||
@ -103,13 +102,15 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
|||||||
def _arp_dvr_dst_mac_match(ofp, ofpp, vlan, dvr_mac):
|
def _arp_dvr_dst_mac_match(ofp, ofpp, vlan, dvr_mac):
|
||||||
# If eth_dst is equal to the dvr mac of this host, then
|
# If eth_dst is equal to the dvr mac of this host, then
|
||||||
# flag it as matched.
|
# flag it as matched.
|
||||||
|
if not vlan:
|
||||||
|
return ofpp.OFPMatch(vlan_vid=ofp.OFPVID_NONE, eth_dst=dvr_mac)
|
||||||
return ofpp.OFPMatch(vlan_vid=vlan | ofp.OFPVID_PRESENT,
|
return ofpp.OFPMatch(vlan_vid=vlan | ofp.OFPVID_PRESENT,
|
||||||
eth_dst=dvr_mac)
|
eth_dst=dvr_mac)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _dvr_dst_mac_table_id(network_type):
|
def _dvr_dst_mac_table_id(network_type):
|
||||||
if network_type == p_const.TYPE_VLAN:
|
if network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
return constants.ARP_DVR_MAC_TO_DST_MAC_VLAN
|
return constants.ARP_DVR_MAC_TO_DST_MAC_PHYSICAL
|
||||||
else:
|
else:
|
||||||
return constants.ARP_DVR_MAC_TO_DST_MAC
|
return constants.ARP_DVR_MAC_TO_DST_MAC
|
||||||
|
|
||||||
@ -137,13 +138,16 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _dvr_to_src_mac_match(ofp, ofpp, vlan_tag, dst_mac):
|
def _dvr_to_src_mac_match(ofp, ofpp, vlan_tag, dst_mac):
|
||||||
|
if not vlan_tag:
|
||||||
|
# When the network is flat type, the vlan_tag will be None.
|
||||||
|
return ofpp.OFPMatch(vlan_vid=ofp.OFPVID_NONE, eth_dst=dst_mac)
|
||||||
return ofpp.OFPMatch(vlan_vid=vlan_tag | ofp.OFPVID_PRESENT,
|
return ofpp.OFPMatch(vlan_vid=vlan_tag | ofp.OFPVID_PRESENT,
|
||||||
eth_dst=dst_mac)
|
eth_dst=dst_mac)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _dvr_to_src_mac_table_id(network_type):
|
def _dvr_to_src_mac_table_id(network_type):
|
||||||
if network_type == p_const.TYPE_VLAN:
|
if network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
return constants.DVR_TO_SRC_MAC_VLAN
|
return constants.DVR_TO_SRC_MAC_PHYSICAL
|
||||||
else:
|
else:
|
||||||
return constants.DVR_TO_SRC_MAC
|
return constants.DVR_TO_SRC_MAC
|
||||||
|
|
||||||
@ -164,10 +168,10 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
|||||||
priority=20,
|
priority=20,
|
||||||
match=match,
|
match=match,
|
||||||
instructions=instructions)
|
instructions=instructions)
|
||||||
actions = [
|
actions = []
|
||||||
ofpp.OFPActionPopVlan(),
|
if vlan_tag:
|
||||||
ofpp.OFPActionOutput(dst_port, 0),
|
actions.append(ofpp.OFPActionPopVlan())
|
||||||
]
|
actions.append(ofpp.OFPActionOutput(dst_port, 0))
|
||||||
self.install_apply_actions(table_id=constants.TRANSIENT_TABLE,
|
self.install_apply_actions(table_id=constants.TRANSIENT_TABLE,
|
||||||
priority=20,
|
priority=20,
|
||||||
match=match,
|
match=match,
|
||||||
@ -182,12 +186,12 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
|||||||
self.uninstall_flows(
|
self.uninstall_flows(
|
||||||
strict=True, priority=20, table_id=table, match=match)
|
strict=True, priority=20, table_id=table, match=match)
|
||||||
|
|
||||||
def add_dvr_mac_vlan(self, mac, port):
|
def add_dvr_mac_physical(self, mac, port):
|
||||||
self.install_goto(table_id=constants.LOCAL_SWITCHING,
|
self.install_goto(table_id=constants.LOCAL_SWITCHING,
|
||||||
priority=4,
|
priority=4,
|
||||||
in_port=port,
|
in_port=port,
|
||||||
eth_src=mac,
|
eth_src=mac,
|
||||||
dest_table_id=constants.DVR_TO_SRC_MAC_VLAN)
|
dest_table_id=constants.DVR_TO_SRC_MAC_PHYSICAL)
|
||||||
|
|
||||||
def remove_dvr_mac_vlan(self, mac):
|
def remove_dvr_mac_vlan(self, mac):
|
||||||
# REVISIT(yamamoto): match in_port as well?
|
# REVISIT(yamamoto): match in_port as well?
|
||||||
@ -214,11 +218,12 @@ class OVSIntegrationBridge(ovs_bridge.OVSAgentBridge):
|
|||||||
strict=True, priority=5, table_id=table_id, match=match)
|
strict=True, priority=5, table_id=table_id, match=match)
|
||||||
|
|
||||||
def add_dvr_gateway_mac_arp_vlan(self, mac, port):
|
def add_dvr_gateway_mac_arp_vlan(self, mac, port):
|
||||||
self.install_goto(table_id=constants.LOCAL_SWITCHING,
|
self.install_goto(
|
||||||
priority=5,
|
table_id=constants.LOCAL_SWITCHING,
|
||||||
in_port=port,
|
priority=5,
|
||||||
eth_dst=mac,
|
in_port=port,
|
||||||
dest_table_id=constants.ARP_DVR_MAC_TO_DST_MAC_VLAN)
|
eth_dst=mac,
|
||||||
|
dest_table_id=constants.ARP_DVR_MAC_TO_DST_MAC_PHYSICAL)
|
||||||
|
|
||||||
def remove_dvr_gateway_mac_arp_vlan(self, mac, port):
|
def remove_dvr_gateway_mac_arp_vlan(self, mac, port):
|
||||||
self.uninstall_flows(table_id=constants.LOCAL_SWITCHING,
|
self.uninstall_flows(table_id=constants.LOCAL_SWITCHING,
|
||||||
|
@ -26,7 +26,7 @@ class OVSPhysicalBridge(ovs_bridge.OVSAgentBridge,
|
|||||||
"""openvswitch agent physical bridge specific logic."""
|
"""openvswitch agent physical bridge specific logic."""
|
||||||
|
|
||||||
# Used by OVSDVRProcessMixin
|
# Used by OVSDVRProcessMixin
|
||||||
dvr_process_table_id = constants.DVR_PROCESS_VLAN
|
dvr_process_table_id = constants.DVR_PROCESS_PHYSICAL
|
||||||
dvr_process_next_table_id = constants.LOCAL_VLAN_TRANSLATION
|
dvr_process_next_table_id = constants.LOCAL_VLAN_TRANSLATION
|
||||||
of_tables = constants.PHY_BR_ALL_TABLES
|
of_tables = constants.PHY_BR_ALL_TABLES
|
||||||
|
|
||||||
@ -57,12 +57,12 @@ class OVSPhysicalBridge(ovs_bridge.OVSAgentBridge,
|
|||||||
match = self._local_vlan_match(ofp, ofpp, port, lvid)
|
match = self._local_vlan_match(ofp, ofpp, port, lvid)
|
||||||
self.uninstall_flows(match=match)
|
self.uninstall_flows(match=match)
|
||||||
|
|
||||||
def add_dvr_mac_vlan(self, mac, port):
|
def add_dvr_mac_physical(self, mac, port):
|
||||||
self.install_output(table_id=constants.DVR_NOT_LEARN_VLAN,
|
self.install_output(table_id=constants.DVR_NOT_LEARN_PHYSICAL,
|
||||||
priority=2, eth_src=mac, port=port)
|
priority=2, eth_src=mac, port=port)
|
||||||
|
|
||||||
def remove_dvr_mac_vlan(self, mac):
|
def remove_dvr_mac_vlan(self, mac):
|
||||||
# REVISIT(yamamoto): match in_port as well?
|
# REVISIT(yamamoto): match in_port as well?
|
||||||
self.uninstall_flows(
|
self.uninstall_flows(
|
||||||
table_id=constants.DVR_NOT_LEARN_VLAN,
|
table_id=constants.DVR_NOT_LEARN_PHYSICAL,
|
||||||
eth_src=mac)
|
eth_src=mac)
|
||||||
|
@ -224,7 +224,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
# Insert 'drop' action as the default for Table DVR_TO_SRC_MAC
|
# Insert 'drop' action as the default for Table DVR_TO_SRC_MAC
|
||||||
self.int_br.install_drop(table_id=constants.DVR_TO_SRC_MAC, priority=1)
|
self.int_br.install_drop(table_id=constants.DVR_TO_SRC_MAC, priority=1)
|
||||||
|
|
||||||
self.int_br.install_drop(table_id=constants.DVR_TO_SRC_MAC_VLAN,
|
self.int_br.install_drop(table_id=constants.DVR_TO_SRC_MAC_PHYSICAL,
|
||||||
priority=1)
|
priority=1)
|
||||||
|
|
||||||
for physical_network in self.bridge_mappings:
|
for physical_network in self.bridge_mappings:
|
||||||
@ -256,12 +256,12 @@ class OVSDVRNeutronAgent(object):
|
|||||||
self.phys_brs[physical_network].install_goto(
|
self.phys_brs[physical_network].install_goto(
|
||||||
in_port=self.phys_ofports[physical_network],
|
in_port=self.phys_ofports[physical_network],
|
||||||
priority=2,
|
priority=2,
|
||||||
dest_table_id=constants.DVR_PROCESS_VLAN)
|
dest_table_id=constants.DVR_PROCESS_PHYSICAL)
|
||||||
self.phys_brs[physical_network].install_goto(
|
self.phys_brs[physical_network].install_goto(
|
||||||
priority=1,
|
priority=1,
|
||||||
dest_table_id=constants.DVR_NOT_LEARN_VLAN)
|
dest_table_id=constants.DVR_NOT_LEARN_PHYSICAL)
|
||||||
self.phys_brs[physical_network].install_goto(
|
self.phys_brs[physical_network].install_goto(
|
||||||
table_id=constants.DVR_PROCESS_VLAN,
|
table_id=constants.DVR_PROCESS_PHYSICAL,
|
||||||
priority=0,
|
priority=0,
|
||||||
dest_table_id=constants.LOCAL_VLAN_TRANSLATION)
|
dest_table_id=constants.LOCAL_VLAN_TRANSLATION)
|
||||||
self.phys_brs[physical_network].install_drop(
|
self.phys_brs[physical_network].install_drop(
|
||||||
@ -269,15 +269,15 @@ class OVSDVRNeutronAgent(object):
|
|||||||
in_port=self.phys_ofports[physical_network],
|
in_port=self.phys_ofports[physical_network],
|
||||||
priority=2)
|
priority=2)
|
||||||
self.phys_brs[physical_network].install_normal(
|
self.phys_brs[physical_network].install_normal(
|
||||||
table_id=constants.DVR_NOT_LEARN_VLAN,
|
table_id=constants.DVR_NOT_LEARN_PHYSICAL,
|
||||||
priority=1)
|
priority=1)
|
||||||
|
|
||||||
def _add_dvr_mac_for_phys_br(self, physical_network, mac):
|
def _add_dvr_mac_for_phys_br(self, physical_network, mac):
|
||||||
self.int_br.add_dvr_mac_vlan(mac=mac,
|
self.int_br.add_dvr_mac_physical(
|
||||||
port=self.int_ofports[physical_network])
|
mac=mac, port=self.int_ofports[physical_network])
|
||||||
phys_br = self.phys_brs[physical_network]
|
phys_br = self.phys_brs[physical_network]
|
||||||
phys_br.add_dvr_mac_vlan(mac=mac,
|
phys_br.add_dvr_mac_physical(
|
||||||
port=self.phys_ofports[physical_network])
|
mac=mac, port=self.phys_ofports[physical_network])
|
||||||
|
|
||||||
def _add_arp_dvr_mac_for_phys_br(self, physical_network, mac):
|
def _add_arp_dvr_mac_for_phys_br(self, physical_network, mac):
|
||||||
self.int_br.add_dvr_gateway_mac_arp_vlan(
|
self.int_br.add_dvr_gateway_mac_arp_vlan(
|
||||||
@ -402,7 +402,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
ldm.set_dvr_owned(True)
|
ldm.set_dvr_owned(True)
|
||||||
|
|
||||||
vlan_to_use = lvm.vlan
|
vlan_to_use = lvm.vlan
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
vlan_to_use = lvm.segmentation_id
|
vlan_to_use = lvm.segmentation_id
|
||||||
|
|
||||||
subnet_info = ldm.get_subnet_info()
|
subnet_info = ldm.get_subnet_info()
|
||||||
@ -456,7 +456,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
dvr_mac=self.dvr_mac_address,
|
dvr_mac=self.dvr_mac_address,
|
||||||
rtr_port=port.ofport)
|
rtr_port=port.ofport)
|
||||||
|
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
# TODO(vivek) remove the IPv6 related flows once SNAT is not
|
# TODO(vivek) remove the IPv6 related flows once SNAT is not
|
||||||
# used for IPv6 DVR.
|
# used for IPv6 DVR.
|
||||||
br = self.phys_brs[lvm.physical_network]
|
br = self.phys_brs[lvm.physical_network]
|
||||||
@ -517,7 +517,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
ovsport.add_subnet(subnet_uuid)
|
ovsport.add_subnet(subnet_uuid)
|
||||||
self.local_ports[port.vif_id] = ovsport
|
self.local_ports[port.vif_id] = ovsport
|
||||||
vlan_to_use = lvm.vlan
|
vlan_to_use = lvm.vlan
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
vlan_to_use = lvm.segmentation_id
|
vlan_to_use = lvm.segmentation_id
|
||||||
# create a rule for this vm port
|
# create a rule for this vm port
|
||||||
self.int_br.install_dvr_to_src_mac(
|
self.int_br.install_dvr_to_src_mac(
|
||||||
@ -577,7 +577,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
ovsport.add_subnet(subnet_uuid)
|
ovsport.add_subnet(subnet_uuid)
|
||||||
self.local_ports[port.vif_id] = ovsport
|
self.local_ports[port.vif_id] = ovsport
|
||||||
vlan_to_use = lvm.vlan
|
vlan_to_use = lvm.vlan
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
vlan_to_use = lvm.segmentation_id
|
vlan_to_use = lvm.segmentation_id
|
||||||
self.int_br.install_dvr_to_src_mac(
|
self.int_br.install_dvr_to_src_mac(
|
||||||
network_type=lvm.network_type,
|
network_type=lvm.network_type,
|
||||||
@ -591,8 +591,9 @@ class OVSDVRNeutronAgent(object):
|
|||||||
if not self.in_distributed_mode():
|
if not self.in_distributed_mode():
|
||||||
return
|
return
|
||||||
|
|
||||||
if local_vlan_map.network_type not in (constants.TUNNEL_NETWORK_TYPES +
|
if (local_vlan_map.network_type not in
|
||||||
[n_const.TYPE_VLAN]):
|
(constants.TUNNEL_NETWORK_TYPES +
|
||||||
|
constants.DVR_PHYSICAL_NETWORK_TYPES)):
|
||||||
LOG.debug("DVR: Port %s is with network_type %s not supported"
|
LOG.debug("DVR: Port %s is with network_type %s not supported"
|
||||||
" for dvr plumbing", port.vif_id,
|
" for dvr plumbing", port.vif_id,
|
||||||
local_vlan_map.network_type)
|
local_vlan_map.network_type)
|
||||||
@ -629,7 +630,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
network_type = lvm.network_type
|
network_type = lvm.network_type
|
||||||
physical_network = lvm.physical_network
|
physical_network = lvm.physical_network
|
||||||
vlan_to_use = lvm.vlan
|
vlan_to_use = lvm.vlan
|
||||||
if network_type == n_const.TYPE_VLAN:
|
if network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
vlan_to_use = lvm.segmentation_id
|
vlan_to_use = lvm.segmentation_id
|
||||||
# ensure we process for all the subnets laid on this removed port
|
# ensure we process for all the subnets laid on this removed port
|
||||||
for sub_uuid in subnet_set:
|
for sub_uuid in subnet_set:
|
||||||
@ -660,7 +661,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
# this subnet from local_dvr_map, as no dvr (or) csnat
|
# this subnet from local_dvr_map, as no dvr (or) csnat
|
||||||
# ports available on this agent anymore
|
# ports available on this agent anymore
|
||||||
self.local_dvr_map.pop(sub_uuid, None)
|
self.local_dvr_map.pop(sub_uuid, None)
|
||||||
if network_type == n_const.TYPE_VLAN:
|
if network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
br = self.phys_brs[physical_network]
|
br = self.phys_brs[physical_network]
|
||||||
if network_type in constants.TUNNEL_NETWORK_TYPES:
|
if network_type in constants.TUNNEL_NETWORK_TYPES:
|
||||||
br = self.tun_br
|
br = self.tun_br
|
||||||
@ -679,7 +680,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
self.firewall.delete_accepted_egress_direct_flow(
|
self.firewall.delete_accepted_egress_direct_flow(
|
||||||
subnet_info['gateway_mac'], lvm.vlan)
|
subnet_info['gateway_mac'], lvm.vlan)
|
||||||
|
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
br = self.phys_brs[physical_network]
|
br = self.phys_brs[physical_network]
|
||||||
if lvm.network_type in constants.TUNNEL_NETWORK_TYPES:
|
if lvm.network_type in constants.TUNNEL_NETWORK_TYPES:
|
||||||
br = self.tun_br
|
br = self.tun_br
|
||||||
@ -701,7 +702,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
ldm = self.local_dvr_map[sub_uuid]
|
ldm = self.local_dvr_map[sub_uuid]
|
||||||
ldm.remove_compute_ofport(port.vif_id)
|
ldm.remove_compute_ofport(port.vif_id)
|
||||||
vlan_to_use = lvm.vlan
|
vlan_to_use = lvm.vlan
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
vlan_to_use = lvm.segmentation_id
|
vlan_to_use = lvm.segmentation_id
|
||||||
# first remove this vm port rule
|
# first remove this vm port rule
|
||||||
self.int_br.delete_dvr_to_src_mac(
|
self.int_br.delete_dvr_to_src_mac(
|
||||||
@ -722,7 +723,7 @@ class OVSDVRNeutronAgent(object):
|
|||||||
ldm = self.local_dvr_map[sub_uuid]
|
ldm = self.local_dvr_map[sub_uuid]
|
||||||
ldm.set_csnat_ofport(constants.OFPORT_INVALID)
|
ldm.set_csnat_ofport(constants.OFPORT_INVALID)
|
||||||
vlan_to_use = lvm.vlan
|
vlan_to_use = lvm.vlan
|
||||||
if lvm.network_type == n_const.TYPE_VLAN:
|
if lvm.network_type in constants.DVR_PHYSICAL_NETWORK_TYPES:
|
||||||
vlan_to_use = lvm.segmentation_id
|
vlan_to_use = lvm.segmentation_id
|
||||||
# then remove csnat port rule
|
# then remove csnat port rule
|
||||||
self.int_br.delete_dvr_to_src_mac(
|
self.int_br.delete_dvr_to_src_mac(
|
||||||
|
@ -901,18 +901,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
|||||||
else:
|
else:
|
||||||
LOG.warning('Action %s not supported', action)
|
LOG.warning('Action %s not supported', action)
|
||||||
|
|
||||||
def _local_vlan_for_flat(self, lvid, physical_network):
|
def _local_vlan_for_physical(self, lvid, physical_network,
|
||||||
phys_br = self.phys_brs[physical_network]
|
segmentation_id=None):
|
||||||
phys_port = self.phys_ofports[physical_network]
|
|
||||||
int_br = self.int_br
|
|
||||||
int_port = self.int_ofports[physical_network]
|
|
||||||
phys_br.provision_local_vlan(port=phys_port, lvid=lvid,
|
|
||||||
segmentation_id=None,
|
|
||||||
distributed=False)
|
|
||||||
int_br.provision_local_vlan(port=int_port, lvid=lvid,
|
|
||||||
segmentation_id=None)
|
|
||||||
|
|
||||||
def _local_vlan_for_vlan(self, lvid, physical_network, segmentation_id):
|
|
||||||
distributed = self.enable_distributed_routing
|
distributed = self.enable_distributed_routing
|
||||||
phys_br = self.phys_brs[physical_network]
|
phys_br = self.phys_brs[physical_network]
|
||||||
phys_port = self.phys_ofports[physical_network]
|
phys_port = self.phys_ofports[physical_network]
|
||||||
@ -993,7 +983,7 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
|||||||
'net_uuid': net_uuid})
|
'net_uuid': net_uuid})
|
||||||
elif network_type == n_const.TYPE_FLAT:
|
elif network_type == n_const.TYPE_FLAT:
|
||||||
if physical_network in self.phys_brs:
|
if physical_network in self.phys_brs:
|
||||||
self._local_vlan_for_flat(lvid, physical_network)
|
self._local_vlan_for_physical(lvid, physical_network)
|
||||||
else:
|
else:
|
||||||
LOG.error("Cannot provision flat network for "
|
LOG.error("Cannot provision flat network for "
|
||||||
"net-id=%(net_uuid)s - no bridge for "
|
"net-id=%(net_uuid)s - no bridge for "
|
||||||
@ -1002,8 +992,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
|||||||
'physical_network': physical_network})
|
'physical_network': physical_network})
|
||||||
elif network_type == n_const.TYPE_VLAN:
|
elif network_type == n_const.TYPE_VLAN:
|
||||||
if physical_network in self.phys_brs:
|
if physical_network in self.phys_brs:
|
||||||
self._local_vlan_for_vlan(lvid, physical_network,
|
self._local_vlan_for_physical(lvid, physical_network,
|
||||||
segmentation_id)
|
segmentation_id)
|
||||||
else:
|
else:
|
||||||
LOG.error("Cannot provision VLAN network for "
|
LOG.error("Cannot provision VLAN network for "
|
||||||
"net-id=%(net_uuid)s - no bridge for "
|
"net-id=%(net_uuid)s - no bridge for "
|
||||||
|
@ -344,7 +344,8 @@ class OVSFlowTestCase(OVSAgentTestBase):
|
|||||||
'dst_mac': '12:34:56:78:cc:dd',
|
'dst_mac': '12:34:56:78:cc:dd',
|
||||||
'dst_port': 123}
|
'dst_port': 123}
|
||||||
self.br_int.install_dvr_to_src_mac(network_type='vlan', **kwargs)
|
self.br_int.install_dvr_to_src_mac(network_type='vlan', **kwargs)
|
||||||
self.br_int.add_dvr_mac_vlan(mac=other_dvr_mac, port=other_dvr_port)
|
self.br_int.add_dvr_mac_physical(mac=other_dvr_mac,
|
||||||
|
port=other_dvr_port)
|
||||||
|
|
||||||
trace = self._run_trace(self.br.br_name,
|
trace = self._run_trace(self.br.br_name,
|
||||||
"in_port=%d," % other_dvr_port +
|
"in_port=%d," % other_dvr_port +
|
||||||
|
@ -38,11 +38,12 @@ TESTING_VLAN_TAG = 1
|
|||||||
TESTING_SEGMENT = 1000
|
TESTING_SEGMENT = 1000
|
||||||
|
|
||||||
|
|
||||||
def create_ofport(port_dict, network_type=None, physical_network=None):
|
def create_ofport(port_dict, network_type=None,
|
||||||
|
physical_network=None, segment_id=TESTING_SEGMENT):
|
||||||
ovs_port = mock.Mock(vif_mac='00:00:00:00:00:00', ofport=1,
|
ovs_port = mock.Mock(vif_mac='00:00:00:00:00:00', ofport=1,
|
||||||
port_name="port-name")
|
port_name="port-name")
|
||||||
return ovsfw.OFPort(port_dict, ovs_port, vlan_tag=TESTING_VLAN_TAG,
|
return ovsfw.OFPort(port_dict, ovs_port, vlan_tag=TESTING_VLAN_TAG,
|
||||||
segment_id=TESTING_SEGMENT,
|
segment_id=segment_id,
|
||||||
network_type=network_type,
|
network_type=network_type,
|
||||||
physical_network=physical_network)
|
physical_network=physical_network)
|
||||||
|
|
||||||
@ -590,18 +591,23 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
self.firewall.prepare_port_filter(port_dict)
|
self.firewall.prepare_port_filter(port_dict)
|
||||||
self.assertFalse(m_init_flows.called)
|
self.assertFalse(m_init_flows.called)
|
||||||
|
|
||||||
def test_initialize_port_flows_vlan_dvr_conntrack_direct(self):
|
def _test_initialize_port_flows_dvr_conntrack_direct(self, network_type):
|
||||||
port_dict = {
|
port_dict = {
|
||||||
'device': 'port-id',
|
'device': 'port-id',
|
||||||
'security_groups': [1]}
|
'security_groups': [1]}
|
||||||
|
segment_id = None
|
||||||
|
if network_type == constants.TYPE_VLAN:
|
||||||
|
segment_id = TESTING_SEGMENT
|
||||||
of_port = create_ofport(port_dict,
|
of_port = create_ofport(port_dict,
|
||||||
network_type=constants.TYPE_VXLAN)
|
network_type=network_type,
|
||||||
|
segment_id=segment_id)
|
||||||
self.firewall.sg_port_map.ports[of_port.id] = of_port
|
self.firewall.sg_port_map.ports[of_port.id] = of_port
|
||||||
port = self.firewall.get_or_create_ofport(port_dict)
|
port = self.firewall.get_or_create_ofport(port_dict)
|
||||||
|
|
||||||
fake_patch_port = 999
|
fake_patch_port = 999
|
||||||
self.mock_bridge.br.get_port_ofport.return_value = fake_patch_port
|
self.mock_bridge.br.get_port_ofport.return_value = fake_patch_port
|
||||||
|
|
||||||
|
expected_calls = []
|
||||||
self.firewall.initialize_port_flows(port)
|
self.firewall.initialize_port_flows(port)
|
||||||
|
|
||||||
call_args1 = {
|
call_args1 = {
|
||||||
@ -616,22 +622,39 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
port.vlan_tag,
|
port.vlan_tag,
|
||||||
ovsfw_consts.REG_NET,
|
ovsfw_consts.REG_NET,
|
||||||
ovs_consts.BASE_EGRESS_TABLE)}
|
ovs_consts.BASE_EGRESS_TABLE)}
|
||||||
egress_flow_call = mock.call(**call_args1)
|
expected_calls.append(mock.call(**call_args1))
|
||||||
|
|
||||||
call_args2 = {
|
if network_type == constants.TYPE_VLAN:
|
||||||
'table': ovs_consts.TRANSIENT_TABLE,
|
call_args2 = {
|
||||||
'priority': 90,
|
'table': ovs_consts.TRANSIENT_TABLE,
|
||||||
'dl_dst': port.mac,
|
'priority': 90,
|
||||||
'dl_vlan': '0x%x' % port.segment_id,
|
'dl_dst': port.mac,
|
||||||
'actions': 'set_field:{:d}->reg{:d},'
|
'dl_vlan': '0x%x' % port.segment_id,
|
||||||
'set_field:{:d}->reg{:d},'
|
'actions': 'set_field:{:d}->reg{:d},'
|
||||||
'strip_vlan,resubmit(,{:d})'.format(
|
'set_field:{:d}->reg{:d},'
|
||||||
port.ofport,
|
'strip_vlan,resubmit(,{:d})'.format(
|
||||||
ovsfw_consts.REG_PORT,
|
port.ofport,
|
||||||
port.vlan_tag,
|
ovsfw_consts.REG_PORT,
|
||||||
ovsfw_consts.REG_NET,
|
port.vlan_tag,
|
||||||
ovs_consts.BASE_INGRESS_TABLE)}
|
ovsfw_consts.REG_NET,
|
||||||
ingress_flow_call1 = mock.call(**call_args2)
|
ovs_consts.BASE_INGRESS_TABLE)}
|
||||||
|
expected_calls.append(mock.call(**call_args2))
|
||||||
|
|
||||||
|
if network_type == constants.TYPE_FLAT:
|
||||||
|
call_args2 = {
|
||||||
|
'table': ovs_consts.TRANSIENT_TABLE,
|
||||||
|
'priority': 90,
|
||||||
|
'dl_dst': port.mac,
|
||||||
|
'vlan_tci': ovs_consts.FLAT_VLAN_TCI,
|
||||||
|
'actions': 'set_field:{:d}->reg{:d},'
|
||||||
|
'set_field:{:d}->reg{:d},'
|
||||||
|
'resubmit(,{:d})'.format(
|
||||||
|
port.ofport,
|
||||||
|
ovsfw_consts.REG_PORT,
|
||||||
|
port.vlan_tag,
|
||||||
|
ovsfw_consts.REG_NET,
|
||||||
|
ovs_consts.BASE_INGRESS_TABLE)}
|
||||||
|
expected_calls.append(mock.call(**call_args2))
|
||||||
|
|
||||||
call_args3 = {
|
call_args3 = {
|
||||||
'table': ovs_consts.TRANSIENT_TABLE,
|
'table': ovs_consts.TRANSIENT_TABLE,
|
||||||
@ -646,9 +669,20 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||||||
port.vlan_tag,
|
port.vlan_tag,
|
||||||
ovsfw_consts.REG_NET,
|
ovsfw_consts.REG_NET,
|
||||||
ovs_consts.BASE_INGRESS_TABLE)}
|
ovs_consts.BASE_INGRESS_TABLE)}
|
||||||
ingress_flow_call2 = mock.call(**call_args3)
|
expected_calls.append(mock.call(**call_args3))
|
||||||
self.mock_bridge.br.add_flow.assert_has_calls(
|
self.mock_bridge.br.add_flow.assert_has_calls(expected_calls)
|
||||||
[egress_flow_call, ingress_flow_call1, ingress_flow_call2])
|
|
||||||
|
def test_initialize_port_flows_dvr_conntrack_direct_vxlan(self):
|
||||||
|
self._test_initialize_port_flows_dvr_conntrack_direct(
|
||||||
|
network_type='vxlan')
|
||||||
|
|
||||||
|
def test_initialize_port_flows_dvr_conntrack_direct_vlan(self):
|
||||||
|
self._test_initialize_port_flows_dvr_conntrack_direct(
|
||||||
|
network_type='vlan')
|
||||||
|
|
||||||
|
def test_initialize_port_flows_dvr_conntrack_direct_flat(self):
|
||||||
|
self._test_initialize_port_flows_dvr_conntrack_direct(
|
||||||
|
network_type='flat')
|
||||||
|
|
||||||
def test_initialize_port_flows_vlan_dvr_conntrack_direct_vlan(self):
|
def test_initialize_port_flows_vlan_dvr_conntrack_direct_vlan(self):
|
||||||
port_dict = {
|
port_dict = {
|
||||||
|
@ -286,6 +286,48 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expected, self.mock.mock_calls)
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
|
def test_install_dvr_to_src_mac_flat(self):
|
||||||
|
network_type = 'flat'
|
||||||
|
gateway_mac = '08:60:6e:7f:74:e7'
|
||||||
|
dst_mac = '00:02:b3:13:fe:3d'
|
||||||
|
dst_port = 6666
|
||||||
|
self.br.install_dvr_to_src_mac(network_type=network_type,
|
||||||
|
vlan_tag=None,
|
||||||
|
gateway_mac=gateway_mac,
|
||||||
|
dst_mac=dst_mac,
|
||||||
|
dst_port=dst_port)
|
||||||
|
(dp, ofp, ofpp) = self._get_dp()
|
||||||
|
expected = [
|
||||||
|
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||||
|
cookie=self.stamp,
|
||||||
|
instructions=[
|
||||||
|
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [
|
||||||
|
ofpp.OFPActionSetField(eth_src=gateway_mac),
|
||||||
|
]),
|
||||||
|
ofpp.OFPInstructionGotoTable(table_id=60),
|
||||||
|
],
|
||||||
|
match=ofpp.OFPMatch(
|
||||||
|
eth_dst=dst_mac,
|
||||||
|
vlan_vid=ofp.OFPVID_NONE),
|
||||||
|
priority=20,
|
||||||
|
table_id=2),
|
||||||
|
active_bundle=None),
|
||||||
|
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||||
|
cookie=self.stamp,
|
||||||
|
instructions=[
|
||||||
|
ofpp.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, [
|
||||||
|
ofpp.OFPActionOutput(dst_port, 0),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
match=ofpp.OFPMatch(
|
||||||
|
eth_dst=dst_mac,
|
||||||
|
vlan_vid=ofp.OFPVID_NONE),
|
||||||
|
priority=20,
|
||||||
|
table_id=60),
|
||||||
|
active_bundle=None),
|
||||||
|
]
|
||||||
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
def test_delete_dvr_to_src_mac_vlan(self):
|
def test_delete_dvr_to_src_mac_vlan(self):
|
||||||
network_type = 'vlan'
|
network_type = 'vlan'
|
||||||
vlan_tag = 1111
|
vlan_tag = 1111
|
||||||
@ -312,10 +354,36 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(expected, self.mock.mock_calls)
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
def test_add_dvr_mac_vlan(self):
|
def test_delete_dvr_to_src_mac_flat(self):
|
||||||
|
network_type = 'flat'
|
||||||
|
vlan_tag = None
|
||||||
|
dst_mac = '00:02:b3:13:fe:3d'
|
||||||
|
self.br.delete_dvr_to_src_mac(network_type=network_type,
|
||||||
|
vlan_tag=vlan_tag,
|
||||||
|
dst_mac=dst_mac)
|
||||||
|
(dp, ofp, ofpp) = self._get_dp()
|
||||||
|
expected = [
|
||||||
|
call.uninstall_flows(
|
||||||
|
strict=True,
|
||||||
|
priority=20,
|
||||||
|
table_id=2,
|
||||||
|
match=ofpp.OFPMatch(
|
||||||
|
eth_dst=dst_mac,
|
||||||
|
vlan_vid=ofp.OFPVID_NONE)),
|
||||||
|
call.uninstall_flows(
|
||||||
|
strict=True,
|
||||||
|
priority=20,
|
||||||
|
table_id=60,
|
||||||
|
match=ofpp.OFPMatch(
|
||||||
|
eth_dst=dst_mac,
|
||||||
|
vlan_vid=ofp.OFPVID_NONE)),
|
||||||
|
]
|
||||||
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
|
def test_add_dvr_mac_physical(self):
|
||||||
mac = '00:02:b3:13:fe:3d'
|
mac = '00:02:b3:13:fe:3d'
|
||||||
port = 8888
|
port = 8888
|
||||||
self.br.add_dvr_mac_vlan(mac=mac, port=port)
|
self.br.add_dvr_mac_physical(mac=mac, port=port)
|
||||||
(dp, ofp, ofpp) = self._get_dp()
|
(dp, ofp, ofpp) = self._get_dp()
|
||||||
expected = [
|
expected = [
|
||||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||||
@ -488,12 +556,15 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
|||||||
self.assertEqual(expected, self.mock.mock_calls)
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
def _test_delete_dvr_dst_mac_for_arp(self, network_type):
|
def _test_delete_dvr_dst_mac_for_arp(self, network_type):
|
||||||
if network_type == p_const.TYPE_VLAN:
|
if network_type in (p_const.TYPE_VLAN, p_const.TYPE_FLAT):
|
||||||
table_id = constants.DVR_TO_SRC_MAC_VLAN
|
table_id = constants.DVR_TO_SRC_MAC_PHYSICAL
|
||||||
else:
|
else:
|
||||||
table_id = constants.DVR_TO_SRC_MAC
|
table_id = constants.DVR_TO_SRC_MAC
|
||||||
|
|
||||||
vlan_tag = 1111
|
if network_type == p_const.TYPE_FLAT:
|
||||||
|
vlan_tag = None
|
||||||
|
else:
|
||||||
|
vlan_tag = 1111
|
||||||
gateway_mac = '00:02:b3:13:fe:3e'
|
gateway_mac = '00:02:b3:13:fe:3e'
|
||||||
dvr_mac = '00:02:b3:13:fe:3f'
|
dvr_mac = '00:02:b3:13:fe:3f'
|
||||||
rtr_port = 8888
|
rtr_port = 8888
|
||||||
@ -503,15 +574,26 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
|||||||
dvr_mac=dvr_mac,
|
dvr_mac=dvr_mac,
|
||||||
rtr_port=rtr_port)
|
rtr_port=rtr_port)
|
||||||
(dp, ofp, ofpp) = self._get_dp()
|
(dp, ofp, ofpp) = self._get_dp()
|
||||||
expected = [
|
if network_type == p_const.TYPE_FLAT:
|
||||||
call.uninstall_flows(
|
expected = [
|
||||||
strict=True,
|
call.uninstall_flows(
|
||||||
priority=5,
|
strict=True,
|
||||||
table_id=table_id,
|
priority=5,
|
||||||
match=ofpp.OFPMatch(
|
table_id=table_id,
|
||||||
eth_dst=dvr_mac,
|
match=ofpp.OFPMatch(
|
||||||
vlan_vid=vlan_tag | ofp.OFPVID_PRESENT)),
|
eth_dst=dvr_mac,
|
||||||
]
|
vlan_vid=ofp.OFPVID_NONE)),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
expected = [
|
||||||
|
call.uninstall_flows(
|
||||||
|
strict=True,
|
||||||
|
priority=5,
|
||||||
|
table_id=table_id,
|
||||||
|
match=ofpp.OFPMatch(
|
||||||
|
eth_dst=dvr_mac,
|
||||||
|
vlan_vid=vlan_tag | ofp.OFPVID_PRESENT)),
|
||||||
|
]
|
||||||
self.assertEqual(expected, self.mock.mock_calls)
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
def test_delete_dvr_dst_mac_for_arp_vlan(self):
|
def test_delete_dvr_dst_mac_for_arp_vlan(self):
|
||||||
@ -520,6 +602,9 @@ class OVSIntegrationBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase):
|
|||||||
def test_delete_dvr_dst_mac_for_arp_tunnel(self):
|
def test_delete_dvr_dst_mac_for_arp_tunnel(self):
|
||||||
self._test_delete_dvr_dst_mac_for_arp(network_type='vxlan')
|
self._test_delete_dvr_dst_mac_for_arp(network_type='vxlan')
|
||||||
|
|
||||||
|
def test_delete_dvr_dst_mac_for_flat(self):
|
||||||
|
self._test_delete_dvr_dst_mac_for_arp(network_type='flat')
|
||||||
|
|
||||||
def test_install_dscp_marking_rule(self):
|
def test_install_dscp_marking_rule(self):
|
||||||
test_port = 8888
|
test_port = 8888
|
||||||
test_mark = 38
|
test_mark = 38
|
||||||
|
@ -27,7 +27,7 @@ call = mock.call # short hand
|
|||||||
|
|
||||||
class OVSPhysicalBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
|
class OVSPhysicalBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
|
||||||
ovs_bridge_test_base.OVSDVRProcessTestMixin):
|
ovs_bridge_test_base.OVSDVRProcessTestMixin):
|
||||||
dvr_process_table_id = ovs_const.DVR_PROCESS_VLAN
|
dvr_process_table_id = ovs_const.DVR_PROCESS_PHYSICAL
|
||||||
dvr_process_next_table_id = ovs_const.LOCAL_VLAN_TRANSLATION
|
dvr_process_next_table_id = ovs_const.LOCAL_VLAN_TRANSLATION
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -125,10 +125,10 @@ class OVSPhysicalBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
|
|||||||
]
|
]
|
||||||
self.assertEqual(expected, self.mock.mock_calls)
|
self.assertEqual(expected, self.mock.mock_calls)
|
||||||
|
|
||||||
def test_add_dvr_mac_vlan(self):
|
def test_add_dvr_mac_physical(self):
|
||||||
mac = '00:02:b3:13:fe:3d'
|
mac = '00:02:b3:13:fe:3d'
|
||||||
port = 8888
|
port = 8888
|
||||||
self.br.add_dvr_mac_vlan(mac=mac, port=port)
|
self.br.add_dvr_mac_physical(mac=mac, port=port)
|
||||||
(dp, ofp, ofpp) = self._get_dp()
|
(dp, ofp, ofpp) = self._get_dp()
|
||||||
expected = [
|
expected = [
|
||||||
call._send_msg(ofpp.OFPFlowMod(dp,
|
call._send_msg(ofpp.OFPFlowMod(dp,
|
||||||
|
@ -3078,8 +3078,8 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def _test_port_bound_for_dvr_on_vlan_network(
|
def _test_port_bound_for_dvr_on_physical_network(
|
||||||
self, device_owner, ip_version=n_const.IP_VERSION_4):
|
self, device_owner, network_type, ip_version=n_const.IP_VERSION_4):
|
||||||
self._setup_for_dvr_test()
|
self._setup_for_dvr_test()
|
||||||
if ip_version == n_const.IP_VERSION_4:
|
if ip_version == n_const.IP_VERSION_4:
|
||||||
gateway_ip = '1.1.1.10'
|
gateway_ip = '1.1.1.10'
|
||||||
@ -3093,7 +3093,8 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
self._compute_port.vif_mac = '77:88:99:00:11:22'
|
self._compute_port.vif_mac = '77:88:99:00:11:22'
|
||||||
physical_network = self._physical_network
|
physical_network = self._physical_network
|
||||||
segmentation_id = self._segmentation_id
|
segmentation_id = self._segmentation_id
|
||||||
network_type = n_const.TYPE_VLAN
|
if network_type == n_const.TYPE_FLAT:
|
||||||
|
segmentation_id = None
|
||||||
int_br = mock.create_autospec(self.agent.int_br)
|
int_br = mock.create_autospec(self.agent.int_br)
|
||||||
tun_br = mock.create_autospec(self.agent.tun_br)
|
tun_br = mock.create_autospec(self.agent.tun_br)
|
||||||
phys_br = mock.create_autospec(self.br_phys_cls('br-phys'))
|
phys_br = mock.create_autospec(self.br_phys_cls('br-phys'))
|
||||||
@ -3256,10 +3257,19 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
phys_br.assert_not_called()
|
phys_br.assert_not_called()
|
||||||
|
|
||||||
def test_port_bound_for_dvr_with_compute_ports(self):
|
def test_port_bound_for_dvr_with_compute_ports(self):
|
||||||
self._test_port_bound_for_dvr_on_vlan_network(
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
device_owner=DEVICE_OWNER_COMPUTE)
|
|
||||||
self._test_port_bound_for_dvr_on_vlan_network(
|
|
||||||
device_owner=DEVICE_OWNER_COMPUTE,
|
device_owner=DEVICE_OWNER_COMPUTE,
|
||||||
|
network_type=n_const.TYPE_VLAN)
|
||||||
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
|
device_owner=DEVICE_OWNER_COMPUTE,
|
||||||
|
network_type=n_const.TYPE_VLAN,
|
||||||
|
ip_version=n_const.IP_VERSION_6)
|
||||||
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
|
device_owner=DEVICE_OWNER_COMPUTE,
|
||||||
|
network_type=n_const.TYPE_FLAT)
|
||||||
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
|
device_owner=DEVICE_OWNER_COMPUTE,
|
||||||
|
network_type=n_const.TYPE_FLAT,
|
||||||
ip_version=n_const.IP_VERSION_6)
|
ip_version=n_const.IP_VERSION_6)
|
||||||
self._test_port_bound_for_dvr_on_vxlan_network(
|
self._test_port_bound_for_dvr_on_vxlan_network(
|
||||||
device_owner=DEVICE_OWNER_COMPUTE)
|
device_owner=DEVICE_OWNER_COMPUTE)
|
||||||
@ -3268,10 +3278,19 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
ip_version=n_const.IP_VERSION_6)
|
ip_version=n_const.IP_VERSION_6)
|
||||||
|
|
||||||
def test_port_bound_for_dvr_with_dhcp_ports(self):
|
def test_port_bound_for_dvr_with_dhcp_ports(self):
|
||||||
self._test_port_bound_for_dvr_on_vlan_network(
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
device_owner=n_const.DEVICE_OWNER_DHCP)
|
|
||||||
self._test_port_bound_for_dvr_on_vlan_network(
|
|
||||||
device_owner=n_const.DEVICE_OWNER_DHCP,
|
device_owner=n_const.DEVICE_OWNER_DHCP,
|
||||||
|
network_type=n_const.TYPE_VLAN)
|
||||||
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
|
device_owner=n_const.DEVICE_OWNER_DHCP,
|
||||||
|
network_type=n_const.TYPE_VLAN,
|
||||||
|
ip_version=n_const.IP_VERSION_6)
|
||||||
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
|
device_owner=n_const.DEVICE_OWNER_DHCP,
|
||||||
|
network_type=n_const.TYPE_FLAT)
|
||||||
|
self._test_port_bound_for_dvr_on_physical_network(
|
||||||
|
device_owner=n_const.DEVICE_OWNER_DHCP,
|
||||||
|
network_type=n_const.TYPE_FLAT,
|
||||||
ip_version=n_const.IP_VERSION_6)
|
ip_version=n_const.IP_VERSION_6)
|
||||||
self._test_port_bound_for_dvr_on_vxlan_network(
|
self._test_port_bound_for_dvr_on_vxlan_network(
|
||||||
device_owner=n_const.DEVICE_OWNER_DHCP)
|
device_owner=n_const.DEVICE_OWNER_DHCP)
|
||||||
@ -3737,8 +3756,9 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
mock.call.setup_canary_table(),
|
mock.call.setup_canary_table(),
|
||||||
mock.call.install_drop(table_id=constants.DVR_TO_SRC_MAC,
|
mock.call.install_drop(table_id=constants.DVR_TO_SRC_MAC,
|
||||||
priority=1),
|
priority=1),
|
||||||
mock.call.install_drop(table_id=constants.DVR_TO_SRC_MAC_VLAN,
|
mock.call.install_drop(
|
||||||
priority=1),
|
table_id=constants.DVR_TO_SRC_MAC_PHYSICAL,
|
||||||
|
priority=1),
|
||||||
mock.call.install_drop(table_id=constants.LOCAL_SWITCHING,
|
mock.call.install_drop(table_id=constants.LOCAL_SWITCHING,
|
||||||
priority=2,
|
priority=2,
|
||||||
in_port=ioport),
|
in_port=ioport),
|
||||||
@ -3829,7 +3849,7 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
dvr_macs=[{'host': newhost,
|
dvr_macs=[{'host': newhost,
|
||||||
'mac_address': newmac}])
|
'mac_address': newmac}])
|
||||||
expected_on_int_br = [
|
expected_on_int_br = [
|
||||||
mock.call.add_dvr_mac_vlan(
|
mock.call.add_dvr_mac_physical(
|
||||||
mac=newmac,
|
mac=newmac,
|
||||||
port=self.agent.int_ofports[physical_network]),
|
port=self.agent.int_ofports[physical_network]),
|
||||||
mock.call.add_dvr_mac_tun(
|
mock.call.add_dvr_mac_tun(
|
||||||
@ -3842,7 +3862,7 @@ class TestOvsDvrNeutronAgent(object):
|
|||||||
port=self.agent.patch_int_ofport),
|
port=self.agent.patch_int_ofport),
|
||||||
]
|
]
|
||||||
expected_on_phys_br = [
|
expected_on_phys_br = [
|
||||||
mock.call.add_dvr_mac_vlan(
|
mock.call.add_dvr_mac_physical(
|
||||||
mac=newmac,
|
mac=newmac,
|
||||||
port=self.agent.phys_ofports[physical_network]),
|
port=self.agent.phys_ofports[physical_network]),
|
||||||
]
|
]
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
``DVR`` routers now support ``flat`` networks.
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fixed bug `1876092 <https://bugs.launchpad.net/neutron/+bug/1876092>`_
|
||||||
|
which caused DUP ICMP replies on the ``flat`` networks used with ``DVR``
|
||||||
|
routers.
|
Loading…
Reference in New Issue
Block a user