Skip to content
Snippets Groups Projects
Commit 8245e259 authored by famelis's avatar famelis
Browse files

wip: timestamp p4 program

parent 3ecbf159
No related branches found
No related tags found
No related merge requests found
...@@ -71,6 +71,48 @@ def create_rule_del(endpoint_a, endpoint_b): ...@@ -71,6 +71,48 @@ def create_rule_del(endpoint_a, endpoint_b):
] ]
} }
) )
def create_int_set(endpoint_a, id):
return json_config_rule_set(
'table',
{
'table-name': 'EgressPipeImpl.int_table',
'match-fields': [
{
'match-field': 'standard_metadata.ingress_port',
'match-value': endpoint_a
}
],
'action-name': 'EgressPipeImpl.add_int_header',
'action-params': [
{
'action-param': 'swid',
'action-value': id
}
]
}
)
def create_int_del(endpoint_a, id):
return json_config_rule_delete(
'table',
{
'table-name': 'EgressPipeImpl.int_table',
'match-fields': [
{
'match-field': 'standard_metadata.ingress_port',
'match-value': endpoint_a
}
],
'action-name': 'EgressPipeImpl.add_int_header',
'action-params': [
{
'action-param': 'swid',
'action-value': id
}
]
}
)
def find_names(uuid_a, uuid_b, device_endpoints): def find_names(uuid_a, uuid_b, device_endpoints):
endpoint_a, endpoint_b = None, None endpoint_a, endpoint_b = None, None
...@@ -156,6 +198,9 @@ class P4ServiceHandler(_ServiceHandler): ...@@ -156,6 +198,9 @@ class P4ServiceHandler(_ServiceHandler):
# The other way # The other way
rule = create_rule_set(endpoint_b, endpoint_a) rule = create_rule_set(endpoint_b, endpoint_a)
device.device_config.config_rules.append(ConfigRule(**rule)) device.device_config.config_rules.append(ConfigRule(**rule))
rule = create_int_set(endpoint_a, device.name[-1])
device.device_config.config_rules.append(ConfigRule(**rule))
self.__task_executor.configure_device(device) self.__task_executor.configure_device(device)
...@@ -228,6 +273,9 @@ class P4ServiceHandler(_ServiceHandler): ...@@ -228,6 +273,9 @@ class P4ServiceHandler(_ServiceHandler):
rule = create_rule_del(endpoint_b, endpoint_a) rule = create_rule_del(endpoint_b, endpoint_a)
device.device_config.config_rules.append(ConfigRule(**rule)) device.device_config.config_rules.append(ConfigRule(**rule))
rule = create_int_del(endpoint_a, device.name[-1])
device.device_config.config_rules.append(ConfigRule(**rule))
self.__task_executor.configure_device(device) self.__task_executor.configure_device(device)
results.append(True) results.append(True)
......
#!/bin/bash
sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list
sed -i 's|security.debian.org|archive.debian.org/debian-security/|g' /etc/apt/sources.list
sed -i '/stretch-updates/d' /etc/apt/sources.list
apt update
apt install -y python-scapy
#!/usr/bin/env python3
import sys
import struct
from scapy.all import sniff, sendp, hexdump, get_if_list, get_if_hwaddr
from scapy.all import Packet, IPOption
from scapy.all import PacketListField, ShortField, IntField, LongField, BitField, FieldListField, FieldLenField
from scapy.all import IP, UDP, Raw
from scapy.layers.inet import _IPOption_HDR
def get_if():
ifs=get_if_list()
iface=None
for i in get_if_list():
if "eth0" in i:
iface=i
break
if not iface:
print("Cannot find eth0 interface")
exit(1)
return iface
class SwitchTrace(Packet):
fields_desc = [ BitField("timestamp", 0, 32)]
def extract_padding(self, p):
return "", p
class IPOption_INT(IPOption):
name = "INT"
option = 31
fields_desc = [ _IPOption_HDR,
FieldLenField("length", None, fmt="B",
length_of="int_headers",
adjust=lambda pkt,l:l*2+4),
ShortField("count", 0),
PacketListField("int_headers",
[],
SwitchTrace,
count_from=lambda pkt:(pkt.count*1)) ]
def handle_pkt(pkt):
print("got a packet")
pkt.show2()
sys.stdout.flush()
def main():
iface = 'server-eth0'
print("sniffing on %s" % iface)
sys.stdout.flush()
sniff(filter="udp and port 4321", iface = iface,
prn = lambda x: handle_pkt(x))
if __name__ == '__main__':
main()
...@@ -35,8 +35,7 @@ typedef bit<48> macAddr_t; ...@@ -35,8 +35,7 @@ typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t; typedef bit<32> ip4Addr_t;
typedef bit<13> switch_id_t; typedef bit<13> switch_id_t;
typedef bit<13> queue_depth_t; typedef bit<32> queue_depth_t;
typedef bit<6> output_port_t;
header ethernet_t { header ethernet_t {
macAddr_t dstAddr; macAddr_t dstAddr;
...@@ -72,9 +71,7 @@ header int_count_t { ...@@ -72,9 +71,7 @@ header int_count_t {
} }
header int_header_t { header int_header_t {
switch_id_t switch_id;
queue_depth_t queue_depth; queue_depth_t queue_depth;
output_port_t output_port;
} }
...@@ -206,9 +203,7 @@ control EgressPipeImpl (inout parsed_headers_t hdr, ...@@ -206,9 +203,7 @@ control EgressPipeImpl (inout parsed_headers_t hdr,
// This was not needed in older specs. Now by default pushed // This was not needed in older specs. Now by default pushed
// invalid elements are // invalid elements are
hdr.int_headers[0].setValid(); hdr.int_headers[0].setValid();
hdr.int_headers[0].switch_id = (bit<13>)swid; hdr.int_headers[0].queue_depth = (bit<32>)standard_metadata.ingress_global_timestamp;
hdr.int_headers[0].queue_depth = (bit<13>)standard_metadata.deq_timedelta;
hdr.int_headers[0].output_port = (bit<6>)standard_metadata.egress_port;
//update ip header length //update ip header length
hdr.ipv4.ihl = hdr.ipv4.ihl + 1; hdr.ipv4.ihl = hdr.ipv4.ihl + 1;
...@@ -217,11 +212,14 @@ control EgressPipeImpl (inout parsed_headers_t hdr, ...@@ -217,11 +212,14 @@ control EgressPipeImpl (inout parsed_headers_t hdr,
} }
table int_table { table int_table {
key = {
standard_metadata.ingress_port: exact;
}
actions = { actions = {
add_int_header; add_int_header;
NoAction; NoAction;
} }
default_action = NoAction(); default_action = NoAction;
} }
apply { apply {
......
/*
* Copyright 2019-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <core.p4>
#include <v1model.p4>
typedef bit<9> port_num_t;
typedef bit<48> mac_addr_t;
//------------------------------------------------------------------------------
// HEADER DEFINITIONS
//------------------------------------------------------------------------------
#define MAX_INT_HEADERS 9
const bit<16> TYPE_IPV4 = 0x800;
const bit<5> IPV4_OPTION_INT = 31;
typedef bit<9> egressSpec_t;
typedef bit<48> macAddr_t;
typedef bit<32> ip4Addr_t;
typedef bit<13> switch_id_t;
typedef bit<13> queue_depth_t;
typedef bit<6> output_port_t;
header ethernet_t {
macAddr_t dstAddr;
macAddr_t srcAddr;
bit<16> etherType;
}
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<6> dscp;
bit<2> ecn;
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;
}
header ipv4_option_t {
bit<1> copyFlag;
bit<2> optClass;
bit<5> option;
bit<8> optionLength;
}
header int_count_t {
bit<16> num_switches;
}
header int_header_t {
switch_id_t switch_id;
queue_depth_t queue_depth;
output_port_t output_port;
}
struct parser_metadata_t {
bit<16> num_headers_remaining;
}
struct local_metadata_t {
parser_metadata_t parser_metadata;
}
struct parsed_headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
ipv4_option_t ipv4_option;
int_count_t int_count;
int_header_t[MAX_INT_HEADERS] int_headers;
}
error { IPHeaderWithoutOptions }
//------------------------------------------------------------------------------
// INGRESS PIPELINE
//------------------------------------------------------------------------------
parser ParserImpl(packet_in packet,
out parsed_headers_t hdr,
inout local_metadata_t local_metadata,
inout standard_metadata_t standard_metadata) {
state start {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType){
TYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
//Check if ihl is bigger than 5. Packets without ip options set ihl to 5.
verify(hdr.ipv4.ihl >= 5, error.IPHeaderWithoutOptions);
transition select(hdr.ipv4.ihl) {
5 : accept;
default : parse_ipv4_option;
}
}
state parse_ipv4_option {
packet.extract(hdr.ipv4_option);
transition select(hdr.ipv4_option.option){
IPV4_OPTION_INT: parse_int;
default: accept;
}
}
state parse_int {
packet.extract(hdr.int_count);
local_metadata.parser_metadata.num_headers_remaining = hdr.int_count.num_switches;
transition select(local_metadata.parser_metadata.num_headers_remaining){
0: accept;
default: parse_int_headers;
}
}
state parse_int_headers {
packet.extract(hdr.int_headers.next);
local_metadata.parser_metadata.num_headers_remaining = local_metadata.parser_metadata.num_headers_remaining -1 ;
transition select(local_metadata.parser_metadata.num_headers_remaining){
0: accept;
default: parse_int_headers;
}
}
}
control VerifyChecksumImpl(inout parsed_headers_t hdr,
inout local_metadata_t meta)
{
apply { /* EMPTY */ }
}
control IngressPipeImpl (inout parsed_headers_t hdr,
inout local_metadata_t local_metadata,
inout standard_metadata_t standard_metadata) {
action drop() {
mark_to_drop(standard_metadata);
}
action set_egress_port(port_num_t port) {
standard_metadata.egress_spec = port;
}
// --- l2_exact_table ------------------
table l2_exact_table {
key = {
standard_metadata.ingress_port: exact;
}
actions = {
set_egress_port;
@defaultonly drop;
}
const default_action = drop;
}
apply {
l2_exact_table.apply();
}
}
//------------------------------------------------------------------------------
// EGRESS PIPELINE
//------------------------------------------------------------------------------
control EgressPipeImpl (inout parsed_headers_t hdr,
inout local_metadata_t local_metadata,
inout standard_metadata_t standard_metadata) {
action add_int_header(switch_id_t swid){
//increase int stack counter by one
hdr.int_count.num_switches = hdr.int_count.num_switches + 1;
hdr.int_headers.push_front(1);
// This was not needed in older specs. Now by default pushed
// invalid elements are
hdr.int_headers[0].setValid();
hdr.int_headers[0].switch_id = (bit<13>)swid;
hdr.int_headers[0].queue_depth = (bit<13>)standard_metadata.deq_qdepth;
hdr.int_headers[0].output_port = (bit<6>)standard_metadata.egress_port;
//update ip header length
hdr.ipv4.ihl = hdr.ipv4.ihl + 1;
hdr.ipv4.totalLen = hdr.ipv4.totalLen + 4;
hdr.ipv4_option.optionLength = hdr.ipv4_option.optionLength + 4;
}
table int_table {
key = {
standard_metadata.ingress_port: exact;
}
actions = {
add_int_header;
NoAction;
}
default_action = NoAction;
}
apply {
if (hdr.int_count.isValid()){
int_table.apply();
}
}
}
control ComputeChecksumImpl(inout parsed_headers_t hdr,
inout local_metadata_t local_metadata)
{
apply {
update_checksum(
hdr.ipv4.isValid(),
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.dscp,
hdr.ipv4.ecn,
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);
}
}
control DeparserImpl(packet_out packet, in parsed_headers_t hdr) {
apply {
//parsed headers have to be added again into the packet.
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
packet.emit(hdr.ipv4_option);
packet.emit(hdr.int_count);
packet.emit(hdr.int_headers);
}
}
V1Switch(
ParserImpl(),
VerifyChecksumImpl(),
IngressPipeImpl(),
EgressPipeImpl(),
ComputeChecksumImpl(),
DeparserImpl()
) main;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment