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

Add pipeline definition #2

Merged
merged 1 commit into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions sirius-pipeline/sirius_acl.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef _SIRIUS_ACL_P4_
#define _SIRIUS_ACL_P4_

#include "sirius_headers.p4"

match_kind {
/* list of ternary values
A/A_len,B/_B-len,...
if empty, then don't care
*/
list,
/* Also possibly range_list - a-b,c-d,... */
range_list
}

#define ACL_STAGE(table_name) \
direct_counter(CounterType.packets_and_bytes) ## table_name ##_counter; \
table table_name { \
key = { \
meta.eni : exact @name("meta.eni:eni"); \
hdr.ipv4.dst_addr : list @name("hdr.ipv4.dst_addr:dip"); \
hdr.ipv4.src_addr : list @name("hdr.ipv4.src_addr:sip"); \
hdr.ipv4.protocol : list @name("hdr.ipv4.src_addr:protocol"); \
hdr.tcp.src_port : range_list @name("hdr.tcp.src_port:sport"); \
hdr.tcp.dst_port : range_list @name("hdr.tcp.dst_port:dport"); \
} \
actions = { \
permit; \
permit_and_continue; \
deny; \
deny_and_continue; \
} \
default_action = deny; \
counters = ## table_name ##_counter; \
}

#define ACL_STAGE_APPLY(table_name) \
switch (table_name.apply().action_run) { \
permit: {return;} \
deny: {return;} \
}

/*
* This control results in a new set of tables every time
* it is applied, i. e. inbound ACL tables are different
* from outbound, and API will be generated for each of them
*/
control acl(inout headers_t hdr,
inout metadata_t meta,
inout standard_metadata_t standard_metadata)
{
action permit() {}
action permit_and_continue() {}
action deny() {meta.dropped = true;}
action deny_and_continue() {meta.dropped = true;}

ACL_STAGE(stage1)
ACL_STAGE(stage2)
ACL_STAGE(stage3)

apply {
ACL_STAGE_APPLY(stage1)
ACL_STAGE_APPLY(stage2)
ACL_STAGE_APPLY(stage3)
}
}
#endif /* _SIRIUS_ACL_P4_ */
81 changes: 81 additions & 0 deletions sirius-pipeline/sirius_conntrack.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef _SIRIUS_CONNTRACK_P4_
#define _SIRIUS_CONNTRACK_P4_

#include "sirius_headers.p4"

#ifdef STATEFUL_P4

state_context ConntrackCtx {
}

state_graph ConnGraphOut(inout state_context flow_ctx,
in headers_t headers,
in standard_metadata_t standard_metadata)
{
state START {
/* Only for new connections */
if (!headers.tcp.isValid() || headers.tcp.flags != 0x2 /* SYN */) {
return;
}

if (meta.direction == INBOUND) {
transition ALLOW;
}
}

state ALLOW {
meta.conntrack_data.allow_out = true;

/* Remove connection based on TCP flags */
if (headers.tcp.flags & 0x101 /* FIN/RST */) {
transition START;
}
}
}

state_graph ConnGraphIn(inout state_context flow_ctx,
in headers_t headers,
in standard_metadata_t standard_metadata)
{
state START {
/* Only for new connections */
if (!headers.tcp.isValid() || headers.tcp.flags != 0x2 /* SYN */) {
return;
}

if (meta.direction == OUTBOUND) {
transition ALLOW;
}
}

state ALLOW {
meta.conntrack_data.allow_in = true;

/* Remove connection based on TCP flags */
if (headers.tcp.flags & 0x101 /* FIN/RST */) {
transition START;
}
}
}

state_table ConntrackOut
{
flow_key[0] = {hdr.ipv4.src, hdr.ipv4.dst , hdr.ipv4.proto, hdr.l4.src_port, hdr.l4.dst_port, meta.eni};
flow_key[1] = {hdr.ipv4.dst, hdr.ipv4.src , hdr.ipv4.proto, hdr.l4.dst_port, hdr.l4.src_port, meta.eni};
eviction_policy = LRU;
context = ConntrackCtx;
graph = ConnGraphOut(ConntrackCtx, hdr, standard_metadata);
}

state_table ConntrackIn
{
flow_key[0] = {hdr.ipv4.src, hdr.ipv4.dst , hdr.ipv4.proto, hdr.l4.src_port, hdr.l4.dst_port, meta.eni};
flow_key[1] = {hdr.ipv4.dst, hdr.ipv4.src , hdr.ipv4.proto, hdr.l4.dst_port, hdr.l4.src_port, meta.eni};
eviction_policy = LRU;
context = ConntrackCtx;
graph = ConnGraphIn(ConntrackCtx, hdr, standard_metadata);
}

#endif /* STATEFUL_P4 */

#endif /* _SIRIUS_CONNTRACK_P4_ */
94 changes: 94 additions & 0 deletions sirius-pipeline/sirius_headers.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#ifndef _SIRIUS_HEADERS_P4_
#define _SIRIUS_HEADERS_P4_

typedef bit<48> EthernetAddress;
typedef bit<32> IPv4Address;
typedef bit<128> IPv6Address;

header ethernet_t {
EthernetAddress dst_addr;
EthernetAddress src_addr;
bit<16> ether_type;
}

const bit<16> ETHER_HDR_SIZE=112/8;

header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> total_len;
bit<16> identification;
bit<3> flags;
bit<13> frag_offset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdr_checksum;
IPv4Address src_addr;
IPv4Address dst_addr;
}

const bit<16> IPV4_HDR_SIZE=160/8;

header udp_t {
bit<16> src_port;
bit<16> dst_port;
bit<16> length;
bit<16> checksum;
}

const bit<16> UDP_HDR_SIZE=64/8;

header vxlan_t {
bit<8> flags;
bit<24> reserved;
bit<24> vni;
bit<8> reserved_2;
}

const bit<16> VXLAN_HDR_SIZE=64/8;

header tcp_t {
bit<16> src_port;
bit<16> dst_port;
bit<32> seq_no;
bit<32> ack_no;
bit<4> data_offset;
bit<3> res;
bit<3> ecn;
bit<6> flags;
bit<16> window;
bit<16> checksum;
bit<16> urgent_ptr;
}

const bit<16> TCP_HDR_SIZE=160/8;

header ipv6_t {
bit<4> version;
bit<8> traffic_class;
bit<20> flow_label;
bit<16> payload_length;
bit<8> next_header;
bit<8> hop_limit;
IPv6Address src_addr;
IPv6Address dst_addr;
}

const bit<16> IPV6_HDR_SIZE=320/8;

struct headers_t {
ethernet_t ethernet;
ipv4_t ipv4;
ipv6_t ipv6;
udp_t udp;
tcp_t tcp;
vxlan_t vxlan;
ethernet_t inner_ethernet;
ipv4_t inner_ipv4;
ipv6_t inner_ipv6;
udp_t inner_udp;
tcp_t inner_tcp;
}

#endif /* _SIRIUS_HEADERS_P4_ */
91 changes: 91 additions & 0 deletions sirius-pipeline/sirius_inbound.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#ifndef _SIRIUS_INBOUND_P4_
#define _SIRIUS_INBOUND_P4_

#include "sirius_headers.p4"
#include "sirius_service_tunnel.p4"
#include "sirius_vxlan.p4"
#include "sirius_acl.p4"

control inbound(inout headers_t hdr,
inout metadata_t meta,
inout standard_metadata_t standard_metadata)
{
action set_eni(bit<16> eni) {
meta.eni = eni;
}

table eni_lookup_to_vm {
key = {
hdr.ethernet.dst_addr : exact @name("hdr.ethernet.dst_addr:dmac");
}

actions = {
set_eni;
}
}

action set_vm_attributes(EthernetAddress underlay_dmac,
IPv4Address underlay_dip,
bit<24> vni) {
meta.encap_data.underlay_dmac = underlay_dmac;
meta.encap_data.underlay_dip = underlay_dip;
meta.encap_data.vni = vni;
}

action set_vm_id(bit<16> vm_id) {
meta.vm_id = vm_id;
}

table eni_to_vm {
key = {
meta.eni: exact @name("meta.eni:eni");
}

actions = {
set_vm_id;
}
}

table vm {
key = {
meta.vm_id: exact @name("meta.vm_id:vm_id");
}

actions = {
set_vm_attributes;
}
}

apply {
eni_lookup_to_vm.apply();

eni_to_vm.apply();

vm.apply();

/* Check if PA is valid */

#ifdef STATEFUL_P4
ConntrackIn.apply(0);
#endif /* STATEFUL_P4 */

/* ACL */
if (meta.conntrack_data.allow_in) {
acl.apply(hdr, meta, standard_metadata);
}

#ifdef STATEFUL_P4
ConntrackOut.apply(1);
#endif /* STATEFUL_P4 */

vxlan_encap(hdr,
meta.encap_data.underlay_dmac,
meta.encap_data.underlay_smac,
meta.encap_data.underlay_dip,
meta.encap_data.underlay_sip,
hdr.ethernet.dst_addr,
meta.encap_data.vni);
}
}

#endif /* _SIRIUS_INBOUND_P4_ */
37 changes: 37 additions & 0 deletions sirius-pipeline/sirius_metadata.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef _SIRIUS_METADATA_P4_
#define _SIRIUS_METADATA_P4_

#include "sirius_headers.p4"

struct encap_data_t {
bit<24> vni;
bit<24> dest_vnet_vni;
IPv4Address underlay_sip;
IPv4Address underlay_dip;
EthernetAddress underlay_smac;
EthernetAddress underlay_dmac;
EthernetAddress overlay_dmac;
}

enum direction_t {
INVALID,
OUTBOUND,
INBOUND
}

struct conntrack_data_t {
bool allow_in;
bool allow_out;
}

struct metadata_t {
bool dropped;
direction_t direction;
encap_data_t encap_data;
bit<16> eni;
bit<16> vm_id;
bit<8> appliance_id;
conntrack_data_t conntrack_data;
}

#endif /* _SIRIUS_METADATA_P4_ */
Loading