VSOMEIP代码阅读整理(1) - 网卡状态监听

embedded/2024/10/18 14:25:07/

一. 概述

在routing进程所使用的配置文件中,存在如下配置项目:
{"unicast" : "192.168.56.101",..."service-discovery" :{"enable" : "true","multicast" : "224.244.224.245",...}
}
其中有 "unicast" : "192.168.56.101"和	"multicast" : "224.244.224.245" 两个通信地址,这两个地址一个是用于vsomeip用于对外通信的单播地址,另一个配置的是service-discovery功能依赖的组播的地址。作为routingmanager的进程需要监听这个单播地址和组播地址所在的网卡的状态,这部分功能主要在netlink_connector中实现,routing_manager_imp依赖netlink_connector来监听网卡状态,并且在网卡状态ready的情况下才会启动routing。netlink_connector中使用到了linux平台的netlink协议用于监听内核上网卡相关事件。

二. netlink protocol

netlink是linux平台上第一种IPC机制,主要用于用户态进程与内核进程通信,此外还可以用于用户态进程之间通信(这个使用unix domain socket)也可以做到。netlink和传统的和内核通信的机制(ioctl,sysfs属性)等不同,netlink是支持全双工的通信的,也就是可以异步通信的,而其他几种传统的内核通信的机制只支持半双工同步通信的方式。在这种情况下,内核甚至支持主动发起通信,而不是由应用发起通信。此外,netlink支持组播的方式,以组播的方式将消息发给多个进程(根据groupid)。

img

netlink的通信方式使用的是socket API,创建NETLINK socket的时候,需要指定NETLINK socket的协议类型类型()
sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);   // NETLINK_ROUTE是协议类型
目前的linxu系统中支持32中协议类型,个人认为这个协议类型就是事件组(网卡/路由/安全/审计/SCSI设备...等等)。
#define NETLINK_ROUTE        0    /* 用于设置和查询路由表等网络核心模块*/
#define NETLINK_UNUSED        1    /* Unused number                */
#define NETLINK_USERSOCK    2    /* Reserved for user mode socket protocols,保留用于用户态进程间通信     */
#define NETLINK_FIREWALL    3    /* Unused number, formerly ip_queue        */
#define NETLINK_SOCK_DIAG    4    /* socket monitoring                */
#define NETLINK_NFLOG        5    /* netfilter/iptables ULOG */
...
...
NETLINK socket需要做bind操作绑定NETLINK的地址,NETLINK地址结构如下:
struct sockaddr_nl {__kernel_sa_family_t    nl_family;    /* 协议族 AF_NETLINK    */unsigned short    nl_pad;        /* 固定填写0 zero        */__u32        nl_pid;        /* 端口ID,内核填0,应用进程填PID port ID    */__u32        nl_groups;    /* 广播组 multicast groups mask */
};
除了nl_pad固定为0以外,其他参数需要填写
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;    // 协议族
// RTMGRP_LINK: 网卡UP/DOWN
// RTMGRP_IPV4_IFADDR: ip地址变化
addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;    // 广播组(事件组中的具体事件)
  设置好NETLINK地址后,将其绑定到socket上面
bind(sock, (struct sockaddr *)&addr, sizeof(addr);
接着,就可以使用该socket和内核进行netlink通信了,通过标准recv接口从内核接收消息
while (running && (len = recv(sock, buffer, 4096, 0)) > 0) {nlh = (struct nlmsghdr *)buffer;while (NLMSG_OK(nlh, len) && (nlh->nlmsg_type != NLMSG_DONE)) {// 解析不同类型的NetLink消息...// 下一条消息nlh = NLMSG_NEXT(nlh, len);}
}
close(sock);

三. netlink_connector

​ netlink_connector类依赖了NETLINK通信机制和内核进行通信,用于监控网卡的状态,根据传入的单播地址和组播地址监控。

​ 首先netlink_connector类中也创建了用于NETLINK通信的socket

class netlink_connector : public std::enable_shared_from_this<netlink_connector> {...
private:...boost::asio::basic_raw_socket<nl_protocol> socket_;  // nl_protocol结构体中默认famliy为PF_NETLINK, type为SOCK_RAW...
}void netlink_connector::start() {...socket_.open(nl_protocol(NETLINK_ROUTE), ec);   // 协议类型为NETLINK_ROUTE,用于设置和查询路由表等网络核心模块...socket_.bind(nl_endpoint<nl_protocol>(RTMGRP_LINK |        // - 当网卡变动时会触发这个多播组RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR |  // 当ipv4/ipv6地址变动时会触发这个多播组RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE |    // 当ipv4/ipv6路由变动时会触发这个多播组RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_MROUTE), ec);   // 当多播路由发生更新时会触发这个多播组

​ 然后,使用创建的socket接收内核的消息并且解析,根据不同的事件回调上层routing_manager_impl

socket_.async_receive(boost::asio::buffer(&recv_buffer_[0], recv_buffer_size),std::bind(&netlink_connector::receive_cbk,shared_from_this(),std::placeholders::_1,std::placeholders::_2)
);void netlink_connector::receive_cbk(boost::system::error_code const &_error,std::size_t _bytes) {while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {char ifname[IF_NAMESIZE];switch (nlh->nlmsg_type) { // 根据多播组内的消息类型分别处理case RTM_NEWADDR: {    // IP地址变化// 解析出消息中的IP地址,如果该IP是VSOMEIP配置的单播地址,则往下// 根据IP地址找到网卡,获取其状态(UP/DOWN)// 通知上层handler处理(handler第一个参数标志是单播还是组播地址的网卡)}break;case RTM_NEWLINK: {    // 网卡变化// 获取网卡IP,如果该IP是VSOMEIP配置的单播地址,则往下// 获取网卡状态// 通知上层handler处理}break;case RTM_NEWROUTE: {   // 路由添加check_sd_multicast_route_match(...) {// 读取路由项的目标地址(RTA_DST),判断地址是否为SD的组播地址// 读取路由项的输出网络设备索引,判断设备索引是否为单播地址通信使用的网络设备的索引// 读取路由项的网关地址// 1. 如果单播地址通信使用的网络设备被加到SD的组播中,返回true// 2. 如果单播地址通信使用的网络设备被添加到组播,但是组播地址长度为0,返回true(使用默认路由作为SD的地址)// 3. 不满足上面两种情况,返回false}// check_sd_multicast_route_match返回true,则通知上层组播准备好了}break;case RTM_DELROUTE: {   // 路由删除check_sd_multicast_route_match(...) {...}// check_sd_multicast_route_match返回true,则通知上层组播未准备好}break;...}
}

​ 对于netlink_connector,其监听网卡以及组播路由的变化事件。routing_manager_impl则是这些事件的消费者

void routing_manager_impl::start() {...netlink_connector_->register_net_if_changes_handler(std::bind(&routing_manager_impl::on_net_interface_or_route_state_changed,this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));...
}

http://www.ppmy.cn/embedded/121801.html

相关文章

【数学分析笔记】第4章第3节 导数四则运算和反函数求导法则(2)

4. 微分 4.3 导数四则运算与反函数求导法则 双曲正弦函数 sh ⁡ x e x − e − x 2 \sh x\frac{e^x-e^{-x}}{2} shx2ex−e−x​ 双曲余弦函数 ch ⁡ x e x e − x 2 \ch x\frac{e^xe^{-x}}{2} chx2exe−x​ ch ⁡ 2 x − sh ⁡ 2 x 1 \ch^2 x-\sh^2 x1 ch2x−sh2x1 ( e…

防范.[support2022@cock.li].colony96勒索病毒:数据保护、恢复与安全意识提升

导言 在数字世界的暗流涌动中&#xff0c;.[support2022cock.li].colony96勒索病毒以其独特的智能监控技术和狡猾的传播策略&#xff0c;悄然成为网络安全领域的一颗“定时炸弹”。本文旨在深入剖析这一新型勒索病毒的运作机制&#xff0c;探索创新的数据恢复方法&#xff0c;…

【网络】web1.0 2.0 3.0各自出现背景/技术原理/演化发展过程,以及Web 3.0 对传统互联网的影响

一、web1.0 2.0 3.0各自出现背景/技术原理/演化发展过程 互联网自诞生以来&#xff0c;经历了三个主要的发展阶段&#xff1a;Web 1.0、Web 2.0 和 Web 3.0&#xff0c;每个阶段都有其独特的特点和影响。 1、Web 1.0 Web 1.0 是互联网的初始阶段&#xff0c;大约从1990年代到…

Redis: 集群测试和集群原理

集群测试 1 ) SET/GET 命令 测试 set 和 get 因为其他命令也基本相似&#xff0c;我们在 101 节点上尝试连接 103 $ /usr/local/redis/bin/redis-cli -c -a 123456 -h 192.168.10.103 -p 6376我们在插入或读取一个 key的时候&#xff0c;会对这个key做一个hash运算&#xff0c…

Ajax开发技术

什么是 Ajax&#xff1f; 概念: Asynchronous JavaScript And XML&#xff0c;异步的 JavaScript 和 XML。作用: 数据交换: 通过 Ajax 可以给服务器发送请求&#xff0c;并获取服务器响应的数据。异步交互: 可以在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更…

滚雪球学Oracle[3.4讲]:事务控制与锁管理

全文目录&#xff1a; 前言一、事务隔离级别的深入探讨1.1 事务的定义与基本特性1.2 事务隔离级别的概念1.3 各隔离级别中的问题案例演示&#xff1a;不同隔离级别的行为 1.4 隔离级别与性能的权衡 二、锁的种类与死锁问题解决2.1 锁的种类2.2 锁的粒度2.3 死锁与解决策略死锁的…

论文阅读(十一):CBAM: Convolutional Block Attention Module

文章目录 IntroductionConvolutional Block Attention ModuleExperimentsConclusion 论文题目&#xff1a;CBAM: Convolutional Block Attention Module&#xff08;CBAM&#xff1a;卷积注意力机制&#xff09;   论文链接&#xff1a;点击跳转   代码链接&#xff1a;Git…

wpa_cli支持EAP-AKA认证运行设计

wpa_cli支持EAP-AKA认证运行设计 1 输入 1 .1启动wpa_supplicant 和 wpa_cli 在OpenHarmony开发板或华为开发机的命令行中输入 wpa_supplicant -Dnl80211 -c/data/service/el1/public/wifi/wpa_supplicant/wpa_supplicant.conf -g@abstract:/data/service/el1/public/wifi/soc…