From 3704a7c310f3f1fb0650f5b968c27ae3cd13deaa Mon Sep 17 00:00:00 2001 From: mukeshmv Date: Tue, 24 May 2022 19:06:07 +0000 Subject: [PATCH] Normalize Sirius P4 pipeline tables --- SAI/sai_api_gen.py | 32 +++--- sirius-pipeline/Makefile | 4 +- sirius-pipeline/bmv2/sirius_acl.p4 | 14 +-- sirius-pipeline/bmv2/sirius_inbound.p4 | 82 -------------- sirius-pipeline/bmv2/sirius_metadata.p4 | 8 ++ sirius-pipeline/bmv2/sirius_outbound.p4 | 51 +-------- sirius-pipeline/bmv2/sirius_pipeline.p4 | 137 ++++++++++++++++++++---- 7 files changed, 154 insertions(+), 174 deletions(-) delete mode 100644 sirius-pipeline/bmv2/sirius_inbound.p4 diff --git a/SAI/sai_api_gen.py b/SAI/sai_api_gen.py index eaf8638e8..7fc5802a5 100755 --- a/SAI/sai_api_gen.py +++ b/SAI/sai_api_gen.py @@ -13,6 +13,7 @@ PIPELINES_TAG = 'pipelines' NAME_TAG = 'name' INGRESS_PIPE = 'ingress' +EGRESS_PIPE = 'egress' TABLES_TAG = 'tables' KEY_TAG = 'key' @@ -23,14 +24,18 @@ def get_ingress_pipeline(json_program): return None +def get_egress_pipeline(json_program): + for pipe in json_program[PIPELINES_TAG]: + if pipe[NAME_TAG] == EGRESS_PIPE: + return pipe -def get_tables(ingress_pipeline): - tables = [] - for table in ingress_pipeline[TABLES_TAG]: + return None + + +def get_tables(tables, pipeline): + for table in pipeline[TABLES_TAG]: if len(table[KEY_TAG]) > 0: tables.append(table) - - return tables def get_sai_key_type(key_size, key_header, key_field): @@ -135,7 +140,9 @@ def get_sai_action_data(program, action_name): def generate_sai_api(program, ignore_tables): sai_api = dict() - tables = get_tables(get_ingress_pipeline(program)) + tables = [] + get_tables(tables, get_ingress_pipeline(program)) + get_tables(tables, get_egress_pipeline(program)) sai_tables = [] for table in tables: sai_table_data = dict() @@ -271,10 +278,6 @@ def write_sai_files(sai_api): exit(1) -if os.path.exists('./SAI'): - print('Directory ./SAI already exists. Please remove in order to proceed') - exit(1) - # Get SAI dictionary from P4 dictionary print("Generating SAI API...") with open(args.filepath) as json_program_file: @@ -283,9 +286,12 @@ def write_sai_files(sai_api): sai_api = generate_sai_api(json_program, args.ignore_tables.split(',')) sai_api['app_name'] = args.apiname -# Clone a clean SAI repo -print("Cloning SAI repository...") -Repo.clone_from(args.sai_git_url, './SAI', branch=args.sai_git_branch) +if os.path.exists('./SAI'): + print('Directory ./SAI already exists.') +else: + # Clone a clean SAI repo + print("Cloning SAI repository...") + Repo.clone_from(args.sai_git_url, './SAI', branch=args.sai_git_branch) # Write SAI dictionary into SAI API headers write_sai_files(sai_api) diff --git a/sirius-pipeline/Makefile b/sirius-pipeline/Makefile index e2c78c2d3..9b19c637f 100644 --- a/sirius-pipeline/Makefile +++ b/sirius-pipeline/Makefile @@ -11,14 +11,14 @@ DOCKER_RUN := docker run \ --rm \ bmv2-$(USER) -bmv2/sirius_pipeline.bmv2/sirius_pipeline.json: +bmv2/sirius_pipeline.bmv2/sirius_pipeline.json: bmv2/*.p4 $(DOCKER_RUN) p4c -b bmv2 bmv2/sirius_pipeline.p4 -o bmv2/sirius_pipeline.bmv2 clean: rm -rf bmv2/sirius_pipeline.bmv2 run-switch: - $(DOCKER_RUN) simple_switch --log-console --interface 0@veth0 --interface 1@veth2 /bmv2/sirius_pipeline.bmv2/sirius_pipeline.json + $(DOCKER_RUN) sudo LD_LIBRARY_PATH=/usr/local/lib simple_switch --log-console --interface 0@veth0 --interface 1@veth2 /bmv2/sirius_pipeline.bmv2/sirius_pipeline.json docker: docker build \ diff --git a/sirius-pipeline/bmv2/sirius_acl.p4 b/sirius-pipeline/bmv2/sirius_acl.p4 index 67c5210e8..91383b481 100644 --- a/sirius-pipeline/bmv2/sirius_acl.p4 +++ b/sirius-pipeline/bmv2/sirius_acl.p4 @@ -17,12 +17,12 @@ match_kind { 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"); \ + meta. ## table_name ##_acl_group_id : exact @name("meta.acl_group_id:acl_group_id"); \ + hdr.ipv4.dst_addr : optional @name("hdr.ipv4.dst_addr:dip"); \ + hdr.ipv4.src_addr : optional @name("hdr.ipv4.src_addr:sip"); \ + hdr.ipv4.protocol : optional @name("hdr.ipv4.src_addr:protocol"); \ + hdr.tcp.src_port : optional @name("hdr.tcp.src_port:sport"); \ + hdr.tcp.dst_port : optional @name("hdr.tcp.dst_port:dport"); \ } \ actions = { \ permit; \ @@ -40,7 +40,7 @@ match_kind { 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 diff --git a/sirius-pipeline/bmv2/sirius_inbound.p4 b/sirius-pipeline/bmv2/sirius_inbound.p4 deleted file mode 100644 index 7d0677112..000000000 --- a/sirius-pipeline/bmv2/sirius_inbound.p4 +++ /dev/null @@ -1,82 +0,0 @@ -#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" -#include "sirius_conntrack.p4" - -control inbound(inout headers_t hdr, - inout metadata_t meta, - inout standard_metadata_t standard_metadata) -{ - 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_to_vm.apply(); - - vm.apply(); - - /* Check if PA is valid */ - -#ifdef STATEFUL_P4 - ConntrackIn.apply(0); -#endif /* STATEFUL_P4 */ -#ifdef PNA_CONNTRACK - ConntrackIn.apply(hdr, meta); -#endif // PNA_CONNTRACK - - /* ACL */ - if (!meta.conntrack_data.allow_in) { - acl.apply(hdr, meta, standard_metadata); - } - -#ifdef STATEFUL_P4 - ConntrackOut.apply(1); -#endif /* STATEFUL_P4 */ -#ifdef PNA_CONNTRACK - ConntrackOut.apply(hdr, meta); -#endif //PNA_CONNTRACK - - 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_ */ diff --git a/sirius-pipeline/bmv2/sirius_metadata.p4 b/sirius-pipeline/bmv2/sirius_metadata.p4 index a5773d8ec..f88334d62 100644 --- a/sirius-pipeline/bmv2/sirius_metadata.p4 +++ b/sirius-pipeline/bmv2/sirius_metadata.p4 @@ -30,6 +30,14 @@ struct metadata_t { encap_data_t encap_data; EthernetAddress eni_addr; bit<16> eni; + bit<16> stage1_acl_group_id; + bit<16> stage2_acl_group_id; + bit<16> stage3_acl_group_id; + bit<16> acl_group_id; + bit<16> route_table_id; + bit<16> tunnel_id; + bit<16> vnet; + bit<24> lookup_vni; bit<16> vm_id; bit<8> appliance_id; bit<1> is_dst_ip_v6; diff --git a/sirius-pipeline/bmv2/sirius_outbound.p4 b/sirius-pipeline/bmv2/sirius_outbound.p4 index 70d300a57..2ed340553 100644 --- a/sirius-pipeline/bmv2/sirius_outbound.p4 +++ b/sirius-pipeline/bmv2/sirius_outbound.p4 @@ -2,27 +2,11 @@ #define _SIRIUS_OUTBOUND_P4_ #include "sirius_headers.p4" -#include "sirius_acl.p4" -#include "sirius_conntrack.p4" control outbound(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) { - action set_vni(bit<24> vni) { - meta.encap_data.vni = vni; - } - - table eni_to_vni { - key = { - meta.eni : exact @name("meta.eni:eni"); - } - - actions = { - set_vni; - } - } - action route_vnet(bit<24> dest_vnet_vni) { meta.encap_data.dest_vnet_vni = dest_vnet_vni; } @@ -43,7 +27,7 @@ control outbound(inout headers_t hdr, counters = routing_counter; } - action set_tunnel_mapping(IPv4Address underlay_dip, + action set_tunnel_mapping(bit<16> tunnel_id, EthernetAddress overlay_dmac, bit<1> use_dst_vni) { /* @@ -54,7 +38,7 @@ control outbound(inout headers_t hdr, */ meta.encap_data.vni = meta.encap_data.vni * (bit<24>)(~use_dst_vni) + meta.encap_data.dest_vnet_vni * (bit<24>)use_dst_vni; meta.encap_data.overlay_dmac = overlay_dmac; - meta.encap_data.underlay_dip = underlay_dip; + meta.tunnel_id = tunnel_id; } direct_counter(CounterType.packets_and_bytes) ca_to_pa_counter; @@ -75,40 +59,9 @@ control outbound(inout headers_t hdr, } apply { - eni_to_vni.apply(); - -#ifdef STATEFUL_P4 - ConntrackOut.apply(0); -#endif /* STATEFUL_P4 */ - -#ifdef PNA_CONNTRACK - ConntrackOut.apply(hdr, meta); -#endif // PNA_CONNTRACK - - /* ACL */ - if (!meta.conntrack_data.allow_out) { - acl.apply(hdr, meta, standard_metadata); - } - -#ifdef STATEFUL_P4 - ConntrackIn.apply(1); -#endif /* STATEFUL_P4 */ - -#ifdef PNA_CONNTRACK - ConntrackIn.apply(hdr, meta); -#endif // PNA_CONNTRACK - switch (routing.apply().action_run) { route_vnet: { ca_to_pa.apply(); - - vxlan_encap(hdr, - meta.encap_data.underlay_dmac, - meta.encap_data.underlay_smac, - meta.encap_data.underlay_dip, - meta.encap_data.underlay_sip, - meta.encap_data.overlay_dmac, - meta.encap_data.vni); } } } diff --git a/sirius-pipeline/bmv2/sirius_pipeline.p4 b/sirius-pipeline/bmv2/sirius_pipeline.p4 index 19bfcd93f..a73a966d6 100644 --- a/sirius-pipeline/bmv2/sirius_pipeline.p4 +++ b/sirius-pipeline/bmv2/sirius_pipeline.p4 @@ -5,8 +5,8 @@ #include "sirius_parser.p4" #include "sirius_vxlan.p4" #include "sirius_outbound.p4" -#include "sirius_inbound.p4" #include "sirius_conntrack.p4" +#include "sirius_acl.p4" control sirius_verify_checksum(inout headers_t hdr, inout metadata_t meta) @@ -75,36 +75,58 @@ control sirius_ingress(inout headers_t hdr, } action permit() { - meta.dropped = false; } action deny() { meta.dropped = true; } - table inbound_routing { + table vnet { key = { - hdr.vxlan.vni : exact @name("hdr.vxlan.vni:vni"); + meta.lookup_vni : exact @name("meta.lookup_vni:vni"); } actions = { - vxlan_decap(hdr); + permit; @defaultonly deny; } const default_action = deny; } - action set_eni(bit<16> eni) { + action set_eni_attributes(bit<16> eni, + bit<24> vni, + bit<16> stage1_outbound_acl_group_id, + bit<16> stage1_inbound_acl_group_id, + bit<16> stage2_outbound_acl_group_id, + bit<16> stage2_inbound_acl_group_id, + bit<16> stage3_outbound_acl_group_id, + bit<16> stage3_inbound_acl_group_id, + bit<16> route_table_id, + bit<16> vnet_id, + bit<16> tunnel_id) { meta.eni = eni; + meta.encap_data.vni = vni; + if (meta.direction == direction_t.OUTBOUND) { + meta.stage1_acl_group_id = stage1_outbound_acl_group_id; + meta.stage2_acl_group_id = stage2_outbound_acl_group_id; + meta.stage3_acl_group_id = stage3_outbound_acl_group_id; + } else { + meta.stage1_acl_group_id = stage1_inbound_acl_group_id; + meta.stage2_acl_group_id = stage2_inbound_acl_group_id; + meta.stage3_acl_group_id = stage3_inbound_acl_group_id; + } + meta.route_table_id = route_table_id; + meta.vnet = vnet_id; + meta.tunnel_id = tunnel_id; } - table eni_ether_address_map { + table eni { key = { - meta.eni_addr : exact @name("meta.eni_addr:address"); + meta.eni_addr : exact @name("meta.eni_addr:eni_addr"); } actions = { - set_eni; + set_eni_attributes; } } @@ -114,12 +136,10 @@ control sirius_ingress(inout headers_t hdr, appliance.apply(); /* Outer header processing */ + meta.lookup_vni = hdr.vxlan.vni; + vxlan_decap(hdr); - if (meta.direction == direction_t.OUTBOUND) { - vxlan_decap(hdr); - } else if (meta.direction == direction_t.INBOUND) { - inbound_routing.apply(); - } + /* At this point the processing is done on customer headers */ meta.dst_ip_addr = 0; meta.is_dst_ip_v6 = 0; @@ -130,24 +150,71 @@ control sirius_ingress(inout headers_t hdr, meta.dst_ip_addr = (bit<128>)hdr.ipv4.dst_addr; } - /* At this point the processing is done on customer headers */ - /* Put VM's MAC in the direction agnostic metadata field */ meta.eni_addr = meta.direction == direction_t.OUTBOUND ? hdr.ethernet.src_addr : hdr.ethernet.dst_addr; - eni_ether_address_map.apply(); + eni.apply(); if (meta.direction == direction_t.OUTBOUND) { - outbound.apply(hdr, meta, standard_metadata); + meta.lookup_vni = meta.encap_data.vni; + } + vnet.apply(); + + if (meta.direction == direction_t.OUTBOUND) { +#ifdef STATEFUL_P4 + ConntrackOut.apply(0); +#endif /* STATEFUL_P4 */ + +#ifdef PNA_CONNTRACK + ConntrackOut.apply(hdr, meta); +#endif // PNA_CONNTRACK + } else { +#ifdef STATEFUL_P4 + ConntrackIn.apply(0); +#endif /* STATEFUL_P4 */ +#ifdef PNA_CONNTRACK + ConntrackIn.apply(hdr, meta); +#endif // PNA_CONNTRACK + } + + /* ACL */ + if (!meta.conntrack_data.allow_out) { + acl.apply(hdr, meta, standard_metadata); + } + + if (meta.direction == direction_t.OUTBOUND) { +#ifdef STATEFUL_P4 + ConntrackIn.apply(1); +#endif /* STATEFUL_P4 */ + +#ifdef PNA_CONNTRACK + ConntrackIn.apply(hdr, meta); +#endif // PNA_CONNTRACK } else if (meta.direction == direction_t.INBOUND) { - inbound.apply(hdr, meta, standard_metadata); +#ifdef STATEFUL_P4 + ConntrackOut.apply(1); +#endif /* STATEFUL_P4 */ +#ifdef PNA_CONNTRACK + ConntrackOut.apply(hdr, meta); +#endif //PNA_CONNTRACK + + } + + if (meta.direction == direction_t.OUTBOUND) { + outbound.apply(hdr, meta, standard_metadata); + } else { + meta.encap_data.overlay_dmac = hdr.ethernet.dst_addr; } eni_meter.apply(); /* Send packet to port 1 by default if we reached the end of pipeline */ - standard_metadata.egress_spec = 1; + if (meta.dropped) { + drop_action(); + } else { + standard_metadata.egress_spec = 1; + } } } @@ -155,7 +222,35 @@ control sirius_egress(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t standard_metadata) { - apply { } + action set_tunnel_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; + } + + table tunnel { + key = { + meta.tunnel_id: exact @name("meta.tunnel_id:tunnel_id"); + } + + actions = { + set_tunnel_attributes; + } + } + + apply { + tunnel.apply(); + + vxlan_encap(hdr, + meta.encap_data.underlay_dmac, + meta.encap_data.underlay_smac, + meta.encap_data.underlay_dip, + meta.encap_data.underlay_sip, + meta.encap_data.overlay_dmac, + meta.encap_data.vni); + } } V1Switch(sirius_parser(),