Djarlo
Djarlo

Reputation: 15

How to let the ryu controller sample one packet everytime

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

Answers (1)

Zohreh Rezaei
Zohreh Rezaei

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

Related Questions