# l3\_agent.py

提供 L3 层服务的 agent，包括 L3NATAgent 类、继承自它的 L3NATAgentWithStateReport 类（作为manager）、继承自 n\_rpc.RpcProxy 类的 L3PluginApi 类（作为 agent 调用 plugin 一侧的 api）和 RouterInfo 类。

主过程为

```
def main(manager='neutron.agent.l3_agent.L3NATAgentWithStateReport'):
    _register_opts(cfg.CONF)
    common_config.init(sys.argv[1:])
    config.setup_logging()
    server = neutron_service.Service.create(
        binary='neutron-l3-agent',
        topic=topics.L3_AGENT,
        report_interval=cfg.CONF.AGENT.report_interval,
        manager=manager)
    service.launch(server).wait()
```

也是标准的 service 流程。

从 conf.CONF 中注册各个系统常量，包括 L3 相关 agent 的参数、接口驱动、命名空间等等。

启动一个管理 neutron-l3-agent 执行程序的服务，该服务将监听 topic 为 topics.L3\_AGENT 的 RPC 消息队列，管理类为 L3NATAgentWithStateReport。

## L3NATAgent 类

继承自 firewall\_l3\_agent.FWaaSL3AgentRpcCallback、l3\_ha\_agent.AgentMixin 和 manager.Manager。

前者是由于现在的 FWaaS 设计都是挂载到 router 上的，因此，在创建router 的时候，需要把对应的 firewall 添加上。

而 Manager 作为一个进行rpc调用管理和执行周期性任务的基础类。 初始化中根据配置信息，导入 driver，获取 admin 的上下文，获取 L3PluginApi，然后定期执行 self.\_rpc\_loop() 方法。该方法根据数据库中的信息来同步本地的 router。

调用 self.\_process\_routers() 方法和 self.\_process\_router\_delete() 方法，这两个方法会进一步对本地的 iptables 进行操作，完成 router 的添加或删除。

## L3NATAgentWithStateReport类

该类是 L3 agent 资源 service 的 manager，其继承自 L3NATAgent，并添加了 rpc.PluginReportStateAPI 类来进行周期性状态汇报。

主要添加了两个方法。

* `_report_state()`：定期的汇报自己的状态，以 `topic.PLUGIN` 作为主题向 rpc 队列中写入 agent 的状态信息消息。这些消息会被各个 plugin 收到。
* `agent_updated()`：收到 agent\_updated 消息的处理。

## L3PluginApi 类

继承自 `neutron.common.rpc.RpcProxy` 类，是一个进行 rpc 调用的代理。

被 L3NATAgent 类来调用，负责向 L3 的 Plugin 发出 rpc 消息（主题为 `topics.L3PLUGIN`），这些消息到达 plugin，最终被 plugin 的父类 neutron.db.l3\_rpc\_base.L3RpcCallbackMixin 类中的对应方法来处理，这些方法进一步调用父类 `neutron.db.l3_db.L3_NAT_db_mixin` 类中的对应方法跟数据库进行交互。

目前定义了下面几个方法：

* `get_routers()` 通过 rpc 调用 L3 Plugin 的 sync\_routers() 方法来来获取外部网络的id。
* `get_external_network_id()` 通过 rpc 调用 external\_network\_id() 来获取外部网络的id。
* `update_floatingip_statuses()` 通过 rpc 调用 update\_floatingip\_statuses() 来更新 floating ip 的状态。
* `get_ports_by_subnet()` 通过 rpc 调用 get\_ports\_by\_subnet() 来获取对应 subnet 中的端口信息。
* `get_service_plugin_list()` 通过 rpc 调用 get\_service\_plugin\_list() 来获取 L3 Plugin 中激活服务的列表。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/openstack_code_neutron/neutron/agent/l3_agentpy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
