ali
ali

Reputation: 21

How to send a packet to all switches using ryu controller?

I need to measure link delay in Ryu controller. I want to send a packet-out message for all switches by the controller and calculate the time between the sent packet-out message and received the packet-in message. I am a beginner in Ryu and don't know how to send a packet with specific EtherType such as 0x8fc to all switches. I have obtained the MAC of all switches and build a packet. how I can send a packet with specific EtherType to all switches? I don't know what is the db parameter for every switch?

    def send_packet(self, dp, port, pkt):
        ofproto = dp.ofproto
        parser = dp.ofproto_parser
        pkt.serialize()
        data = pkt.data
        action = [parser.OFPActionOutput(port=port)]

        out = parser.OFPPacketOut(
            datapath=dp, buffer_id=ofproto.OFP_NO_BUFFER,
            in_port=ofproto.OFPP_CONTROLLER,
            actions=action, data=data)
        dp.send_msg(out)

def create_packet(self):
        i=l=0
        for l in range(1,len(self.adjacency)+1):
            #print("\n")
            for i in self.adjacency[l]:
                ethertype = 0x8fc
                dst = self.macaddr(i)
                src = self.macaddr(l) 
                e = ethernet.ethernet(dst, src, ethertype)                
                p = packet.Packet()
                p.add_protocol(e)
                p.add_protocol(time.time())
                p.serialize()
                port=self.adjacency[l][i]
                send_packet(self, dp **??????** , port, p):

Upvotes: 0

Views: 1493

Answers (2)

Himanshu Tanwar
Himanshu Tanwar

Reputation: 336

I don't think p.add_protocol(time.time()) would work.

Create a protocol class rather:

from ryu.lib.packet import packet_base, packet_utils


class timep(packet_base.PacketBase):
    _PACK_STR = '!I'
    _PACK_LEN = struct.calcsize(_PACK_STR)
    _MIN_LEN = _PACK_LEN + struct.calcsize(_CHECKSUM_STR)
    _TYPE = {}

    def __init__(self, timestamp, payload_len=0):
        super().__init__()
        self.timestamp = int(timestamp)
        self.payload_len = payload_len

    def __len__(self):
        return timep._PACK_LEN

    @classmethod
    def parser(cls, buf):
        (timestamp, payload_len) = struct.unpack_from(cls._PACK_STR, buf)
        payload = buf[ppdp._MIN_LEN : ppdp._MIN_LEN + payload_len]
        msg = cls(timestamp, payload_len)
        return msg, None, payload

    def serialize(self, payload, prev):
        length = len(self)
        buf = bytearray(length)
        self.payload_len = len(payload)
        
        struct.pack_into(ppdp._PACK_STR, buf, 0,
            self.timestamp,
            self.payload_len
        )
        return buf

No you can do p.add_protocol(timep(time.time()))

Upvotes: 0

Hesam0x47
Hesam0x47

Reputation: 177

DP is the abbreviation for DataPathID that is kind of Uniq ID for an OpenFlow switch in your network.

According to the OpenFlow specification:

“The datapath_id field uniquely identifies a datapath. The lower 48 bits are intended for the switch MAC address, while the top 16 bits are up to the implementer. An example use of the top 16 bits would be a VLAN ID to distinguish multiple virtual switch instances on a single physical switch.”

If you're using Mininet and for example, you run linear topology:

mn --controller remote --topo linear,3

Your topology will be:

s1 -- s2 -- s3

 |    |      |

h1    h2     h3

DataPathID's will be:

s1: 0x0000000000000001

s2: 0x0000000000000002

s3: 0x0000000000000003

Pay attention that in other testbeds this numbers may be different but they're alway 16 digit hex.

Upvotes: 0

Related Questions