上一篇文章是关于Hub的,有关一些函数的用法都在上一篇文章里,大家有需要可以自行查看。
一个简单的交换机需要具有以下功能:
1.能够学习MAC地址,并且把MAC地址和接口联合起来填充MAC地址表。
2.当收到数据包的目的MAC地址在MAC地址表里面时,将数据包发送出去。
3.当收到的数据包目的MAC地址不在MAC地址表里面的时候,进行泛洪。
下面我们开始讲一下需要的算法:
1.使用Packet-In报文来学习MAC地址。
2.在学习到MAC地址之后,再收到数据包,交换机会先检查MAC地址表里面有没有目标地址,如果有,就用Packet-Out报文来把数据包送出去;如果没有,就泛洪数据包。
3.所谓的流表,就是包含了源和目的一个表,它是根据MAC地址表建立的,只有MAC地址表里面同时包含源和目的的时候,才会增加流表项。流表是在源和目的双向通信完成后建立的(这个表述可能有点牵强,我举个例子说明一下)
一台交换机连接两个主机,主机A向主机B发了数据包,主机B应答A的数据包经过交换机后,就建立了一条流表项,但是要注意:这个流表项的源是主机B,目的是A,大家可以分析一下为什么。
如果流表里面没有对应的流表项,在OpenFlow1.3版本,交换机可以选择丢弃数据包,或者匹配下一个流表,或者是传输给控制器,默认是丢弃数据包的,而在1.0,交换机只会Packet-In上报控制器。
控制器和交换机握手完成之后,一条默认流表项应该被添加进流表。它的作用是为了让交换机发送Packet-In消息。这条默认流表项被称为Table-Miss,不过Table-Miss不是默认存在的,他也是由控制器下发的。
我们在控制器代码里面定义的MAC地址表是只有控制器知道的,对于交换机来说,只有流表才能帮助它转发,所以控制器要给交换机下发流表,如果你不在交换机添加详细的流表项,那么你应该让交换机收到每一个数据包都上报控制器,由控制器下发Packet-Out报文进行处理,否则数据包会被丢弃。
下面展示源代码,源代码是ryu/app目录下面的simple_switch_13.py。13对应的是OpenFlow1.3版本。
#!/usr/bin/env python
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet