Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combination of Mesh Wi-Fi and P4 access point(AP) #518

Closed
davidchen0970 opened this issue Dec 24, 2023 · 0 comments
Closed

Combination of Mesh Wi-Fi and P4 access point(AP) #518

davidchen0970 opened this issue Dec 24, 2023 · 0 comments

Comments

@davidchen0970
Copy link

Hi, I tried to create a topology using mesh Wi-Fi and P4 AP, but it failed to pass the ping test at all during the test. After opening the Wireshark program, I found that the source MAC address and destination MAC address will become the same in ping test.

The topology and P4 code are as follows:

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 {
    /* empty */
}

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 {

        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType){

            TYPE_IPV4: ipv4;
            default: accept;

        }

    }

    state 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(standard_metadata);
    }

    action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {

        //set the src mac address as the previous dst, this is not correct right?
        hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;

       //set the destination mac address that we got from the match in the table
        hdr.ethernet.dstAddr = dstAddr;

        //set the output port that we also get from the table
        standard_metadata.egress_spec = port;

        //decrease ttl by 1
        hdr.ipv4.ttl = hdr.ipv4.ttl -1;

    }

    table ipv4_lpm {
        key = {
            hdr.ipv4.dstAddr: exact;
        }
        actions = {
            ipv4_forward;
            drop;
            NoAction;
        }
        size = 1024;
        default_action = NoAction();
    }

    apply {

        //only if IPV4 the rule is applied. Therefore other packets will not be forwarded.
        if (hdr.ipv4.isValid()){
            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 {

        //parsed headers have to be added again into the packet.
        packet.emit(hdr.ethernet);
        packet.emit(hdr.ipv4);

    }
}

/*************************************************************************
***********************  S W I T C H  *******************************
*************************************************************************/

//switch architecture
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;

commands_ap1.txt

table_set_default ipv4_lpm drop
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.1 => 00:00:00:00:00:01 3
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.2 => 00:00:00:00:00:02 1
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.3 => 00:00:00:00:00:03 2
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.4 => 00:00:00:00:00:04 1

commands_ap2.txt

table_set_default ipv4_lpm drop
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.1 => 00:00:00:00:00:01 1
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.2 => 00:00:00:00:00:02 3
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.3 => 00:00:00:00:00:03 1
table_add MyIngress.ipv4_lpm ipv4_forward 10.0.0.4 => 00:00:00:00:00:04 2

p4.py

import os
import sys

from mininet.log import setLogLevel, info
from mn_wifi.cli import CLI
from mn_wifi.net import Mininet_wifi
from mn_wifi.bmv2 import P4AP, P4Host
from mininet.node import RemoteController, Controller
import time
from mn_wifi.link import wmediumd, mesh

def topology(remote_controller):

    net = Mininet_wifi()
    h1 = net.addHost('h1', ip='10.0.0.1', cls=P4Host, mac="00:00:00:00:00:01")
    h2 = net.addHost('h2', ip='10.0.0.2', cls=P4Host, mac="00:00:00:00:00:02")
    sta1 = net.addStation('sta1', ip='10.0.0.3', mac="00:00:00:00:00:03", position='100,50,0')
    sta2 = net.addStation('sta2', ip='10.0.0.4', mac="00:00:00:00:00:04", position='300,50,0')
    
    args1 = dict()
    args2 = dict()
    if not remote_controller:
        path = os.path.dirname(os.path.abspath(__file__))
        json_file = path + '/ap-runtime.json'
        config1 = path + '/commands_ap1.txt'
        config2 = path + '/commands_ap2.txt'
        args1 = {'json': json_file, 'switch_config': config1}
        args2 = {'json': json_file, 'switch_config': config2}

    ap1 = net.addAccessPoint('ap1', cls=P4AP, netcfg=True, ssid='ssid1', position='100,100,0', dpid='1', wlans=2, **args1)
    ap2 = net.addAccessPoint('ap2', cls=P4AP, netcfg=True, ssid='ssid2', position='300,100,0', dpid='2', wlans=2, **args2)

    if remote_controller:
        info('*** Adding Controller\n')
        net.addController('c0', controller=RemoteController)
    
    info("*** Configuring propagation model\n")
    net.setPropagationModel(model="logDistance", exp=4)

    net.configureWifiNodes()

    net.addLink(sta1, ap1)
    net.addLink(sta2, ap2)
    net.addLink(h1, ap1)
    net.addLink(h2, ap2)
    net.addLink(ap1, intf='ap1-wlan2', cls=mesh, ssid='mesh-ssid', channel=5)
    net.addLink(ap2, intf='ap2-wlan2', cls=mesh, ssid='mesh-ssid', channel=5)

    info('*** Plotting Graph\n')
    net.plotGraph(max_x=500, max_y=500)

    net.start()
    if not remote_controller:
        net.staticArp()

    CLI(net)

    net.stop()

if __name__ == '__main__':
    setLogLevel('info')
    remote_controller = True if '-r' in sys.argv else False
    topology(remote_controller)

螢幕擷取畫面 2023-12-25 035936
螢幕擷取畫面 2023-12-25 040154

The virtual environment uses the virtual machine provided by the official GitHub.

Thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant