zoukankan      html  css  js  c++  java
  • DPDK KNI 接口2

    参考文献:

      DPDK官网

    ........................................................................................................................................

    一. DPDK KNI 作用

    DPDK Kernel NIC Interface(KNI)允许用户空间应用程序访问Linux *控制面。

    使用DPDK KNI的好处是:

    • 比现有的Linux TUN / TAP接口更快(通过消除系统调用和copy_to_user()/copy_from_user()操作)。
    • 允许使用标准Linux网络工具(如ethtool,ifconfig和tcpdump)管理DPDK端口。
    • 允许与内核网络堆栈的接口。

    使用DPDK内核NIC接口的应用程序的组件如图所示。

    Figure 21-1 Components of a DPDK KNI Application

     

    KNI内核可加载模块支持两种类型的设备:

    • 其他设备:
      • 创建网络设备(通过ioctl调用)。
      • 维护所有KNI实例共享的内核线程上下文(模拟网络驱动程序的RX端)。
      • 对于单内核线程模式,维护所有KNI实例共享的内核线程上下文(模拟网络驱动程序的RX端)。
      • 对于多个内核线程模式,为每个KNI实例(模拟新驱动程序的RX侧)维护一个内核线程上下文。

    网络设备:

    • 通过实现由struct net_device定义的诸如netdev_ops,header_ops,ethtool_ops之类的几个操作提供的Net功能,包括支持DPDK mbufs和FIFO。
    • 接口名称由用户空间提供。
    • MAC地址可以是真正的NIC MAC地址或随机

     

    DPDK缓冲区流  

    为了最小化在内核空间中运行的DPDK代码的数量,mbuf mempool仅在用户空间中进行管理。内核模块可以感知mbufs,但是所有mbuf分配和释放操作将仅由DPDK应用程序处理。

     

      • Figure 21-2 Packet Flow via mbufs in the DPDK KNI

    kni 源码讲解

     1     /* Initialise EAL */
     2     ret = rte_eal_init(argc, argv);
     3     if (ret < 0)
     4         rte_exit(EXIT_FAILURE, "Could not initialise EAL (%d)
    ", ret);
     5     argc -= ret;
     6     argv += ret;
     7 
     8     /* Parse application arguments (after the EAL ones) */
     9     ret = parse_args(argc, argv);
    10     if (ret < 0)
    11         rte_exit(EXIT_FAILURE, "Could not parse input parameters
    ");
    12 
    13     /* Create the mbuf pool */
    14     pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF,
    15         MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ, rte_socket_id());
    16     if (pktmbuf_pool == NULL) {
    17         rte_exit(EXIT_FAILURE, "Could not initialise mbuf pool
    ");
    18         return -1;
    19     }
    20 
    21     /* Get number of ports found in scan */
    22     nb_sys_ports = rte_eth_dev_count_avail();
    23     if (nb_sys_ports == 0)
    24         rte_exit(EXIT_FAILURE, "No supported Ethernet device found
    ");
    25 
    26     /* Check if the configured port ID is valid */
    27     for (i = 0; i < RTE_MAX_ETHPORTS; i++)
    28         if (kni_port_params_array[i] && !rte_eth_dev_is_valid_port(i))
    29             rte_exit(EXIT_FAILURE, "Configured invalid "
    30                         "port ID %u
    ", i);
    31 
    32     /* Initialize KNI subsystem */
    33     init_kni();
    34 
    35     /* Initialise each port */
    36     RTE_ETH_FOREACH_DEV(port) {
    37         /* Skip ports that are not enabled */
    38         if (!(ports_mask & (1 << port)))
    39             continue;
    40         init_port(port);
    41 
    42         if (port >= RTE_MAX_ETHPORTS)
    43             rte_exit(EXIT_FAILURE, "Can not use more than "
    44                 "%d ports for kni
    ", RTE_MAX_ETHPORTS);
    45 
    46         kni_alloc(port);
    47     }
    48     check_all_ports_link_status(ports_mask);
    49 
    50     pid = getpid();
    51     RTE_LOG(INFO, APP, "========================
    ");
    52     RTE_LOG(INFO, APP, "KNI Running
    ");
    53     RTE_LOG(INFO, APP, "kill -SIGUSR1 %d
    ", pid);
    54     RTE_LOG(INFO, APP, "    Show KNI Statistics.
    ");
    55     RTE_LOG(INFO, APP, "kill -SIGUSR2 %d
    ", pid);
    56     RTE_LOG(INFO, APP, "    Zero KNI Statistics.
    ");
    57     RTE_LOG(INFO, APP, "========================
    ");
    58     fflush(stdout);
    59 
    60     ret = rte_ctrl_thread_create(&kni_link_tid,
    61                      "KNI link status check", NULL,
    62                      monitor_all_ports_link_status, NULL);
    63     if (ret < 0)
    64         rte_exit(EXIT_FAILURE,
    65             "Could not create link status thread!
    ");
    66 
    67     /* Launch per-lcore function on every lcore */
    68     rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER);
    69     RTE_LCORE_FOREACH_SLAVE(i) {
    70         if (rte_eal_wait_lcore(i) < 0)
    71             return -1;
    72     }
    73     monitor_links = 0;
    74     pthread_join(kni_link_tid, &retval);
    75 
    76     /* Release resources */
    77     RTE_ETH_FOREACH_DEV(port) {
    78         if (!(ports_mask & (1 << port)))
    79             continue;
    80         kni_free_kni(port);
    81     }
    82     for (i = 0; i < RTE_MAX_ETHPORTS; i++)
    83         if (kni_port_params_array[i]) {
    84             rte_free(kni_port_params_array[i]);
    85             kni_port_params_array[i] = NULL;
    86         }
    87 
    88     return 0;

    main 主要完成步骤:

      1.进行EAL层的初始化

      2.解析DPDK和应用层的参数

      3.分配报文的mempool,为接收报文做准备

      4.初始化以及启动接口

      5.启动各个核上的线程

  • 相关阅读:
    POJ_2513Colored Sticks 字典树+
    hdu1098:Ignatius's puzzle
    hdu1010:Tempter of the Bone 搜索+剪枝
    轻院1875: 蛤玮的财宝
    POJ3069:Saruman's Army
    轻院1874: 蛤玮学计网
    Educational Codeforces Round 18 E. Colored Balls
    浏览器f12的方法下载资源
    把手机上的新浪微博客户端卸载了
    Xmind使用总结
  • 原文地址:https://www.cnblogs.com/mysky007/p/11219609.html
Copyright © 2011-2022 走看看