Multipath Transmission for P4
[topology]
Single path transmission: if h1 sends the packets via s1-s2 to h2, h2 can get at most around 500kbps.
Multipath transmission: if h1 sends 50% traffic via s1-s2 to h2 and 50% traffic via s1-s3-s2 to h2, h2 can get at most around 1000kbps.
[topology.json]
{ "hosts": [
"h1",
"h2",
"h3" ], "switches": {
"s1": { "cli_input"
: "s1-commands.txt" },
"s2": { "cli_input"
: "s2-commands.txt" },
"s3": { "cli_input"
: "s3-commands.txt" } }, "links": [
["h1", "s1"], ["s1", "s2",
"0", 0.5], ["s1", "s3", "0", 0.5],
["s3", "s2", "0", 0.5], ["s2",
"h2"], ["s3", "h3"] ] } |
[basic.p4]
/* -*- P4_16 -*- */ #include <core.p4> #include <v1model.p4> const bit<16> TYPE_IPV4 = 0x800; /************************************************************************* *********************** H E A D E R S *********************************** *************************************************************************/ typedef bit<9> egressSpec_t; typedef bit<48> macAddr_t; typedef bit<32> ip4Addr_t; header ethernet_t
{ macAddr_t
dstAddr; macAddr_t
srcAddr; bit<16> etherType; } header ipv4_t { bit<4> version; bit<4> ihl; bit<8> diffserv; bit<16> totalLen; bit<16> identification; bit<3> flags; bit<13> fragOffset; bit<8> ttl; bit<8> protocol; bit<16> hdrChecksum; ip4Addr_t srcAddr; ip4Addr_t dstAddr; } struct metadata { macAddr_t
dstAddr; egressSpec_t
port; bit<8> lower; bit<8> upper; bit<8> result; bit<1> final; } struct headers { ethernet_t ethernet; ipv4_t ipv4; } /************************************************************************* *********************** P A R S E R *********************************** *************************************************************************/ parser MyParser(packet_in packet,
out headers hdr,
inout metadata meta,
inout standard_metadata_t
standard_metadata) { state start { meta.result=127; meta.final=0;
transition parse_ethernet; } state parse_ethernet
{ packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType)
{
TYPE_IPV4: parse_ipv4;
default: accept; } } state parse_ipv4 { packet.extract(hdr.ipv4);
transition accept; } } /************************************************************************* ************ C H E C K S U M V E R I F I C A T I O N
************* *************************************************************************/ control MyVerifyChecksum(inout headers hdr, inout metadata meta) { apply { } } /************************************************************************* ************** I N G R E S S P R O C E S S
I N G ******************* *************************************************************************/ control MyIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t
standard_metadata) { action drop()
{ mark_to_drop(); } action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) { standard_metadata.egress_spec =
port; hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; hdr.ethernet.dstAddr = dstAddr;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1; } table ipv4_lpm {
key = {
hdr.ipv4.dstAddr: lpm; }
actions = {
ipv4_forward;
drop;
NoAction; }
size = 1024; default_action = NoAction(); } action myforward(){ standard_metadata.egress_spec = meta.port; hdr.ethernet.srcAddr = hdr.ethernet.dstAddr; hdr.ethernet.dstAddr = meta.dstAddr;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
meta.final=1; } action
set_param1(bit<8> lower, bit<8> upper, macAddr_t
dstAddr, egressSpec_t
port) { random(meta.result,
(bit<8>)0,(bit<8>)100); meta.lower=lower; meta.upper=upper; meta.dstAddr=dstAddr; meta.port=port; } action
set_param2(bit<8> lower, bit<8> upper, macAddr_t
dstAddr, egressSpec_t
port) { meta.lower=lower; meta.upper=upper; meta.dstAddr=dstAddr; meta.port=port; } action
set_param3(bit<8> lower, bit<8> upper, macAddr_t
dstAddr, egressSpec_t
port) { meta.lower=lower; meta.upper=upper; meta.dstAddr=dstAddr; meta.port=port; } table ipv4_lpm2 {
key = {
hdr.ipv4.dstAddr: lpm;
meta.final: exact; }
actions = {
set_param1;
drop;
NoAction; }
size = 1024; default_action = NoAction(); } table ipv4_lpm3 {
key = {
hdr.ipv4.dstAddr: lpm;
meta.final: exact; }
actions = {
set_param2;
drop;
NoAction; }
size = 1024; default_action = NoAction(); } table ipv4_lpm4 {
key = {
hdr.ipv4.dstAddr: lpm;
meta.final: exact; }
actions = {
set_param3;
drop;
NoAction; }
size = 1024; default_action = NoAction(); } apply { if (hdr.ipv4.isValid())
{
ipv4_lpm2.apply();
if (meta.result
>= meta.lower && meta.result
<= meta.upper){
myforward();
}
if (meta.final==0){
ipv4_lpm3.apply();
if (meta.result
>= meta.lower && meta.result
<= meta.upper){
myforward();
}
}
if (meta.final==0){
ipv4_lpm4.apply();
if (meta.result
>= meta.lower && meta.result
<= meta.upper){
myforward();
}
} } if
(hdr.ipv4.isValid() && meta.result==127)
{
ipv4_lpm.apply(); } } } /************************************************************************* **************** E G R E S S P R O C E S S
I N G ******************* *************************************************************************/ control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t
standard_metadata) { apply { } } /************************************************************************* ************* C H E C K S U M C O M P U T A T I O N
************** *************************************************************************/ control MyComputeChecksum(inout headers
hdr, inout
metadata meta) { apply { update_checksum( hdr.ipv4.isValid(),
{ hdr.ipv4.version, hdr.ipv4.ihl,
hdr.ipv4.diffserv,
hdr.ipv4.totalLen,
hdr.ipv4.identification,
hdr.ipv4.flags,
hdr.ipv4.fragOffset,
hdr.ipv4.ttl,
hdr.ipv4.protocol, hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr },
hdr.ipv4.hdrChecksum,
HashAlgorithm.csum16); } } /************************************************************************* *********************** D E P A R S E R ******************************* *************************************************************************/ control MyDeparser(packet_out packet, in headers hdr)
{ apply { packet.emit(hdr.ethernet); packet.emit(hdr.ipv4); } } /************************************************************************* *********************** S W I T C H ******************************* *************************************************************************/ V1Switch( MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), MyComputeChecksum(), MyDeparser() ) main; |
[s1-commands.txt –single path]
table_set_default ipv4_lpm drop table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:00:01:01 1 table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:02:02:00 2 table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:03:03:00 3 #table_add
ipv4_lpm2 set_param1 10.0.2.2/32 0 => 0 49 00:00:00:02:02:00 2 #table_add ipv4_lpm3 set_param2 10.0.2.2/32 0 => 50 100 00:00:00:03:03:00 3 |
[s1-commands.txt –multipath]
table_set_default ipv4_lpm drop table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:00:01:01 1 #table_add
ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:02:02:00 2 table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:03:03:00 3 table_add ipv4_lpm2 set_param1 10.0.2.2/32 0 => 0 49 00:00:00:02:02:00 2 table_add ipv4_lpm3 set_param2 10.0.2.2/32 0 => 50 100 00:00:00:03:03:00
3 |
[s2-commands.txt]
table_set_default ipv4_lpm drop table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:01:02:00 2 table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:00:02:02 1 table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:03:03:00 3 |
[s3-commands.txt]
table_set_default ipv4_lpm drop table_add ipv4_lpm ipv4_forward 10.0.1.1/32 => 00:00:00:01:03:00 2 table_add ipv4_lpm ipv4_forward 10.0.2.2/32 => 00:00:00:02:03:00 3 table_add ipv4_lpm ipv4_forward 10.0.3.3/32 => 00:00:00:00:03:03 1 |
[Execution]
Single path transmission
Multipath transmission
Dr. Chih-Heng Ke
Department of Computer Science and
Information Engineering, National Quemoy University, Kinmen, Taiwan
Email: smallko@gmail.com