Featured image of post P4示例程序-3 L2基本交换机

P4示例程序-3 L2基本交换机

交换机根据MAC地址查表确定转发出端口

拓扑图像

p4app.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
    "p4_src": "p4src/l2_basic_forwarding.p4",
    "cli": true,
    "pcap_dump": false,
    "enable_log": false,
    "topology": {
      "assignment_strategy": "l2",
      "links": [["h1", "s1"], ["h2", "s1"], ["h3", "s1"], ["h4","s1"]],
      "hosts": {
        "h1": { },
        "h2": { },
        "h3": { },
        "h4": { }
      },
      "switches": {
        "s1": {
          "cli_input": "s1-commands.txt"
        }
      }
    }
  }

L2基本交换机

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>

/*************************************************************************
*********************** H E A D E R S  ***********************************
*************************************************************************/
typedef bit<9>  egressSpec_t;
// 定义占48个比特的链路层MAC地址
typedef bit<48> macAddr_t;
// 定义占32个比特的IP地址 该定义在本例程中未用
typedef bit<32> ip4Addr_t;

// 定义链路层header
header ethernet_t {
    macAddr_t dstAddr;
    macAddr_t srcAddr;
    bit<16>   etherType;
}

// 即使未使用到元数据 但同样需求
struct metadata {
}

// 实例化header
struct headers {
    ethernet_t   ethernet;
}

/*************************************************************************
*********************** 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解析提取到hdr中的ethernet
        packet.extract(hdr.ethernet);
		// 解析完成accept
        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() {
		// v1model提供的动作原语mark_to_drop
		// 功能是将standard_metadata.egress_spec赋值为DROP_PORT
        mark_to_drop(standard_metadata);
    }

	// 转发动作 将表中查询到的egress_port写入元数据中的转发端口
    action forward(bit<9> egress_port) {
        standard_metadata.egress_spec = egress_port;
    }

	// 定义名为dmac的表
    table dmac {
		// 精确匹配以太网头部的dstAddr字段
        key = {
            hdr.ethernet.dstAddr: exact;
        }
		// 定义动作集合
        actions = {
            forward;
            NoAction;
        }
		// 定义表的大小
        size = 256;
		// 定义默认动作
        default_action = NoAction;
    }

    apply {
		// 执行查表dmac
        dmac.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 { }
}

/*************************************************************************
***********************  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);
    }
}

/*************************************************************************
***********************  S W I T C H  *******************************
*************************************************************************/
//switch architecture
V1Switch(
    MyParser(),
    MyVerifyChecksum(),
    MyIngress(),
    MyEgress(),
    MyComputeChecksum(),
    MyDeparser()
) main;

运行测试

s1-commands.txt

1
table-add <表的名字> <动作的名字> <匹配项> => <目标端口>
1
2
3
4
table_add dmac forward 00:00:0a:00:00:01 => 1
table_add dmac forward 00:00:0a:00:00:02 => 2
table_add dmac forward 00:00:0a:00:00:03 => 3
table_add dmac forward 00:00:0a:00:00:04 => 4

Licensed under CC BY-NC-SA 4.0
皖ICP备2025083746号-1
公安备案 陕公网安备61019002003315号



使用 Hugo 构建
主题 StackJimmy 设计