def _test_del_arp_table_entry_non_tunnel(self, network_type):
     self._prepare_l2_pop_ofports(network_type=network_type)
     fdb_entry = {
         self.lvms[0].net: {
             'network_type': network_type,
             'segment_id': 'tun1',
             '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)
         calls = [
             mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
                       'ip1'),
             mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
                       'ip2')
         ]
         self.ryuapp.del_arp_table_entry.assert_has_calls(calls,
                                                          any_order=True)
         self.assertFalse(cleanup_tun_fn.called)
 def test_add_arp_table_entry(self):
     self._prepare_l2_pop_ofports()
     fdb_entry = {
         self.lvms[0].net: {
             'network_type': self.tunnel_type,
             'segment_id': 'tun1',
             '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)
         calls = [
             mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
                       'ip1', 'mac1'),
             mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan,
                       'ip2', 'mac2')
         ]
         self.ryuapp.add_arp_table_entry.assert_has_calls(calls,
                                                          any_order=True)
         setup_tun_fn.assert_called_once_with(self.agent.int_br,
                                              '192.0.2.1', 'gre')
Example #3
0
    def _fixed_ips_changed(self, context, orig, port, diff_ips):
        orig_ips, port_ips = diff_ips

        if (port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE):
            agent_host = context.host
        else:
            agent_host = context.original_host

        if not agent_host:
            return

        agent_ip = l2pop_db.get_agent_ip_by_host(context._plugin_context,
                                                 agent_host)

        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: {}}}

        ports = upd_fdb_entries[port['network_id']][agent_ip]
        if orig_mac_ip:
            ports['before'] = orig_mac_ip

        if port_mac_ip:
            ports['after'] = port_mac_ip

        self.L2populationAgentNotify.update_fdb_entries(
            self.rpc_ctx, {'chg_ip': upd_fdb_entries})

        return True
Example #4
0
    def test_fdb_add_called_two_networks(self):
        self._register_ml2_agents()

        with self.subnet(network=self._network) as subnet:
            host_arg = {portbindings.HOST_ID: HOST + '_2'}
            with self.port(subnet=subnet,
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID,),
                           **host_arg) as port1:
                with self.subnet(cidr='10.1.0.0/24') as subnet2:
                    with self.port(subnet=subnet2,
                                   device_owner=DEVICE_OWNER_COMPUTE,
                                   arg_list=(portbindings.HOST_ID,),
                                   **host_arg):
                        host_arg = {portbindings.HOST_ID: HOST}
                        with self.port(subnet=subnet,
                                       device_owner=DEVICE_OWNER_COMPUTE,
                                       arg_list=(portbindings.HOST_ID,),
                                       **host_arg) as port3:
                            p1 = port1['port']
                            p3 = port3['port']

                            device = 'tap' + p3['id']

                            self.mock_cast.reset_mock()
                            self.mock_fanout.reset_mock()
                            self.callbacks.update_device_up(
                                self.adminContext, agent_id=HOST,
                                device=device)

                            p1_ips = [p['ip_address']
                                      for p in p1['fixed_ips']]
                            expected1 = {p1['network_id']:
                                         {'ports':
                                          {'20.0.0.2':
                                           [constants.FLOODING_ENTRY,
                                            l2pop_rpc.PortInfo(
                                                p1['mac_address'],
                                                p1_ips[0])]},
                                         'network_type': 'vxlan',
                                         'segment_id': 1}}

                            self.mock_cast.assert_called_with(
                                    mock.ANY, 'add_fdb_entries', expected1,
                                    HOST)

                            p3_ips = [p['ip_address']
                                      for p in p3['fixed_ips']]
                            expected2 = {p1['network_id']:
                                         {'ports':
                                          {'20.0.0.1':
                                           [constants.FLOODING_ENTRY,
                                            l2pop_rpc.PortInfo(
                                                p3['mac_address'],
                                                p3_ips[0])]},
                                         'network_type': 'vxlan',
                                         'segment_id': 1}}

                            self.mock_fanout.assert_called_with(
                                mock.ANY, 'add_fdb_entries', expected2)
Example #5
0
    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)
Example #6
0
    def test_mac_addr_changed(self):
        self._register_ml2_agents()

        with self.subnet(network=self._network) as subnet:
            host_arg = {portbindings.HOST_ID: HOST + '_5'}
            with self.port(subnet=subnet,
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID, ),
                           **host_arg) as port1:
                p1 = port1['port']

                self.mock_fanout.reset_mock()
                device = 'tap' + p1['id']

                old_mac = p1['mac_address']
                mac = old_mac.split(':')
                mac[5] = '01' if mac[5] != '01' else '00'
                new_mac = ':'.join(mac)
                data = {
                    'port': {
                        'mac_address': new_mac,
                        portbindings.HOST_ID: HOST
                    }
                }
                req = self.new_update_request('ports', data, p1['id'])
                res = self.deserialize(self.fmt, req.get_response(self.api))
                self.assertIn('port', res)
                self.assertEqual(new_mac, res['port']['mac_address'])

                # port was not bound before, so no fdb call expected yet
                self.assertFalse(self.mock_fanout.called)

                self.callbacks.update_device_up(self.adminContext,
                                                agent_id=HOST,
                                                device=device)

                self.assertEqual(1, self.mock_fanout.call_count)
                add_expected = {
                    p1['network_id']: {
                        'segment_id': 1,
                        'network_type': 'vxlan',
                        'ports': {
                            '20.0.0.1': [
                                l2pop_rpc.PortInfo('00:00:00:00:00:00',
                                                   '0.0.0.0'),
                                l2pop_rpc.PortInfo(new_mac, '10.0.0.2')
                            ]
                        }
                    }
                }
                self.mock_fanout.assert_called_with(mock.ANY,
                                                    'add_fdb_entries',
                                                    add_expected)
Example #7
0
    def test_fdb_add_called_dualstack(self):
        self._register_ml2_agents()

        host_arg = {portbindings.HOST_ID: HOST, 'admin_state_up': True}
        with self.subnet(self._network) as subnet,\
            self.subnet(
                self._network,
                cidr='2001:db8::/64',
                ip_version=6,
                gateway_ip='fe80::1',
                ipv6_address_mode=n_const.IPV6_SLAAC) as subnet2:
            with self.port(subnet,
                           fixed_ips=[{
                               'subnet_id': subnet['subnet']['id']
                           }, {
                               'subnet_id': subnet2['subnet']['id']
                           }],
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID, ),
                           **host_arg) as port:
                p1 = port['port']

                device = 'tap' + p1['id']

                self.mock_fanout.reset_mock()
                self.callbacks.update_device_up(self.adminContext,
                                                agent_id=HOST,
                                                device=device)

                p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
                expected = {
                    p1['network_id']: {
                        'ports': {
                            '20.0.0.1': [
                                constants.FLOODING_ENTRY,
                                l2pop_rpc.PortInfo(p1['mac_address'],
                                                   p1_ips[0]),
                                l2pop_rpc.PortInfo(p1['mac_address'],
                                                   p1_ips[1])
                            ]
                        },
                        'network_type': 'vxlan',
                        'segment_id': 1
                    }
                }

                self.mock_fanout.assert_called_with(mock.ANY,
                                                    'add_fdb_entries',
                                                    expected)
 def test_fdb_add_port(self):
     self._prepare_l2_pop_ofports()
     tunnel_ip = '10.10.10.10'
     fdb_entry = {self.lvms[0].net:
                  {'network_type': self.tunnel_type,
                   'segment_id': 'tun1',
                   '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] = [
             l2pop_rpc.PortInfo('mac', 'ip')]
         self.agent.fdb_add(None, fdb_entry)
         self.assertFalse(add_tun_fn.called)
Example #9
0
    def test_create_agent_fdb(self):
        binding = mock.Mock()
        binding.port = {
            'mac_address': '00:00:DE:AD:BE:EF',
            'fixed_ips': [{
                'ip_address': '1.1.1.1'
            }]
        }
        fdb_network_ports, fdb_agent = (self._mock_network_ports(
            HOST + '2', binding))
        agent_ips = {fdb_agent: '20.0.0.1'}

        agent_fdb = self._test_create_agent_fdb(fdb_network_ports, agent_ips)
        result = agent_fdb['network_id']

        expected_result = {
            'segment_id': 1,
            'network_type': 'vxlan',
            'ports': {
                '10.0.0.1': [constants.FLOODING_ENTRY],
                '20.0.0.1': [
                    constants.FLOODING_ENTRY,
                    l2pop_rpc.PortInfo(mac_address='00:00:DE:AD:BE:EF',
                                       ip_address='1.1.1.1')
                ]
            }
        }
        self.assertEqual(expected_result, result)
 def test_fdb_add_flows(self):
     self._prepare_l2_pop_ofports()
     fdb_entry = {
         self.lvms[0].net: {
             'network_type': self.tunnel_type,
             'segment_id': 'tun1',
             'ports': {
                 self.lvms[1].ip:
                 [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'),
             mock.patch.object(self.agent.int_br, 'delete_tunnel_output'),
     ) as (add_tun_fn, install_fn, delete_fn):
         add_tun_fn.return_value = 2
         self.agent.fdb_add(None, fdb_entry)
         self.assertEqual(2, install_fn.call_count)
         expected_calls = [
             mock.call(7, 11, 21, set([2]), eth_dst='mac', goto_next=False),
             mock.call(10, 11, 21, set([1, 2]), goto_next=True)
         ]
         install_fn.assert_has_calls(expected_calls)
         self.assertFalse(delete_fn.called)
Example #11
0
    def test_host_changed_twice(self):
        self._register_ml2_agents()
        with self.subnet(network=self._network) as subnet:
            host_arg = {portbindings.HOST_ID: L2_AGENT['host']}
            host2_arg = {portbindings.HOST_ID: L2_AGENT_2['host']}
            with self.port(subnet=subnet,
                           cidr='10.0.0.0/24',
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID, ),
                           **host_arg) as port1:
                with self.port(subnet=subnet,
                               cidr='10.0.0.0/24',
                               device_owner=DEVICE_OWNER_COMPUTE,
                               arg_list=(portbindings.HOST_ID, ),
                               **host2_arg) as port2:
                    p1 = port1['port']
                    device1 = 'tap' + p1['id']
                    self.callbacks.update_device_up(self.adminContext,
                                                    agent_id=L2_AGENT['host'],
                                                    device=device1)
                    p2 = port2['port']
                    device2 = 'tap' + p2['id']
                    self.callbacks.update_device_up(
                        self.adminContext,
                        agent_id=L2_AGENT_2['host'],
                        device=device2)
                    data2 = {'port': {'binding:host_id': L2_AGENT_2['host']}}
                    req = self.new_update_request('ports', data2, p1['id'])
                    res = self.deserialize(self.fmt,
                                           req.get_response(self.api))
                    self.assertEqual(res['port']['binding:host_id'],
                                     L2_AGENT_2['host'])
                    data4 = {'port': {'binding:host_id': L2_AGENT_4['host']}}
                    req = self.new_update_request('ports', data4, p1['id'])
                    res = self.deserialize(self.fmt,
                                           req.get_response(self.api))
                    self.assertEqual(res['port']['binding:host_id'],
                                     L2_AGENT_4['host'])
                    self.mock_fanout.reset_mock()
                    self.callbacks.get_device_details(
                        self.adminContext,
                        device=device1,
                        agent_id=L2_AGENT_4['host'])
                    p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
                    expected = {
                        p1['network_id']: {
                            'ports': {
                                '20.0.0.1': [
                                    constants.FLOODING_ENTRY,
                                    l2pop_rpc.PortInfo(p1['mac_address'],
                                                       p1_ips[0])
                                ]
                            },
                            'network_type': 'vxlan',
                            'segment_id': 1
                        }
                    }

                    self.mock_fanout.assert_called_with(
                        mock.ANY, 'remove_fdb_entries', expected)
Example #12
0
    def _get_port_infos(self, port, segment, agent_host):
        if not agent_host:
            return

        session = db_api.get_session()
        agent = l2pop_db.get_agent_by_host(session, agent_host)
        if not agent:
            return

        agent_ip = l2pop_db.get_agent_ip(agent)
        if not agent_ip:
            LOG.warning(_LW("Unable to retrieve the agent ip, check the agent "
                            "configuration."))
            return

        if not segment:
            LOG.warning(_LW("Port %(port)s updated by agent %(agent)s "
                            "isn't bound to any segment"),
                        {'port': port['id'], 'agent': agent})
            return

        network_types = l2pop_db.get_agent_l2pop_network_types(agent)
        if network_types is None:
            network_types = l2pop_db.get_agent_tunnel_types(agent)
        if segment['network_type'] not in network_types:
            return

        fdb_entries = [l2pop_rpc.PortInfo(mac_address=port['mac_address'],
                                          ip_address=ip['ip_address'])
                       for ip in port['fixed_ips']]
        return agent_ip, fdb_entries
Example #13
0
    def test_fdb_add_called_for_l2pop_network_types(self):
        self._register_ml2_agents()

        host = HOST + '_5'
        with self.subnet(network=self._network2) as subnet:
            host_arg = {portbindings.HOST_ID: host}
            with self.port(subnet=subnet,
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID,),
                           **host_arg) as port1:
                with self.port(subnet=subnet,
                               arg_list=(portbindings.HOST_ID,),
                               **host_arg):
                    p1 = port1['port']

                    device = 'tap' + p1['id']

                    self.mock_fanout.reset_mock()
                    self.callbacks.update_device_up(self.adminContext,
                                                    agent_id=host,
                                                    device=device)

                    p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
                    expected = {p1['network_id']:
                                {'ports':
                                 {'20.0.0.5': [constants.FLOODING_ENTRY,
                                               l2pop_rpc.PortInfo(
                                                   p1['mac_address'],
                                                   p1_ips[0])]},
                                 'network_type': 'vlan',
                                 'segment_id': 2}}

                    self.mock_fanout.assert_called_with(
                        mock.ANY, 'add_fdb_entries', expected)
Example #14
0
    def test_delete_port_last_port_up(self):
        self._register_ml2_agents()

        with self.subnet(network=self._network) as subnet:
            host_arg = {portbindings.HOST_ID: HOST}
            with self.port(subnet=subnet,
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID,),
                           **host_arg):
                with self.port(subnet=subnet,
                               device_owner=DEVICE_OWNER_COMPUTE,
                               arg_list=(portbindings.HOST_ID,),
                               **host_arg) as port:
                    p1 = port['port']

                    device = 'tap' + p1['id']

                    self.callbacks.update_device_up(self.adminContext,
                                                    agent_id=HOST,
                                                    device=device)
                self._delete('ports', port['port']['id'])
                p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
                expected = {p1['network_id']:
                            {'ports':
                             {'20.0.0.1': [constants.FLOODING_ENTRY,
                                           l2pop_rpc.PortInfo(
                                               p1['mac_address'],
                                               p1_ips[0])]},
                             'network_type': 'vxlan',
                             'segment_id': 1}}

                self.mock_fanout.assert_any_call(
                    mock.ANY, 'remove_fdb_entries', expected)
Example #15
0
    def _get_port_fdb_entries(self, port):
        # the port might be concurrently deleted
        if not port or not port.get('fixed_ips'):
            return []

        return [l2pop_rpc.PortInfo(mac_address=port['mac_address'],
                                   ip_address=ip['ip_address'])
                for ip in port['fixed_ips']]
Example #16
0
    def _fixed_ips_changed(self, context, orig, port, diff_ips):
        segment = context.bottom_bound_segment
        if not segment:
            LOG.warning(("No segment for port {} diff {}").format(
                context.current, diff_ips))
            return

        orig_ips, port_ips = diff_ips

        if (port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE):
            agent_host = context.host
        else:
            agent_host = context.original_host

        if not agent_host:
            return

        agent_ip = l2pop_db.get_agent_ip_by_host(
            db_api.get_reader_session(),
            agent_host,
            physical_network=segment.get('physical_network'))

        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: {}}}

        ports = upd_fdb_entries[port['network_id']][agent_ip]
        if orig_mac_ip:
            ports['before'] = orig_mac_ip

        if port_mac_ip:
            ports['after'] = port_mac_ip

        self.L2populationAgentNotify.update_fdb_entries(
            self.rpc_ctx, {'chg_ip': upd_fdb_entries})

        return True
Example #17
0
 def _merge_device_results(self, results, network, inserts, removes):
     """Merges a set of device results to the appropriate FDB table."""
     for r in results:
         fdb = removes if 'withdrawn' in r else inserts
         if network['id'] not in fdb:
             fdb.update(self._build_fdb_template(network))
         ports = fdb[network['id']]['ports']
         if r['gateway_ip'] not in ports:
             ports[r['gateway_ip']] = set()
         info = l2pop_rpc.PortInfo(r['mac_address'], r['ip_address'])
         ports[r['gateway_ip']].add(info)
Example #18
0
    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>], ...  ],
                        ...
        Or in the case of an update:
            { 'chg_ip': {
                '<uuid>': {
                    '<agent1-IP>': {
                        'before': [ [<mac>, <ip>], ... ],
                        'after' : [ [<mac>, <ip>], ... ],
                    },
                    '<agent2-IP>': {
                        'before': ...

        :returns: Deep copy with [<mac>, <ip>] converted to PortInfo
        """
        unmarshalled = dict(fdb_entries)
        chg_ip_nets = [
            net.values() for net in unmarshalled.get('chg_ip', {}).values()
        ]
        for agent in itertools.chain.from_iterable(chg_ip_nets):
            for when in ('before', 'after'):
                if when in agent:
                    agent[when] = [
                        l2pop_rpc.PortInfo(*pi) for pi in agent[when]
                    ]
        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
Example #19
0
    def test_update_port_down(self):
        self._register_ml2_agents()

        with self.subnet(network=self._network) as subnet:
            host_arg = {portbindings.HOST_ID: HOST}
            with self.port(subnet=subnet,
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID, ),
                           **host_arg) as port1:
                with self.port(subnet=subnet,
                               device_owner=DEVICE_OWNER_COMPUTE,
                               arg_list=(portbindings.HOST_ID, ),
                               **host_arg) as port2:
                    p2 = port2['port']
                    device2 = 'tap' + p2['id']

                    self.mock_fanout.reset_mock()
                    self.callbacks.update_device_up(self.adminContext,
                                                    agent_id=HOST,
                                                    device=device2)

                    p1 = port1['port']
                    device1 = 'tap' + p1['id']

                    self.callbacks.update_device_up(self.adminContext,
                                                    agent_id=HOST,
                                                    device=device1)
                    self.mock_fanout.reset_mock()
                    self.callbacks.update_device_down(self.adminContext,
                                                      agent_id=HOST,
                                                      device=device2)

                    p2_ips = [p['ip_address'] for p in p2['fixed_ips']]
                    expected = {
                        p2['network_id']: {
                            'ports': {
                                '20.0.0.1': [
                                    l2pop_rpc.PortInfo(p2['mac_address'],
                                                       p2_ips[0])
                                ]
                            },
                            'network_type': 'vxlan',
                            'segment_id': 1
                        }
                    }

                    self.mock_fanout.assert_called_with(
                        mock.ANY, 'remove_fdb_entries', expected)
Example #20
0
 def _get_network_fdb_entries(self, context, network, bgpvpn_id):
     """Return an L2POP compatible dict of FDB entries for one network."""
     fdb_entries = self._build_fdb_template(network)
     ports = fdb_entries[network['id']]['ports']
     # Add a device entry for each device in this bgpvpn
     devices = self.bgpvpn_db.get_bgpvpn_active_devices(context, bgpvpn_id)
     for d in devices:
         if d['gateway_ip'] not in ports:
             ports[d['gateway_ip']] = [const.FLOODING_ENTRY]
         info = l2pop_rpc.PortInfo(d['mac_address'], d['ip_address'])
         ports[d['gateway_ip']].append(info)
     # Add a flood entry for any VTEP instance that is not already present
     gateways = self.bgpvpn_db.get_bgpvpn_gateways(context, bgpvpn_id)
     for g in gateways:
         if g['ip_address'] not in ports:
             ports[g['ip_address']] = [const.FLOODING_ENTRY]
     return fdb_entries
Example #21
0
 def test_fdb_del_flows(self):
     self._prepare_l2_pop_ofports()
     fdb_entry = {self.lvms[1].net:
                  {'network_type': self.tunnel_type,
                   'segment_id': 'tun2',
                   'ports':
                   {self.lvms[1].ip:
                    [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'),
     ) as (install_fn, delete_fn):
         self.agent.fdb_remove(None, fdb_entry)
         install_fn.assert_called_once_with(10, 12, 22, 1,
                                            set([self.lvms[0].ip]),
                                            goto_next=True)
         delete_fn.assert_called_once_with(7, 12, eth_dst='mac')
Example #22
0
    def _test_host_changed(self, twice):
        self._register_ml2_agents()
        with self.subnet(network=self._network) as subnet:
            host_arg = {portbindings.HOST_ID: HOST}
            with self.port(subnet=subnet,
                           cidr='10.0.0.0/24',
                           device_owner=DEVICE_OWNER_COMPUTE,
                           arg_list=(portbindings.HOST_ID, ),
                           **host_arg) as port1:
                tunnel_ip = '20.0.0.1'
                p1 = port1['port']
                device1 = 'tap' + p1['id']
                self.callbacks.update_device_up(self.adminContext,
                                                agent_id=HOST,
                                                device=device1)
                if twice:
                    tunnel_ip = '20.0.0.4'
                    self._update_and_check_portbinding(p1['id'], HOST_4)
                    self.callbacks.update_device_up(self.adminContext,
                                                    agent_id=HOST_4,
                                                    device=device1)

                self.mock_fanout.reset_mock()
                self._update_and_check_portbinding(p1['id'], HOST_2)
                p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
                expected = {
                    p1['network_id']: {
                        'ports': {
                            tunnel_ip: [
                                constants.FLOODING_ENTRY,
                                l2pop_rpc.PortInfo(p1['mac_address'],
                                                   p1_ips[0])
                            ]
                        },
                        'network_type': 'vxlan',
                        'segment_id': 1
                    }
                }

                self.mock_fanout.assert_called_with(mock.ANY,
                                                    'remove_fdb_entries',
                                                    expected)
 def test_fdb_ignore_self(self):
     self._prepare_l2_pop_ofports()
     self.agent.local_ip = 'agent_ip'
     fdb_entry = {self.lvms[1].net:
                  {'network_type': self.tunnel_type,
                   'segment_id': 'tun2',
                   'ports':
                   {'agent_ip':
                    [l2pop_rpc.PortInfo('mac', 'ip'),
                     FLOODING_ENTRY]}}}
     with mock.patch.object(self.agent.ryuapp,
                            "add_arp_table_entry") as add_fn,\
             mock.patch.object(self.agent.ryuapp,
                               "del_arp_table_entry") as del_fn:
         self.agent.fdb_add(None, copy.deepcopy(fdb_entry))
         add_fn.assert_called_once_with(12, 'ip', 'mac')
         self.assertFalse(del_fn.called)
         self.agent.fdb_remove(None, fdb_entry)
         add_fn.assert_called_once_with(12, 'ip', 'mac')
         del_fn.assert_called_once_with(12, 'ip')
    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
Example #25
0
 def test_portinfo_marshalled_as_list(self):
     entry = ['fa:16:3e:ff:8c:0f', '10.0.0.6']
     payload = {'netuuid': {'ports': {'1': [l2pop_rpc.PortInfo(*entry)]}}}
     result = jsonutils.loads(jsonutils.dumps(payload))
     self.assertEqual(entry, result['netuuid']['ports']['1'][0])
Example #26
0
 def _get_port_fdb_entries(self, port):
     return [
         l2pop_rpc.PortInfo(mac_address=port['mac_address'],
                            ip_address=ip['ip_address'])
         for ip in port['fixed_ips']
     ]
    def setUp(self):
        super(TestL2populationRpcCallBackTunnelMixinBase, self).setUp()
        self.vlan_manager = self.useFixture(
            test_vlanmanager.LocalVlanManagerFixture()).manager
        self.fakeagent = FakeNeutronAgent()
        self.fakebr = mock.Mock()
        Port = collections.namedtuple('Port', 'ip, ofport')
        LVM = collections.namedtuple(
            'LVM', 'net, vlan, phys, segid, mac, ip, vif, port')

        self.local_ip = '127.0.0.1'
        self.type_gre = 'gre'
        self.ports = [
            Port(ip='10.1.0.1', ofport='ofport1'),
            Port(ip='10.1.0.2', ofport='ofport2'),
            Port(ip='10.1.0.3', ofport='ofport3')
        ]
        self.ofports = {
            self.type_gre: {
                self.ports[0].ip: self.ports[0].ofport,
                self.ports[1].ip: self.ports[1].ofport,
                self.ports[2].ip: self.ports[2].ofport,
            }
        }

        self.lvms = [
            LVM(net='net1',
                vlan=1,
                phys='phys1',
                segid='tun1',
                mac='mac1',
                ip='1.1.1.1',
                vif='vifid1',
                port='port1'),
            LVM(net='net2',
                vlan=2,
                phys='phys2',
                segid='tun2',
                mac='mac2',
                ip='2.2.2.2',
                vif='vifid2',
                port='port2'),
            LVM(net='net3',
                vlan=3,
                phys='phys3',
                segid='tun3',
                mac='mac3',
                ip='3.3.3.3',
                vif='vifid3',
                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.fdb_entries1 = {
            self.lvms[0].net: {
                'network_type': self.type_gre,
                'segment_id': self.lvms[0].segid,
                'ports': {
                    self.local_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.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)]
                },
            },
        }

        for i in range(3):
            self.vlan_manager.add(self.lvms[i].net, self.lvms[i].vlan,
                                  self.type_gre, self.lvms[i].phys,
                                  self.lvms[i].segid,
                                  {self.lvms[i].vif: self.lvms[i].port})
            setattr(self, 'lvm%d' % i, self.vlan_manager.get(self.lvms[i].net))

        self.upd_fdb_entry1_val = {
            self.lvms[0].net: {
                self.ports[0].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':
                    [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':
                    [l2pop_rpc.PortInfo(self.lvms[0].mac, self.lvms[0].ip)],
                    'after':
                    [l2pop_rpc.PortInfo(self.lvms[2].mac, self.lvms[2].ip)],
                },
            },
        }
        self.upd_fdb_entry1 = {'chg_ip': self.upd_fdb_entry1_val}
import contextlib
import copy

import mock
import netaddr
from oslo.config import cfg
from oslo.utils import importutils
import testtools

from neutron.common import constants as n_const
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):
    p = mock.Mock()
    p.is_neutron_port.return_value = is_neutron
    if normalized_name:
        p.normalized_port_name.return_value = normalized_name
    return p


class CreateAgentConfigMap(ofa_test_base.OFAAgentTestBase):
    def test_create_agent_config_map_succeeds(self):
        self.assertTrue(self.mod_agent.create_agent_config_map(cfg.CONF))

    def test_create_agent_config_map_fails_for_invalid_tunnel_config(self):