Added tor.p4 to p4src
Change-Id: I8c3a02dee76cbe45e0f9a4f7ca1f93a6f1d8a016
diff --git a/tools/test/p4src/tor/l3_fwd.p4 b/tools/test/p4src/tor/l3_fwd.p4
new file mode 100644
index 0000000..b5b8aa6
--- /dev/null
+++ b/tools/test/p4src/tor/l3_fwd.p4
@@ -0,0 +1,194 @@
+// Copyright (c) 2017, Google Inc.
+//
+// P4_16 specification for a L3 forwarding app.
+// Note: This code has not been tested and is expected to contain bugs.
+
+#ifndef P4_SPEC_L3_FWD_P4_
+#define P4_SPEC_L3_FWD_P4_
+
+#include "headers.p4"
+#include "parser.p4"
+
+#ifdef P4_EXPLICIT_LAG
+#include "lag.p4"
+#endif
+
+//------------------------------------------------------------------------------
+// IPv4/v6 L3 Forwarding
+//------------------------------------------------------------------------------
+
+control l3_fwd(inout parsed_packet_t hdr,
+ inout local_metadata_t local_metadata,
+ inout standard_metadata_t standard_metadata) {
+
+
+ @proto_package("l3_fwd")
+ action set_nexthop(@proto_tag(1) PortNum port,
+ @proto_tag(2) EthernetAddress smac,
+ @proto_tag(3) EthernetAddress dmac) {
+ standard_metadata.egress_spec = port;
+ hdr.ethernet.src_addr = smac;
+ hdr.ethernet.dst_addr = dmac;
+ // if (hdr.ipv4_base.isValid()) {
+ hdr.ipv4_base.ttl = hdr.ipv4_base.ttl - 1;
+ // } else if (hdr.ipv6_base.isValid()) {
+ // hdr.ipv6_base.hop_limit = hdr.ipv6_base.hop_limit - 1;
+ // }
+ }
+
+ // Hit implies that the packet needs to be L3 forwarded.
+ // Equivalent of BCM MY_STATION table
+ @proto_package("l3_fwd")
+ table l3_routing_classifier_table {
+ key = {
+ hdr.ethernet.dst_addr : exact @proto_tag(1);
+ }
+ actions = {
+ @proto_tag(1) NoAction;
+ }
+ const default_action = NoAction();
+ }
+
+ action_selector(HashAlgorithm.crc16, 32w1024, 32w14) wcmp_action_profile;
+
+ // LPM forwarding tables for IPV4 packets.
+ @proto_package("l3_fwd")
+ table l3_ipv4_override_table {
+ key = {
+ hdr.ipv4_base.dst_addr : lpm @proto_tag(1);
+
+ hdr.ipv4_base.dst_addr : selector @proto_tag(2);
+ hdr.ipv4_base.src_addr : selector @proto_tag(3);
+ hdr.ipv4_base.protocol : selector @proto_tag(4);
+ local_metadata.l4_src_port : selector @proto_tag(5);
+ local_metadata.l4_dst_port : selector @proto_tag(6);
+ }
+ actions = {
+ @proto_tag(1) set_nexthop;
+ @proto_tag(2) NoAction;
+ }
+ const default_action = NoAction();
+ // TODO(samarabdi): do we need to specify selector size?
+ implementation = wcmp_action_profile;
+ }
+
+ @proto_package("l3_fwd")
+ table l3_ipv4_vrf_table {
+ key = {
+ local_metadata.vrf_id: exact @proto_tag(1);
+ hdr.ipv4_base.dst_addr : lpm @proto_tag(2);
+ hdr.ipv4_base.dst_addr : selector @proto_tag(3);
+ hdr.ipv4_base.src_addr : selector @proto_tag(4);
+ hdr.ipv4_base.protocol : selector @proto_tag(5);
+ local_metadata.l4_src_port : selector @proto_tag(6);
+ local_metadata.l4_dst_port : selector @proto_tag(7);
+ }
+ actions = {
+ @proto_tag(1) set_nexthop;
+ @proto_tag(2) NoAction;
+ }
+ const default_action = NoAction();
+ implementation = wcmp_action_profile;
+ }
+
+ @proto_package("l3_fwd")
+ table l3_ipv4_fallback_table {
+ key = {
+ hdr.ipv4_base.dst_addr : lpm @proto_tag(1);
+ hdr.ipv4_base.dst_addr : selector @proto_tag(2);
+ hdr.ipv4_base.src_addr : selector @proto_tag(3);
+ hdr.ipv4_base.protocol : selector @proto_tag(4);
+ local_metadata.l4_src_port : selector @proto_tag(5);
+ local_metadata.l4_dst_port : selector @proto_tag(6);
+ }
+ actions = {
+ @proto_tag(1) set_nexthop;
+ @proto_tag(2) NoAction;
+ }
+ const default_action = NoAction();
+ implementation = wcmp_action_profile;
+ }
+
+ // LPM forwarding tables for IPV6 packets.
+
+ // @proto_package("l3_fwd")
+ // table l3_ipv6_override_table {
+ // key = {
+ // hdr.ipv6_base.dst_addr : lpm @proto_tag(1);
+ // hdr.ipv6_base.dst_addr : selector @proto_tag(2);
+ // hdr.ipv6_base.src_addr : selector @proto_tag(3);
+ // hdr.ipv6_base.flow_label : selector @proto_tag(4);
+ // local_metadata.l4_src_port : selector @proto_tag(5);
+ // local_metadata.l4_dst_port : selector @proto_tag(6);
+ // }
+ // actions = {
+ // @proto_tag(1) set_nexthop;
+ // }
+ // implementation = wcmp_action_profile;
+ // }
+
+ // @proto_package("l3_fwd")
+ // table l3_ipv6_vrf_table {
+ // key = {
+ // local_metadata.vrf_id: exact @proto_tag(1);
+ // hdr.ipv6_base.dst_addr : lpm @proto_tag(2);
+ // hdr.ipv6_base.dst_addr : selector @proto_tag(3);
+ // hdr.ipv6_base.src_addr : selector @proto_tag(4);
+ // hdr.ipv6_base.flow_label : selector @proto_tag(5);
+ // local_metadata.l4_src_port : selector @proto_tag(6);
+ // local_metadata.l4_dst_port : selector @proto_tag(7);
+ // }
+ // actions = {
+ // @proto_tag(1) set_nexthop;
+ // }
+ // implementation = wcmp_action_profile;
+ // }
+
+ // @proto_package("l3_fwd")
+ // table l3_ipv6_fallback_table {
+ // key = {
+ // hdr.ipv6_base.dst_addr : lpm @proto_tag(1);
+ // hdr.ipv6_base.dst_addr : selector @proto_tag(2);
+ // hdr.ipv6_base.src_addr : selector @proto_tag(3);
+ // hdr.ipv6_base.flow_label : selector @proto_tag(4);
+ // local_metadata.l4_src_port : selector @proto_tag(5);
+ // local_metadata.l4_dst_port : selector @proto_tag(6);
+ // }
+ // actions = {
+ // @proto_tag(1) set_nexthop;
+ // }
+ // implementation = wcmp_action_profile;
+ // }
+
+ apply {
+ if(l3_routing_classifier_table.apply().hit) {
+ if (hdr.ipv4_base.isValid()) {
+ if(!l3_ipv4_override_table.apply().hit) {
+ if(!l3_ipv4_vrf_table.apply().hit) {
+ l3_ipv4_fallback_table.apply();
+ }
+ }
+ if(hdr.ipv4_base.ttl == 0) {
+ mark_to_drop();
+ return;
+ }
+ }// else if (hdr.ipv6_base.isValid()) {
+ // if(!l3_ipv6_override_table.apply().hit) {
+ // if(!l3_ipv6_vrf_table.apply().hit) {
+ // l3_ipv6_fallback_table.apply();
+ // }
+ // }
+ // if(hdr.ipv6_base.hop_limit == 0) {
+ // mark_to_drop();
+ // return;
+ // }
+ // }
+ }
+ }
+#ifdef P4_EXPLICIT_LAG
+ lag_handling() lag;
+ lag(hdr, local_metadata, standard_metadata);
+#endif
+} // end l3_fwd
+
+#endif // P4_SPEC_L3_FWD_P4_