openstack Neuturon组件在何处创建tap口

tap口创建流程

dhcp agent先通过plugin创建dhcp port,plugin返回Port详情,包括port ID,mac地址,IP地址等信息。

然后通过interface driver先ovs-vsctl add-port 创建一个internal的tap口,然后加入到br-int中。然后创建namespace,将tap加入namespace,在tap口上配置IP地址。

创建接口的操作是neturonn干的,不归dhcp_agent,dhcp_agent只不过是rpc远程调用
在/neuturon/agent/dhcp/agent.py

class DhcpPluginApi(object):
    """Agent side of the dhcp rpc API.

    This class implements the client side of an rpc interface.  The server side
    of this interface can be found in
    neutron.api.rpc.handlers.dhcp_rpc.DhcpRpcCallback.  For more information
    about changing rpc interfaces, see doc/source/devref/rpc_api.rst.

    API version history:
        1.0 - Initial version.
        1.1 - Added get_active_networks_info, create_dhcp_port,
              and update_dhcp_port methods.
        1.5 - Added dhcp_ready_on_ports

    """

    def __init__(self, topic, host):
        self.host = host
        target = oslo_messaging.Target(
                topic=topic,
                namespace=n_const.RPC_NAMESPACE_DHCP_PLUGIN,
                version='1.0')
        self.client = n_rpc.get_client(target)

    @property
    def context(self):
        # TODO(kevinbenton): the context should really be passed in to each of
        # these methods so a call can be tracked all of the way through the
        # system but that will require a larger refactor to pass the context
        # everywhere. We just generate a new one here on each call so requests
        # can be independently tracked server side.
        return context.get_admin_context_without_session()

    def get_active_networks_info(self):
        """Make a remote process call to retrieve all network info."""
        cctxt = self.client.prepare(version='1.1')
        networks = cctxt.call(self.context, 'get_active_networks_info',
                              host=self.host)
        return [dhcp.NetModel(n) for n in networks]

    def get_network_info(self, network_id):
        """Make a remote process call to retrieve network info."""
        cctxt = self.client.prepare()
        network = cctxt.call(self.context, 'get_network_info',
                             network_id=network_id, host=self.host)
        if network:
            return dhcp.NetModel(network)

    def create_dhcp_port(self, port):
        """Make a remote process call to create the dhcp port."""
        cctxt = self.client.prepare(version='1.1')
        port = cctxt.call(self.context, 'create_dhcp_port',
                          port=port, host=self.host)
        if port:
            return dhcp.DictModel(port)

    def update_dhcp_port(self, port_id, port):
        """Make a remote process call to update the dhcp port."""
        cctxt = self.client.prepare(version='1.1')
        port = cctxt.call(self.context, 'update_dhcp_port',
                          port_id=port_id, port=port, host=self.host)
        if port:
            return dhcp.DictModel(port)

    def release_dhcp_port(self, network_id, device_id):
        """Make a remote process call to release the dhcp port."""
        cctxt = self.client.prepare()
        return cctxt.call(self.context, 'release_dhcp_port',
                          network_id=network_id, device_id=device_id,
                          host=self.host)

    def dhcp_ready_on_ports(self, port_ids):
        """Notify the server that DHCP is configured for the port."""
        cctxt = self.client.prepare(version='1.5')
        return cctxt.call(self.context, 'dhcp_ready_on_ports',
                          port_ids=port_ids)

这边又看到一个人写的流程很好:
neutron-dhcp-agent收到neutron server创建网络的通知和neutron-dhcp-agent主动承载一个网络的操作基本上是一样的,如下
dhcp-agent.ini中dhcp_driver设置为 dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq

  1. 检查网络中是否有enable dhcp的subnet, 有则会调用dhcp_driver的enable操作
  2. Dnsmasq.enable()
    2.1 如果当前存在Dnsmasq的进程,则重启, 没有则继续操作
    2.2. 调用DeviceManager的setup方法,
    2.2.1. setup_dhcp_port() 如果有dhcp_port,则返回,没有则创建, 根据port里面的device_id选项来区分这个port是否属于这个agent的dhcp port
    2.2.2. 判断port的interface名字是否存在(如:tape613727f-c3 ),如果不存在则会创建这个interface, 调用driver的plug(这个方法中会创建namespace,创建设备(创建的过程需要openvswitch agent配合,在下面介绍),并将设备绑定到br-int上)
    2.2.3. fill_dhcp_udp_checksum(),在dhcp namespace中创建udp checksum规则?, 如: -A neutron-dhcp-age-POSTROUTING -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
    2.2.4. 调用driver的init_l3(),初始化dhcp namespace中的路由规则, 其中包括subnet中的默认网关以及metadata相关的路由。
    2.2.5 调用dhcp_driver的spawn_process()
    2.2.5.1 在创建Dnsmasq服务之前需要初始化它的配置文件, 包括三个文件(hosts_file, addn_hosts_file, opts_file)
    hosts_file: 记录mac, hostname, ip的映射关系
    addn_hosts_file: 记录ip, 长hostname,短hostname的映射关系
    opts_file: 记录默认路由以及dns server
    2.2.5.2 创建Dnsmasq进程。

这样创建一个网络,包括subnet的过程基本结束了。

原文链接:https://blog.csdn.net/allenson1/article/details/54602007

就是在\neutron\agent\linux\dhcp.py中class DhcpLocalProcess(DhcpBase):类里的device_manager.setup(self.network)

    def enable(self):
        """Enables DHCP for this network by spawning a local process."""
        if self.active:
            self.restart()
        elif self._enable_dhcp():
            fileutils.ensure_tree(self.network_conf_dir, mode=0o755)
            interface_name = self.device_manager.setup(self.network)
            self.interface_name = interface_name
            self.spawn_process()
    def setup_dhcp_port(self, network):
        """Create/update DHCP port for the host if needed and return port."""

        # The ID that the DHCP port will have (or already has).
        device_id = self.get_device_id(network)

        # Get the set of DHCP-enabled local subnets on this network.
        dhcp_subnets = {subnet.id: subnet for subnet in network.subnets
                        if subnet.enable_dhcp}

        # There are 3 cases: either the DHCP port already exists (but
        # might need to be updated for a changed set of subnets); or
        # some other code has already prepared a 'reserved' DHCP port,
        # and we just need to adopt that; or we need to create a new
        # DHCP port.  Try each of those in turn until we have a DHCP
        # port.
        for setup_method in (self._setup_existing_dhcp_port,
                             self._setup_reserved_dhcp_port,
                             self._setup_new_dhcp_port):
            dhcp_port = setup_method(network, device_id, dhcp_subnets)
            if dhcp_port:
                break
        else:
            raise exceptions.Conflict()
    def _setup_new_dhcp_port(self, network, device_id, dhcp_subnets):
        """Create and set up new DHCP port for the specified network."""
        LOG.debug('DHCP port %(device_id)s on network %(network_id)s'
                  ' does not yet exist. Creating new one.',
                  {'device_id': device_id, 'network_id': network.id})

        # Make a list of the subnets that need a unique IP address for
        # this DHCP port.
        if self.driver.use_gateway_ips:
            unique_ip_subnets = []
        else:
            unique_ip_subnets = [dict(subnet_id=s) for s in dhcp_subnets]

        port_dict = dict(
            name='',
            admin_state_up=True,
            device_id=device_id,
            network_id=network.id,
            tenant_id=network.tenant_id,
            fixed_ips=unique_ip_subnets)
        return self.plugin.create_dhcp_port({'port': port_dict})

self.plugin.create_dhcp_port({‘port’: port_dict}) 为远程rpc调用

然后找到配置 文件的位置

  def spawn_process(self):
        """Spawn the process, if it's not spawned already."""
        # we only need to generate the lease file the first time dnsmasq starts
        # rather than on every reload since dnsmasq will keep the file current
        self._output_init_lease_file()
        self._spawn_or_reload_process(reload_with_HUP=False)

    def _spawn_or_reload_process(self, reload_with_HUP):
        """Spawns or reloads a Dnsmasq process for the network.

        When reload_with_HUP is True, dnsmasq receives a HUP signal,
        or it's reloaded if the process is not running.
        """

        self._output_config_files()

        pm = self._get_process_manager(
            cmd_callback=self._build_cmdline_callback)

        pm.enable(reload_cfg=reload_with_HUP)

        self.process_monitor.register(uuid=self.network.id,
                                      service_name=DNSMASQ_SERVICE_NAME,
                                      monitored_process=pm)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

举世无双勇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值