文章目录
团队博客: 汽车电子社区
1. 源码结构和文件组织
1.1 目录结构概览
src/network/
├── networkd.c # 主程序入口
├── networkd-manager.c/.h # 核心管理器
├── networkd-network.c/.h # 网络配置管理
├── networkd-link.c/.h # 网络设备管理
├── networkd-address.c/.h # IP地址管理
├── networkd-route.c/.h # 路由管理
├── networkd-dhcp4.c/.h # DHCPv4客户端
├── networkd-dhcp6.c/.h # DHCPv6客户端
├── networkd-ndisc.c/.h # IPv6邻居发现
├── networkd-dns.c # DNS配置集成
├── netdev/ # 虚拟网络设备
├── tc/ # 流量控制
└── generator/ # 配置生成器
1.2 核心文件职责
主程序和核心管理
- networkd.c: 主程序入口,初始化和事件循环
- networkd-manager.c: 核心管理器,协调所有网络组件
网络组件管理
- networkd-link.c: 网络设备生命周期管理
- networkd-address.c: IP地址配置和管理
- networkd-route.c: 路由表管理
协议实现
- networkd-dhcp4.c: DHCPv4客户端实现
- networkd-dhcp6.c: DHCPv6客户端实现
- networkd-ndisc.c: IPv6邻居发现协议
虚拟化支持
- netdev/: 各种虚拟网络设备实现
- tc/: 流量控制和服务质量
2. 核心功能和架构设计
2.1 整体架构
systemd-networkd 采用分层架构设计:
2.2 核心数据结构
Manager 结构 (networkd-manager.h)
typedef struct Manager {
sd_netlink *rtnl; // 路由网络链接套接字
sd_netlink *genl; // 通用网络链接套接字
sd_netlink *nfnl; // Netfilter网络链接套接字
sd_event *event; // 事件循环
sd_resolve *resolve; // DNS解析器
sd_bus *bus; // D-Bus连接
Hashmap *links_by_index; // 按索引索引的链路
Hashmap *links_by_name; // 按名称索引的链路
OrderedHashmap *networks; // 网络配置
Hashmap *netdevs; // 网络设备
ManagerState state; // 管理器状态
bool enumerating; // 是否正在枚举
bool dirty; // 是否需要保存状态
} Manager;
Link 结构 (networkd-link.h)
typedef struct Link {
Manager *manager; // 父管理器
int ifindex; // 接口索引
char *ifname; // 接口名称
Network *network; // 关联的网络配置
NetDev *netdev; // 关联的网络设备
LinkState state; // 链路状态
LinkOperationalState operstate; // 操作状态
LinkCarrierState carrier_state; // 载波状态
Set *addresses; // IP地址集合
Set *routes; // 路由集合
// DHCP相关
sd_dhcp_client *dhcp_client;
sd_dhcp_lease *dhcp_lease;
bool dhcp4_configured;
// IPv6相关
sd_ndisc *ndisc;
sd_dhcp6_client *dhcp6_client;
sd_radv *radv;
} Link;
Network 结构 (networkd-network.h)
typedef struct Network {
Manager *manager;
char *name; // 网络名称
char *filename; // 配置文件名
// 匹配条件
NetMatch match;
LIST_HEAD(Condition, conditions);
// 主设备配置
NetDev *bridge;
NetDev *bond;
NetDev *vrf;
// 地址配置
OrderedHashmap *addresses_by_section;
Hashmap *routes_by_section;
// DHCP配置
bool dhcp_use_dns;
bool dhcp_use_routes;
UseDomains dhcp_use_domains;
} Network;
3. 网络设备管理
3.1 设备生命周期管理
网络设备通过以下状态机进行管理:
3.2 设备枚举过程
在 manager_enumerate() 中实现完整枚举:
// 枚举网络链路
r = manager_enumerate_links(m);
// 枚举地址
r = manager_enumerate_addresses(m);
// 枚举路由
r = manager_enumerate_routes(m);
// 枚举邻居
r = manager_enumerate_neighbors(m);
3.3 设备状态跟踪
typedef enum LinkState {
LINK_STATE_PENDING, // 等待udev初始化
LINK_STATE_INITIALIZED, // udev已初始化
LINK_STATE_CONFIGURING, // 正在配置
LINK_STATE_CONFIGURED, // 配置完成
LINK_STATE_UNMANAGED, // 非托管
LINK_STATE_FAILED, // 配置失败
LINK_STATE_LINGER, // 链路已删除
} LinkState;
typedef enum LinkOperationalState {
LINK_OPERSTATE_OFF, // 关闭
LINK_OPERSTATE_NO_CARRIER, // 无载波
LINK_OPERSTATE_DORMANT, // 休眠
LINK_OPERSTATE_DEGRADED, // 降级
LINK_OPERSTATE_CARRIER, // 有载波
LINK_OPERSTATE_IP_CONFIGURE, // IP配置中
LINK_OPERSTATE_IP_CHECK, // IP检查中
LINK_OPERSTATE_DEGRADED_IP_CONFIGURE, // 降级IP配置
LINK_OPERSTATE_ROUTABLE, // 可路由
} LinkOperationalState;
4. 网络配置解析
4.1 配置文件加载
配置文件通过 network_load() 加载:
int network_load(Manager *manager, OrderedHashmap **ret) {
// 枚举.network文件
r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
// 加载每个配置文件
STRV_FOREACH(f, files)
(void) network_load_one(manager, &networks, *f);
}
4.2 配置节解析
支持的配置节包括:
- [Match]: 设备匹配条件
- [Link]: 链路层配置
- [Network]: 网络层配置
- [Address]: IP地址配置
- [Route]: 路由配置
- [DHCPv4]/[DHCPv6]: DHCP配置
- [IPv6AcceptRA]: IPv6路由器接受配置
4.3 设备匹配机制
// 匹配条件结构
typedef struct NetMatch {
char *name; // 设备名通配符
char *path; // 设备路径
char *driver; // 驱动名称
NetKind kind; // 设备类型
char *mac_address; // MAC地址
uint32_t mtu; // MTU大小
// ... 更多匹配条件
} NetMatch;
5. DHCP客户端实现
5.1 DHCPv4客户端架构
// DHCPv4配置调整
void network_adjust_dhcp4(Network *network) {
if (network->dhcp_use_gateway < 0)
network->dhcp_use_gateway = network->dhcp_use_routes;
// 匿名化设置下的客户端标识符处理
if (network->dhcp_anonymize &&
network->dhcp_client_identifier != DHCP_CLIENT_ID_MAC) {
network->dhcp_client_identifier = DHCP_CLIENT_ID_MAC;
}
}
5.2 DHCPv6客户端特性
- 支持前缀委托 (DHCP-PD)
- 支持快速提交 (Rapid Commit)
- 支持无RA模式启动
- 集成IPv6邻居发现
5.3 DHCP流程
5.4 DHCP事件处理
// DHCP事件回调
static int dhcp4_handler(sd_dhcp_client *client, int event,
void *userdata, void *event_data) {
Link *link = userdata;
switch (event) {
case SD_DHCP_CLIENT_EVENT_EXPIRED:
log_link_debug(link, "DHCPv4 lease expired");
link dhcp4_lost(link);
break;
case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
log_link_debug(link, "DHCPv4 lease acquired");
link_dhcp4_configure(link, event_data);
break;
case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
log_link_debug(link, "DHCPv4 lease changed");
link_dhcp4_update(link, event_data);
break;
}
return 0;
}
6. 网络链接管理
6.1 链路配置流程
int link_configure(Link *link) {
// 配置链路层参数
r = link_configure_mtu(link);
r = link_configure_mac(link);
// 配置地址
r = link_configure_addresses(link);
// 配置路由
r = link_configure_routes(link);
// 启动DHCP客户端
if (link_dhcp4_enabled(link))
r = dhcp4_configure(link);
return r;
}
6.2 地址管理
typedef struct Address {
Network *network; // 关联网络
Link *link; // 关联链路
int family; // 地址族 (AF_INET/AF_INET6)
unsigned char prefixlen; // 前缀长度
union in_addr_union in_addr; // IP地址
AddressFlags flags; // 地址标志
uint32_t lifetime; // 生命周期
uint32_t preferred_lifetime; // 首选生命周期
} Address;
6.3 链路监控
// netlink事件处理
static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message,
void *userdata) {
Manager *m = userdata;
Link *link;
int ifindex;
// 获取接口索引
r = sd_netlink_message_get_type(message, &type);
r = sd_netlink_message_get_u32(message, IFLA_IFINDEX, &ifindex);
switch (type) {
case RTM_NEWLINK:
link = hashmap_get(m->links_by_index, INT_TO_PTR(ifindex));
if (!link) {
// 新链路,创建Link对象
manager_new_link(m, message);
} else {
// 现有链路,更新状态
link_update(link, message);
}
break;
case RTM_DELLINK:
// 链路删除
link_remove(m, ifindex);
break;
}
return 0;
}
7. 路由配置
7.1 路由数据结构
typedef struct Route {
Network *network; // 关联网络
Link *link; // 关联链路
int family; // 地址族 (AF_INET/AF_INET6)
unsigned char dst_prefixlen; // 目标前缀长度
union in_addr_union dst; // 目标地址
uint32_t priority; // 优先级/度量
RouteNextHop nexthop; // 下一跳
RouteMetric metric; // 路由度量
uint32_t table; // 路由表
RouteScope scope; // 路由范围
RouteType type; // 路由类型
RouteProtocol protocol; // 路由协议
} Route;
7.2 路由管理功能
- 静态路由: 通过配置文件配置
- 动态路由: DHCP/RA获取
- 策略路由: 支持路由策略规则
- 多路径路由: 支持ECMP
7.3 路由配置流程
int link_configure_routes(Link *link) {
Route *route;
int r;
// 配置静态路由
HASHMAP_FOREACH(route, link->network->routes_by_section) {
r = route_configure(route, link);
if (r < 0)
log_link_warning(link, "Failed to configure route: %s", strerror(-r));
}
// 配置DHCP路由
if (link->network->dhcp_use_routes && link->dhcp_lease) {
r = dhcp4_configure_routes(link);
if (r < 0)
log_link_warning(link, "Failed to configure DHCP routes: %s", strerror(-r));
}
return 0;
}
8. DNS解析集成
8.1 DNS配置管理
typedef struct {
struct in_addr_full **dns; // DNS服务器地址
unsigned n_dns;
OrderedSet *search_domains; // 搜索域
OrderedSet *route_domains; // 路由域
DnssecMode dnssec_mode; // DNSSEC模式
DnsOverTlsMode dns_over_tls_mode; // DNS over TLS模式
} DNSConfiguration;
8.2 DNS源支持
- 静态配置: 配置文件指定
- DHCP: DHCP服务器提供
- RA: 路由器通告提供
- LLDP: 链路层发现协议提供
8.3 DNS集成流程
// DNS配置更新
int link_update_dns(Link *link) {
DNSConfiguration dns_config = {};
int r;
// 收集DNS配置
r = network_collect_dns(link->network, &dns_config);
if (r < 0)
return r;
// 应用DHCP DNS配置
if (link->dhcp_lease && link->network->dhcp_use_dns) {
r = dhcp4_collect_dns(link->dhcp_lease, &dns_config);
if (r < 0)
return r;
}
// 应用到systemd-resolved
r = dns_apply_config(link->manager->resolve, link->ifname, &dns_config);
dns_config_clear(&dns_config);
return r;
}
9. 网络监控和状态
9.1 状态监控机制
- netlink事件: 监听内核网络事件
- udev事件: 监听设备事件
- 定时器监控: 定期检查链路状态
- 速度测量: 网络接口速度监控
9.2 事件处理
// netlink消息处理
netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link);
netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address);
netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route);
// udev事件处理
sd_device_monitor_start(m->device_monitor, manager_process_uevent, m);
9.3 状态持久化
// 保存网络状态
int manager_save_state(Manager *m) {
_cleanup_fclose_ FILE *f = NULL;
f = fopen("/run/systemd/netif/state", "we");
if (!f)
return -errno;
// 保存链路状态
HASHMAP_FOREACH(link, m->links_by_index) {
if (link->state == LINK_STATE_CONFIGURED)
link_save_state(link, f);
}
return 0;
}
10. 软件架构图
10.1 Network 模块分层架构
10.2 数据流程图
11. 接口调用流程
11.1 网络设备初始化流程
11.2 DHCP配置流程
11.3 路由管理流程
12. 源码分析
12.1 核心管理器实现
// src/network/networkd-manager.c:800-900
int manager_new(Manager **ret) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
m = new0(Manager, 1);
if (!m)
return -ENOMEM;
// 1. 创建事件循环
r = sd_event_default(&m->event);
if (r < 0)
return r;
// 2. 创建netlink套接字
r = sd_netlink_open(&m->rtnl);
if (r < 0)
return r;
// 3. 创建通用netlink套接字
r = sd_netlink_open(&m->genl);
if (r < 0)
return r;
// 4. 创建D-Bus连接
r = sd_bus_open_system(&m->bus);
if (r < 0)
return r;
// 5. 创建DNS解析器
r = sd_resolve_new(&m->resolve);
if (r < 0)
return r;
// 6. 创建哈希表
m->links_by_index = hashmap_new(NULL);
m->links_by_name = hashmap_new(NULL);
m->networks = ordered_hashmap_new(&network_hash_ops);
m->netdevs = hashmap_new(&netdev_hash_ops);
*ret = TAKE_PTR(m);
return 0;
}
12.2 链路管理核心实现
// src/network/networkd-link.c:1200-1300
int link_configure(Link *link) {
Network *network = link->network;
int r;
assert(link);
assert(network);
// 1. 配置链路层参数
if (network->mtu) {
r = link_set_mtu(link, network->mtu);
if (r < 0)
log_link_warning(link, "Failed to set MTU: %s", strerror(-r));
}
// 2. 配置MAC地址
if (network->mac) {
r = link_set_mac(link, network->mac);
if (r < 0)
log_link_warning(link, "Failed to set MAC address: %s", strerror(-r));
}
// 3. 配置IP地址
r = link_configure_addresses(link);
if (r < 0)
return r;
// 4. 配置路由
r = link_configure_routes(link);
if (r < 0)
return r;
// 5. 启动DHCPv4客户端
if (network->dhcp && network->dhcp != DHCP_NO) {
r = dhcp4_configure(link);
if (r < 0)
log_link_warning(link, "Failed to start DHCPv4 client: %s", strerror(-r));
}
// 6. 配置IPv6
if (socket_ipv6_is_enabled()) {
r = link_configure_ipv6(link);
if (r < 0)
log_link_warning(link, "Failed to configure IPv6: %s", strerror(-r));
}
return 0;
}
12.3 DHCP客户端实现
// src/network/networkd-dhcp4.c:400-500
int dhcp4_configure(Link *link) {
int r;
assert(link);
assert(link->network);
// 1. 创建DHCP客户端
r = sd_dhcp_client_new(&link->dhcp_client);
if (r < 0)
return r;
// 2. 设置接口索引
r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex);
if (r < 0)
return r;
// 3. 设置客户端标识符
r = sd_dhcp_client_set_client_id(link->dhcp_client,
link->network->dhcp_client_identifier);
if (r < 0)
return r;
// 4. 设置MAC地址
r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
if (r < 0)
return r;
// 5. 设置广播模式
r = sd_dhcp_client_set_broadcast(link->dhcp_client,
link->network->dhcp_broadcast);
if (r < 0)
return r;
// 6. 设置事件回调
r = sd_dhcp_client_attach_event(link->dhcp_client, link->manager->event);
if (r < 0)
return r;
r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
if (r < 0)
return r;
// 7. 启动DHCP客户端
r = sd_dhcp_client_start(link->dhcp_client);
if (r < 0)
return r;
link->dhcp4_configured = true;
return 0;
}
12.4 地址管理实现
// src/network/networkd-address.c:600-700
int address_configure(Address *address, Link *link) {
int r;
assert(address);
assert(link);
// 1. 检查地址是否已存在
r = address_exists(link, address);
if (r < 0)
return r;
if (r > 0) {
log_link_debug(link, "Address %s already exists",
in_addr_to_string(address->family, &address->in_addr,
address->prefixlen));
return 0;
}
// 2. 添加地址到接口
r = rtnl_add_address(link->manager->rtnl,
link->ifindex,
address->family,
&address->in_addr,
address->prefixlen,
address->flags,
address->scope);
if (r < 0) {
log_link_error(link, "Failed to add address %s: %s",
in_addr_to_string(address->family, &address->in_addr,
address->prefixlen),
strerror(-r));
return r;
}
// 3. 更新地址对象状态
address->link = link;
log_link_info(link, "Configured address %s",
in_addr_to_string(address->family, &address->in_addr,
address->prefixlen));
return 0;
}
12.5 网络配置加载实现
// src/network/networkd-network.c:800-900
int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
_cleanup_(network_freep) Network *network = NULL;
const char *dropin_dirname;
int r;
assert(manager);
assert(filename);
// 1. 创建Network对象
network = new0(Network, 1);
if (!network)
return -ENOMEM;
network->manager = manager;
network->filename = strdup(filename);
if (!network->filename)
return -ENOMEM;
// 2. 解析配置文件
r = config_parse(filename, "Network\0",
config_item_perf_lookup, network_network_gperf_lookup,
CONFIG_PARSE_WARN, network, NULL);
if (r < 0)
return r;
// 3. 验证网络配置
r = network_verify(network);
if (r < 0)
return r;
// 4. 处理drop-in配置
r = network_load_dropin(network);
if (r < 0)
return r;
// 5. 添加到哈希表
r = ordered_hashmap_put(*networks, network->name, network);
if (r < 0)
return r;
TAKE_PTR(network);
return 0;
}
13. 虚拟网络设备支持
13.1 支持的设备类型
- Bridge: 网桥
- Bond: 网卡绑定
- VLAN: 虚拟局域网
- VXLAN: 虚拟扩展局域网
- MACVLAN: MAC虚拟局域网
- IP Tunnel: IP隧道
- WireGuard: VPN隧道
13.2 设备管理架构
const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_BRIDGE] = &bridge_vtable,
[NETDEV_KIND_BOND] = &bond_vtable,
[NETDEV_KIND_VLAN] = &vlan_vtable,
[NETDEV_KIND_VXLAN] = &vxlan_vtable,
// ... 更多设备类型
};
13.3 虚拟设备创建
int netdev_create(NetDev *netdev) {
int r;
assert(netdev);
assert(netdev->ifindex == 0);
// 1. 调用设备特定的创建函数
r = NETDEV_VTABLE(netdev)->create(netdev);
if (r < 0)
return r;
// 2. 设置设备名称
if (netdev->ifname) {
r = rtnl_set_link_name(netdev->manager->rtnl,
netdev->ifindex, netdev->ifname);
if (r < 0)
return r;
}
// 3. 配置设备参数
r = netdev_configure(netdev);
if (r < 0)
return r;
netdev->state = NETDEV_STATE_CONFIGURED;
return 0;
}
14. 与其他模块的集成
14.1 系统集成
14.2 D-Bus API
提供完整的D-Bus接口:
org.freedesktop.network1.Managerorg.freedesktop.network1.Linkorg.freedesktop.network1.Network
14.3 Varlink接口
提供现代化的Varlink API用于:
- 网络配置查询
- 状态监控
- 动态配置更新
15. 关键特性和优化
15.1 性能优化
- BPF过滤器: netlink消息过滤
- 批量操作: 地址/路由批量配置
- 延迟初始化: 按需加载组件
- 缓存机制: DNS查询缓存
15.2 可靠性特性
- 状态持久化: 重启后恢复状态
- 优雅降级: 配置失败时的回退
- 热重载: 运行时配置更新
- 故障检测: 自动故障检测和恢复
16. 总结
systemd-networkd 是一个功能完整、架构优雅的网络管理系统,具有以下优势:
1. 统一管理: 集成网络设备、地址、路由、DNS等所有网络功能
2. 配置灵活: 支持多种配置方式和复杂网络拓扑
3. 性能优秀: 通过事件驱动和批量操作实现高性能
4. 可靠性高: 完善的状态管理和错误处理机制
5. 扩展性好: 模块化设计便于功能扩展
该模块为现代Linux系统提供了企业级的网络管理解决方案,是systemd生态系统的重要组成部分。通过精心设计的架构和丰富的功能集,systemd-networkd成功替代了传统的网络配置工具,为Linux网络管理提供了更加现代化和可靠的解决方案。

710

被折叠的 条评论
为什么被折叠?



