1.配置流程
环境:centos 7.2.1511,内核版本3.10.0-327.el7.x86_64
[1]下载内核源码,https://buildlogs.cdn.centos.org/c7.1511.00/kernel/20151119220809/3.10.0-327.el7.x86_64/kernel-devel-3.10.0-327.el7.x86_64.rpm
1)cp kernel-devel-3.10.0-327.el7.x86_64.rpm /usr/local/src
2)cd /usr/local/src/
3)rpm -ivh kernel-devel-3.10.0-327.el7.x86_64.rpm //此时内核源码就安装到了/usr/src/kernels/3.10.0-327.el7.x86_64
[2]下载netmap源码:https://github.com/luigirizzo/netmap
1)cp netmap-master /usr/local/src
2)cd /usr/local/src/netmap-master/LINUX
3)./configure --drivers=igb --kernel-sources=/usr/src/kernels/3.10.0-327.el7.x86_64 //表示只编译igb驱动
4)make
5)make install //此时在当前目录会生成netmap.ko和igb/igb.ko
[3]加载驱动(在当前LINUX目录下执行)
1)rmmod igb //卸载当前的igb驱动
2)insmod netmap.ko //加载netmap.ko驱动
3)insmod igb/igb.ko //加载netmap的igb驱动,这个igb驱动和之前的igb驱动是不一样的,另外如果当前管理口网卡用的就是igb驱动,执行第一步后会连不上设备,所以可以把这三步写到脚本里面执行。
2.测试代码
下面的代码从网卡eth1收包:
#include <stdio.h> #include <poll.h> #define NETMAP_WITH_LIBS #include <net/netmap_user.h> unsigned long pps = 0; static void receive_packets(struct netmap_ring *ring) { int i; char *buf; while (!nm_ring_empty(ring)) { i = ring->cur; buf = NETMAP_BUF(ring, ring->slot[i].buf_idx); pps++; ring->head = ring->cur = nm_ring_next(ring, i); } } int main(void) { struct nm_desc *d; struct pollfd fds; struct netmap_ring *ring; int i; d = nm_open("netmap:eth1", NULL, 0, 0); fds.fd = d->fd; fds.events = POLLIN; while (1) { if (poll(&fds, 1, 1) < 0) { perror("poll()"); exit(1); } for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) { ring = NETMAP_RXRING(d->nifp, i); receive_packets(ring); } } return 0; }
3.说明
[1]安装netmap的igb驱动后,所有当前使用igb的网卡都支持使用netmap处理报文。
[2]如果不调用nm_open()函数,所有网卡还是正常进内核处理。对一个网卡调用了nm_open()函数之后,这个网卡的所有包就不会进内核处理,所以此时需要在程序中处理这些报文。