コード例 #1
0
 def _process_ucast_macs_remote(self, uuid, uuid_dict, data_dict):
     """Processes Ucast_Macs_Remote record from the OVSDB event."""
     new_row = uuid_dict.get('new', None)
     old_row = uuid_dict.get('old', None)
     if new_row:
         locator_list = new_row.get('locator')
         locator_id = locator_list[1]
         logical_switch_list = new_row.get('logical_switch')
         logical_switch_id = logical_switch_list[1]
         mac_remote = ovsdb_schema.UcastMacsRemote(uuid, new_row.get('MAC'),
                                                   logical_switch_id,
                                                   locator_id,
                                                   new_row.get('ipaddr'))
         if old_row:
             modified_remote_macs = data_dict.get('modified_remote_macs')
             modified_remote_macs.append(mac_remote)
         else:
             new_remote_macs = data_dict.get('new_remote_macs')
             new_remote_macs.append(mac_remote)
     elif old_row:
         logical_switch_list = old_row.get('logical_switch')
         l_sw_id = logical_switch_list[1]
         mac_remote = ovsdb_schema.UcastMacsRemote(uuid, old_row.get('MAC'),
                                                   l_sw_id, None, None)
         deleted_remote_macs = data_dict.get('deleted_remote_macs')
         deleted_remote_macs.append(mac_remote)
コード例 #2
0
    def update_ucast_macs_remote(self, locator_dict, mac_dict):
        """Update an entry in Ucast_Macs_Remote OVSDB table."""
        # It is possible that the locator may not exist already.
        locator = ovsdb_schema.PhysicalLocator(locator_dict['uuid'],
                                               locator_dict['dst_ip'])
        macObject = ovsdb_schema.UcastMacsRemote(
            mac_dict['uuid'], mac_dict['mac'], mac_dict['logical_switch_id'],
            mac_dict['physical_locator_id'], mac_dict['ip_address'])
        # Form the insert query now.
        commit_dict = {"op": "commit", "durable": True}
        op_id = str(random.getrandbits(128))
        params = [n_const.OVSDB_SCHEMA_NAME]

        # If the physical_locator does not exist (VM moving to a new compute
        # node), then insert a new record in Physical_Locator first.
        if locator.uuid:
            locator_list = ['uuid', locator.uuid]
        else:
            locator.uuid = ''.join(['a', str(random.getrandbits(128))])
            locator_list = ["named-uuid", locator.uuid]
            params.append(self._get_physical_locator_dict(locator))

        params.append(
            self._get_dict_for_update_ucast_mac_remote(macObject,
                                                       locator_list))
        params.append(commit_dict)
        query = {"method": "transact", "params": params, "id": op_id}
        LOG.debug("update_ucast_macs_remote: query: %s", query)
        self._send_and_receive(query, op_id)
コード例 #3
0
ファイル: data.py プロジェクト: oferby/networking-l2gw
    def notify_ovsdb_states(self, context, ovsdb_states):
        """RPC to notify the OVSDB servers connection state."""
        for ovsdb_identifier, state in ovsdb_states.items():
            if state == 'connected':
                pending_recs = db.get_all_pending_remote_macs_in_asc_order(
                    context, ovsdb_identifier)
                if pending_recs:
                    for pending_mac in pending_recs:
                        logical_switch_uuid = pending_mac[
                            'logical_switch_uuid']
                        mac = pending_mac['mac']
                        operation = pending_mac['operation']
                        try:
                            if operation == 'insert' or operation == 'update':
                                l_switch = ovsdb_schema.LogicalSwitch(
                                    logical_switch_uuid, None, None, None)
                                locator_uuid = pending_mac.get(
                                    'locator_uuid', None)
                                dst_ip = pending_mac.get('dst_ip', None)
                                locator = ovsdb_schema.PhysicalLocator(
                                    locator_uuid, dst_ip)
                                mac_remote = ovsdb_schema.UcastMacsRemote(
                                    pending_mac.get('uuid', None), mac,
                                    logical_switch_uuid, locator_uuid,
                                    pending_mac['vm_ip'])
                                if operation == 'insert':
                                    self.agent_rpc.add_vif_to_gateway(
                                        context, ovsdb_identifier,
                                        l_switch.__dict__, locator.__dict__,
                                        mac_remote.__dict__)
                                else:
                                    # update operation
                                    self.agent_rpc.update_vif_to_gateway(
                                        context, ovsdb_identifier,
                                        locator.__dict__, mac_remote.__dict__)
                            else:
                                self.agent_rpc.delete_vif_from_gateway(
                                    context, ovsdb_identifier,
                                    logical_switch_uuid, [mac])

                            # As the pending operation is over, delete the
                            # record from the pending_ucast_mac_remote table
                            db.delete_pending_ucast_mac_remote(
                                context, operation, ovsdb_identifier,
                                logical_switch_uuid, mac)
                        except Exception as ex:
                            LOG.exception(_LE("Exception occurred = %s"),
                                          str(ex))
コード例 #4
0
    def insert_ucast_macs_remote(self, l_switch_dict, locator_dict,
                                 mac_dict, ovsdb_identifier,
                                 rcv_required=True):
        """Insert an entry in Ucast_Macs_Remote OVSDB table."""
        # To insert an entry in Ucast_Macs_Remote table, it requires
        # corresponding entry in Physical_Locator (Compute node VTEP IP)
        # and Logical_Switch (Neutron network) tables.
        logical_switch = ovsdb_schema.LogicalSwitch(l_switch_dict['uuid'],
                                                    l_switch_dict['name'],
                                                    l_switch_dict['key'],
                                                    l_switch_dict['description'
                                                                  ])
        locator = ovsdb_schema.PhysicalLocator(locator_dict['uuid'],
                                               locator_dict['dst_ip'])
        macObject = ovsdb_schema.UcastMacsRemote(mac_dict['uuid'],
                                                 mac_dict['mac'],
                                                 mac_dict['logical_switch_id'],
                                                 mac_dict['physical_locator_id'
                                                          ],
                                                 mac_dict['ip_address'])
        # Form the insert query now.
        commit_dict = {"op": "commit", "durable": True}
        op_id = str(random.getrandbits(128))
        params = [n_const.OVSDB_SCHEMA_NAME]

        if locator.uuid:
            locator_list = ['uuid', locator.uuid]
        else:
            locator.uuid = ''.join(['a', str(random.getrandbits(128))])
            locator_list = ["named-uuid", locator.uuid]
            params.append(self._get_physical_locator_dict(locator))

        if logical_switch.uuid:
            l_switches = ['uuid', logical_switch.uuid]
        else:
            logical_switch.uuid = ''.join(['a', str(random.getrandbits(128))])
            l_switches = ["named-uuid", logical_switch.uuid]
            params.append(self._get_logical_switch_dict(logical_switch))

        params.append(self._get_ucast_macs_remote_dict(
            macObject, locator_list, l_switches))
        params.append(commit_dict)
        query = {"method": "transact",
                 "params": params,
                 "id": op_id}
        LOG.debug("insert_ucast_macs_remote: query: %s", query)
        self._send_and_receive(query, op_id, ovsdb_identifier, rcv_required)
コード例 #5
0
    def test_get_bindings_to_update1(self):
        """Test case to test _get_bindings_to_update."""
        fake_op_method = 'CREATE'
        with mock.patch.object(
                ovsdb_writer.OVSDBWriter,
                '_form_logical_switch') as form_ls, \
                mock.patch.object(
                    ovsdb_writer.OVSDBWriter,
                    '_form_physical_locators') as form_pl, \
                mock.patch.object(
                    ovsdb_writer.OVSDBWriter, '_form_ports') as form_pp, \
                mock.patch.object(
                    ovsdb_schema, 'LogicalSwitch') as mock_ls, \
                mock.patch.object(
                    ovsdb_schema, 'PhysicalLocator') as mock_pl, \
                mock.patch.object(
                    ovsdb_schema, 'UcastMacsRemote') as mock_ucmr, \
                mock.patch.object(ovsdb_schema, 'PhysicalPort') as mock_pp:
            ls = mock_ls.return_value = ovsdb_schema.LogicalSwitch(
                'ls_uuid', 'ls_name', 'ls_key', 'ls_desc')
            pl = mock_pl.return_value = ovsdb_schema.PhysicalLocator(
                'pl_uuid', 'pl_dst_ip')
            mock_ucmr.return_value = ovsdb_schema.UcastMacsRemote(
                'ucmr_uuid', 'ucmr_mac', 'ucmr_ls_id', 'ucmr_pl_id', 'ucmr_ip')
            pp = mock_pp.return_value = ovsdb_schema.PhysicalPort(
                'pp_uuid', 'pp_name', 'pp_ps_id', 'pp_vlan_bindings')
            form_ls.return_value = ['uuid', ls.uuid]
            self.l2gw_ovsdb._get_bindings_to_update(
                mock.MagicMock(), [{
                    'uuid': 'uuid',
                    'dst_ip': 'dst_ip'
                }], mock.MagicMock(), [{
                    'uuid': 'uuid',
                    'name': 'name',
                    'physical_switch_id': 'physical_switch_id',
                    'vlan_bindings': 'vlan_bindings',
                    'port_fault_status': 'port_fault_status'
                }], fake_op_method)

            form_ls.assert_called_with(ls, mock.ANY)
            form_pl.assert_called_with(['uuid', ls.uuid], [pl], mock.ANY,
                                       mock.ANY)
            form_pp.assert_called_with(['uuid', ls.uuid], [pp], mock.ANY,
                                       fake_op_method)
コード例 #6
0
    def _get_bindings_to_update(self, l_switch_dict, locator_dicts, mac_dicts,
                                port_dicts):
        # For connection-create, there are two cases to be handled
        # Case 1: VMs exist in a network on compute nodes.
        #         Connection request will contain locators, ports, MACs and
        #         network.
        # Case 2: VMs do not exist in a network on compute nodes.
        #         Connection request will contain only ports and network
        #
        # For connection-delete, we do not need logical_switch and locators
        # information, we just need ports.
        locator_list = []
        port_list = []
        ls_list = []
        logical_switch = None
        # Convert logical switch dict to a class object
        if l_switch_dict:
            logical_switch = ovsdb_schema.LogicalSwitch(
                l_switch_dict['uuid'], l_switch_dict['name'],
                l_switch_dict['key'], l_switch_dict['description'])

        # Convert locator dicts into class objects
        for locator in locator_dicts:
            locator_list.append(
                ovsdb_schema.PhysicalLocator(locator['uuid'],
                                             locator['dst_ip']))

        # Convert MAC dicts into class objects. mac_dicts is a dictionary with
        # locator VTEP IP as the key and list of MACs as the value.
        locator_macs = {}
        for locator_ip, mac_list in mac_dicts.items():
            mac_object_list = []
            for mac_dict in mac_list:
                mac_object = ovsdb_schema.UcastMacsRemote(
                    mac_dict['uuid'], mac_dict['mac'],
                    mac_dict['logical_switch_id'],
                    mac_dict['physical_locator_id'], mac_dict['ip_address'])
                mac_object_list.append(mac_object)
            locator_macs[locator_ip] = mac_object_list

        # Convert port dicts into class objects
        for port in port_dicts:
            phys_port = ovsdb_schema.PhysicalPort(port['uuid'], port['name'],
                                                  port['physical_switch_id'],
                                                  port['vlan_bindings'],
                                                  port['port_fault_status'])
            port_list.append(phys_port)

        bindings = []
        bindings.append(n_const.OVSDB_SCHEMA_NAME)

        # Form the query.
        commit_dict = {"op": "commit", "durable": True}
        params = [n_const.OVSDB_SCHEMA_NAME]

        # Use logical switch
        if logical_switch:
            ls_list = self._form_logical_switch(logical_switch, params)

        # Use physical locators
        if locator_list:
            self._form_physical_locators(ls_list, locator_list, locator_macs,
                                         params)

        # Use ports
        self._form_ports(ls_list, port_list, params)
        params.append(commit_dict)
        return params
コード例 #7
0
    def create_l2_gateway_connection(self, context, l2_gateway_connection):
        """Process the call from the CLI and trigger the RPC,

        to update the connection to the gateway.
        """
        u_mac_dict = {}
        ls_dict = {}
        mac_dict = {}
        is_mac = False
        self._admin_check(context, 'CREATE')
        gw_connection = l2_gateway_connection.get('l2_gateway_connection')
        # validate connection
        self._validate_connection(context, gw_connection)
        # get l2 gateway devices
        l2gateway_devices = self.get_l2gateway_devices_by_gateway_id(
            context, gw_connection.get('l2_gateway_id'))
        for device in l2gateway_devices:
            locator_list = []
            ovsdb_identifier, logical_switch, port_dict = (
                self._process_port_list(context, device,
                                        gw_connection, "CREATE"))
            ls_dict = self._get_logical_switch_dict(
                context, logical_switch, gw_connection)
            ports = self._get_port_details(context,
                                           gw_connection.get('network_id'))
            if not is_mac:
                is_mac = True
                for port in ports:
                    mac_list = []
                    if port['device_owner']:
                        dst_ip, ip_address = self._get_ip_details(context,
                                                                  port)
                        mac_remote = self._get_dict(
                            ovsdb_schema.UcastMacsRemote(
                                uuid=None,
                                mac=port.get('mac_address'),
                                logical_switch_id=None,
                                physical_locator_id=None,
                                ip_address=ip_address))
                        if logical_switch:
                            u_mac_dict['mac'] = port.get('mac_address')
                            u_mac_dict['ovsdb_identifier'] = ovsdb_identifier
                            u_mac_dict['logical_switch_uuid'] = (
                                logical_switch.get('uuid'))
                            ucast_mac_remote = (
                                db.get_ucast_mac_remote_by_mac_and_ls(
                                    context, u_mac_dict))
                            if not ucast_mac_remote:
                                mac_list.append(mac_remote)
                        else:
                            mac_list.append(mac_remote)
                        locator_list = self._get_locator_list(
                            context, dst_ip, ovsdb_identifier, mac_list,
                            locator_list)
            for locator in locator_list:
                mac_dict[locator.get('dst_ip')] = locator.pop('macs')
                locator.pop('ovsdb_identifier')
            self.agent_rpc.update_connection_to_gateway(
                context, ovsdb_identifier, ls_dict, locator_list, mac_dict,
                port_dict)
        return super(L2GatewayPlugin, self).create_l2_gateway_connection(
            context, l2_gateway_connection)
コード例 #8
0
    def add_port_mac(self, context, port_dict):
        """Process the created port and trigger the RPC

        to add to the gateway.
        """
        port_id = port_dict.get("id")
        port = self._core_plugin.get_port(context, port_id)
        if port['device_owner']:
            network_id = port.get("network_id")
            dst_ip, ip_address = self._get_ip_details(context, port)
            network = self._get_network_details(context, network_id)
            l2gateway_connections = self.get_l2_gateway_connections(
                context, filters={'network_id': [network_id]})
            if not l2gateway_connections:
                return
            logical_switches = db.get_all_logical_switches_by_name(context,
                                                                   network_id)
            if not logical_switches:
                return
            for logical_switch in logical_switches:
                logical_switch['description'] = network.get('name')
                ovsdb_identifier = logical_switch.get('ovsdb_identifier')
                locator_dict = {'dst_ip': dst_ip,
                                'ovsdb_identifier': ovsdb_identifier}
                physical_locator = self._form_physical_locator_schema(
                    context, locator_dict)
                locator_uuid = physical_locator.get('uuid')
                logical_switch_uuid = logical_switch.get('uuid')
                mac_remote = self._get_dict(ovsdb_schema.UcastMacsRemote(
                    uuid=None,
                    mac=port['mac_address'],
                    logical_switch_id=logical_switch_uuid,
                    physical_locator_id=locator_uuid,
                    ip_address=ip_address))
                mac_dict = mac_remote
                mac_dict['ovsdb_identifier'] = ovsdb_identifier
                mac_dict['logical_switch_uuid'] = logical_switch_uuid
                ucast_mac_remote = db.get_ucast_mac_remote_by_mac_and_ls(
                    context, mac_dict)
                if ucast_mac_remote:
                    # check whether locator got changed in vm migration
                    if ucast_mac_remote['physical_locator_id'
                                        ] != physical_locator['uuid']:
                        mac_remote['uuid'] = ucast_mac_remote['uuid']
                        try:
                            self.agent_rpc.update_vif_to_gateway(
                                context, ovsdb_identifier,
                                physical_locator, mac_remote)
                            LOG.debug(
                                "VM migrated from %s to %s. Update"
                                "locator in Ucast_Macs_Remote",
                                ucast_mac_remote['physical_locator_id'],
                                physical_locator['uuid'])
                        except messaging.MessagingTimeout:
                            # If RPC is timed out, then the RabbitMQ
                            # will retry the operation.
                            LOG.exception(_LE("Communication error with "
                                              "the L2 gateway agent"))
                        except Exception:
                            # The remote OVSDB server may be down.
                            # We need to retry this operation later.
                            db.add_pending_ucast_mac_remote(
                                context, 'update',
                                ovsdb_identifier,
                                logical_switch_uuid,
                                physical_locator,
                                [mac_remote])
                    else:
                        LOG.debug("add_port_mac: MAC %s exists "
                                  "in Gateway", mac_dict['mac'])
                        ovsdb_data_handler = (
                            self.ovsdb_callback.get_ovsdbdata_object(
                                ovsdb_identifier))
                        ovsdb_data_handler._handle_l2pop(
                            context, [ucast_mac_remote])
                    continue
                # else it is a new port created
                try:
                    self.agent_rpc.add_vif_to_gateway(
                        context, ovsdb_identifier, logical_switch,
                        physical_locator, mac_remote)
                except messaging.MessagingTimeout:
                    # If RPC is timed out, then the RabbitMQ
                    # will retry the operation.
                    LOG.exception(_LE("Communication error with "
                                      "the L2 gateway agent"))
                except Exception:
                    # The remote OVSDB server may be down.
                    # We need to retry this operation later.
                    LOG.debug("The remote OVSDB server may be down")
                    db.add_pending_ucast_mac_remote(
                        context, 'insert', ovsdb_identifier,
                        logical_switch_uuid,
                        physical_locator,
                        [mac_remote])
コード例 #9
0
ファイル: rpc_l2gw.py プロジェクト: bestjie/networking-l2gw
    def create_l2_gateway_connection(self, context, l2_gateway_connection):
        """Process the call from the CLI and trigger the RPC,

        to update the connection to the gateway.
        """
        u_mac_dict = {}
        ls_dict = {}
        mac_dict = {}
        self.service_plugin._admin_check(context, 'CREATE')
        gw_connection = l2_gateway_connection.get('l2_gateway_connection')
        # validate connection
        self._validate_connection(context, gw_connection)
        # get l2 gateway devices
        l2gateway_devices = (
            self.service_plugin.get_l2gateway_devices_by_gateway_id(
                context, gw_connection.get('l2_gateway_id')))
        for device in l2gateway_devices:
            locator_list = []
            ovsdb_identifier, logical_switch, port_dict = (
                self._process_port_list(context, device, gw_connection,
                                        "CREATE"))
            ls_dict = self._get_logical_switch_dict(context, logical_switch,
                                                    gw_connection)
            ports = self._get_port_details(context,
                                           gw_connection.get('network_id'))
            for port in ports:
                mac_list = []
                if port['device_owner']:
                    dst_ip, ip_address = self._get_ip_details(context, port)
                    mac_ip_pairs = []
                    if isinstance(port.get("allowed_address_pairs"), list):
                        for address_pair in port['allowed_address_pairs']:
                            mac = address_pair['mac_address']
                            mac_ip_pairs.append(
                                (mac, address_pair['ip_address']))
                    mac_ip_pairs.append((port.get('mac_address'), ip_address))

                    for mac, ip in mac_ip_pairs:
                        mac_remote = self._get_dict(
                            ovsdb_schema.UcastMacsRemote(
                                uuid=None,
                                mac=mac,
                                logical_switch_id=None,
                                physical_locator_id=None,
                                ip_address=ip))
                        if logical_switch:
                            u_mac_dict['mac'] = mac
                            u_mac_dict['ovsdb_identifier'] = ovsdb_identifier
                            u_mac_dict['logical_switch_uuid'] = (
                                logical_switch.get('uuid'))
                            ucast_mac_remote = (
                                db.get_ucast_mac_remote_by_mac_and_ls(
                                    context, u_mac_dict))
                            if not ucast_mac_remote:
                                mac_list.append(mac_remote)
                        else:
                            mac_list.append(mac_remote)
                    locator_list = self._get_locator_list(
                        context, dst_ip, ovsdb_identifier, mac_list,
                        locator_list)
            for locator in locator_list:
                mac_dict[locator.get('dst_ip')] = locator.pop('macs')
                locator.pop('ovsdb_identifier')
            self.agent_rpc.update_connection_to_gateway(
                context, ovsdb_identifier, ls_dict, locator_list, mac_dict,
                port_dict, 'CREATE')
コード例 #10
0
ファイル: rpc_l2gw.py プロジェクト: bestjie/networking-l2gw
    def update_l2_gateway_postcommit(self, context, l2_gateway):
        """Process the call from the CLI and trigger the RPC,

        to update the connection of the gateway.
        """
        self.service_plugin._admin_check(context, 'UPDATE')

        # get l2 gateway devices
        l2gateway_devices = (
            self.service_plugin.get_l2gateway_devices_by_gateway_id(
                context, l2_gateway['id']))
        # get l2 gateway connections
        gw_connections = self.service_plugin._get_l2_gateway_connections(
            context)

        for gw_connection in gw_connections:
            u_mac_dict = {}
            mac_dict = {}
            for device in l2gateway_devices:
                locator_list = []
                ovsdb_identifier, logical_switch, port_dict = (
                    self._process_port_list(context, device, gw_connection,
                                            "UPDATE"))
                ls_dict = self._get_logical_switch_dict(
                    context, logical_switch, gw_connection)
                port_dict_before_update_con = \
                    [port for port in self.port_dict_before_update
                     if port['vlan_bindings'][0]['logical_switch_uuid'] ==
                     logical_switch['uuid']]
                port_dict_add = \
                    [port for port in port_dict
                     if port not in port_dict_before_update_con]
                port_dict_delete = \
                    [port for port in port_dict_before_update_con
                     if port not in port_dict]
                if port_dict_add:
                    ports = self._get_port_details(
                        context, gw_connection.get('network_id'))
                    LOG.debug("L2gwRpcDriver.update_l2_gw: ports=%s", ports)
                    for port in ports:
                        mac_list = []
                        if port['device_owner']:
                            dst_ip, ip_address = self._get_ip_details(
                                context, port)
                            mac_ip_pairs = []
                            if isinstance(port.get("allowed_address_pairs"),
                                          list):
                                for address_pair in \
                                        port['allowed_address_pairs']:
                                    mac = address_pair['mac_address']
                                    mac_ip_pairs.append(
                                        (mac, address_pair['ip_address']))
                            mac_ip_pairs.append(
                                (port.get('mac_address'), ip_address))

                            for mac, ip in mac_ip_pairs:
                                mac_remote = self._get_dict(
                                    ovsdb_schema.UcastMacsRemote(
                                        uuid=None,
                                        mac=mac,
                                        logical_switch_id=None,
                                        physical_locator_id=None,
                                        ip_address=ip))
                                if logical_switch:
                                    u_mac_dict['mac'] = mac
                                    u_mac_dict['ovsdb_identifier'] = \
                                        ovsdb_identifier
                                    u_mac_dict['logical_switch_uuid'] = (
                                        logical_switch.get('uuid'))
                                    ucast_mac_remote = (
                                        db.get_ucast_mac_remote_by_mac_and_ls(
                                            context, u_mac_dict))
                                    if not ucast_mac_remote:
                                        mac_list.append(mac_remote)
                                else:
                                    mac_list.append(mac_remote)
                            locator_list = self._get_locator_list(
                                context, dst_ip, ovsdb_identifier, mac_list,
                                locator_list)
                    for locator in locator_list:
                        mac_dict[locator.get('dst_ip')] = locator.pop('macs')
                        locator.pop('ovsdb_identifier')
                    self.agent_rpc.update_connection_to_gateway(
                        context, ovsdb_identifier, ls_dict, locator_list,
                        mac_dict, port_dict_add, 'CREATE')

                if port_dict_delete:
                    self.agent_rpc.update_connection_to_gateway(
                        context, ovsdb_identifier, ls_dict, locator_list,
                        mac_dict, port_dict_delete, 'DELETE')