Reputation: 15
I am new to the area of SDN and now I am trying to implement a function in Ryu controller: let's assume we let host1 send packets to host2. And I'd like to let the controller receive each 5th flow with src=h1 and dst=h2. And the other flows ( every 1st - 4th flows) should be dropped.
I have added a variable "count" and written a mechanism in the packet_in handler like
def packet_in_handler(self, event):
msg = event.msg
datapath = msg.datapath
ofproto = datapath.ofproto
ofp_parser = datapath.ofproto_parser
dpid = datapath.id
pkt = packet.Packet(msg.data)
ip = pkt.get_protocols(ipv4.ipv4)
dst = ip[0].dst
src = ip[0].src
match = ofp_parser.OFPMatch()
#is ip_to_port a dict?
self.ip_to_port.setdefault(dpid, {})
self.ip_to_port[dpid][src]=msg.in_port
if dst in self.ip_to_port[dpid]:
out_port = self.ip_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD
if src == "10.0.0.1" and dst == "10.0.0.3":
self.count = self.count+1
if self.count % 5 == 0:
print("send to controller")
actions = [datapath.ofproto_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)] #send the flow to controller
else:
actions = []
else:
actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
But under this case, everytime when there is a packet with src=h1 and dst=h2 sent, there must always be a packet_in message to the controller. Because if I add the flow entry for that, I cannot count the number of flows any more and this handler will not work properly.Can someone help with this issue?
Upvotes: 1
Views: 346
Reputation: 11
I have no idea about your question, but shouldn't your code continue to send a message to the switch?
for example in ryu/ryu/app/simple_switch_13.py:
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]
if eth.ethertype == ether_types.ETH_TYPE_LLDP:
# ignore lldp packet
return
dst = eth.dst
src = eth.src
dpid = format(datapath.id, "d").zfill(16)
self.mac_to_port.setdefault(dpid, {})
self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
# 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)]
# install a flow to avoid packet_in next time
if out_port != ofproto.OFPP_FLOOD:
match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src)
# 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)
datapath.send_msg(out)
After making action,match,and out , you see that the send_msg function has called for the switch
Upvotes: 0