问题描述

用户执行 ifconfig netcard down、up 时 rte_kni 模块中的哪部分起作用?

ifconfig up down 接口的正常流程

ifconfig 是通过调用 ioctl 来完成工作的。期间经过了一系列的函数,最终调用到的是在网卡驱动在 netdev 中注册的 netdev_ops 虚函数表中的函数指针。

netdev_ops 虚函数表中与 up 、down 相关的虚函数如下:

ndo_open
ndo_close

dpdk 中 kni 口 ifconfig up down 的不同流程

dpdk kni 中并不会调用 ndo_open、ndo_start 虚函数接口,它会发送一个控制命令到用户态程序中,用户态程序接收到这个控制命令后,判断命令的类型,然后调用 pmd 中实现的 start 与 stop 函数来完成 up、down。

dpdk 中 kni 模块 ifconfig up down 的具体流程

kni 模块中关联的函数是 kni_net_open 与 kni_net_close,这两个函数在 kni_net.c 中被定义。

进一步的分析上面提到的两个函数发现它们会调用 kni_net_process_request 来通过共享队列的方式向 dpdk 的用户态程序发送命令,真正的 up、down 实际是在用户态程序中完成的。

dpdk 用户态程序注册的 rte_kni_ops 结构

dpdk 用户态程序需要预先注册一个 rte_kni_ops 结构,相关的代码如下:

     ops.config_network_if = kni_config_network_interface;ops.set_ethtools_cmd = kni_set_ethtool;.........

这个 ops 作为 rte_kni_alloc 函数的第三个参数传入到 dpdk 中。

这里需要关注的是 kni_config_network_interface 这个函数。这个函数中会完成网络设备的 up 与 down。

dpdk-19.11 examples 中的 kni 代码中就是 kni_config_network_interface 的标准实现。

其代码如下:

/* Callback for request of configuring network interface up/down */
static int
kni_config_network_interface(uint16_t port_id, uint8_t if_up)
{int ret = 0; if (!rte_eth_dev_is_valid_port(port_id)) {RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);return -EINVAL;}    RTE_LOG(INFO, APP, "Configure network interface of %d %s\n",port_id, if_up ? "up" : "down");rte_atomic32_inc(&kni_pause);if (if_up != 0) { /* Configure network interface up */rte_eth_dev_stop(port_id);ret = rte_eth_dev_start(port_id);} else /* Configure network interface down */rte_eth_dev_stop(port_id);rte_atomic32_dec(&kni_pause);if (ret < 0) RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);return ret;
}

可以看到它实际是调用 rte_eth_dev_stop、rte_eth_dev_start 来完成接口的 up、down。

rte_kni_handle_request

上文中我提到 kni 会通过共享队列发送一个控制消息到用户态,在 dpdk 用户态程序中需要轮询获取 kni 共享队列中的消息,这一般是在收发包间隙或者单独创建的一个管理线程中执行的。

其核心逻辑是调用 rte_kni_handle_request 函数进行处理。dpdk-19.11 中该函数的实现部分内容截取如下:

int
rte_kni_handle_request(struct rte_kni *kni)
{unsigned int ret;struct rte_kni_request *req = NULL;if (kni == NULL)return -1; /* Get request mbuf */ret = kni_fifo_get(kni->req_q, (void **)&req, 1); if (ret != 1)return 0; /* It is OK of can not getting the request mbuf */if (req != kni->sync_addr) {RTE_LOG(ERR, KNI, "Wrong req pointer %p\n", req);return -1; }   /* Analyze the request and call the relevant actions for it */switch (req->req_id) {case RTE_KNI_REQ_CHANGE_MTU: /* Change MTU */if (kni->ops.change_mtu)req->result = kni->ops.change_mtu(kni->ops.port_id,req->new_mtu);break;case RTE_KNI_REQ_CFG_NETWORK_IF: /* Set network interface up/down */if (kni->ops.config_network_if)req->result = kni->ops.config_network_if(kni->ops.port_id,req->if_up);break;

上述代码中 kni_fifo_get 负责从共享队列中获取消息,获取成功后校验消息是否合法,合法的消息则根据 req_id 进行分发,RTE_KNI_REQ_CFG_NETWORK_IF类型的消息会调用 kni 初始化中注册的 ops 中的 config_network_if 接口来处理。

总结

对 dpdk kni 口执行 ifconfig up down 操作会涉及内核与用户态的通信,kni 共享队列实现了内核与用户态的一种高效的通信方式。可以看到对 dpdk kni 口执行 up、down 其流程与普通的网卡驱动处理方式不同,实际是调用用户态的 pmd 驱动来完成的。

dpdk kni 口 ifconfig up、down 的执行流程相关推荐

  1. DPDK KNI实现(二十五)

    一.为什么要用kni 通常情况下dpdk用于二三层报文转发,接收到来自网卡的报文后,如果是二层报文则查找fdb表: 如果是三层报文,则进行dnat, snat处理后,查找路由表, 将报文转发给下一跳路 ...

  2. DPDK KNI介绍

    DPDK KNI KNI = Kernel NIC Interface 可以通过KNI与内核交互数据包.一些不便于用户态的处理的包可以通过KNI交于内核处理. DPDK KNI 优势 比 linux ...

  3. DHCP执行流程详解

    DHCP执行流程介绍 DHCP简介 DHCP大致执行流程 新主机向DHCP Server申请IP地址 DHCP Server将分配好的IP发送给新主机 新主机发送DHCP Request广播数据包,告 ...

  4. 动态执行流程分析和性能瓶颈分析的利器——gperftools的Cpu Profiler

    在<动态执行流程分析和性能瓶颈分析的利器--valgrind的callgrind>中,我们领略了valgrind对流程和性能瓶颈分析的强大能力.本文将介绍拥有相似能力的gperftools ...

  5. 动态执行流程分析和性能瓶颈分析的利器——valgrind的callgrind

    在<内存.性能问题分析的利器--valgrind>一文中我们简单介绍了下valgrind工具集,本文将使用callgrind工具进行动态执行流程分析和性能瓶颈分析.(转载请指明出于brea ...

  6. 使用Caffe进行手写数字识别执行流程解析

    之前在 http://blog.csdn.net/fengbingchun/article/details/50987185 中仿照Caffe中的examples实现对手写数字进行识别,这里详细介绍下 ...

  7. Caffe中对MNIST执行train操作执行流程解析

    之前在 http://blog.csdn.net/fengbingchun/article/details/49849225 中简单介绍过使用Caffe train MNIST的文章,当时只是仿照ca ...

  8. pip包管理工具-install执行流程简单查看

    pip概述 pip是python提供的包管理工具,该工具提供了对python包的查找.下载.安装与卸载等功能的工具,当前是python中比较主流的管理工具. pip下载安装包的概述 pip工具的本质通 ...

  9. djangorestframework源码分析2:serializer序列化数据的执行流程

    djangorestframework源码分析 本文环境python3.5.2,djangorestframework (3.5.1)系列 djangorestframework源码分析-serial ...

最新文章

  1. 你为世界杯而战,我为生活而战!
  2. centos7 docker 安装
  3. 【分布式】通过Numpy创建Dask.array
  4. python flask(1)
  5. TensorFlow(一)
  6. java中的基本数据类型_Java中的基本数据类型和引用数据类型
  7. python截图识别文字_用百度ocr+微信截图实现文字识别
  8. head first java原文_Head First Java
  9. python实例属性引用-python之对象(实例)
  10. h3c 华三路由器分类区别及命令配置笔记
  11. Java 内存模型(Java Memory Model,JMM)
  12. docker 内部ping不通宿主机_修改docker网段
  13. admin登录 404_Shiro Springboot 集群共享Session (Redis)+单用户登录
  14. sentinel——SLC数据下载、DEM数据下载拼接、精密轨道数据下载方法
  15. 锋利的jquery(认识jquery)
  16. java中继承applet类_Java - 33 Java Applet基础
  17. 怎么有效提高淘宝店铺的转化率方法步骤
  18. ACM程序设计之马拉松竞赛
  19. 简单典型二阶系统_威海召开迎接全国医疗保障系统行风建设专项评价工作会议...
  20. 瑞典皇家理工学院计算机,瑞典皇家理工学院

热门文章

  1. 刷脸支付有什么好处?| 超算科技
  2. 2023最新C++面经(一):vector内存预分配,左值引用和右值引用,move语义
  3. 登录页面右上角切换二维码
  4. c语言平面向量加法考点,平面向量的加减法怎么死活都不会?有没有什么口诀?
  5. 利用Javaweb做的教师信息管理系统
  6. HTML 统一资源定位器(Uniform Resource Locators)简介
  7. android,获取北京时区时间
  8. 纳皮尔筹——老外是如何「运筹帷幄」的
  9. CSS_03_盒子模型
  10. SnackBar的使用