// NOTE: new type added here const bit<16> TYPE_MYTUNNEL = 0x1212; const bit<16> TYPE_IPV4 = 0x800;
/************************************************************************* *********************** H E A D E R S *********************************** *************************************************************************/
/************************************************************************* *********************** P A R S E R *********************************** *************************************************************************/
// TODO: Update the parser to parse the myTunnel header as well parser MyParser(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
/************************************************************************* *********************** P A R S E R *********************************** *************************************************************************/
// TODO: Update the parser to parse the myTunnel header as well parser MyParser(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
/************************************************************************* ************ C H E C K S U M V E R I F I C A T I O N ************* *************************************************************************/
/************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* *************************************************************************/
/************************************************************************* ************ C H E C K S U M V E R I F I C A T I O N ************* *************************************************************************/
/************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* *************************************************************************/
match_kind { //检查是否值在一个范围里,比如取 0x01020304 - 0x010203FF 之间的值 range, // Either an exact match, or a wildcard (matching any value).精准匹配或者通配 optional, // Used for implementing dynamic_action_selection 用于实现dynamic_action_selection selector }
/************************************************************************* **************** E G R E S S P R O C E S S I N G ******************* *************************************************************************/
/************************************************************************* ************* C H E C K S U M C O M P U T A T I O N ************** *************************************************************************/
/************************************************************************* *********************** D E P A R S E R ******************************* *************************************************************************/
control MyDeparser(packet_out packet, in headers hdr) { apply { packet.emit(hdr.ethernet); // TODO: emit myTunnel header as well packet.emit(hdr.ipv4); } }
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13
/************************************************************************* *********************** D E P A R S E R ******************************* *************************************************************************/
control MyDeparser(packet_out packet, in headers hdr) { apply { packet.emit(hdr.ethernet); // TODO: emit myTunnel header as well packet.emit(hdr.myTunnel); packet.emit(hdr.ipv4); } }
实例化部分:
1 2 3 4 5 6 7 8 9 10 11 12
/************************************************************************* *********************** S W I T C H ******************************* *************************************************************************/
from scapy.all import sendp, send, get_if_list, get_if_hwaddr, hexdump from scapy.all import Packet from scapy.all import Ether, IP, UDP, TCP from myTunnel_header import MyTunnel
defget_if(): ifs=get_if_list() # # type: () -> List[str] """Return a list of interface names""",返回接口(网卡)名字 iface=None# "h1-eth0" for i in get_if_list(): if"eth0"in i: iface=i break; ifnot iface: print"Cannot find eth0 interface" exit(1) return iface
defmain(): parser = argparse.ArgumentParser()#argsparse是python的命令行解析的标准模块,相当于就是解析./send.py后面的参数 parser.add_argument('ip_addr', type=str, help="The destination IP address to use")#type是要传入的参数的数据类型 help是该参数的提示信息,使用python send.py -h可以看到 parser.add_argument('message', type=str, help="The message to include in packet") parser.add_argument('--dst_id', type=int, default=None, help='The myTunnel dst_id to use, if unspecified then myTunnel header will not be included in packet') args = parser.parse_args()##获得传入的参数
#!/usr/bin/env python import sys import struct import os
from scapy.all import sniff, sendp, hexdump, get_if_list, get_if_hwaddr from scapy.all import Packet, IPOption from scapy.all import ShortField, IntField, LongField, BitField, FieldListField, FieldLenField from scapy.all import IP, TCP, UDP, Raw from scapy.layers.inet import _IPOption_HDR from myTunnel_header import MyTunnel
defget_if():# 获得网卡接口 ifs=get_if_list() iface=None for i in get_if_list(): if"eth0"in i: iface=i break; ifnot iface: print"Cannot find eth0 interface" exit(1) return iface
defhandle_pkt(pkt): if MyTunnel in pkt or (TCP in pkt and pkt[TCP].dport == 1234): print"got a packet" pkt.show2() # hexdump(pkt) # print "len(pkt) = ", len(pkt) sys.stdout.flush()
In this exercise, we will add support for a basic tunneling protocol to the IP router that you completed in the previous assignment. The basic switch forwards based on the destination IP address. Your jobs is to define a new header type to encapsulate the IP packet and modify the switch code, so that it instead decides the destination port using a new tunnel header.
The new header type will contain a protocol ID, which indicates the type of packet being encapsulated, along with a destination ID to be used for routing.
Spoiler alert: There is a reference solution in the solution sub-directory. Feel free to compare your implementation to the reference.
The starter code for this assignment is in a file called basic_tunnel.p4 and is simply the solution to the IP router from the previous exercise.
A note about the control plane
A P4 program defines a packet-processing pipeline, but the rules within each table are inserted by the control plane. When a rule matches a packet, its action is invoked with parameters supplied by the control plane as part of the rule.
For this exercise, we have already added the necessary static control plane entries. As part of bringing up the Mininet instance, the make run command will install packet-processing rules in the tables of each switch. These are defined in the sX-runtime.json files, where X corresponds to the switch number.
Since the control plane tries to access the myTunnel_exact table, and that table does not yet exist, the make run command will not work with the starter code.
Important: We use P4Runtime to install the control plane rules. The content of files sX-runtime.json refer to specific names of tables, keys, and actions, as defined in the P4Info file produced by the compiler (look for the file build/basic.p4info after executing make run). Any changes in the P4 program that add or rename tables, keys, or actions will need to be reflected in these sX-runtime.json files.