前面做了一大堆的准备就是为了分析下upcall调用,但是现在因为工作重心已经从OpenVswitch上转移到了openstack,所以根本没时间去研究OpenVswitch了。(openstack是用Python写的,我大学没接触过Python,所以现在要一边学Python一边学openstack)后面的OpenVswitch分析更新的时间可能会有点久。
由于前面做了很多准备,所以这里不能只分析NetLink通信机制(否则可能会感觉没意思了),首先来分析下upcall函数调用的原因。如果看了前面的源码分析的就会知道,在什么情况下会调用upcall函数呢?就是在一个数据包查找不到相应的流表项时,才会调用upcall函数(比如一个数据包第一次进入这个内核,里面没有为这个数据包设定相应的流表规则)。upcall函数的调用其实就是把数据包的信息下发到用户 空间去,而由内核空间到用户空间的通信则要用到linux中的NetLink机制。所以熟悉下NetLink通信可以知道upcall函数调用需要什么样的参数以及整个函数的作用和功能。
现在来测试下NetLink的使用,NetLink由两部分程序构成,一部分是用户空间的,另外一部分是内核空间的。用户空间的和大多数socket编程一样,只是用的协议时AF_NETLINK,其他基本都市一样的步骤。
下面是NetLine程序中的用户代码NetLinke_user.c:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<linux/netlink.h>
#define NETLINK_TEST 30
#define MAX_MSG 1024
int main(void)
{
/*按代码规范所有变量都要定义在函数的开始部分,但为了便于理解,所以顺序定义变量*/
/*
* struct sockaddr_nl addr;
* struct nlmsghdr *nlhdr;
* struct iovec iov;
* struct msghdr msg;
* int sockId;
*/
//创建socket套接字
int socketId = socket(AF_NETLINK,SOCK_RAW,NETLINK_TEST);
if (0 > socketId){
printf("The error in socket_create!\