OpenvSwitch 2.5 代码分析与编译安装
来源:互联网 发布:阿里域名备案查询 编辑:程序博客网 时间:2024/05/16 12:25
首先,写这篇博客主要是记录一下博主在前前后后两三个月的时间里,编译安装OVS所采过的坑。水平有限,牛人勿喷。
OpenvSwitch代码分析:
首先看一下OVS在一个SDN网络中的位置和与各部分组件的关系图:
上图绿框部分是博主想自己写的模块,也是想改动的地方。
继续看一张OVS自身的架构图:
每个模块都有不同的功能,主要就是 内核模块 + ovs-vswitchd + ovsdb-server:
ovs-vswitchd 为主要模块,实现交换机的守护进程daemon
openvswitch.ko为Linux内核模块,支持数据流在内核的交换
ovsdb-server为轻量级数据库服务器,保存配置信息,ovs-vswitchd通过这个数据库获取配置信息
博主就是在安装内核模块的时候踩过了一些坑,一会再说。= =!
再看一下openvswitch的代码结构:
在如上的代码结构中,vswitchd中就是ovs-vswitchd的入口代码,ovsdb就是ovsdb-server的代码,ofproto即上述的中间抽象层,lib下面有netdev,dpif的实现,datapath里面就是内核模块openvswitch.ko的代码。
在OVS中有很多复杂而精妙的数据结构和程序构架,博主也是看了很多大牛的分析分享在这推荐几个博客:
庾志辉OVS 专栏
http://blog.csdn.net/column/details/openvswitch.html
datapath 模块分析
http://vinllen.com/ovs-datapathbi-ji/
NightCat的分析整理
http://www.jianshu.com/p/bf112793d658
OpenvSwitch安装
安装Open vSwitch,主要是两大块:内核层的openvswitch-datapath模块和用户层的openvswitch-common模块和openvswitch-switch模块。
因为博主的特殊需求,所以要对openvswitch的代码进行自己编译安装。所以如果只是想安装openvswitch的话,大可不必自己编译安装,直接用apt-get或者yum等包管理工具直接自动化安装即可。
因为博主主要是想实现对OpenFlow消息的加密和认证,所以修改openvswitch 2.5 源代码的 ovs/ofproto/ofproto.c 中的handle_flow_mod函数。该函数用来处理FLOW_MOD消息,方便后续的验证和调试。
博主在这想让OVS接收到FLOW_MOD消息后在桌面上创建一个文件并连接本机的一个socket端口发送一个消息。改动如下:
static enum ofperrhandle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh) OVS_EXCLUDED(ofproto_mutex){ struct ofproto *ofproto = ofconn_get_ofproto(ofconn); struct ofproto_flow_mod ofm; uint64_t ofpacts_stub[1024 / 8]; struct ofpbuf ofpacts; enum ofperr error; FILE *FSpointer; #define MYPORT 11777 #define BUFFER_SIZE 1024 error = reject_slave_controller(ofconn); if (error) { goto exit; } ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub); error = ofputil_decode_flow_mod(&ofm.fm, oh, ofconn_get_protocol(ofconn), &ofpacts, u16_to_ofp(ofproto->max_ports), ofproto->n_tables); /* @PeterWang 2017-06-24 @Create a flie to FS&Connect to socket */ //*******************************************************************************// FSpointer = fopen("/home/peter/Desktop/test.txt","a"); fprintf(FSpointer, "%s\n","received a FLOW_MOD Info:"); fprintf(FSpointer, "%x / %x :%d\n\n",ofm.fm.cookie,ofm.fm.cookie_mask,ofm.fm.command); int sock_cli = socket(AF_INET,SOCK_STREAM, 0); ///定义sockaddr_in struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MYPORT); ///服务器端口 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ///服务器ip ///连接服务器,成功返回0,错误返回-1 if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("connect error!"); fprintf(FSpointer, "%s\n","connect error!"); } char sendbuf[BUFFER_SIZE]="received a FLOW_MOD Info."; ///发送 if(send(sock_cli, sendbuf, strlen(sendbuf),0)<0){ perror("send error!"); fprintf(FSpointer, "%s\n","send error!"); } memset(sendbuf, 0, sizeof(sendbuf)); //关闭文件和连接 close(sock_cli); fclose(FSpointer); //*******************************************************************************// if (!error) { error = ofproto_check_ofpacts(ofproto, ofm.fm.ofpacts, ofm.fm.ofpacts_len); } if (!error) { struct flow_mod_requester req; req.ofconn = ofconn; req.request = oh; error = handle_flow_mod__(ofproto, &ofm, &req); } if (error) { goto exit_free_ofpacts; } ofconn_report_flow_mod(ofconn, ofm.fm.command);exit_free_ofpacts: ofpbuf_uninit(&ofpacts);exit: return error;}
接下来就是编译安装了,关于编译安装,博主使用两种方法,一种是直接make编译安装,另一种是打包成各个独立的deb安装包。这其中因为OVS的内核模块与Linux内核有的版本不兼容所以OVS官方给出了以下的版本对应关系:
博主修改的是2.5.2版本的OVS源码,所以按上述表格来看linux内核应该是2.6.32到4.3是都可以兼容的。所以博主在https://www.kernel.org 下载并安装了3.16.44的内核并安装了,但是在后续的OVS安装过程中却并没有那么顺利。主要遇到问题是安装内核模块的时候总是报依赖错误,但是所报的依赖关系博主都一一用modprobe载入到内核了 = =!
后来换到了3.4.113的内核版本才正常安装,关于在3.16.44的内核报错,在后来看的一些博文中有的牛人曾提到,需要提前将内核中bridge模块卸载掉用openvswitch来替换。但是博主也试验过就算是卸载了bridge模块openvswitch模块还是报依赖错误。
(关于安装内核的时候遇到的问题请见博主的另一篇博客)
直接make编译安装
下载源码:
wget https://github.com/openvswitch/ovs/archive/branch-2.5.zip
解压:
unzip branch-2.5.zip cd ovs-branch-2.5/
配置编译环境(root用户):
./configure --with-linux=/lib/modules/`uname -r`/build 2>/dev/null./boot.sh
需要的编译的工具(root用户):
apt-get updateapt-get install graphviz autoconf automake automake1.10 dh-autoreconf libssl-dev libtool python-all python-twisted-conch
关于解决其他依赖关系:
用 dpkg-checkbuilddeps 可以查看一下当前主机还有什么依赖关系没有安装,用apt-get或yum等包管理工具安装上即可
编译安装(root用户):
./boot.shmake -j4 #这里-j后边的数字代表用多线程来进行编译,可以按自己机器配置选择make install modprobe greinsmod datapath/linux/openvswitch.komake modules_installmodprobe openvswitch
打包成deb安装
博主第一次就是通过这种办法安装成功的,这也是OVS2.5官方给出的安装方法:
下载源码:
wget https://github.com/openvswitch/ovs/archive/branch-2.5.zip
解压:
unzip branch-2.5.zip cd ovs-branch-2.5/
首先,先安装两个工具:
apt-get install build-essential fakeroot
用 dpkg-checkbuilddeps 命令来检查依赖关系有没有安装好,将其提示的依赖关系用apt-get或yum包管理工具安装好。
安装好依赖关系后,执行以下命令来进行打包:
fakeroot debian/rules binary
编译打包过程有10分钟左右,时间因为机器配置可能有所差异。产生的 .deb安装包会在源码目录的上一级文件目录中看到,如下图:
打包完了,下面就开始安装了。首先安装内核模块,博主在此费了不少时间,因为之前没有用过module-assistant安装过内核模块所以走了很多弯路。在上述的图片中可以看到跟内核有关的.deb文件(跟datapath有关的)有两个:
openvswitch-datapath-source_2.5.3-1_all.deb
openvswitch-datapath-dkms_2.5.3-1_all.deb
再次博主一直以为 -dkms是所谓的内核模块,安装好以后也加载不上 = =
其实,正确的安装方法如下:
首先安装openvswitch-datapath-source:
dpkg -i openvswitch-datapath-source_2.5.3-1_all.deb
module-assistant build openvswitch-datapathmodule-assistant install openvswitch-datapath
现在lsmod就可以看到当前跟openvswitch相关的内核模块:
继续安装其他组件:
dpkg -i openvswitch-common_2.5.3-1_amd64.debdpkg -i openvswitch-switch_2.5.3-1_amd64.deb
安装上这两个模块,OVS的大部分功能已经可以用了,其他几个模块组件用的很少。
到此安装就结束了,为了验证一下自己的改动是否被执行,所以将ovs创建一个br0 并将其连接到内网的一个ODL控制器,配置如下:
然后我准备用postman向ODL发送下发流表请求:
其中请求连接为:
http://192.168.1.177:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:59781766371651/flow-node-inventory:table/0
发送内容为(json格式):
{ "table": [ { "id": "0", "flow": [ { "id": "0", "match": { "in-port": "1", "vlan-match": { "vlan-id": { "vlan-id-present": "true", "vlan-id": "20" } } }, "instructions": { "instruction": [ { "apply-actions": { "action": [ { "output-action": { "output-node-connector": "3", "max-length": "65535" }, "order": "1" }, { "pop-vlan-action": {}, "order": "0" } ] }, "order": "0" } ] }, "buffer_id": "65535", "installHw": "true", "barrier": "true", "strict": "true", "priority": "162", "idle-timeout": "0", "hard-timeout": "0", "table_id": "0" } ] } ]}
然后在OVS的主机上运行一个python脚本来监听,代码如下:
#!/usr/bin/python#coding=utf-8import socket import commands import threadingfrom time import ctimeimport timeimport fcntlimport structglobal host_IP,porthost_IP = "127.0.0.1"port = 11111def serverCallMulti(host_ip = "127.0.0.1",port = 11777): count = 0 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 定义socket类型,网络通信,TCP s.bind((host_ip, port)) # 套接字绑定的IP与端口 s.listen(1) # 开始TCP监听 print "开始监听..." while True : conn, addr = s.accept() # 接受TCP连接,并返回新的套接字与IP地址 print'Connected by', addr ,". Create a new thread :(",count,")" # 输出客户端的IP地址 t = threading.Thread(target=oneThread, args=(addr,count,conn,),name=addr[0]+'|'+str(count)) t.start() count+=1def oneThread(addr,count,conn): print ctime(),'开启新线程', threading.current_thread().getName() date = conn.recv(1024) # 把接收的数据实例化 !!考虑存在阻塞 print threading.current_thread().getName(),'send: ',date print "校验数据库流表信息..." time.sleep(0.2) print"ok.."if __name__ =='__main__': host_ip = socket.gethostname() # serverCallMulti(host_ip=host) # host_ip = get_ip_address('eth0') print '监听IP :',host_ip serverCallMulti()
下面是执行情况:
可以看到,OVS接收到FLOW_MOD消息时就会执行博主所加的代码,向python脚本发送一句“received a FLOW_MOD Info.”
至此,博主喜极而泣啊…..
- OpenvSwitch 2.5 代码分析与编译安装
- Openvswitch原理与代码分析(8): 修改Openvswitch代码添加自定义action
- Openvswitch原理与代码分析(4): 修改Openvswitch代码添加自定义action
- Openvswitch原理与代码分析(3): openvswitch内核模块的加载
- Openvswitch原理与代码分析(1):总体架构
- Openvswitch原理与代码分析(2): ovs-vswitchd的启动
- Openvswitch原理与代码分析(2): ovs-vswitchd的启动
- Ubuntu14.04编译安装OpenvSwitch
- Openvswitch在Ubuntu编译并安装
- CentOS7编译安装Openvswitch 2.3.0 LTS
- OpenvSwitch自动化重新编译和安装
- Openvswitch原理与代码分析(4):网络包的处理过程
- Openvswitch原理与代码分析(5): 内核中的流表flow table操作
- Openvswitch原理与代码分析(6):用户态流表flow table的操作
- Openvswitch原理与代码分析(7): 添加一条流表flow
- Openvswitch原理与代码分析(2):用户态流表flow table的操作
- Openvswitch原理与代码分析(3): 添加一条流表flow
- CentOS7安装Openvswitch 2.5.1
- log4j日志配置文件及将日志根据不同的等级输入到不同的文件之中
- Recyclerview支持下拉刷新、上拉加载,包括线性布局、网格布局和 流布局
- sonarQube中StartSonar.bat启动不了。win7下
- 6174问题
- GitHub分支(branch)合并
- OpenvSwitch 2.5 代码分析与编译安装
- AngularJS 最常用的八种功能
- robotium获取某一个按钮上的文字
- ActivityOptionsCompat动画的使用
- CountDownLatch 源码分析
- MTK编译笔记1
- 【Python】遍历文件夹中所有文件
- 计算机网络实验ethereal
- C# 线程控制