P4 switch: Monitor the queue lengths of different output interfaces

[Topology]

 

The bandwidth of link s1-s2 is set to 0.5 Mbps. The bandwidth of link s1-s3 is set to 0.8 Mbps. H1 will send the traffic to h2 via s1-s2. H11 will send the traffic to h22 via s1-s2. H33 will send the traffic to h44 via s1-s3-s2.

 

The following code was based on multi-hop route inspection (mri).

 

[topology.py]

{

    "hosts": [

        "h1",

        "h2",

        "h3",

        "h11",

        "h22",

        "h33",

        "h44"

    ],

    "switches": {

        "s1": { "cli_input" : "s1-commands.txt" },

        "s2": { "cli_input" : "s2-commands.txt" },

        "s3": { "cli_input" : "s3-commands.txt" }

    },

    "links": [

              ["h1", "s1"], ["h11", "s1"], ["s1", "s2", "0", 0.5], ["s1", "s3", "0", 0.8],

              ["s3", "s2"], ["s2", "h2"], ["s2", "h22"], ["s3", "h3"],

                  ["h33", "s1"], ["s2", "h44"]

    ]

}

 

[s1-commands.txt]

table_set_default ipv4_lpm drop

table_set_default swtrace add_swtrace 1

table_add ipv4_lpm ipv4_forward 10.0.1.1/32  => 00:00:00:00:01:01 2

table_add ipv4_lpm ipv4_forward 10.0.1.11/32 => 00:00:00:00:01:0b 1

table_add ipv4_lpm ipv4_forward 10.0.1.33/32 => 00:00:00:00:01:0b 3

table_add ipv4_lpm ipv4_forward 10.0.2.44/32 => 00:00:00:03:02:00 5

table_add ipv4_lpm ipv4_forward 10.0.2.0/24 => 00:00:00:02:03:00 4

table_add ipv4_lpm ipv4_forward 10.0.3.0/24 => 00:00:00:03:02:00 5

 

[s2-commands.txt]

table_set_default ipv4_lpm drop

table_set_default swtrace add_swtrace 2

table_add ipv4_lpm ipv4_forward 10.0.2.2/32  => 00:00:00:00:02:02 2

table_add ipv4_lpm ipv4_forward 10.0.2.22/32 => 00:00:00:00:02:16 1

table_add ipv4_lpm ipv4_forward 10.0.2.44/32 => 00:00:00:00:02:2c 3

table_add ipv4_lpm ipv4_forward 10.0.1.0/24 => 00:00:00:01:03:00 4

table_add ipv4_lpm ipv4_forward 10.0.3.0/24 => 00:00:00:03:03:00 5

 

[s3-commands.txt]

table_set_default ipv4_lpm drop

table_set_default swtrace add_swtrace 3

table_add ipv4_lpm ipv4_forward 10.0.3.3/32  => 00:00:00:00:03:01 1

table_add ipv4_lpm ipv4_forward 10.0.1.0/24 => 00:00:00:01:04:00 2

table_add ipv4_lpm ipv4_forward 10.0.2.0/24 => 00:00:00:02:04:00 3

 

[receive2.py] (executed at h44)

#!/usr/bin/env python

import sys

import struct

 

from scapy.all import sniff, sendp, hexdump, get_if_list, get_if_hwaddr

from scapy.all import Packet, IPOption

from scapy.all import PacketListField, ShortField, IntField, LongField, BitField, FieldListField, FieldLenField

from scapy.all import IP, UDP, Raw

from scapy.layers.inet import _IPOption_HDR

 

def get_if():

    ifs=get_if_list()

    iface=None

    for i in get_if_list():

        if "eth0" in i:

            iface=i

            break;

    if not iface:

        print "Cannot find eth0 interface"

        exit(1)

    return iface

 

class SwitchTrace(Packet):

    fields_desc = [ IntField("swid", 0),

                  IntField("qdepth", 0)]

    def extract_padding(self, p):

                return "", p

 

class IPOption_MRI(IPOption):

    name = "MRI"

    option = 31

    fields_desc = [ _IPOption_HDR,

                    FieldLenField("length", None, fmt="B",

                                  length_of="swtraces",

                                  adjust=lambda pkt,l:l*2+4),

                    ShortField("count", 0),

                    PacketListField("swtraces",

                                   [],

                                   SwitchTrace,

                                   count_from=lambda pkt:(pkt.count*1)) ]

 

def handle_pkt(pkt):

    print "got a packet"

    pkt.show2()

#    hexdump(pkt)

    sys.stdout.flush()

 

 

def main():

    iface = 'h44-eth0'

    print "sniffing on %s" % iface

    sys.stdout.flush()

    sniff(filter="udp and port 4321", iface = iface,

          prn = lambda x: handle_pkt(x))

 

if __name__ == '__main__':

    main()

 

For other codes, refer to mri (mri.p4, send.py, receive.py).

 

[Execution]

 

 

Experiment 1: Only link s1-s2 is congested

 

From the following figure, we can see that the qdepth shown at h2 terminal is 36 and qdepth shown at h44 is 0. Because the link between s1-s2 is congested.

 

Experiment 2: link s1-s2 and s1-s3 are congested.

 

Open another two terminal for h33 and h44.

 

Send traffic through s1-s3-s2 and make link s1-s3 congested.

 

We can get different qdepth values at h2 and h44.

 

Dr. Chih-Heng Ke (smallko@gmail.com)

Department of Computer Science and Information Engineering,

National Quemoy University, Kinmen, Taiwan.