Netd 中 NetworkManager 分析

本文介绍了NetlinkManager如何初始化并启动NetlinkHandler,监听Kernel事件并通过Socket通信。详细讲解了SocketListener、SocketClient、NativeDaemonConnector的角色,以及NetworkManagementService如何注册listener接收Kernel消息。重点涉及网络管理框架中的关键技术点。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

NetlinkManager 管理 netd 中 NetlinkHandler 的初始化并启动监听和处理;

NetlinkHandler 处理和转发 Kernel 的相应事件;

SocketListener 监听 socket,启动监听并接收 socket 事件;

SocketClient 实际的消息处理者,他将 event 通过 socket 发送给 java 层进行处理;

NativeDaemonConnector java 层的 socket 通讯端,用于接收和下发事件;

NetworkManagementService Framework 层的网络相关核心服务;

 

① 在 netd 的 main 函数中通过 NetworkManager 的 Instance 方法创建 NetworkManager 对象,并且调用其 start 方法

int main() {
  ...
  NetlinkManager *nm;
  ...
  if (!(nm = NetlinkManager::Instance())) {
      ALOGE("Unable to create NetlinkManager");
      exit(1);
  };
  ...
  if (nm->start()) {
      ALOGE("Unable to start NetlinkManager (%s)", strerror(errno));
      exit(1);
  }
  ...
}

② 在 start 接口中创建了三个 socket 用于接收 Kernel 消息

int NetlinkManager::start() {
    if ((mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT,
         0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII)) == NULL) {
        return -1;
    }

    if ((mRouteHandler = setupSocket(&mRouteSock, NETLINK_ROUTE,
                                     RTMGRP_LINK |
                                     RTMGRP_IPV4_IFADDR |
                                     RTMGRP_IPV6_IFADDR,
         NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) {
        return -1;
    }

    if ((mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG,
        NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) {
        ALOGE("Unable to open quota2 logging socket");
        // TODO: return -1 once the emulator gets a new kernel.
    }

    return 0;
}

套接字的类型均为 PF_NETLINK,报文类型是 SOCK_DGRAM,协议分别为:

NETLINK_KOBJECT_UEVENT,NETLINK_ROUTE 和 NETLINK_NETFILTER; 

③ 对每个新创建的 NETLINK_SOCKET 而言,又以其为参数创建了对应的 NetlinkHandler 对象,socket 的 fd 作为参数,用于 NetlinkHandler->NetlinkListener->SocketListener 的构造函数以及 init 函数初始化:

void SocketListener::init(const char *socketName, int socketFd, bool listen, bool useCmdNum) {
    mListen = listen;
    mSocketName = socketName;
    mSock = socketFd;
    mUseCmdNum = useCmdNum;
    pthread_mutex_init(&mClientsLock, nullptr);
}

这里面 listen 是 false,useCmdNum 也为 false,socketName 为 nullptr;

④ 继续对每个 NetlinkHandler 调用其 start 方法,其实最终调用了 SocketListener 的 startListener 方法,进而在其中以此 socket 的 fd 为参数创建了 So

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值