作者简介:刘敬一,盛科网络SDN交换机产品线测试主管
前言
- 关于OFTest的介绍,请戳这里
- 总的来说,就是用python写的测试Openflow协议一致性的测试套件
- 可以将OFTest扩展为测试Openflow的测试平台,例如做压力测试
扩展OXM的需求
- Openflow已经定义了很多match class,涉及到L2/L3/MPLS/TCP/UDP等
- 有时flow需要匹配特定的情况,例如我司的交换芯片可以match mpls label的个数
- 下面以支持match mpls_label_num为例
预备知识
- OXM的match field,由如下字段组成
- class(16bits)
- field(7bits)
- has_mask(1bit) #如果是0就是没有mask
- length(8bits) #表明vlalue长度,单位bytes
- value(长度由lenghth决定)
- mask(长度由length决定) #可选,取决于has_mask这个bitpad(长度不定) #可选
- 关于字段长度和格式
- ! 表示按原字节序
- B 1 byte 整数
- H 2 byte整数
- L 4 bytes整数
- OFTest使用type_len来定义class+field+has_mask+length,是一个正整数
预定义相关参数
- 下面参数都是已经定义好的
- class=0x0001 #这个是自定义的NXM,如果是openflow spec1.3规定的,这个值就是0x8000
- field=49=0110001 #补齐7bits
- has_mask=0 # 没有掩码
- 合并field和has_mask=0110001 0=0x62
- length=1=0x01
- 得到OFTest OXM需要的type_len值为
- type_len=0x0001 6201=90625
添加新的OXM定义
- 在~/src/python/loxi/of13/oxm.py中添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
class mpls_label_num(oxm): type_len = 90625 def __init__(self, value=None): if value != None: self.value = value else: self.value = 0 return def pack(self): packed = [] #定义一个空列表,用来幢packet内容 packed.append(struct.pack("!L", self.type_len)) #将上一步计算的type_len按照4 bytes格式填入 packed.append(struct.pack("!B", self.value)) #填入传入的值,就是期望mpls报文包含几层label return ''.join(packed) @staticmethod def unpack(reader): obj = mpls_label_num() _type_len = reader.read("!L")[0] assert(_type_len == 90625) obj.value = reader.read("!B")[0] return obj def __eq__(self, other): if type(self) != type(other): return False if self.value != other.value: return False return True def pretty_print(self, q): q.text("mpls_label_num {") with q.group(): with q.indent(2): q.breakable() q.text("value = "); q.text("%#x" % self.value) q.breakable() q.text('}') oxm.subtypes[90625] = mpls_label_num |
验证
- 调用新加oxm class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
def runTest(self): self.in_port, self.out_port = openflow_ports(2) match = ofp.match([ ofp.oxm.eth_type(0x8847), ofp.oxm.mpls_label_num(5), ] ) actions = [ofp.action.output(self.out_port)] request = ofp.message.flow_add( table_id=test_param_get("table", 0), match=match, instructions=[ ofp.instruction.apply_actions(actions)], buffer_id=ofp.OFP_NO_BUFFER, priority=1000) self.controller.message_send(request) |
- 在OVS上dump-flows,得到
1 |
OFPT_FLOW_MOD (OF1.3) (xid=0xcb7b1ea3): ADD priority=1000,mpls,mpls_label_num=5, out_port:0 actions=output:2 |
- 发送mpls报文,发现只有包含三层mpls的报文可以匹配到这条流表
--------------华丽的分割线------------------
本文系《SDNLAB原创文章奖励计划》投稿文章,该计划旨在鼓励广大从业人员在SDN/NFV/Cloud网络领域创新技术、开源项目、产业动态等方面进行经验和成果的文字传播、分享、交流。有意向投稿的同学请通过官方唯一指定投稿通道进行文章投递,投稿细则请参考《SDNLAB原创文章奖励计划》