P4语言——source_routing

练习:源路由

本练习的目的是实现源路由。 使用源路由,源主机引导网络中的每个交换机将数据包发送到特定的端口。 主机在数据包中放置一个输出端口堆栈。 在本例中,我们只是将堆栈放在Ethernet报头之后,并选择一个特殊的etherType来表示。 每个交换机从堆栈中弹出一个项目,并根据指定的端口号转发数据包。

拓扑图代码

{
    "hosts": {
        "h1": {"ip": "10.0.1.1/24", "mac": "08:00:00:00:01:11",
               "commands":["route add default gw 10.0.1.10 dev eth0",
                           "arp -i eth0 -s 10.0.1.10 08:00:00:00:01:00"]},
        "h2": {"ip": "10.0.2.2/24", "mac": "08:00:00:00:02:22",
               "commands":["route add default gw 10.0.2.20 dev eth0",
                           "arp -i eth0 -s 10.0.2.20 08:00:00:00:02:00"]},
        "h3": {"ip": "10.0.3.3/24", "mac": "08:00:00:00:03:33",
               "commands":["route add default gw 10.0.3.30 dev eth0",
                           "arp -i eth0 -s 10.0.3.30 08:00:00:00:03:00"]}
    },
    "switches": {
        "s1": { "runtime_json" : "s1-runtime.json" },
        "s2": { "runtime_json" : "s2-runtime.json" },
        "s3": { "runtime_json" : "s3-runtime.json" }
    },
    "links": [
        ["h1", "s1-p1"], ["s1-p2", "s2-p2"], ["s1-p3", "s3-p2"],
        ["s3-p3", "s2-p3"], ["h2", "s2-p1"], ["h3", "s3-p1"]
    ]
}

p4文件

  1. 头部包含链路层协议、源路由协议、ipv4协议
  2. 源路由协议参数设置
  3. 源路由下一跳action设置
  4. packet包的处理流程逻辑关系
  5. 封装header出交换机
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

const bit<16> TYPE_IPV4 = 0x800;
const bit<16> TYPE_SRCROUTING = 0x1234;

#define MAX_HOPS 9

/*************************************************************************
*********************** 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 srcRoute_t {
    bit<1>    bos;//标记是否是最后一个
    bit<15>   port;//标记出端口
}

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;
    srcRoute_t[MAX_HOPS]    srcRoutes;//header有多条srcRoutes实现多跳
    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 {
        transition parse_ethernet;
    }

    state parse_ethernet {
        packet.extract(hdr.ethernet);
        transition select(hdr.ethernet.etherType) {
            TYPE_SRCROUTING: parse_srcRouting;
            default: accept;
        }
    }

    state parse_srcRouting {
        packet.extract(hdr.srcRoutes.next);//包的解封,使用next和extract移动指针
        transition select(hdr.srcRoutes.last.bos) {//这是指针的上一层也就是刚刚解封的一层
            1: parse_ipv4;
            default: parse_srcRouting;
        }
    }

    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(standard_metadata);
    }
    
    action srcRoute_nhop() {
        standard_metadata.egress_spec = (bit<9>)hdr.srcRoutes[0].port;//下一跳端口
        hdr.srcRoutes.pop_front(1);//总是删除第一层的srcRoute
    }

    action srcRoute_finish() {
        hdr.ethernet.etherType = TYPE_IPV4;//结束srcRoutes就会全部删除
    }

    action update_ttl(){
        hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
    }
    
    apply {
        if (hdr.srcRoutes[0].isValid()){
            if (hdr.srcRoutes[0].bos == 1){//检查是否是最后一跳
                srcRoute_finish();
            }
            srcRoute_nhop();
            if (hdr.ipv4.isValid()){
                update_ttl();
            }
        }else{
            drop();
        } 
    }
}

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

/*************************************************************************
***********************  D E P A R S E R  *******************************
*************************************************************************/

control MyDeparser(packet_out packet, in headers hdr) {
    apply {
        packet.emit(hdr.ethernet);
        packet.emit(hdr.srcRoutes);
        packet.emit(hdr.ipv4);
    }
}

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

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

<think>好的,我现在需要帮助用户解决在特定目录下执行make run后,如何对s1的端口2进行抓包的问题。首先,用户提到的是在Mininet环境下,可能是在使用P4编程的相关项目,比如source_routing练习。 首先,我需要确认用户的环境。通常,在Mininet中,交换机s1的端口对应的网络接口名称可能遵循特定的命名规则,比如s1-eth2。因此,抓包的命令应该是针对这个接口的,使用tcpdump或者Wireshark。 接下来,我需要考虑用户执行make run后的环境。通常,make run会启动Mininet,并创建相应的网络拓扑。这时候用户可能需要打开另一个终端窗口,或者使用Mininet自带的xterm命令来访问交换机的命名空间,以便执行抓包命令。 可能的步骤包括: 1. 在Mininet CLI中使用xterm s1命令打开交换机的终端。 2. 在新的终端窗口中,使用tcpdump -i s1-eth2 -w s1-eth2.pcap命令进行抓包,并将输出保存到文件。 3. 或者用户可能希望实时查看流量,可以使用tcpdump -i s1-eth2 -l -n命令。 另外,需要注意权限问题,可能需要使用sudo来执行tcpdump,或者在Mininet环境中可能已经具备足够的权限。 还要确认接口名称是否正确,如果用户的环境不同,接口名称可能有变化。比如有些情况下可能命名为s1-eth2,或者其他格式。如果用户不确定,可以建议他们使用ip link show或者ifconfig查看可用的接口。 最后,要确保用户在正确的目录下执行命令,并且了解如何终止抓包(比如Ctrl+C)以及如何分析生成的pcap文件,比如使用Wireshark。 总结步骤时,需要清晰列出每一步,并给出可能的选项,比如保存到文件或实时显示。同时,提醒用户可能需要的权限和验证接口名称的方法,确保他们能够顺利执行。</think>在Mininet环境下对交换机s1的端口2抓包,可按以下步骤操作: **Step 1 - 启动环境** ```bash cd ~/p4/tutorials/exercises/source_routing make run ``` **Step 2 - 打开交换机控制台** 在Mininet CLI中执行: ```bash xterm s1 ``` (将弹出新终端窗口) **Step 3 - 确认接口名称** 在新终端执行: ```bash ip link show | grep s1-eth ``` 典型输出会显示类似: ``` 2: s1-eth1@... 3: s1-eth2@... ``` **Step 4 - 开始抓包** 选择以下任意一种方式: **方式一:实时显示流量** ```bash tcpdump -i s1-eth2 -l -n ``` * `-l` 实时刷新 * `-n` 不解析域名 **方式二:保存到文件** ```bash tcpdump -i s1-eth2 -w s1-eth2.pcap ``` (按 `Ctrl+C` 停止后可用Wireshark分析) **补充说明:** 1. 若无法使用xterm,可通过`mn --mac`启动时添加`--nat`参数 2. 特权问题可能需要加`sudo` 3. 捕获特定流量可添加过滤条件,如: ```bash tcpdump -i s1-eth2 'icmp or arp' ``` 完成操作后,在Mininet CLI输入`exit`退出仿真环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值