我正在用Python开发一个带有Ryu Framework的SDN控制器。
我遇到一个奇怪的问题,也许是一个简单的问题,因为它是我第一次用Python编程。我有以下句子:
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
# If you hit this you might want to increase
# the "miss_send_length" of your switch
if ev.msg.msg_len < ev.msg.total_len:
self.logger.debug("packet truncated: only %s of %s bytes",
ev.msg.msg_len, ev.msg.total_len)
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocols(ethernet.ethernet)[0]
pkt_ip = pkt.get_protocol(ipv4.ipv4)
ipv4_src = None
ipv4_dst = None
if pkt_ip is not None:
print "pkt_ip is not none"
ipv4_src = pkt_ip.src
ipv4_dst = pkt_ip.dst
print ipv4_src
print ipv4_dst
if eth.ethertype == ether_types.ETH_TYPE_LLDP:
# ignore lldp packet
return
dst = eth.dst
src = eth.src
dpid = datapath.id
self.mac_to_port.setdefault(dpid, {})
self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
self.logger.info("learn a mac address")
# learn a mac address to avoid FLOOD next time.
self.mac_to_port[dpid][src] = in_port
if dst in self.mac_to_port[dpid]:
out_port = self.mac_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD
actions = [parser.OFPActionOutput(out_port)]
#print "before avoid packet_in"
#print ipv4_src
# install a flow to avoid packet_in next time
self.logger.info("install a flow to avoid packet_in next time")
if out_port != ofproto.OFPP_FLOOD:
print "into if out_port"
print ipv4_src
print in_port
print dst
match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
# verify if we have a valid buffer_id, if yes avoid to send both
# flow_mod & packet_out
if msg.buffer_id != ofproto.OFP_NO_BUFFER:
self.add_flow(datapath, 1, match, actions, msg.buffer_id)
return
else:
self.add_flow(datapath, 1, match, actions)
data = None
if msg.buffer_id == ofproto.OFP_NO_BUFFER:
data = msg.data
out = parser.OFPPacketOut(datapath=datapath,buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data)
self.logger.info("send_msg_out")
print out
datapath.send_msg(out)
self.logger.info("sent send_msg_out in packet_in")
当我没有将ipv4_src
作为参数(match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
)传递时,代码运行正常。打印变量并且没有错误。
但是,当我将ipv4_src
作为参数(match = parser.OFPMatch(in_port=in_port, eth_dst=dst ipv4_src=ipv4_src)
)传递时,我总是得到“无”#39; print dst
中的parser.OFPMatch
和into if out_port
192.168.1.200
2
00:00:00:00:00:01
会给我一个长度错误(当然,因为它正在获得&#39;无&#39;)。
除了在 parser.OFPMatch 中使用 ipv4_src 作为参数外, in_port 和 dst 总是成功打印。
是否与我跳过的Python特性有关?
编辑:
参见两个输出示例:
不使用ipv4_src作为参数:
into if out_port
None
2
00:00:00:00:00:01
使用ipv4_src作为参数:
into if out_port
None
1
00:00:00:00:00:02
SimpleSwitch13: Exception occurred during handler processing. Backtrace from offending handler [_packet_in_handler] servicing event [EventOFPPacketIn] follows.
Traceback (most recent call last):
File "/home/ryu/ryu/ryu/base/app_manager.py", line 290, in _event_loop
handler(ev)
File "/home/ryu/ryu/ryu/app/simple_switch_13.py", line 134, in _packet_in_handler
self.add_flow(datapath, 1, match, actions, msg.buffer_id)
File "/home/ryu/ryu/ryu/app/simple_switch_13.py", line 68, in add_flow
datapath.send_msg(mod)
File "/home/ryu/ryu/ryu/controller/controller.py", line 289, in send_msg
msg.serialize()
File "/home/ryu/ryu/ryu/ofproto/ofproto_parser.py", line 211, in serialize
self._serialize_body()
File "/home/ryu/ryu/ryu/ofproto/ofproto_v1_3_parser.py", line 2655, in _serialize_body
match_len = self.match.serialize(self.buf, offset)
File "/home/ryu/ryu/ryu/ofproto/ofproto_v1_3_parser.py", line 1008, in serialize
field_offset)
File "/home/ryu/ryu/ryu/ofproto/oxx_fields.py", line 250, in _serialize
value_len = len(value)
TypeError: object of type 'NoneType' has no len()
当我使用 ipv4_src 时,我得到以下内容(因为该方法正在获得&#39;无法&#39;它无法达到他的长度,我想):
require('lodash')()