from neutron.common import constants as n_const
from neutron.common import log
from neutron.openstack.common import log as logging
+from neutron.plugins.ml2.drivers.l2pop import rpc as l2pop_rpc
LOG = logging.getLogger(__name__)
@log.log
def add_fdb_entries(self, context, fdb_entries, host=None):
if not host or host == cfg.CONF.host:
- self.fdb_add(context, fdb_entries)
+ self.fdb_add(context, self._unmarshall_fdb_entries(fdb_entries))
@log.log
def remove_fdb_entries(self, context, fdb_entries, host=None):
if not host or host == cfg.CONF.host:
- self.fdb_remove(context, fdb_entries)
+ self.fdb_remove(context, self._unmarshall_fdb_entries(fdb_entries))
@log.log
def update_fdb_entries(self, context, fdb_entries, host=None):
if not host or host == cfg.CONF.host:
- self.fdb_update(context, fdb_entries)
+ self.fdb_update(context, self._unmarshall_fdb_entries(fdb_entries))
+
+ @staticmethod
+ def _unmarshall_fdb_entries(fdb_entries):
+ """Prepares fdb_entries from JSON.
+
+ All methods in this class that receive messages should call this to
+ unmarshall fdb_entries from the wire.
+
+ :param fdb_entries: Original fdb_entries data-structure. Looks like:
+ {
+ <uuid>: {
+ ...,
+ 'ports': {
+ <ip address>: [ [<mac>, <ip>], ... ],
+ ...
+
+ :returns: Deep copy with [<mac>, <ip>] converted to PortInfo
+ """
+ unmarshalled = dict(fdb_entries)
+ for value in unmarshalled.values():
+ if 'ports' in value:
+ value['ports'] = dict(
+ (address, [l2pop_rpc.PortInfo(*pi) for pi in port_infos])
+ for address, port_infos in value['ports'].items()
+ )
+ return unmarshalled
@abc.abstractmethod
def fdb_add(self, context, fdb_entries):
:param br: represent the bridge on which add_fdb_flow should be
applied.
- :param port_info: list to include mac and ip.
+ :param port_info: PortInfo instance to include mac and ip.
+ .mac_address
+ .ip_address
- [mac, ip]
:remote_ip: remote ip address.
:param lvm: a local VLAN map of network.
:param ofport: a port to add.
:param br: represent the bridge on which del_fdb_flow should be
applied.
- :param port_info: a list to contain mac and ip.
- [mac, ip]
+ :param port_info: PortInfo instance to include mac and ip.
+ .mac_address
+ .ip_address
+
:remote_ip: remote ip address.
:param lvm: local VLAN map of network.
:param ofport: a port to delete.
agent and network.
{'net1':
{'agent_ip':
- {'before': [[mac, ip]],
- 'after': [[mac, ip]]
+ {'before': PortInfo,
+ 'after': PortInfo
}
}
'net2':
...
}
+
+ PortInfo has .mac_address and .ip_address attrs.
+
:param local_ip: local IP address of this agent.
:local_vlan_map: local VLAN map of network.
'''
continue
after = state.get('after', [])
- for mac, ip in after:
- self.setup_entry_for_arp_reply(br, 'add', lvm.vlan, mac,
- ip)
+ for mac_ip in after:
+ self.setup_entry_for_arp_reply(br, 'add', lvm.vlan,
+ mac_ip.mac_address,
+ mac_ip.ip_address)
before = state.get('before', [])
- for mac, ip in before:
- self.setup_entry_for_arp_reply(br, 'remove', lvm.vlan, mac,
- ip)
+ for mac_ip in before:
+ self.setup_entry_for_arp_reply(br, 'remove', lvm.vlan,
+ mac_ip.mac_address,
+ mac_ip.ip_address)
MIN_VXLAN_VNI = 1
MAX_VXLAN_VNI = 2 ** 24 - 1
-FLOODING_ENTRY = ['00:00:00:00:00:00', '0.0.0.0']
+FLOODING_ENTRY = ('00:00:00:00:00:00', '0.0.0.0')
EXT_NS_COMP = '_backward_comp_e_ns'
EXT_NS = '_extension_ns'
self.migrated_ports = {}
def _get_port_fdb_entries(self, port):
- return [[port['mac_address'],
- ip['ip_address']] for ip in port['fixed_ips']]
+ return [l2pop_rpc.PortInfo(mac_address=port['mac_address'],
+ ip_address=ip['ip_address'])
+ for ip in port['fixed_ips']]
def delete_port_postcommit(self, context):
port = context.current
return
agent, agent_host, agent_ip, segment, port_fdb_entries = port_infos
- orig_mac_ip = [[port['mac_address'], ip] for ip in orig_ips]
- port_mac_ip = [[port['mac_address'], ip] for ip in port_ips]
+ orig_mac_ip = [l2pop_rpc.PortInfo(mac_address=port['mac_address'],
+ ip_address=ip)
+ for ip in orig_ips]
+ port_mac_ip = [l2pop_rpc.PortInfo(mac_address=port['mac_address'],
+ ip_address=ip)
+ for ip in port_ips]
upd_fdb_entries = {port['network_id']: {agent_ip: {}}}
# License for the specific language governing permissions and limitations
# under the License.
+import collections
+import copy
+
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron.openstack.common import log as logging
LOG = logging.getLogger(__name__)
+PortInfo = collections.namedtuple("PortInfo", "mac_address ip_address")
+
+
class L2populationAgentNotifyAPI(n_rpc.RpcProxy):
BASE_RPC_API_VERSION = '1.0'
'method': method,
'fdb_entries': fdb_entries})
+ marshalled_fdb_entries = self._marshall_fdb_entries(fdb_entries)
self.fanout_cast(context,
- self.make_msg(method, fdb_entries=fdb_entries),
+ self.make_msg(method,
+ fdb_entries=marshalled_fdb_entries),
topic=self.topic_l2pop_update)
def _notification_host(self, context, method, fdb_entries, host):
'topic': self.topic,
'method': method,
'fdb_entries': fdb_entries})
+ marshalled_fdb_entries = self._marshall_fdb_entries(fdb_entries)
self.cast(context,
- self.make_msg(method, fdb_entries=fdb_entries),
+ self.make_msg(method,
+ fdb_entries=marshalled_fdb_entries),
topic='%s.%s' % (self.topic_l2pop_update, host))
def add_fdb_entries(self, context, fdb_entries, host=None):
else:
self._notification_fanout(context, 'update_fdb_entries',
fdb_entries)
+
+ @staticmethod
+ def _marshall_fdb_entries(fdb_entries):
+ """Prepares fdb_entries for serialization to JSON for RPC.
+
+ All methods in this class that send messages should call this to
+ marshall fdb_entries for the wire.
+
+ :param fdb_entries: Original fdb_entries data-structure. Looks like:
+ {
+ <uuid>: {
+ ...,
+ 'ports': {
+ <ip address>: [ PortInfo, ... ],
+ ...
+
+ :returns: Deep copy with PortInfo converted to [mac, ip]
+ """
+ marshalled = copy.deepcopy(fdb_entries)
+ for value in marshalled.values():
+ if 'ports' in value:
+ for address, port_infos in value['ports'].items():
+ value['ports'][address] = [[mac, ip]
+ for mac, ip in port_infos]
+ return marshalled
for port_info in port_infos:
if port_info == n_const.FLOODING_ENTRY:
continue
- self.ryuapp.add_arp_table_entry(
- lvm.vlan, port_info[1], port_info[0])
+ self.ryuapp.add_arp_table_entry(lvm.vlan,
+ port_info.ip_address,
+ port_info.mac_address)
@log.log
def _fdb_remove_arp(self, lvm, agent_ports):
for port_info in port_infos:
if port_info == n_const.FLOODING_ENTRY:
continue
- self.ryuapp.del_arp_table_entry(lvm.vlan, port_info[1])
+ self.ryuapp.del_arp_table_entry(lvm.vlan, port_info.ip_address)
def add_fdb_flow(self, br, port_info, remote_ip, lvm, ofport):
if port_info == n_const.FLOODING_ENTRY:
lvm.tun_ofports, goto_next=True)
else:
self.ryuapp.add_arp_table_entry(
- lvm.vlan, port_info[1], port_info[0])
+ lvm.vlan,
+ port_info.ip_address,
+ port_info.mac_address)
br.install_tunnel_output(
tables.TUNNEL_OUT,
lvm.vlan, lvm.segmentation_id,
- set([ofport]), goto_next=False, eth_dst=port_info[0])
+ set([ofport]), goto_next=False, eth_dst=port_info.mac_address)
def del_fdb_flow(self, br, port_info, remote_ip, lvm, ofport):
if port_info == n_const.FLOODING_ENTRY:
tables.TUNNEL_FLOOD[lvm.network_type],
lvm.vlan)
else:
- self.ryuapp.del_arp_table_entry(lvm.vlan, port_info[1])
+ self.ryuapp.del_arp_table_entry(lvm.vlan, port_info.ip_address)
br.delete_tunnel_output(tables.TUNNEL_OUT,
- lvm.vlan, eth_dst=port_info[0])
+ lvm.vlan, eth_dst=port_info.mac_address)
def setup_entry_for_arp_reply(self, br, action, local_vid, mac_address,
ip_address):
actions="strip_vlan,set_tunnel:%s,output:%s" %
(lvm.segmentation_id, ofports))
else:
- self.setup_entry_for_arp_reply(br, 'add', lvm.vlan, port_info[0],
- port_info[1])
+ self.setup_entry_for_arp_reply(br, 'add', lvm.vlan,
+ port_info.mac_address,
+ port_info.ip_address)
br.add_flow(table=constants.UCAST_TO_TUN,
priority=2,
dl_vlan=lvm.vlan,
- dl_dst=port_info[0],
+ dl_dst=port_info.mac_address,
actions="strip_vlan,set_tunnel:%s,output:%s" %
(lvm.segmentation_id, ofport))
br.delete_flows(table=constants.FLOOD_TO_TUN, dl_vlan=lvm.vlan)
else:
self.setup_entry_for_arp_reply(br, 'remove', lvm.vlan,
- port_info[0], port_info[1])
+ port_info.mac_address,
+ port_info.ip_address)
br.delete_flows(table=constants.UCAST_TO_TUN,
dl_vlan=lvm.vlan,
- dl_dst=port_info[0])
+ dl_dst=port_info.mac_address)
def _fdb_chg_ip(self, context, fdb_entries):
LOG.debug("update chg_ip received")
import mock
from neutron.agent import l2population_rpc
+from neutron.plugins.ml2.drivers.l2pop import rpc as l2pop_rpc
from neutron.plugins.openvswitch.agent import ovs_neutron_agent
from neutron.tests import base
port='port3')]
self.agent_ports = {
- self.ports[0].ip: [[self.lvms[0].mac, self.lvms[0].ip]],
- self.ports[1].ip: [[self.lvms[1].mac, self.lvms[1].ip]],
- self.ports[2].ip: [[self.lvms[2].mac, self.lvms[2].ip]],
+ self.ports[0].ip: [(self.lvms[0].mac, self.lvms[0].ip)],
+ self.ports[1].ip: [(self.lvms[1].mac, self.lvms[1].ip)],
+ self.ports[2].ip: [(self.lvms[2].mac, self.lvms[2].ip)],
}
self.fdb_entries1 = {
'segment_id': self.lvms[0].segid,
'ports': {
self.local_ip: [],
- self.ports[0].ip: [[self.lvms[0].mac, self.lvms[0].ip]]},
+ self.ports[0].ip: [(self.lvms[0].mac, self.lvms[0].ip)]},
},
self.lvms[1].net: {
'network_type': self.type_gre,
'segment_id': self.lvms[1].segid,
'ports': {
self.local_ip: [],
- self.ports[1].ip: [[self.lvms[1].mac, self.lvms[1].ip]]},
+ self.ports[1].ip: [(self.lvms[1].mac, self.lvms[1].ip)]},
},
self.lvms[2].net: {
'network_type': self.type_gre,
'segment_id': self.lvms[2].segid,
'ports': {
self.local_ip: [],
- self.ports[2].ip: [[self.lvms[2].mac, self.lvms[2].ip]]},
+ self.ports[2].ip: [(self.lvms[2].mac, self.lvms[2].ip)]},
},
}
self.upd_fdb_entry1_val = {
self.lvms[0].net: {
self.ports[0].ip: {
- 'before': [[self.lvms[0].mac, self.lvms[0].ip]],
- 'after': [[self.lvms[1].mac, self.lvms[1].ip]],
+ 'before': [l2pop_rpc.PortInfo(self.lvms[0].mac,
+ self.lvms[0].ip)],
+ 'after': [l2pop_rpc.PortInfo(self.lvms[1].mac,
+ self.lvms[1].ip)],
},
self.ports[1].ip: {
- 'before': [[self.lvms[0].mac, self.lvms[0].ip]],
- 'after': [[self.lvms[1].mac, self.lvms[1].ip]],
+ 'before': [l2pop_rpc.PortInfo(self.lvms[0].mac,
+ self.lvms[0].ip)],
+ 'after': [l2pop_rpc.PortInfo(self.lvms[1].mac,
+ self.lvms[1].ip)],
},
},
self.lvms[1].net: {
self.ports[2].ip: {
- 'before': [[self.lvms[0].mac, self.lvms[0].ip]],
- 'after': [[self.lvms[2].mac, self.lvms[2].ip]],
+ 'before': [l2pop_rpc.PortInfo(self.lvms[0].mac,
+ self.lvms[0].ip)],
+ 'after': [l2pop_rpc.PortInfo(self.lvms[2].mac,
+ self.lvms[2].ip)],
},
},
}
results[lvm] = agent_ports
expected = {
self.lvm1: {
- self.ports[0].ip: [[self.lvms[0].mac, self.lvms[0].ip]],
+ self.ports[0].ip: [(self.lvms[0].mac, self.lvms[0].ip)],
self.local_ip: []},
self.lvm3: {
- self.ports[2].ip: [[self.lvms[2].mac, self.lvms[2].ip]],
+ self.ports[2].ip: [(self.lvms[2].mac, self.lvms[2].ip)],
self.local_ip: []},
}
self.assertEqual(expected, results)
results[lvm] = agent_ports
expected = {
self.lvm1: {
- self.ports[0].ip: [[self.lvms[0].mac, self.lvms[0].ip]],
+ self.ports[0].ip: [(self.lvms[0].mac, self.lvms[0].ip)],
self.local_ip: []},
self.lvm2: {},
self.lvm3: {
- self.ports[2].ip: [[self.lvms[2].mac, self.lvms[2].ip]],
+ self.ports[2].ip: [(self.lvms[2].mac, self.lvms[2].ip)],
self.local_ip: []},
}
self.assertEqual(expected, results)
self.fakeagent.fdb_add_tun('context', self.fakebr, self.lvm1,
self.agent_ports, self.ofports)
expected = [
- mock.call(self.fakebr, [self.lvms[0].mac, self.lvms[0].ip],
+ mock.call(self.fakebr, (self.lvms[0].mac, self.lvms[0].ip),
self.ports[0].ip, self.lvm1, self.ports[0].ofport),
- mock.call(self.fakebr, [self.lvms[1].mac, self.lvms[1].ip],
+ mock.call(self.fakebr, (self.lvms[1].mac, self.lvms[1].ip),
self.ports[1].ip, self.lvm1, self.ports[1].ofport),
- mock.call(self.fakebr, [self.lvms[2].mac, self.lvms[2].ip],
+ mock.call(self.fakebr, (self.lvms[2].mac, self.lvms[2].ip),
self.ports[2].ip, self.lvm1, self.ports[2].ofport),
]
self.assertEqual(sorted(expected),
mock_setup_tunnel_port.assert_called_once_with(
self.fakebr, self.ports[1].ip, self.lvm1.network_type)
expected = [
- mock.call(self.fakebr, [self.lvms[0].mac, self.lvms[0].ip],
+ mock.call(self.fakebr, (self.lvms[0].mac, self.lvms[0].ip),
self.ports[0].ip, self.lvm1, self.ports[0].ofport),
- mock.call(self.fakebr, [self.lvms[1].mac, self.lvms[1].ip],
+ mock.call(self.fakebr, (self.lvms[1].mac, self.lvms[1].ip),
self.ports[1].ip, self.lvm1, ofport),
- mock.call(self.fakebr, [self.lvms[2].mac, self.lvms[2].ip],
+ mock.call(self.fakebr, (self.lvms[2].mac, self.lvms[2].ip),
self.ports[2].ip, self.lvm1, self.ports[2].ofport),
]
self.assertEqual(sorted(expected),
mock_setup_tunnel_port.assert_called_once_with(
self.fakebr, self.ports[1].ip, self.lvm1.network_type)
expected = [
- mock.call(self.fakebr, [self.lvms[0].mac, self.lvms[0].ip],
+ mock.call(self.fakebr, (self.lvms[0].mac, self.lvms[0].ip),
self.ports[0].ip, self.lvm1, self.ports[0].ofport),
- mock.call(self.fakebr, [self.lvms[2].mac, self.lvms[2].ip],
+ mock.call(self.fakebr, (self.lvms[2].mac, self.lvms[2].ip),
self.ports[2].ip, self.lvm1, self.ports[2].ofport),
]
self.assertEqual(sorted(expected),
self.fakeagent.fdb_remove_tun('context', self.fakebr, self.lvm1,
self.agent_ports, self.ofports)
expected = [
- mock.call(self.fakebr, [self.lvms[0].mac, self.lvms[0].ip],
+ mock.call(self.fakebr, (self.lvms[0].mac, self.lvms[0].ip),
self.ports[0].ip, self.lvm1, self.ports[0].ofport),
- mock.call(self.fakebr, [self.lvms[1].mac, self.lvms[1].ip],
+ mock.call(self.fakebr, (self.lvms[1].mac, self.lvms[1].ip),
self.ports[1].ip, self.lvm1, self.ports[1].ofport),
- mock.call(self.fakebr, [self.lvms[2].mac, self.lvms[2].ip],
+ mock.call(self.fakebr, (self.lvms[2].mac, self.lvms[2].ip),
self.ports[2].ip, self.lvm1, self.ports[2].ofport),
]
self.assertEqual(sorted(expected),
self.fakeagent.fdb_remove_tun('context', self.fakebr, self.lvm1,
self.agent_ports, self.ofports)
expected = [
- mock.call(self.fakebr, [self.lvms[0].mac, self.lvms[0].ip],
+ mock.call(self.fakebr, (self.lvms[0].mac, self.lvms[0].ip),
self.ports[0].ip, self.lvm1, self.ports[0].ofport),
mock.call(self.fakebr,
- [n_const.FLOODING_ENTRY[0], n_const.FLOODING_ENTRY[1]],
+ (n_const.FLOODING_ENTRY[0], n_const.FLOODING_ENTRY[1]),
self.ports[1].ip, self.lvm1, self.ports[1].ofport),
- mock.call(self.fakebr, [self.lvms[2].mac, self.lvms[2].ip],
+ mock.call(self.fakebr, (self.lvms[2].mac, self.lvms[2].ip),
self.ports[2].ip, self.lvm1, self.ports[2].ofport),
]
self.assertEqual(sorted(expected),
self.fakeagent.fdb_remove_tun('context', self.fakebr, self.lvm1,
self.agent_ports, self.ofports)
expected = [
- mock.call(self.fakebr, [self.lvms[0].mac, self.lvms[0].ip],
+ mock.call(self.fakebr, (self.lvms[0].mac, self.lvms[0].ip),
self.ports[0].ip, self.lvm1, self.ports[0].ofport),
- mock.call(self.fakebr, [self.lvms[2].mac, self.lvms[2].ip],
+ mock.call(self.fakebr, (self.lvms[2].mac, self.lvms[2].ip),
self.ports[2].ip, self.lvm1, self.ports[2].ofport),
]
self.assertEqual(sorted(expected),
upd_fdb_entry_val = {
self.lvms[0].net: {
self.local_ip: {
- 'before': [[self.lvms[0].mac, self.lvms[0].ip]],
- 'after': [[self.lvms[1].mac, self.lvms[1].ip]],
+ 'before': [(self.lvms[0].mac, self.lvms[0].ip)],
+ 'after': [(self.lvms[1].mac, self.lvms[1].ip)],
},
},
}
import contextlib
import mock
+from neutron.agent import l2population_rpc
from neutron.common import constants
from neutron.common import topics
from neutron import context
from neutron.openstack.common import timeutils
from neutron.plugins.ml2 import config as config
from neutron.plugins.ml2.drivers.l2pop import mech_driver as l2pop_mech_driver
+from neutron.plugins.ml2.drivers.l2pop import rpc as l2pop_rpc
from neutron.plugins.ml2 import managers
from neutron.plugins.ml2 import rpc
from neutron.tests.unit import test_db_plugin as test_plugin
NOTIFIER = 'neutron.plugins.ml2.rpc.AgentNotifierApi'
DEVICE_OWNER_COMPUTE = 'compute:None'
+FLOODING_ENTRY_AS_LIST = list(constants.FLOODING_ENTRY)
+
class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
agent_state={'agent_state': L2_AGENT_5},
time=timeutils.strtime())
+ def test_port_info_compare(self):
+ # An assumption the code makes is that PortInfo compares equal to
+ # equivalent regular tuples.
+ self.assertEqual(("mac", "ip"), l2pop_rpc.PortInfo("mac", "ip"))
+
+ flooding_entry = l2pop_rpc.PortInfo(*constants.FLOODING_ENTRY)
+ self.assertEqual(constants.FLOODING_ENTRY, flooding_entry)
+
+ def test__unmarshall_fdb_entries(self):
+ entries = {'foouuid': {
+ 'segment_id': 1001,
+ 'ports': {'192.168.0.10': [['00:00:00:00:00:00', '0.0.0.0'],
+ ['fa:16:3e:ff:8c:0f', '10.0.0.6']]},
+ 'network_type': 'vxlan'}}
+
+ mixin = l2population_rpc.L2populationRpcCallBackMixin
+ entries = mixin._unmarshall_fdb_entries(entries)
+
+ port_info_list = entries['foouuid']['ports']['192.168.0.10']
+ # Check that the lists have been properly converted to PortInfo
+ self.assertIsInstance(port_info_list[0], l2pop_rpc.PortInfo)
+ self.assertIsInstance(port_info_list[1], l2pop_rpc.PortInfo)
+ self.assertEqual(('00:00:00:00:00:00', '0.0.0.0'), port_info_list[0])
+ self.assertEqual(('fa:16:3e:ff:8c:0f', '10.0.0.6'), port_info_list[1])
+
+ def test__marshall_fdb_entries(self):
+ entries = {'foouuid': {
+ 'segment_id': 1001,
+ 'ports': {'192.168.0.10': [('00:00:00:00:00:00', '0.0.0.0'),
+ ('fa:16:3e:ff:8c:0f', '10.0.0.6')]},
+ 'network_type': 'vxlan'}}
+
+ entries = l2pop_rpc.L2populationAgentNotifyAPI._marshall_fdb_entries(
+ entries)
+
+ port_info_list = entries['foouuid']['ports']['192.168.0.10']
+ # Check that the PortInfo tuples have been converted to list
+ self.assertIsInstance(port_info_list[0], list)
+ self.assertIsInstance(port_info_list[1], list)
+ self.assertEqual(['00:00:00:00:00:00', '0.0.0.0'], port_info_list[0])
+ self.assertEqual(['fa:16:3e:ff:8c:0f', '10.0.0.6'], port_info_list[1])
+
def test_fdb_add_called(self):
self._register_ml2_agents()
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.1': [constants.FLOODING_ENTRY,
+ {'20.0.0.1': [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vxlan',
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.5': [constants.FLOODING_ENTRY,
+ {'20.0.0.5': [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vlan',
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.2': [constants.FLOODING_ENTRY,
+ {'20.0.0.2': [FLOODING_ENTRY_AS_LIST,
[p2['mac_address'],
p2_ips[0]]]},
'network_type': 'vxlan',
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.1': [constants.FLOODING_ENTRY,
+ {'20.0.0.1': [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vxlan',
{p1['network_id']:
{'ports':
{'20.0.0.2':
- [constants.FLOODING_ENTRY,
+ [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vxlan',
{p1['network_id']:
{'ports':
{'20.0.0.1':
- [constants.FLOODING_ENTRY,
+ [FLOODING_ENTRY_AS_LIST,
[p3['mac_address'],
p3_ips[0]]]},
'network_type': 'vxlan',
{'fdb_entries':
{p2['network_id']:
{'ports':
- {'20.0.0.1': [constants.FLOODING_ENTRY,
+ {'20.0.0.1': [FLOODING_ENTRY_AS_LIST,
[p2['mac_address'],
p2_ips[0]]]},
'network_type': 'vxlan',
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.1': [constants.FLOODING_ENTRY,
+ {'20.0.0.1': [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vxlan',
{'chg_ip':
{p1['network_id']:
{'20.0.0.1':
- {'after': [[p1['mac_address'],
- '10.0.0.10']]}}}}},
+ {'after': [(p1['mac_address'],
+ '10.0.0.10')]}}}}},
'namespace': None,
'method': 'update_fdb_entries'}
{'chg_ip':
{p1['network_id']:
{'20.0.0.1':
- {'before': [[p1['mac_address'],
- '10.0.0.10']],
- 'after': [[p1['mac_address'],
- '10.0.0.16']]}}}}},
+ {'before': [(p1['mac_address'],
+ '10.0.0.10')],
+ 'after': [(p1['mac_address'],
+ '10.0.0.16')]}}}}},
'namespace': None,
'method': 'update_fdb_entries'}
{'chg_ip':
{p1['network_id']:
{'20.0.0.1':
- {'before': [[p1['mac_address'],
- '10.0.0.2']]}}}}},
+ {'before': [(p1['mac_address'],
+ '10.0.0.2')]}}}}},
'namespace': None,
'method': 'update_fdb_entries'}
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.1': [constants.FLOODING_ENTRY,
+ {'20.0.0.1': [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vxlan',
{'fdb_entries':
{p1['network_id']:
{'ports':
- {'20.0.0.1': [constants.FLOODING_ENTRY,
+ {'20.0.0.1': [FLOODING_ENTRY_AS_LIST,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vxlan',
'remove_fdb_entries')) as (upd_port_down,
rem_fdb_entries):
l2pop_mech.delete_port_postcommit(mock.Mock())
- self.assertTrue(upd_port_down.called)
\ No newline at end of file
+ self.assertTrue(upd_port_down.called)
from neutron.common import constants as n_const
from neutron.openstack.common import importutils
from neutron.plugins.common import constants as p_const
+from neutron.plugins.ml2.drivers.l2pop import rpc as l2pop_rpc
from neutron.tests.unit.ofagent import ofa_test_base
NOTIFIER = ('neutron.plugins.ml2.rpc.AgentNotifierApi')
+FLOODING_ENTRY = l2pop_rpc.PortInfo(*n_const.FLOODING_ENTRY)
def _mock_port(is_neutron=True, normalized_name=None):
'segment_id': 'tun2',
'ports':
{'agent_ip':
- [['mac', 'ip'],
- n_const.FLOODING_ENTRY]}}}
+ [l2pop_rpc.PortInfo('mac', 'ip'),
+ FLOODING_ENTRY]}}}
with contextlib.nested(
mock.patch.object(self.agent.ryuapp, "add_arp_table_entry"),
mock.patch.object(self.agent.ryuapp, "del_arp_table_entry"),
'segment_id': 'tun1',
'ports':
{self.lvms[1].ip:
- [['mac', 'ip'],
- n_const.FLOODING_ENTRY]}}}
+ [l2pop_rpc.PortInfo('mac', 'ip'),
+ FLOODING_ENTRY]}}}
with contextlib.nested(
mock.patch.object(self.agent, '_setup_tunnel_port'),
mock.patch.object(self.agent.int_br, 'install_tunnel_output'),
'segment_id': 'tun2',
'ports':
{self.lvms[1].ip:
- [['mac', 'ip'],
- n_const.FLOODING_ENTRY]}}}
+ [l2pop_rpc.PortInfo('mac', 'ip'),
+ FLOODING_ENTRY]}}}
with contextlib.nested(
mock.patch.object(self.agent.int_br, 'install_tunnel_output'),
mock.patch.object(self.agent.int_br, 'delete_tunnel_output'),
fdb_entry = {self.lvms[0].net:
{'network_type': self.tunnel_type,
'segment_id': 'tun1',
- 'ports': {self.lvms[0].ip: [['mac', 'ip']]}}}
+ 'ports': {self.lvms[0].ip: [l2pop_rpc.PortInfo('mac',
+ 'ip')]}}}
with mock.patch.object(self.agent, '_setup_tunnel_port') as add_tun_fn:
self.agent.fdb_add(None, fdb_entry)
self.assertFalse(add_tun_fn.called)
- fdb_entry[self.lvms[0].net]['ports'][tunnel_ip] = [['mac', 'ip']]
+ fdb_entry[self.lvms[0].net]['ports'][tunnel_ip] = [
+ l2pop_rpc.PortInfo('mac', 'ip')]
self.agent.fdb_add(None, fdb_entry)
add_tun_fn.assert_called_with(
self.agent.int_br, tun_name, tunnel_ip, self.tunnel_type)
fdb_entry = {self.lvms[1].net:
{'network_type': self.tunnel_type,
'segment_id': 'tun2',
- 'ports': {self.lvms[1].ip: [n_const.FLOODING_ENTRY]}}}
+ 'ports': {self.lvms[1].ip: [FLOODING_ENTRY]}}}
with mock.patch.object(self.agent.int_br,
'delete_port') as del_port_fn:
self.agent.fdb_remove(None, fdb_entry)
fdb_entry = {self.lvms[0].net:
{'network_type': self.tunnel_type,
'segment_id': 'tun1',
- 'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
- ['mac1', 'ip1']],
- self.lvms[1].ip: [['mac2', 'ip2']],
- '192.0.2.1': [n_const.FLOODING_ENTRY,
- ['mac3', 'ip3']]}}}
+ 'ports': {self.lvms[0].ip: [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac1', 'ip1')],
+ self.lvms[1].ip: [
+ l2pop_rpc.PortInfo('mac2', 'ip2')],
+ '192.0.2.1': [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac3', 'ip3')]}}}
with mock.patch.object(self.agent,
'setup_tunnel_port') as setup_tun_fn:
self.agent.fdb_add(None, fdb_entry)
fdb_entry = {self.lvms[0].net:
{'network_type': network_type,
'segment_id': 'tun1',
- 'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
- ['mac1', 'ip1']],
- self.lvms[1].ip: [['mac2', 'ip2']],
- '192.0.2.1': [n_const.FLOODING_ENTRY,
- ['mac3', 'ip3']]}}}
+ 'ports': {self.lvms[0].ip: [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac1', 'ip1')],
+ self.lvms[1].ip: [
+ l2pop_rpc.PortInfo('mac2', 'ip2')],
+ '192.0.2.1': [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac3', 'ip3')]}}}
with mock.patch.object(self.agent,
'setup_tunnel_port') as setup_tun_fn:
self.agent.fdb_add(None, fdb_entry)
fdb_entry = {self.lvms[0].net:
{'network_type': self.tunnel_type,
'segment_id': 'tun1',
- 'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
- ['mac1', 'ip1']],
- self.lvms[1].ip: [['mac2', 'ip2']],
- '192.0.2.1': [n_const.FLOODING_ENTRY,
- ['mac3', 'ip3']]}}}
+ 'ports': {self.lvms[0].ip: [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac1', 'ip1')],
+ self.lvms[1].ip: [
+ l2pop_rpc.PortInfo('mac2', 'ip2')],
+ '192.0.2.1': [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac3', 'ip3')]}}}
with mock.patch.object(self.agent,
'cleanup_tunnel_port') as cleanup_tun_fn:
self.agent.fdb_remove(None, fdb_entry)
fdb_entry = {self.lvms[0].net:
{'network_type': network_type,
'segment_id': 'tun1',
- 'ports': {self.lvms[0].ip: [n_const.FLOODING_ENTRY,
- ['mac1', 'ip1']],
- self.lvms[1].ip: [['mac2', 'ip2']],
- '192.0.2.1': [n_const.FLOODING_ENTRY,
- ['mac3', 'ip3']]}}}
+ 'ports': {self.lvms[0].ip: [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac1', 'ip1')],
+ self.lvms[1].ip: [
+ l2pop_rpc.PortInfo('mac2', 'ip2')],
+ '192.0.2.1': [
+ FLOODING_ENTRY,
+ l2pop_rpc.PortInfo('mac3', 'ip3')]}}}
with mock.patch.object(self.agent,
'cleanup_tunnel_port') as cleanup_tun_fn:
self.agent.fdb_remove(None, fdb_entry)
from neutron.common import constants as n_const
from neutron.openstack.common import log
from neutron.plugins.common import constants as p_const
+from neutron.plugins.ml2.drivers.l2pop import rpc as l2pop_rpc
from neutron.plugins.openvswitch.agent import ovs_neutron_agent
from neutron.plugins.openvswitch.common import constants
from neutron.tests import base
'segment_id': 'tun2',
'ports':
{'agent_ip':
- [[FAKE_MAC, FAKE_IP1],
+ [l2pop_rpc.PortInfo(FAKE_MAC, FAKE_IP1),
n_const.FLOODING_ENTRY]}}}
with mock.patch.object(self.agent.tun_br,
"deferred") as defer_fn:
'segment_id': 'tun1',
'ports':
{'2.2.2.2':
- [[FAKE_MAC, FAKE_IP1],
+ [l2pop_rpc.PortInfo(FAKE_MAC, FAKE_IP1),
n_const.FLOODING_ENTRY]}}}
class ActionMatcher(object):
'segment_id': 'tun2',
'ports':
{'2.2.2.2':
- [[FAKE_MAC, FAKE_IP1],
+ [l2pop_rpc.PortInfo(FAKE_MAC, FAKE_IP1),
n_const.FLOODING_ENTRY]}}}
with contextlib.nested(
mock.patch.object(self.agent.tun_br, 'deferred'),
fdb_entry = {'net1':
{'network_type': 'gre',
'segment_id': 'tun1',
- 'ports': {'1.1.1.1': [[FAKE_MAC, FAKE_IP1]]}}}
+ 'ports': {'1.1.1.1': [l2pop_rpc.PortInfo(FAKE_MAC,
+ FAKE_IP1)]}}}
with contextlib.nested(
mock.patch.object(self.agent.tun_br, 'deferred'),
mock.patch.object(self.agent.tun_br, 'do_action_flows'),
deferred_fn.return_value = deferred_br
self.agent.fdb_add(None, fdb_entry)
self.assertFalse(add_tun_fn.called)
- fdb_entry['net1']['ports']['10.10.10.10'] = [[FAKE_MAC, FAKE_IP1]]
+ fdb_entry['net1']['ports']['10.10.10.10'] = [
+ l2pop_rpc.PortInfo(FAKE_MAC, FAKE_IP1)]
self.agent.fdb_add(None, fdb_entry)
add_tun_fn.assert_called_with(
deferred_br, 'gre-0a0a0a0a', '10.10.10.10', 'gre')
fdb_entries = {'chg_ip':
{'net1':
{'agent_ip':
- {'before': [[FAKE_MAC, FAKE_IP1]],
- 'after': [[FAKE_MAC, FAKE_IP2]]}}}}
+ {'before': [l2pop_rpc.PortInfo(FAKE_MAC, FAKE_IP1)],
+ 'after': [l2pop_rpc.PortInfo(FAKE_MAC, FAKE_IP2)]}}}}
with contextlib.nested(
mock.patch.object(self.agent.tun_br, 'deferred'),
mock.patch.object(self.agent.tun_br, 'do_action_flows'),