From 61c263cb501fdd58113ab2b39bd7b70837584c30 Mon Sep 17 00:00:00 2001 From: krishna Date: Thu, 14 Apr 2016 10:42:16 -0700 Subject: [PATCH 1/4] initial commit for fpath lookup --- .gitignore | 50 ++ README.md | 46 ++ p4src/README.md | 2 +- p4src/acl.p4 | 29 +- p4src/archdeps.p4 | 16 + p4src/egress_filter.p4 | 4 +- p4src/fabric.p4 | 108 ++- p4src/hashes.p4 | 4 - p4src/includes/defines.p4 | 15 + p4src/includes/p4features.h | 13 + p4src/includes/parser.p4 | 64 +- p4src/includes/sizes.p4 | 1 + p4src/ipv4.p4 | 8 +- p4src/ipv6.p4 | 8 +- p4src/l2.p4 | 14 +- p4src/l3.p4 | 12 +- p4src/meter.p4 | 8 +- p4src/multicast.p4 | 165 +++-- p4src/nexthop.p4 | 24 +- p4src/openflow.p4 | 41 +- p4src/port.p4 | 80 +-- p4src/rewrite.p4 | 2 + p4src/security.p4 | 11 +- p4src/switch.p4 | 92 ++- p4src/switch_config.p4 | 7 +- p4src/tunnel.p4 | 292 +++++--- switchapi/Doxyfile | 22 +- switchapi/README.md | 8 +- switchapi/configure.ac | 1 - switchapi/inc/switchapi/switch_acl.h | 21 +- switchapi/inc/switchapi/switch_base_types.h | 10 +- switchapi/inc/switchapi/switch_hostif.h | 62 +- switchapi/inc/switchapi/switch_interface.h | 18 + switchapi/inc/switchapi/switch_lag.h | 10 +- switchapi/inc/switchapi/switch_mcast.h | 2 +- switchapi/inc/switchapi/switch_meter.h | 5 +- switchapi/inc/switchapi/switch_mirror.h | 82 ++- switchapi/inc/switchapi/switch_protocol.h | 7 +- switchapi/inc/switchapi/switch_tunnel.h | 14 +- switchapi/inc/switchapi/switch_vlan.h | 34 +- switchapi/src/switch_api.thrift | 3 +- switchapi/src/switch_api_rpc_server.cpp | 13 +- switchapi/src/switch_hostif.c | 97 +-- switchapi/src/switch_hostif_int.h | 7 +- switchapi/src/switch_id.c | 4 +- switchapi/src/switch_init.c | 1 + switchapi/src/switch_interface.c | 405 ++++++++++- switchapi/src/switch_interface_int.h | 25 +- switchapi/src/switch_l2.c | 70 +- switchapi/src/switch_lag.c | 6 +- switchapi/src/switch_lag_int.h | 2 +- switchapi/src/switch_mcast.c | 117 ++- switchapi/src/switch_mcast_int.h | 5 + switchapi/src/switch_meter.c | 2 +- switchapi/src/switch_neighbor.c | 8 +- switchapi/src/switch_packet.c | 621 +++++++++++++++- switchapi/src/switch_packet_int.h | 74 ++ switchapi/src/switch_pd.c | 648 ++++++++++------- switchapi/src/switch_pd.h | 30 +- switchapi/src/switch_pd_mcast.c | 72 +- switchapi/src/switch_port.c | 27 +- switchapi/src/switch_port_int.h | 8 +- switchapi/src/switch_stp.c | 83 +-- switchapi/src/switch_tunnel.c | 187 +++-- switchapi/src/switch_tunnel_int.h | 13 +- switchapi/src/switch_vlan.c | 427 +++++------ switchapi/src/switch_vlan_int.h | 34 +- switchapi/src/thrift_cache.h | 11 +- switchlink/src/switchlink_db.c | 12 + switchlink/src/switchlink_main.c | 2 +- switchlink/src/switchlink_neigh.c | 7 - switchlink/src/switchlink_route.c | 18 +- switchlink/src/switchlink_sai.c | 27 +- switchsai/src/sai_bmlib.c | 47 +- switchsai/src/saiacl.c | 13 +- switchsai/src/saifdb.c | 10 +- switchsai/src/saimirror.c | 4 +- switchsai/src/sainexthop.c | 7 +- switchsai/src/sainexthopgroup.c | 6 +- switchsai/src/saipolicer.c | 12 +- switchsai/src/saiport.c | 12 +- switchsai/src/sairouterintf.c | 10 +- switchsai/src/switch_sai.thrift | 5 +- switchsai/src/switch_sai_rpc_server.cpp | 89 ++- tests/ptf-tests/api-tests/switch.py | 754 +++++++++++++++++++- tests/ptf-tests/api-tests/switch_acl.py | 42 +- tests/ptf-tests/common/pd_utils.py | 71 +- tests/ptf-tests/common/sai_utils.py | 30 +- tests/ptf-tests/pd-tests/switch.py | 4 +- tests/ptf-tests/sai-tests/switch.py | 120 +++- 90 files changed, 4136 insertions(+), 1578 deletions(-) create mode 100644 p4src/archdeps.p4 diff --git a/.gitignore b/.gitignore index f04ffdf..04221fd 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,53 @@ *~ *.swp + +*.pcap + +*.ts + +# compiled Python +*.pyc + +# Files generated by autotools +.deps +.libs +Makefile +Makefile.in +configure +config.log +config.h +aclocal.m4 +autom4te.cache/ +compile +config.h.in +config.status +depcomp +install-sh +missing +stamp-h1 +targets/simple_router/simple_router +test-driver +.dirstamp +*.log +*.trs +config.guess +config.sub +ltmain.sh +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +m4/libtool.m4 +py-compile +libtool + +bmswitchp4_drivers + +gen-cpp +gen-py + +tests/run_tests.py + +switchapi/switch_api_thrift +switchsai/switch_sai_thrift diff --git a/README.md b/README.md index d240911..cc8a4e6 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,49 @@ switchapi - SwitchAPI switchlink - Linux netlink listener tests/ptf-tests - P4 dependent(PD), SAI and API tests tests/of-tests - Openflow tests + + +Running switch in bmv2 without p4factory +---------------------------------------- +You can now run `switch.p4` in bmv2 without cloning `p4factory`. In order to do +this you first need to install [bmv2] +(https://github.com/p4lang/behavioral-model) and its compiler [p4c-bmv2] +(https://github.com/p4lang/p4c-bm) on your system. Additionally, if you plan on +running the tests for `switch.p4`, please make sure you install [PTF] +(https://github.com/p4lang/ptf) with `sudo python setup.py install`. + +Once this is done, you can follow this steps: + + ./autogen.sh + ./configure --with-bmv2 --with-switchsai + make + +The `--with-switchsai` flag will make sure that the compiled drivers include +`switchapi` and `switchsai`. If you just need `switchapi`, replace the flag will +`--with-switchapi`. Replace the flag with `--with-switchlink` if you need +`switchlink` as well. If you omit these flags, the drivers will only include the +`PD`. + +Note that you should be using a fresh clone for this, not the `switch` submodule +that comes with `p4factory`. + +Make sure to look at the output of `configure` to spot any missing dependency. + +Once everything has compiled, you can run the tests for `switch.p4` (assuming +you have installed [PTF] (https://github.com/p4lang/ptf). Please make sure that +you have all the necessary veth pairs setup (you can use [tools/veth_setup.sh] +(tools/veth_setup.sh)). + +First, start the software switch with: + + sudo ./bmv2/run_bm.sh + +Then, start the drivers with: + + sudo ./bmv2/run_drivers.sh + +You can now run all the tests: + + sudo ./bmv2/run_tests.sh # for the PD tests + sudo ./bmv2/run_tests.sh --test-dir tests/ptf-tests/api-tests # for the switchapi tests + sudo ./bmv2/run_tests.sh --test-dir tests/ptf-tests/sai-tests # for the switchsai tests diff --git a/p4src/README.md b/p4src/README.md index 5934d32..26741b3 100644 --- a/p4src/README.md +++ b/p4src/README.md @@ -11,7 +11,7 @@ Supported Features 4. L3 Multicast 5. LAG 6. ECMP -7. Tunneling: VXLAN and NVGRE (including L2/L3 Gateway), Geneve, and GRE +7. Tunneling: VXLAN and NVGRE (including L2/L3 Gateway), Geneve, GRE and IPinIP 8. Basic ACL: MAC and IP ACLs 9. Unicast RPF check 10. MPLS: LER, LSR, IPVPN, VPLS, L2VPN diff --git a/p4src/acl.p4 b/p4src/acl.p4 index 9903bd3..d3bb812 100644 --- a/p4src/acl.p4 +++ b/p4src/acl.p4 @@ -33,9 +33,8 @@ header_type acl_metadata_t { racl_nexthop_type : 1; /* ecmp or nexthop */ acl_redirect : 1; /* ifacl/vacl redirect action */ racl_redirect : 1; /* racl redirect action */ - if_label : 15; /* if label for acls */ + if_label : 16; /* if label for acls */ bd_label : 16; /* bd label for acls */ - mirror_session_id : 10; /* mirror session id */ acl_stats_index : 14; /* acl stats index */ } } @@ -154,7 +153,9 @@ table mac_acl { control process_mac_acl { #if !defined(ACL_DISABLE) && !defined(L2_DISABLE) - apply(mac_acl); + if (DO_LOOKUP(ACL)) { + apply(mac_acl); + } #endif /* !ACL_DISABLE && !L2_DISABLE */ } @@ -225,15 +226,17 @@ table ipv6_acl { /*****************************************************************************/ control process_ip_acl { #ifndef ACL_DISABLE - if (l3_metadata.lkp_ip_type == IPTYPE_IPV4) { + if (DO_LOOKUP(ACL)) { + if (l3_metadata.lkp_ip_type == IPTYPE_IPV4) { #ifndef IPV4_DISABLE - apply(ip_acl); + apply(ip_acl); #endif /* IPV4_DISABLE */ - } else { - if (l3_metadata.lkp_ip_type == IPTYPE_IPV6) { + } else { + if (l3_metadata.lkp_ip_type == IPTYPE_IPV6) { #ifndef IPV6_DISABLE - apply(ipv6_acl); + apply(ipv6_acl); #endif /* IPV6_DISABLE */ + } } } #endif /* ACL_DISABLE */ @@ -474,9 +477,7 @@ action drop_packet() { } action drop_packet_with_reason(drop_reason) { -#ifndef STATS_DISABLE count(drop_stats, drop_reason); -#endif drop(); } @@ -550,9 +551,11 @@ table drop_stats { } control process_system_acl { - apply(system_acl); - if (ingress_metadata.drop_flag == TRUE) { - apply(drop_stats); + if (DO_LOOKUP(SYSTEM_ACL)) { + apply(system_acl); + if (ingress_metadata.drop_flag == TRUE) { + apply(drop_stats); + } } } diff --git a/p4src/archdeps.p4 b/p4src/archdeps.p4 new file mode 100644 index 0000000..4f0cb0f --- /dev/null +++ b/p4src/archdeps.p4 @@ -0,0 +1,16 @@ +/* +archdeps.p4 +*/ + +#ifndef _ARCH_DEPS_H + +#define _ARCH_DEPS_H + +#define ingress_input_port standard_metadata.ingress_port +#define ingress_egress_port standard_metadata.egress_spec +#define egress_egress_port standard_metadata.egress_port +#define intrinsic_mcast_grp intrinsic_metadata.mcast_grp +#define egress_egress_rid intrinsic_metadata.egress_rid + +#endif + diff --git a/p4src/egress_filter.p4 b/p4src/egress_filter.p4 index b016073..78c1f0d 100644 --- a/p4src/egress_filter.p4 +++ b/p4src/egress_filter.p4 @@ -36,13 +36,13 @@ action egress_filter_check() { egress_metadata.bd); } -action egress_filter_drop() { +action set_egress_filter_drop() { drop(); } table egress_filter_drop { actions { - egress_filter_drop; + set_egress_filter_drop; } } diff --git a/p4src/fabric.p4 b/p4src/fabric.p4 index c55a4a1..c87cc97 100644 --- a/p4src/fabric.p4 +++ b/p4src/fabric.p4 @@ -37,7 +37,7 @@ metadata fabric_metadata_t fabric_metadata; /* Fabric header - destination lookup */ /*****************************************************************************/ action terminate_cpu_packet() { - modify_field(standard_metadata.egress_spec, + modify_field(ingress_egress_port, fabric_header.dstPortOrGroup); modify_field(egress_metadata.bypass, fabric_header_cpu.txBypass); @@ -49,7 +49,7 @@ action terminate_cpu_packet() { #ifdef FABRIC_ENABLE action terminate_fabric_unicast_packet() { - modify_field(standard_metadata.egress_spec, + modify_field(ingress_egress_port, fabric_header.dstPortOrGroup); modify_field(tunnel_metadata.tunnel_terminate, @@ -85,7 +85,7 @@ action terminate_fabric_multicast_packet() { modify_field(l3_metadata.outer_routed, fabric_header_multicast.outerRouted); - modify_field(intrinsic_metadata.mcast_grp, + modify_field(intrinsic_mcast_grp, fabric_header_multicast.mcastGrp); modify_field(ethernet.etherType, fabric_payload_header.etherType); @@ -96,7 +96,7 @@ action terminate_fabric_multicast_packet() { action switch_fabric_multicast_packet() { modify_field(fabric_metadata.fabric_header_present, TRUE); - modify_field(intrinsic_metadata.mcast_grp, fabric_header.dstPortOrGroup); + modify_field(intrinsic_mcast_grp, fabric_header.dstPortOrGroup); } #endif /* MULTICAST_DISABLE */ #endif /* FABRIC_ENABLE */ @@ -138,66 +138,42 @@ table fabric_ingress_src_lkp { } #endif /* FABRIC_ENABLE */ -action terminate_inner_ethernet_non_ip_over_fabric() { - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); - modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); +action non_ip_over_fabric() { + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); } -action terminate_inner_ethernet_ipv4_over_fabric() { - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); - modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); - modify_field(ipv4_metadata.lkp_ipv4_sa, inner_ipv4.srcAddr); - modify_field(ipv4_metadata.lkp_ipv4_da, inner_ipv4.dstAddr); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv4.protocol); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); +action ipv4_over_fabric() { + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr); + modify_field(ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr); + modify_field(l3_metadata.lkp_ip_proto, ipv4.protocol); + modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_outer_l4_sport); + modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_outer_l4_dport); } -action terminate_inner_ipv4_over_fabric() { - modify_field(ipv4_metadata.lkp_ipv4_sa, inner_ipv4.srcAddr); - modify_field(ipv4_metadata.lkp_ipv4_da, inner_ipv4.dstAddr); - modify_field(l3_metadata.lkp_ip_version, inner_ipv4.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv4.protocol); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv4.ttl); - modify_field(l3_metadata.lkp_ip_tc, inner_ipv4.diffserv); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); +action ipv6_over_fabric() { + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ipv6_metadata.lkp_ipv6_sa, ipv6.srcAddr); + modify_field(ipv6_metadata.lkp_ipv6_da, ipv6.dstAddr); + modify_field(l3_metadata.lkp_ip_proto, ipv6.nextHdr); + modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_outer_l4_sport); + modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_outer_l4_dport); } -action terminate_inner_ethernet_ipv6_over_fabric() { - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); - modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); - modify_field(ipv6_metadata.lkp_ipv6_sa, inner_ipv6.srcAddr); - modify_field(ipv6_metadata.lkp_ipv6_da, inner_ipv6.dstAddr); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv6.nextHdr); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); -} - -action terminate_inner_ipv6_over_fabric() { - modify_field(ipv6_metadata.lkp_ipv6_sa, inner_ipv6.srcAddr); - modify_field(ipv6_metadata.lkp_ipv6_da, inner_ipv6.dstAddr); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv6.nextHdr); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); -} - -table tunneled_packet_over_fabric { +table native_packet_over_fabric { reads { - tunnel_metadata.ingress_tunnel_type : exact; - inner_ipv4 : valid; - inner_ipv6 : valid; + ipv4 : valid; + ipv6 : valid; } actions { - terminate_inner_ethernet_non_ip_over_fabric; - terminate_inner_ethernet_ipv4_over_fabric; - terminate_inner_ipv4_over_fabric; + non_ip_over_fabric; + ipv4_over_fabric; #ifndef IPV6_DISABLE - terminate_inner_ethernet_ipv6_over_fabric; - terminate_inner_ipv6_over_fabric; + ipv6_over_fabric; #endif /* IPV6_DISABLE */ } size : 1024; @@ -207,15 +183,19 @@ table tunneled_packet_over_fabric { /* Ingress fabric header processing */ /*****************************************************************************/ control process_ingress_fabric { - apply(fabric_ingress_dst_lkp); + if (ingress_metadata.port_type != PORT_TYPE_NORMAL) { + apply(fabric_ingress_dst_lkp); #ifdef FABRIC_ENABLE - if (valid(fabric_header_multicast)) { - apply(fabric_ingress_src_lkp); - } - if (tunnel_metadata.tunnel_terminate == TRUE) { - apply(tunneled_packet_over_fabric); - } + if (ingress_metadata.port_type == PORT_TYPE_FABRIC) { + if (valid(fabric_header_multicast)) { + apply(fabric_ingress_src_lkp); + } + if (tunnel_metadata.tunnel_terminate == FALSE) { + apply(native_packet_over_fabric); + } + } #endif /* FABRIC_ENABLE */ + } } /*****************************************************************************/ @@ -223,16 +203,16 @@ control process_ingress_fabric { /*****************************************************************************/ #ifdef FABRIC_ENABLE action set_fabric_lag_port(port) { - modify_field(standard_metadata.egress_spec, port); + modify_field(ingress_egress_port, port); } #ifndef MULTICAST_DISABLE action set_fabric_multicast(fabric_mgid) { - modify_field(multicast_metadata.mcast_grp, intrinsic_metadata.mcast_grp); + modify_field(multicast_metadata.mcast_grp, intrinsic_mcast_grp); #ifdef FABRIC_NO_LOCAL_SWITCHING // no local switching, reset fields to send packet on fabric mgid - modify_field(intrinsic_metadata.mcast_grp, fabric_mgid); + modify_field(intrinsic_mcast_grp, fabric_mgid); #endif /* FABRIC_NO_LOCAL_SWITCHING */ } #endif /* MULTICAST_DISABLE */ diff --git a/p4src/hashes.p4 b/p4src/hashes.p4 index a4620df..2746ce7 100644 --- a/p4src/hashes.p4 +++ b/p4src/hashes.p4 @@ -9,10 +9,6 @@ header_type hash_metadata_t { } } -@pragma pa_atomic ingress hash_metadata.hash1 -@pragma pa_solitary ingress hash_metadata.hash1 -@pragma pa_atomic ingress hash_metadata.hash2 -@pragma pa_solitary ingress hash_metadata.hash2 metadata hash_metadata_t hash_metadata; field_list lkp_ipv4_hash1_fields { diff --git a/p4src/includes/defines.p4 b/p4src/includes/defines.p4 index d906a55..1fb6ba2 100644 --- a/p4src/includes/defines.p4 +++ b/p4src/includes/defines.p4 @@ -99,3 +99,18 @@ limitations under the License. #define PORT_TYPE_NORMAL 0 #define PORT_TYPE_FABRIC 1 #define PORT_TYPE_CPU 2 + +/* BYPASS LOOKUP */ +#define BYPASS_L2 0x0001 +#define BYPASS_L3 0x0002 +#define BYPASS_ACL 0x0004 +#define BYPASS_QOS 0x0008 +#define BYPASS_METER 0x0010 +#define BYPASS_SYSTEM_ACL 0x0020 +#define BYPASS_ALL 0xFFFF + +#define DO_LOOKUP(l) \ + ((ingress_metadata.bypass_lookups & BYPASS_##l) == 0) + +#define BYPASS_ALL_LOOKUPS \ + (ingress_metadata.bypass_lookups == BYPASS_ALL) diff --git a/p4src/includes/p4features.h b/p4src/includes/p4features.h index e559f05..0033787 100644 --- a/p4src/includes/p4features.h +++ b/p4src/includes/p4features.h @@ -21,6 +21,11 @@ limitations under the License. #define OUTER_PIM_BIDIR_OPTIMIZATION #define PIM_BIDIR_OPTIMIZATION +#ifdef MULTICAST_DISABLE +#define L2_MULTICAST_DISABLE +#define L3_MULTICAST_DISABLE +#endif + // Defines for switchapi library #ifdef URPF_DISABLE #define P4_URPF_DISABLE @@ -38,6 +43,14 @@ limitations under the License. #define P4_MULTICAST_DISABLE #endif +#ifdef L2_MULTICAST_DISABLE +#define P4_L2_MULTICAST_DISABLE +#endif + +#ifdef L3_MULTICAST_DISABLE +#define P4_L3_MULTICAST_DISABLE +#endif + #ifdef TUNNEL_DISABLE #define P4_TUNNEL_DISABLE #endif diff --git a/p4src/includes/parser.p4 b/p4src/includes/parser.p4 index 22f2532..cd8100c 100644 --- a/p4src/includes/parser.p4 +++ b/p4src/includes/parser.p4 @@ -113,8 +113,6 @@ header ethernet_t ethernet; parser parse_ethernet { extract(ethernet); - set_metadata(l2_metadata.lkp_mac_sa, ethernet.srcAddr); - set_metadata(l2_metadata.lkp_mac_da, ethernet.dstAddr); return select(latest.etherType) { 0 mask 0xfe00: parse_llc_header; 0 mask 0xfa00: parse_llc_header; @@ -183,21 +181,28 @@ parser parse_qinq_vlan { } #define MPLS_DEPTH 3 +/* all the tags but the last one */ header mpls_t mpls[MPLS_DEPTH]; parser parse_mpls { +#ifndef MPLS_DISABLE extract(mpls[next]); return select(latest.bos) { 0 : parse_mpls; 1 : parse_mpls_bos; default: ingress; } +#else + return ingress; +#endif } parser parse_mpls_bos { return select(current(0, 4)) { +#ifndef MPLS_DISABLE 0x4 : parse_mpls_inner_ipv4; 0x6 : parse_mpls_inner_ipv6; +#endif default: parse_eompls; } } @@ -284,17 +289,15 @@ calculated_field ipv4.hdrChecksum { parser parse_ipv4 { extract(ipv4); - set_metadata(ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr); - set_metadata(ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr); - set_metadata(l3_metadata.lkp_ip_proto, ipv4.protocol); - set_metadata(l3_metadata.lkp_ip_ttl, ipv4.ttl); return select(latest.fragOffset, latest.ihl, latest.protocol) { IP_PROTOCOLS_IPHL_ICMP : parse_icmp; IP_PROTOCOLS_IPHL_TCP : parse_tcp; IP_PROTOCOLS_IPHL_UDP : parse_udp; +#ifndef TUNNEL_DISABLE IP_PROTOCOLS_IPHL_GRE : parse_gre; IP_PROTOCOLS_IPHL_IPV4 : parse_ipv4_in_ip; IP_PROTOCOLS_IPHL_IPV6 : parse_ipv6_in_ip; +#endif /* TUNNEL_DISABLE */ IP_PROTOCOLS_IGMP : parse_set_prio_med; IP_PROTOCOLS_EIGRP : parse_set_prio_med; IP_PROTOCOLS_OSPF : parse_set_prio_med; @@ -335,8 +338,8 @@ header ipv6_t ipv6; parser parse_udp_v6 { extract(udp); - set_metadata(l3_metadata.lkp_l4_sport, latest.srcPort); - set_metadata(l3_metadata.lkp_l4_dport, latest.dstPort); + set_metadata(l3_metadata.lkp_outer_l4_sport, latest.srcPort); + set_metadata(l3_metadata.lkp_outer_l4_dport, latest.dstPort); return select(latest.dstPort) { UDP_PORT_BOOTPS : parse_set_prio_med; UDP_PORT_BOOTPC : parse_set_prio_med; @@ -360,16 +363,11 @@ parser parse_gre_v6 { parser parse_ipv6 { extract(ipv6); -#if !defined(IPV6_DISABLE) - set_metadata(ipv6_metadata.lkp_ipv6_sa, latest.srcAddr); - set_metadata(ipv6_metadata.lkp_ipv6_da, latest.dstAddr); - set_metadata(l3_metadata.lkp_ip_proto, ipv6.nextHdr); - set_metadata(l3_metadata.lkp_ip_ttl, ipv6.hopLimit); -#endif /* !defined(IPV6_DISABLE) */ return select(latest.nextHdr) { IP_PROTOCOLS_ICMPV6 : parse_icmp; IP_PROTOCOLS_TCP : parse_tcp; IP_PROTOCOLS_IPV4 : parse_ipv4_in_ip; +#ifndef TUNNEL_DISABLE #ifndef TUNNEL_OVER_IPV6_DISABLE IP_PROTOCOLS_UDP : parse_udp; IP_PROTOCOLS_GRE : parse_gre; @@ -378,6 +376,7 @@ parser parse_ipv6 { IP_PROTOCOLS_UDP : parse_udp_v6; IP_PROTOCOLS_GRE : parse_gre_v6; #endif +#endif /* TUNNEL_DISABLE */ IP_PROTOCOLS_EIGRP : parse_set_prio_med; IP_PROTOCOLS_OSPF : parse_set_prio_med; IP_PROTOCOLS_PIM : parse_set_prio_med; @@ -391,7 +390,7 @@ header icmp_t icmp; parser parse_icmp { extract(icmp); - set_metadata(l3_metadata.lkp_l4_sport, latest.typeCode); + set_metadata(l3_metadata.lkp_outer_l4_sport, latest.typeCode); return select(latest.typeCode) { /* MLD and ND, 130-136 */ 0x8200 mask 0xfe00 : parse_set_prio_med; @@ -408,8 +407,8 @@ header tcp_t tcp; parser parse_tcp { extract(tcp); - set_metadata(l3_metadata.lkp_l4_sport, latest.srcPort); - set_metadata(l3_metadata.lkp_l4_dport, latest.dstPort); + set_metadata(l3_metadata.lkp_outer_l4_sport, latest.srcPort); + set_metadata(l3_metadata.lkp_outer_l4_dport, latest.dstPort); return select(latest.dstPort) { TCP_PORT_BGP : parse_set_prio_med; TCP_PORT_MSDP : parse_set_prio_med; @@ -428,11 +427,13 @@ parser parse_roce_v2 { parser parse_udp { extract(udp); - set_metadata(l3_metadata.lkp_l4_sport, latest.srcPort); - set_metadata(l3_metadata.lkp_l4_dport, latest.dstPort); + set_metadata(l3_metadata.lkp_outer_l4_sport, latest.srcPort); + set_metadata(l3_metadata.lkp_outer_l4_dport, latest.dstPort); return select(latest.dstPort) { +#ifndef TUNNEL_DISABLE UDP_PORT_VXLAN : parse_vxlan; UDP_PORT_GENV: parse_geneve; +#endif /* TUNNEL_DISABLE */ #ifdef INT_ENABLE // vxlan-gpe is only supported in the context of INT at this time UDP_PORT_VXLAN_GPE : parse_vxlan_gpe; @@ -711,6 +712,10 @@ parser parse_lisp { parser parse_inner_ipv4 { extract(inner_ipv4); + set_metadata(ipv4_metadata.lkp_ipv4_sa, latest.srcAddr); + set_metadata(ipv4_metadata.lkp_ipv4_da, latest.dstAddr); + set_metadata(l3_metadata.lkp_ip_proto, latest.protocol); + set_metadata(l3_metadata.lkp_ip_ttl, latest.ttl); return select(latest.fragOffset, latest.ihl, latest.protocol) { IP_PROTOCOLS_IPHL_ICMP : parse_inner_icmp; IP_PROTOCOLS_IPHL_TCP : parse_inner_tcp; @@ -723,7 +728,7 @@ header icmp_t inner_icmp; parser parse_inner_icmp { extract(inner_icmp); - set_metadata(l3_metadata.lkp_inner_l4_sport, latest.typeCode); + set_metadata(l3_metadata.lkp_l4_sport, latest.typeCode); return ingress; } @@ -732,8 +737,8 @@ header tcp_t inner_tcp; parser parse_inner_tcp { extract(inner_tcp); - set_metadata(l3_metadata.lkp_inner_l4_sport, latest.srcPort); - set_metadata(l3_metadata.lkp_inner_l4_dport, latest.dstPort); + set_metadata(l3_metadata.lkp_l4_sport, latest.srcPort); + set_metadata(l3_metadata.lkp_l4_dport, latest.dstPort); return ingress; } @@ -741,8 +746,8 @@ header udp_t inner_udp; parser parse_inner_udp { extract(inner_udp); - set_metadata(l3_metadata.lkp_inner_l4_sport, latest.srcPort); - set_metadata(l3_metadata.lkp_inner_l4_dport, latest.dstPort); + set_metadata(l3_metadata.lkp_l4_sport, latest.srcPort); + set_metadata(l3_metadata.lkp_l4_dport, latest.dstPort); return ingress; } @@ -755,6 +760,12 @@ parser parse_inner_sctp { parser parse_inner_ipv6 { extract(inner_ipv6); +#if !defined(IPV6_DISABLE) + set_metadata(ipv6_metadata.lkp_ipv6_sa, latest.srcAddr); + set_metadata(ipv6_metadata.lkp_ipv6_da, latest.dstAddr); + set_metadata(l3_metadata.lkp_ip_proto, latest.nextHdr); + set_metadata(l3_metadata.lkp_ip_ttl, latest.hopLimit); +#endif /* !defined(IPV6_DISABLE) */ return select(latest.nextHdr) { IP_PROTOCOLS_ICMPV6 : parse_inner_icmp; IP_PROTOCOLS_TCP : parse_inner_tcp; @@ -765,9 +776,13 @@ parser parse_inner_ipv6 { parser parse_inner_ethernet { extract(inner_ethernet); + set_metadata(l2_metadata.lkp_mac_sa, latest.srcAddr); + set_metadata(l2_metadata.lkp_mac_da, latest.dstAddr); return select(latest.etherType) { ETHERTYPE_IPV4 : parse_inner_ipv4; +#ifndef TUNNEL_OVER_IPV6_DISABLE ETHERTYPE_IPV6 : parse_inner_ipv6; +#endif default: ingress; } } @@ -847,6 +862,7 @@ parser parse_fabric_header_mirror { parser parse_fabric_header_cpu { extract(fabric_header_cpu); + set_metadata(ingress_metadata.bypass_lookups, latest.reasonCode); return parse_fabric_payload_header; } diff --git a/p4src/includes/sizes.p4 b/p4src/includes/sizes.p4 index ab24d47..9e63b2c 100644 --- a/p4src/includes/sizes.p4 +++ b/p4src/includes/sizes.p4 @@ -27,6 +27,7 @@ limitations under the License. #define OUTER_ROUTER_MAC_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define DEST_TUNNEL_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define SRC_TUNNEL_TABLE_SIZE MIN_SRAM_TABLE_SIZE +#define IPV6_SRC_TUNNEL_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define OUTER_MULTICAST_STAR_G_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define OUTER_MULTICAST_S_G_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define VNID_MAPPING_TABLE_SIZE MIN_SRAM_TABLE_SIZE diff --git a/p4src/ipv4.p4 b/p4src/ipv4.p4 index b1a7247..9095478 100644 --- a/p4src/ipv4.p4 +++ b/p4src/ipv4.p4 @@ -39,7 +39,7 @@ metadata ipv4_metadata_t ipv4_metadata; action set_valid_outer_ipv4_packet() { modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV4); modify_field(l3_metadata.lkp_ip_tc, ipv4.diffserv); - modify_field(l3_metadata.lkp_ip_version, 4); + modify_field(l3_metadata.lkp_ip_version, ipv4.version); } action set_malformed_outer_ipv4_packet(drop_reason) { @@ -50,11 +50,11 @@ action set_malformed_outer_ipv4_packet(drop_reason) { table validate_outer_ipv4_packet { reads { ipv4.version : ternary; - l3_metadata.lkp_ip_ttl : ternary; + ipv4.ttl : ternary; #ifndef __TARGET_BMV2__ - ipv4_metadata.lkp_ipv4_sa mask 0xFF000000 : ternary; + ipv4.srcAddr mask 0xFF000000 : ternary; #else - ipv4_metadata.lkp_ipv4_sa : ternary; + ipv4.srcAddr : ternary; #endif } actions { diff --git a/p4src/ipv6.p4 b/p4src/ipv6.p4 index 2a26f08..d6767ea 100644 --- a/p4src/ipv6.p4 +++ b/p4src/ipv6.p4 @@ -40,7 +40,7 @@ metadata ipv6_metadata_t ipv6_metadata; action set_valid_outer_ipv6_packet() { modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV6); modify_field(l3_metadata.lkp_ip_tc, ipv6.trafficClass); - modify_field(l3_metadata.lkp_ip_version, 6); + modify_field(l3_metadata.lkp_ip_version, ipv6.version); } action set_malformed_outer_ipv6_packet(drop_reason) { @@ -56,11 +56,11 @@ action set_malformed_outer_ipv6_packet(drop_reason) { table validate_outer_ipv6_packet { reads { ipv6.version : ternary; - l3_metadata.lkp_ip_ttl : ternary; + ipv6.hopLimit : ternary; #ifndef __TARGET_BMV2__ - ipv6_metadata.lkp_ipv6_sa mask 0xFFFF0000000000000000000000000000 : ternary; + ipv6.srcAddr mask 0xFFFF0000000000000000000000000000 : ternary; #else - ipv6_metadata.lkp_ipv6_sa : ternary; + ipv6.srcAddr : ternary; #endif } actions { diff --git a/p4src/l2.p4 b/p4src/l2.p4 index 2dac98a..dad7a52 100644 --- a/p4src/l2.p4 +++ b/p4src/l2.p4 @@ -63,7 +63,8 @@ table spanning_tree { control process_spanning_tree { #ifndef L2_DISABLE - if (l2_metadata.stp_group != STP_GROUP_NONE) { + if ((ingress_metadata.port_type == PORT_TYPE_NORMAL) and + (l2_metadata.stp_group != STP_GROUP_NONE)) { apply(spanning_tree); } #endif /* L2_DISABLE */ @@ -103,7 +104,7 @@ action dmac_hit(ifindex) { } action dmac_multicast_hit(mc_index) { - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); #endif /* FABRIC_ENABLE */ @@ -157,8 +158,12 @@ table dmac { control process_mac { #ifndef L2_DISABLE - apply(smac); - apply(dmac); + if (ingress_metadata.port_type == PORT_TYPE_NORMAL) { + apply(smac); + } + if (DO_LOOKUP(L2)) { + apply(dmac); + } #endif /* L2_DISABLE */ } @@ -307,7 +312,6 @@ action set_egress_bd_properties(smac_idx) { modify_field(egress_metadata.smac_idx, smac_idx); } -@pragma ternary 1 table egress_bd_map { reads { egress_metadata.bd : exact; diff --git a/p4src/l3.p4 b/p4src/l3.p4 index 78cb39b..cadbc0a 100644 --- a/p4src/l3.p4 +++ b/p4src/l3.p4 @@ -31,8 +31,8 @@ header_type l3_metadata_t { lkp_ip_ttl : 8; lkp_l4_sport : 16; lkp_l4_dport : 16; - lkp_inner_l4_sport : 16; - lkp_inner_l4_dport : 16; + lkp_outer_l4_sport : 16; + lkp_outer_l4_dport : 16; vrf : VRF_BIT_WIDTH; /* VRF */ rmac_group : 10; /* Rmac group, for rmac indirection */ @@ -192,14 +192,14 @@ table l3_rewrite { actions { nop; ipv4_unicast_rewrite; -#ifndef MULTICAST_DISABLE +#ifndef L3_MULTICAST_DISABLE ipv4_multicast_rewrite; -#endif /* MULTICAST_DISABLE */ +#endif /* L3_MULTICAST_DISABLE */ #ifndef IPV6_DISABLE ipv6_unicast_rewrite; -#ifndef MULTICAST_DISABLE +#ifndef L3_MULTICAST_DISABLE ipv6_multicast_rewrite; -#endif /* MULTICAST_DISABLE */ +#endif /* L3_MULTICAST_DISABLE */ #endif /* IPV6_DISABLE */ #ifndef MPLS_DISABLE mpls_rewrite; diff --git a/p4src/meter.p4 b/p4src/meter.p4 index 0719ea2..52c0442 100644 --- a/p4src/meter.p4 +++ b/p4src/meter.p4 @@ -75,12 +75,16 @@ table meter_index { control process_meter_index { #ifndef METER_DISABLE - apply(meter_index); + if (DO_LOOKUP(METER)) { + apply(meter_index); + } #endif /* METER_DISABLE */ } control process_meter_action { #ifndef METER_DISABLE - apply(meter_action); + if (DO_LOOKUP(METER)) { + apply(meter_action); + } #endif /* METER_DISABLE */ } diff --git a/p4src/multicast.p4 b/p4src/multicast.p4 index d4d2bfb..e23e6a6 100644 --- a/p4src/multicast.p4 +++ b/p4src/multicast.p4 @@ -47,10 +47,10 @@ header_type multicast_metadata_t { metadata multicast_metadata_t multicast_metadata; -#ifndef MULTICAST_DISABLE /*****************************************************************************/ /* Outer IP multicast RPF check */ /*****************************************************************************/ +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) action outer_multicast_rpf_check_pass() { modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(l3_metadata.outer_routed, TRUE); @@ -67,24 +67,24 @@ table outer_multicast_rpf { } size : OUTER_MCAST_RPF_TABLE_SIZE; } -#endif /* MULTICAST_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE */ control process_outer_multicast_rpf { -#if !defined(MULTICAST_DISABLE) && !defined(OUTER_PIM_BIDIR_OPTIMIZATION) +#if !defined(OUTER_PIM_BIDIR_OPTIMIZATION) /* outer mutlicast RPF check - sparse and bidir */ if (multicast_metadata.outer_mcast_route_hit == TRUE) { apply(outer_multicast_rpf); } -#endif /* !MULTICAST_DISABLE && !OUTER_PIM_BIDIR_OPTIMIZATION */ +#endif /* !OUTER_PIM_BIDIR_OPTIMIZATION */ } /*****************************************************************************/ /* Outer IP mutlicast lookup actions */ /*****************************************************************************/ -#ifndef MULTICAST_DISABLE +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) action outer_multicast_bridge_star_g_hit(mc_index) { - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); modify_field(tunnel_metadata.tunnel_terminate, TRUE); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); @@ -92,7 +92,7 @@ action outer_multicast_bridge_star_g_hit(mc_index) { } action outer_multicast_bridge_s_g_hit(mc_index) { - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); modify_field(tunnel_metadata.tunnel_terminate, TRUE); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); @@ -101,7 +101,7 @@ action outer_multicast_bridge_s_g_hit(mc_index) { action outer_multicast_route_sm_star_g_hit(mc_index, mcast_rpf_group) { modify_field(multicast_metadata.outer_mcast_mode, MCAST_MODE_SM); - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); modify_field(multicast_metadata.outer_mcast_route_hit, TRUE); bit_xor(multicast_metadata.mcast_rpf_group, mcast_rpf_group, multicast_metadata.bd_mrpf_group); @@ -112,7 +112,7 @@ action outer_multicast_route_sm_star_g_hit(mc_index, mcast_rpf_group) { action outer_multicast_route_bidir_star_g_hit(mc_index, mcast_rpf_group) { modify_field(multicast_metadata.outer_mcast_mode, MCAST_MODE_BIDIR); - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); modify_field(multicast_metadata.outer_mcast_route_hit, TRUE); #ifdef OUTER_PIM_BIDIR_OPTIMIZATION bit_or(multicast_metadata.mcast_rpf_group, mcast_rpf_group, @@ -126,7 +126,7 @@ action outer_multicast_route_bidir_star_g_hit(mc_index, mcast_rpf_group) { } action outer_multicast_route_s_g_hit(mc_index, mcast_rpf_group) { - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); modify_field(multicast_metadata.outer_mcast_route_hit, TRUE); bit_xor(multicast_metadata.mcast_rpf_group, mcast_rpf_group, multicast_metadata.bd_mrpf_group); @@ -134,17 +134,18 @@ action outer_multicast_route_s_g_hit(mc_index, mcast_rpf_group) { modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); #endif /* FABRIC_ENABLE */ } -#endif /* MULTICAST_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE */ + -#if !defined(MULTICAST_DISABLE) && !defined(IPV4_DISABLE) /*****************************************************************************/ /* Outer IPv4 multicast lookup */ /*****************************************************************************/ +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) && !defined(IPV4_DISABLE) table outer_ipv4_multicast_star_g { reads { multicast_metadata.ipv4_mcast_key_type : exact; multicast_metadata.ipv4_mcast_key : exact; - ipv4_metadata.lkp_ipv4_da : ternary; + ipv4.dstAddr : ternary; } actions { nop; @@ -159,8 +160,8 @@ table outer_ipv4_multicast { reads { multicast_metadata.ipv4_mcast_key_type : exact; multicast_metadata.ipv4_mcast_key : exact; - ipv4_metadata.lkp_ipv4_sa : exact; - ipv4_metadata.lkp_ipv4_da : exact; + ipv4.srcAddr : exact; + ipv4.dstAddr : exact; } actions { nop; @@ -170,28 +171,29 @@ table outer_ipv4_multicast { } size : OUTER_MULTICAST_S_G_TABLE_SIZE; } -#endif /* !MULTICAST_DISABLE && !IPV4_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE && !IPV4_DISABLE */ control process_outer_ipv4_multicast { -#if !defined(MULTICAST_DISABLE) && !defined(IPV4_DISABLE) +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) && !defined(IPV4_DISABLE) /* check for ipv4 multicast tunnel termination */ apply(outer_ipv4_multicast) { on_miss { apply(outer_ipv4_multicast_star_g); } } -#endif /* !MULTICAST_DISABLE && !IPV4_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE && !IPV4_DISABLE */ } -#if !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) + /*****************************************************************************/ /* Outer IPv6 multicast lookup */ /*****************************************************************************/ +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) table outer_ipv6_multicast_star_g { reads { multicast_metadata.ipv6_mcast_key_type : exact; multicast_metadata.ipv6_mcast_key : exact; - ipv6_metadata.lkp_ipv6_da : ternary; + ipv6.dstAddr : ternary; } actions { nop; @@ -206,8 +208,8 @@ table outer_ipv6_multicast { reads { multicast_metadata.ipv6_mcast_key_type : exact; multicast_metadata.ipv6_mcast_key : exact; - ipv6_metadata.lkp_ipv6_sa : exact; - ipv6_metadata.lkp_ipv6_da : exact; + ipv6.srcAddr : exact; + ipv6.dstAddr : exact; } actions { nop; @@ -217,17 +219,17 @@ table outer_ipv6_multicast { } size : OUTER_MULTICAST_S_G_TABLE_SIZE; } -#endif /* !MULTICAST_DISABLE && !IPV6_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE && !IPV6_DISABLE */ control process_outer_ipv6_multicast { -#if !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) /* check for ipv6 multicast tunnel termination */ apply(outer_ipv6_multicast) { on_miss { apply(outer_ipv6_multicast_star_g); } } -#endif /* !MULTICAST_DISABLE && !IPV6_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE && !IPV6_DISABLE */ } @@ -235,7 +237,7 @@ control process_outer_ipv6_multicast { /* Process outer IP multicast */ /*****************************************************************************/ control process_outer_multicast { -#ifndef MULTICAST_DISABLE +#if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) if (valid(ipv4)) { process_outer_ipv4_multicast(); } else { @@ -244,13 +246,14 @@ control process_outer_multicast { } } process_outer_multicast_rpf(); -#endif /* MULTICAST_DISABLE */ +#endif /* !TUNNEL_DISABLE && !MULTICAST_DISABLE */ } -#ifndef MULTICAST_DISABLE + /*****************************************************************************/ /* IP multicast RPF check */ /*****************************************************************************/ +#ifndef L3_MULTICAST_DISABLE action multicast_rpf_check_pass() { modify_field(l3_metadata.routed, TRUE); } @@ -274,20 +277,21 @@ table multicast_rpf { } size : MCAST_RPF_TABLE_SIZE; } -#endif /* MULTICAST_DISABLE */ +#endif /* L3_MULTICAST_DISABLE */ control process_multicast_rpf { -#if !defined(MULTICAST_DISABLE) && !defined(PIM_BIDIR_OPTIMIZATION) +#if !defined(L3_MULTICAST_DISABLE) && !defined(PIM_BIDIR_OPTIMIZATION) if (multicast_metadata.mcast_route_hit == TRUE) { apply(multicast_rpf); } -#endif /* !MULTICAST_DISABLE && !PIM_BIDIR_OPTIMIZATION */ +#endif /* !L3_MULTICAST_DISABLE && !PIM_BIDIR_OPTIMIZATION */ } -#ifndef MULTICAST_DISABLE + /*****************************************************************************/ /* IP multicast lookup actions */ /*****************************************************************************/ +#ifndef MULTICAST_DISABLE action multicast_bridge_star_g_hit(mc_index) { modify_field(multicast_metadata.multicast_bridge_mc_index, mc_index); modify_field(multicast_metadata.mcast_bridge_hit, TRUE); @@ -331,20 +335,11 @@ action multicast_route_s_g_hit(mc_index, mcast_rpf_group) { } #endif /* MULTICAST_DISABLE */ + /*****************************************************************************/ /* IPv4 multicast lookup */ /*****************************************************************************/ -#if !defined(MULTICAST_DISABLE) && !defined(IPV4_DISABLE) -counter ipv4_multicast_route_star_g_stats { - type : packets; - direct : ipv4_multicast_route_star_g; -} - -counter ipv4_multicast_route_s_g_stats { - type : packets; - direct : ipv4_multicast_route; -} - +#if !defined(L2_MULTICAST_DISABLE) && !defined(IPV4_DISABLE) table ipv4_multicast_bridge_star_g { reads { ingress_metadata.bd : exact; @@ -369,6 +364,18 @@ table ipv4_multicast_bridge { } size : IPV4_MULTICAST_S_G_TABLE_SIZE; } +#endif /* !L2_MULTICAST_DISABLE && !IPV4_DISABLE */ + +#if !defined(L3_MULTICAST_DISABLE) && !defined(IPV4_DISABLE) +counter ipv4_multicast_route_star_g_stats { + type : packets; + direct : ipv4_multicast_route_star_g; +} + +counter ipv4_multicast_route_s_g_stats { + type : packets; + direct : ipv4_multicast_route; +} table ipv4_multicast_route_star_g { reads { @@ -395,40 +402,37 @@ table ipv4_multicast_route { } size : IPV4_MULTICAST_S_G_TABLE_SIZE; } -#endif /* !MULTICAST_DISABLE && !IPV4_DISABLE */ +#endif /* !L3_MULTICAST_DISABLE && !IPV4_DISABLE */ control process_ipv4_multicast { -#if !defined(MULTICAST_DISABLE) && !defined(IPV4_DISABLE) +#if !defined(L2_MULTICAST_DISABLE) && !defined(IPV4_DISABLE) /* ipv4 multicast lookup */ - apply(ipv4_multicast_bridge) { - on_miss { - apply(ipv4_multicast_bridge_star_g); + if (DO_LOOKUP(L2)) { + apply(ipv4_multicast_bridge) { + on_miss { + apply(ipv4_multicast_bridge_star_g); + } } } - if (multicast_metadata.ipv4_multicast_enabled == TRUE) { +#endif /* !L2_MULTICAST_DISABLE && !IPV4_DISABLE */ + +#if !defined(L3_MULTICAST_DISABLE) && !defined(IPV4_DISABLE) + if (DO_LOOKUP(L3) and + (multicast_metadata.ipv4_multicast_enabled == TRUE)) { apply(ipv4_multicast_route) { on_miss { apply(ipv4_multicast_route_star_g); } } } -#endif /* !MULTICAST_DISABLE && !IPV4_DISABLE */ +#endif /* !L3_MULTICAST_DISABLE && !IPV4_DISABLE */ } + /*****************************************************************************/ /* IPv6 multicast lookup */ /*****************************************************************************/ -#if !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) -counter ipv6_multicast_route_star_g_stats { - type : packets; - direct : ipv6_multicast_route_star_g; -} - -counter ipv6_multicast_route_s_g_stats { - type : packets; - direct : ipv6_multicast_route; -} - +#if !defined(L2_MULTICAST_DISABLE) && !defined(IPV6_DISABLE) table ipv6_multicast_bridge_star_g { reads { ingress_metadata.bd : exact; @@ -453,6 +457,18 @@ table ipv6_multicast_bridge { } size : IPV6_MULTICAST_S_G_TABLE_SIZE; } +#endif /* !L2_MULTICAST_DISABLE && !IPV6_DISABLE */ + +#if !defined(L3_MULTICAST_DISABLE) && !defined(IPV6_DISABLE) +counter ipv6_multicast_route_star_g_stats { + type : packets; + direct : ipv6_multicast_route_star_g; +} + +counter ipv6_multicast_route_s_g_stats { + type : packets; + direct : ipv6_multicast_route; +} table ipv6_multicast_route_star_g { reads { @@ -479,25 +495,32 @@ table ipv6_multicast_route { } size : IPV6_MULTICAST_S_G_TABLE_SIZE; } -#endif /* !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) */ +#endif /* !L3_MULTICAST_DISABLE && !IPV6_DISABLE */ control process_ipv6_multicast { -#if !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) - apply(ipv6_multicast_bridge) { - on_miss { - apply(ipv6_multicast_bridge_star_g); +#if !defined(L2_MULTICAST_DISABLE) && !defined(IPV6_DISABLE) + if (DO_LOOKUP(L2)) { + apply(ipv6_multicast_bridge) { + on_miss { + apply(ipv6_multicast_bridge_star_g); + } } } - if (multicast_metadata.ipv6_multicast_enabled == TRUE) { +#endif /* !L2_MULTICAST_DISABLE && !IPV6_DISABLE */ + +#if !defined(L3_MULTICAST_DISABLE) && !defined(IPV6_DISABLE) + if (DO_LOOKUP(L3) and + (multicast_metadata.ipv6_multicast_enabled == TRUE)) { apply(ipv6_multicast_route) { on_miss { apply(ipv6_multicast_route_star_g); } } } -#endif /* !defined(MULTICAST_DISABLE) && !defined(IPV6_DISABLE) */ +#endif /* !L3_MULTICAST_DISABLE && !IPV6_DISABLE */ } + /*****************************************************************************/ /* IP multicast processing */ /*****************************************************************************/ @@ -519,7 +542,7 @@ control process_multicast { /* Multicast flooding */ /*****************************************************************************/ action set_bd_flood_mc_index(mc_index) { - modify_field(intrinsic_metadata.mcast_grp, mc_index); + modify_field(intrinsic_mcast_grp, mc_index); } table bd_flood { @@ -569,7 +592,7 @@ action inner_replica_from_rid(bd, tunnel_index, tunnel_type, header_count) { table rid { reads { - intrinsic_metadata.egress_rid : exact; + egress_egress_rid : exact; } actions { nop; @@ -598,7 +621,7 @@ table replica_type { control process_replication { #ifndef MULTICAST_DISABLE - if (intrinsic_metadata.egress_rid != 0) { + if(egress_egress_rid != 0) { /* set info from rid */ apply(rid); diff --git a/p4src/nexthop.p4 b/p4src/nexthop.p4 index 1b04f8f..c88e577 100644 --- a/p4src/nexthop.p4 +++ b/p4src/nexthop.p4 @@ -36,7 +36,7 @@ action set_l2_redirect_action() { modify_field(l3_metadata.nexthop_index, l2_metadata.l2_nexthop); modify_field(nexthop_metadata.nexthop_type, l2_metadata.l2_nexthop_type); modify_field(ingress_metadata.egress_ifindex, 0); - modify_field(intrinsic_metadata.mcast_grp, 0); + modify_field(intrinsic_mcast_grp, 0); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); #endif /* FABRIC_ENABLE */ @@ -46,7 +46,7 @@ action set_acl_redirect_action() { modify_field(l3_metadata.nexthop_index, acl_metadata.acl_nexthop); modify_field(nexthop_metadata.nexthop_type, acl_metadata.acl_nexthop_type); modify_field(ingress_metadata.egress_ifindex, 0); - modify_field(intrinsic_metadata.mcast_grp, 0); + modify_field(intrinsic_mcast_grp, 0); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); #endif /* FABRIC_ENABLE */ @@ -57,7 +57,7 @@ action set_racl_redirect_action() { modify_field(nexthop_metadata.nexthop_type, acl_metadata.racl_nexthop_type); modify_field(l3_metadata.routed, TRUE); modify_field(ingress_metadata.egress_ifindex, 0); - modify_field(intrinsic_metadata.mcast_grp, 0); + modify_field(intrinsic_mcast_grp, 0); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); #endif /* FABRIC_ENABLE */ @@ -67,7 +67,7 @@ action set_fib_redirect_action() { modify_field(l3_metadata.nexthop_index, l3_metadata.fib_nexthop); modify_field(nexthop_metadata.nexthop_type, l3_metadata.fib_nexthop_type); modify_field(l3_metadata.routed, TRUE); - modify_field(intrinsic_metadata.mcast_grp, 0); + modify_field(intrinsic_mcast_grp, 0); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); #endif /* FABRIC_ENABLE */ @@ -75,8 +75,8 @@ action set_fib_redirect_action() { action set_cpu_redirect_action() { modify_field(l3_metadata.routed, FALSE); - modify_field(intrinsic_metadata.mcast_grp, 0); - modify_field(standard_metadata.egress_spec, CPU_PORT_ID); + modify_field(intrinsic_mcast_grp, 0); + modify_field(ingress_egress_port, CPU_PORT_ID); modify_field(ingress_metadata.egress_ifindex, 0); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); @@ -88,7 +88,7 @@ action set_multicast_route_action() { modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); #endif /* FABRIC_ENABLE */ modify_field(ingress_metadata.egress_ifindex, 0); - modify_field(intrinsic_metadata.mcast_grp, + modify_field(intrinsic_mcast_grp, multicast_metadata.multicast_route_mc_index); modify_field(l3_metadata.routed, TRUE); modify_field(l3_metadata.same_bd_check, 0xFFFF); @@ -99,7 +99,7 @@ action set_multicast_bridge_action() { modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); #endif /* FABRIC_ENABLE */ modify_field(ingress_metadata.egress_ifindex, 0); - modify_field(intrinsic_metadata.mcast_grp, + modify_field(intrinsic_mcast_grp, multicast_metadata.multicast_bridge_mc_index); } @@ -151,7 +151,9 @@ table fwd_result { } control process_fwd_results { - apply(fwd_result); + if (not (BYPASS_ALL_LOOKUPS)) { + apply(fwd_result); + } } @@ -164,7 +166,7 @@ control process_fwd_results { */ action set_ecmp_nexthop_details_for_post_routed_flood(bd, uuc_mc_index, nhop_index) { - modify_field(intrinsic_metadata.mcast_grp, uuc_mc_index); + modify_field(intrinsic_mcast_grp, uuc_mc_index); modify_field(l3_metadata.nexthop_index, nhop_index); modify_field(ingress_metadata.egress_ifindex, 0); bit_xor(l3_metadata.same_bd_check, ingress_metadata.bd, bd); @@ -226,7 +228,7 @@ table ecmp_group { * egress BD */ action set_nexthop_details_for_post_routed_flood(bd, uuc_mc_index) { - modify_field(intrinsic_metadata.mcast_grp, uuc_mc_index); + modify_field(intrinsic_mcast_grp, uuc_mc_index); modify_field(ingress_metadata.egress_ifindex, 0); bit_xor(l3_metadata.same_bd_check, ingress_metadata.bd, bd); #ifdef FABRIC_ENABLE diff --git a/p4src/openflow.p4 b/p4src/openflow.p4 index 4ab764a..66dd965 100644 --- a/p4src/openflow.p4 +++ b/p4src/openflow.p4 @@ -96,7 +96,7 @@ action nop () { } action terminate_cpu_packet() { - modify_field(standard_metadata.egress_spec,fabric_header.dstPortOrGroup); + modify_field(ingress_egress_port,fabric_header.dstPortOrGroup); modify_field(ethernet.etherType, fabric_payload_header.etherType); remove_header(fabric_header); @@ -124,7 +124,7 @@ action openflow_miss(reason, table_id) { shift_left(fabric_metadata.reason_code, fabric_metadata.reason_code, 8); bit_or(fabric_metadata.reason_code, fabric_metadata.reason_code, table_id); - modify_field(standard_metadata.egress_spec, CPU_PORT_ID); + modify_field(ingress_egress_port, CPU_PORT_ID); } /*************************************************************** @@ -138,7 +138,7 @@ action packet_out_eth_flood() { } action packet_out_unicast() { - modify_field(standard_metadata.egress_spec, fabric_header.dstPortOrGroup); + modify_field(ingress_egress_port, fabric_header.dstPortOrGroup); terminate_cpu_packet(); modify_field(openflow_metadata.ofvalid, TRUE); } @@ -167,7 +167,7 @@ action ofpat_group_egress_update(bmap) { table ofpat_group_egress { reads { openflow_metadata.group_id : exact; - standard_metadata.egress_port : exact; + egress_egress_port : exact; } actions { @@ -181,11 +181,11 @@ table ofpat_group_egress { ****************************************************************/ action ofpat_group_ingress_uc(ifindex) { - modify_field(standard_metadata.egress_spec, ifindex); + modify_field(ingress_egress_port, ifindex); } action ofpat_group_ingress_mc(mcindex) { - modify_field(intrinsic_metadata.mcast_grp, mcindex); + modify_field(intrinsic_mcast_grp, mcindex); } table ofpat_group_ingress { @@ -204,15 +204,16 @@ table ofpat_group_ingress { * OFPAT_OUTPUT ****************************************************************/ -action ofpat_output(ifindex) { - modify_field(standard_metadata.egress_spec, ifindex); +action ofpat_output(egress_port) { + modify_field(ingress_egress_port, egress_port); + modify_field(ingress_metadata.egress_ifindex, 0); } table ofpat_output { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_spec : ternary; + ingress_egress_port : ternary; } actions { @@ -234,7 +235,7 @@ table ofpat_set_mpls_ttl { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -255,7 +256,7 @@ table ofpat_dec_mpls_ttl { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -277,7 +278,7 @@ table ofpat_push_mpls { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -298,7 +299,7 @@ table ofpat_pop_mpls { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -322,7 +323,7 @@ table ofpat_push_vlan { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -344,7 +345,7 @@ table ofpat_pop_vlan { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -365,7 +366,7 @@ table ofpat_set_field { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -396,7 +397,7 @@ table ofpat_set_nw_ttl_ipv4 { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -417,7 +418,7 @@ table ofpat_set_nw_ttl_ipv6 { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -438,7 +439,7 @@ table ofpat_dec_nw_ttl_ipv4 { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { @@ -459,7 +460,7 @@ table ofpat_dec_nw_ttl_ipv6 { reads { openflow_metadata.index : ternary; openflow_metadata.group_id : ternary; - standard_metadata.egress_port : ternary; + egress_egress_port : ternary; } actions { diff --git a/p4src/port.p4 b/p4src/port.p4 index 589a2fb..333c857 100644 --- a/p4src/port.p4 +++ b/p4src/port.p4 @@ -24,122 +24,72 @@ limitations under the License. action set_valid_outer_unicast_packet_untagged() { modify_field(l2_metadata.lkp_pkt_type, L2_UNICAST); modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_unicast_packet_single_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_UNICAST); modify_field(l2_metadata.lkp_mac_type, vlan_tag_[0].etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_unicast_packet_double_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_UNICAST); modify_field(l2_metadata.lkp_mac_type, vlan_tag_[1].etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_unicast_packet_qinq_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_UNICAST); modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_multicast_packet_untagged() { modify_field(l2_metadata.lkp_pkt_type, L2_MULTICAST); modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_multicast_packet_single_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_MULTICAST); modify_field(l2_metadata.lkp_mac_type, vlan_tag_[0].etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_multicast_packet_double_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_MULTICAST); modify_field(l2_metadata.lkp_mac_type, vlan_tag_[1].etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_multicast_packet_qinq_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_MULTICAST); modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_broadcast_packet_untagged() { modify_field(l2_metadata.lkp_pkt_type, L2_BROADCAST); modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_broadcast_packet_single_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_BROADCAST); modify_field(l2_metadata.lkp_mac_type, vlan_tag_[0].etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_broadcast_packet_double_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_BROADCAST); modify_field(l2_metadata.lkp_mac_type, vlan_tag_[1].etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action set_valid_outer_broadcast_packet_qinq_tagged() { modify_field(l2_metadata.lkp_pkt_type, L2_BROADCAST); modify_field(l2_metadata.lkp_mac_type, ethernet.etherType); - modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } action malformed_outer_ethernet_packet(drop_reason) { modify_field(ingress_metadata.drop_flag, TRUE); modify_field(ingress_metadata.drop_reason, drop_reason); - modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); - modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); } table validate_outer_ethernet { reads { - l2_metadata.lkp_mac_sa : ternary; - l2_metadata.lkp_mac_da : ternary; + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; vlan_tag_[0] : valid; vlan_tag_[1] : valid; } @@ -173,9 +123,11 @@ control process_validate_outer_header { if (valid(ipv6)) { validate_outer_ipv6_header(); } else { +#ifndef MPLS_DISABLE if (valid(mpls[0])) { validate_mpls_header(); } +#endif } } } @@ -186,9 +138,8 @@ control process_validate_outer_header { /*****************************************************************************/ /* Ingress port lookup */ /*****************************************************************************/ -action set_ifindex(ifindex, if_label, port_type) { +action set_ifindex(ifindex, port_type) { modify_field(ingress_metadata.ifindex, ifindex); - modify_field(acl_metadata.if_label, if_label); modify_field(ingress_metadata.port_type, port_type); } @@ -202,8 +153,23 @@ table ingress_port_mapping { size : PORTMAP_TABLE_SIZE; } +action set_ingress_port_properties(if_label) { + modify_field(acl_metadata.if_label, if_label); +} + +table ingress_port_properties { + reads { + ingress_input_port : exact; + } + actions { + set_ingress_port_properties; + } + size : PORTMAP_TABLE_SIZE; +} + control process_ingress_port_mapping { apply(ingress_port_mapping); + apply(ingress_port_properties); } @@ -334,7 +300,7 @@ action set_lag_remote_port(device, port) { #endif /* FABRIC_ENABLE */ action set_lag_port(port) { - modify_field(standard_metadata.egress_spec, port); + modify_field(ingress_egress_port, port); } action set_lag_miss() { @@ -375,19 +341,21 @@ action egress_port_type_normal(ifindex) { action egress_port_type_fabric(ifindex) { modify_field(egress_metadata.port_type, PORT_TYPE_FABRIC); + modify_field(egress_metadata.ifindex, ifindex); modify_field(tunnel_metadata.egress_tunnel_type, EGRESS_TUNNEL_TYPE_FABRIC); modify_field(egress_metadata.ifindex, ifindex); } action egress_port_type_cpu(ifindex) { modify_field(egress_metadata.port_type, PORT_TYPE_CPU); + modify_field(egress_metadata.ifindex, ifindex); modify_field(tunnel_metadata.egress_tunnel_type, EGRESS_TUNNEL_TYPE_CPU); modify_field(egress_metadata.ifindex, ifindex); } table egress_port_mapping { reads { - standard_metadata.egress_port : exact; + egress_egress_port : exact; } actions { egress_port_type_normal; diff --git a/p4src/rewrite.p4 b/p4src/rewrite.p4 index 3872d68..3d6028c 100644 --- a/p4src/rewrite.p4 +++ b/p4src/rewrite.p4 @@ -147,6 +147,8 @@ control process_rewrite { (l3_metadata.nexthop_index != 0)) { apply(rewrite); } else { +#ifndef MULTICAST_DISABLE apply(rewrite_multicast); +#endif /* MULTICAST_DISABLE */ } } diff --git a/p4src/security.p4 b/p4src/security.p4 index 0b86e55..48e4f71 100644 --- a/p4src/security.p4 +++ b/p4src/security.p4 @@ -44,7 +44,7 @@ counter storm_control_stats { table storm_control_stats { reads { meter_metadata.meter_color: exact; - ingress_metadata.ingress_port: exact; + ingress_input_port: exact; } actions { nop; @@ -72,7 +72,7 @@ action set_storm_control_meter(meter_idx) { table storm_control { reads { - ingress_metadata.ingress_port : exact; + ingress_input_port : exact; l2_metadata.lkp_pkt_type : ternary; } actions { @@ -85,7 +85,9 @@ table storm_control { control process_storm_control { #ifndef STORM_CONTROL_DISABLE - apply(storm_control); + if (ingress_metadata.port_type == PORT_TYPE_NORMAL) { + apply(storm_control); + } #endif /* STORM_CONTROL_DISABLE */ } @@ -135,7 +137,8 @@ table ipsg { control process_ip_sourceguard { #ifndef IPSG_DISABLE /* l2 security features */ - if (security_metadata.ipsg_enabled == TRUE) { + if ((ingress_metadata.port_type == PORT_TYPE_NORMAL) and + (security_metadata.ipsg_enabled == TRUE)) { apply(ipsg) { on_miss { apply(ipsg_permit_special); diff --git a/p4src/switch.p4 b/p4src/switch.p4 index 61d95d8..3afe011 100644 --- a/p4src/switch.p4 +++ b/p4src/switch.p4 @@ -21,6 +21,7 @@ limitations under the License. #include "includes/sizes.p4" #include "includes/defines.p4" #include "includes/intrinsic.p4" +#include "archdeps.p4" /* METADATA */ header_type ingress_metadata_t { @@ -36,6 +37,7 @@ header_type ingress_metadata_t { drop_flag : 1; /* if set, drop the packet */ drop_reason : 8; /* drop reason */ control_frame: 1; /* control frame */ + bypass_lookups : 16; /* list of lookups to skip */ } } @@ -105,30 +107,34 @@ control ingress { /* read and apply system confuration parametes */ process_global_params(); - if (ingress_metadata.port_type == PORT_TYPE_NORMAL) { +#ifdef OPENFLOW_ENABLE + if (ingress_metadata.port_type == PORT_TYPE_CPU) { + apply(packet_out); + } +#endif /* OPENFLOW_ENABLE */ - /* derive bd */ - process_port_vlan_mapping(); + /* derive bd and its properties */ + process_port_vlan_mapping(); - /* spanning tree state checks */ - process_spanning_tree(); + /* spanning tree state checks */ + process_spanning_tree(); - /* IPSG */ - process_ip_sourceguard(); + /* IPSG */ + process_ip_sourceguard(); - /* INT src,sink determination */ - process_int_endpoint(); + /* INT src,sink determination */ + process_int_endpoint(); - /* tunnel termination processing */ - process_tunnel(); + /* tunnel termination processing */ + process_tunnel(); - /* storm control */ - process_storm_control(); + /* storm control */ + process_storm_control(); -#ifndef TUNNEL_DISABLE - if ((not valid(mpls[0])) or - (valid(mpls[0]) and (tunnel_metadata.tunnel_terminate == TRUE))) { -#endif /* TUNNEL_DISABLE */ + if (ingress_metadata.port_type != PORT_TYPE_FABRIC) { +#ifndef MPLS_DISABLE + if (not (valid(mpls[0]) and (l3_metadata.fib_hit == TRUE))) { +#endif /* MPLS_DISABLE */ /* validate packet */ process_validate_packet(); @@ -150,52 +156,42 @@ control ingress { process_multicast(); } default { - if ((l3_metadata.lkp_ip_type == IPTYPE_IPV4) and - (ipv4_metadata.ipv4_unicast_enabled == TRUE)) { - /* router ACL/PBR */ - process_ipv4_racl(); + if (DO_LOOKUP(L3)) { + if ((l3_metadata.lkp_ip_type == IPTYPE_IPV4) and + (ipv4_metadata.ipv4_unicast_enabled == TRUE)) { + /* router ACL/PBR */ + process_ipv4_racl(); - process_ipv4_urpf(); - process_ipv4_fib(); + process_ipv4_urpf(); + process_ipv4_fib(); - } else { - if ((l3_metadata.lkp_ip_type == IPTYPE_IPV6) and - (ipv6_metadata.ipv6_unicast_enabled == TRUE)) { + } else { + if ((l3_metadata.lkp_ip_type == IPTYPE_IPV6) and + (ipv6_metadata.ipv6_unicast_enabled == TRUE)) { - /* router ACL/PBR */ - process_ipv6_racl(); - process_ipv6_urpf(); - process_ipv6_fib(); + /* router ACL/PBR */ + process_ipv6_racl(); + process_ipv6_urpf(); + process_ipv6_fib(); + } } + process_urpf_bd(); } - process_urpf_bd(); } } -#ifndef TUNNEL_DISABLE +#ifndef MPLS_DISABLE } -#endif /* TUNNEL_DISABLE */ - } else { - -#ifdef OPENFLOW_ENABLE - apply(packet_out) { - nop { -#endif /* OPENFLOW_ENABLE */ - /* ingress fabric processing */ - process_ingress_fabric(); -#ifdef OPENFLOW_ENABLE - } - } -#endif /* OPENFLOW_ENABLE */ +#endif /* MPLS_DISABLE */ } process_meter_index(); - /* compute hashes based on packet type */ + /* compute hashes based on packet type */ process_hashes(); process_meter_action(); - if (ingress_metadata.port_type == PORT_TYPE_NORMAL) { + if (ingress_metadata.port_type != PORT_TYPE_FABRIC) { /* update statistics */ process_ingress_bd_stats(); process_ingress_acl_stats(); @@ -227,7 +223,7 @@ control ingress { /* resolve fabric port to destination device */ process_fabric_lag(); - if (ingress_metadata.port_type == PORT_TYPE_NORMAL) { + if (ingress_metadata.port_type != PORT_TYPE_FABRIC) { /* system acls */ process_system_acl(); } diff --git a/p4src/switch_config.p4 b/p4src/switch_config.p4 index c600c7d..93ee27a 100644 --- a/p4src/switch_config.p4 +++ b/p4src/switch_config.p4 @@ -23,7 +23,12 @@ action set_config_parameters(enable_dod) { * or take appropriate action */ deflect_on_drop(enable_dod); - /* Add more parameters here */ + + /* initialization */ + modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); + modify_field(ingress_metadata.ingress_port, ingress_input_port); + modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); + modify_field(ingress_egress_port, INVALID_PORT_ID); } table switch_config_params { diff --git a/p4src/tunnel.p4 b/p4src/tunnel.p4 index ab24586..075dc27 100644 --- a/p4src/tunnel.p4 +++ b/p4src/tunnel.p4 @@ -39,6 +39,7 @@ header_type tunnel_metadata_t { tunnel_terminate : 1; /* is tunnel being terminated? */ tunnel_if_check : 1; /* tun terminate xor originate */ egress_header_count: 4; /* number of mpls header stack */ + inner_ip_proto : 8; /* Inner IP protocol */ } } metadata tunnel_metadata_t tunnel_metadata; @@ -54,7 +55,7 @@ action outer_rmac_hit() { table outer_rmac { reads { l3_metadata.rmac_group : exact; - l2_metadata.lkp_mac_da : exact; + ethernet.dstAddr : exact; } actions { on_miss; @@ -72,6 +73,10 @@ action set_tunnel_termination_flag() { modify_field(tunnel_metadata.tunnel_terminate, TRUE); } +action set_tunnel_vni_and_termination_flag(tunnel_vni) { + modify_field(tunnel_metadata.tunnel_vni, tunnel_vni); + modify_field(tunnel_metadata.tunnel_terminate, TRUE); +} action src_vtep_hit(ifindex) { modify_field(ingress_metadata.ifindex, ifindex); } @@ -80,12 +85,13 @@ action src_vtep_hit(ifindex) { table ipv4_dest_vtep { reads { l3_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_da : exact; + ipv4.dstAddr : exact; tunnel_metadata.ingress_tunnel_type : exact; } actions { nop; set_tunnel_termination_flag; + set_tunnel_vni_and_termination_flag; } size : DEST_TUNNEL_TABLE_SIZE; } @@ -93,7 +99,8 @@ table ipv4_dest_vtep { table ipv4_src_vtep { reads { l3_metadata.vrf : exact; - ipv4_metadata.lkp_ipv4_sa : exact; + ipv4.srcAddr : exact; + tunnel_metadata.ingress_tunnel_type : exact; } actions { on_miss; @@ -111,12 +118,13 @@ table ipv4_src_vtep { table ipv6_dest_vtep { reads { l3_metadata.vrf : exact; - ipv6_metadata.lkp_ipv6_da : exact; + ipv6.dstAddr : exact; tunnel_metadata.ingress_tunnel_type : exact; } actions { nop; set_tunnel_termination_flag; + set_tunnel_vni_and_termination_flag; } size : DEST_TUNNEL_TABLE_SIZE; } @@ -124,13 +132,14 @@ table ipv6_dest_vtep { table ipv6_src_vtep { reads { l3_metadata.vrf : exact; - ipv6_metadata.lkp_ipv6_sa : exact; + ipv6.srcAddr : exact; + tunnel_metadata.ingress_tunnel_type : exact; } actions { on_miss; src_vtep_hit; } - size : SRC_TUNNEL_TABLE_SIZE; + size : IPV6_SRC_TUNNEL_TABLE_SIZE; } #endif /* IPV6_DISABLE */ #endif /* TUNNEL_DISABLE */ @@ -163,12 +172,11 @@ control process_ipv6_vtep { action terminate_tunnel_inner_non_ip(bd, bd_label, stats_idx) { modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(ingress_metadata.bd, bd); - modify_field(l3_metadata.lkp_ip_type, IPTYPE_NONE); - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); - modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); modify_field(acl_metadata.bd_label, bd_label); modify_field(l2_metadata.bd_stats_idx, stats_idx); + + modify_field(l3_metadata.lkp_ip_type, IPTYPE_NONE); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); } #ifndef IPV4_DISABLE @@ -181,25 +189,17 @@ action terminate_tunnel_inner_ethernet_ipv4(bd, vrf, modify_field(ingress_metadata.bd, bd); modify_field(l3_metadata.vrf, vrf); modify_field(qos_metadata.outer_dscp, l3_metadata.lkp_ip_tc); - - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); - modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); - modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV4); - modify_field(ipv4_metadata.lkp_ipv4_sa, inner_ipv4.srcAddr); - modify_field(ipv4_metadata.lkp_ipv4_da, inner_ipv4.dstAddr); - modify_field(l3_metadata.lkp_ip_version, inner_ipv4.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv4.protocol); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv4.ttl); - modify_field(l3_metadata.lkp_ip_tc, inner_ipv4.diffserv); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); modify_field(l3_metadata.rmac_group, rmac_group); modify_field(acl_metadata.bd_label, bd_label); modify_field(l2_metadata.bd_stats_idx, stats_idx); + modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV4); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); + modify_field(l3_metadata.lkp_ip_version, inner_ipv4.version); + modify_field(l3_metadata.lkp_ip_tc, inner_ipv4.diffserv); + modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); modify_field(multicast_metadata.ipv4_multicast_enabled, @@ -213,19 +213,15 @@ action terminate_tunnel_inner_ipv4(vrf, rmac_group, modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(l3_metadata.vrf, vrf); modify_field(qos_metadata.outer_dscp, l3_metadata.lkp_ip_tc); + modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); + modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV4); - modify_field(ipv4_metadata.lkp_ipv4_sa, inner_ipv4.srcAddr); - modify_field(ipv4_metadata.lkp_ipv4_da, inner_ipv4.dstAddr); modify_field(l3_metadata.lkp_ip_version, inner_ipv4.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv4.protocol); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv4.ttl); modify_field(l3_metadata.lkp_ip_tc, inner_ipv4.diffserv); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); - modify_field(ipv4_metadata.ipv4_unicast_enabled, ipv4_unicast_enabled); - modify_field(ipv4_metadata.ipv4_urpf_mode, ipv4_urpf_mode); - modify_field(l3_metadata.rmac_group, rmac_group); modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); modify_field(multicast_metadata.ipv4_multicast_enabled, @@ -243,25 +239,17 @@ action terminate_tunnel_inner_ethernet_ipv6(bd, vrf, modify_field(ingress_metadata.bd, bd); modify_field(l3_metadata.vrf, vrf); modify_field(qos_metadata.outer_dscp, l3_metadata.lkp_ip_tc); - - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); - modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); - modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV6); - modify_field(ipv6_metadata.lkp_ipv6_sa, inner_ipv6.srcAddr); - modify_field(ipv6_metadata.lkp_ipv6_da, inner_ipv6.dstAddr); - modify_field(l3_metadata.lkp_ip_version, inner_ipv6.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv6.nextHdr); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv6.hopLimit); - modify_field(l3_metadata.lkp_ip_tc, inner_ipv6.trafficClass); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); modify_field(l3_metadata.rmac_group, rmac_group); modify_field(acl_metadata.bd_label, bd_label); modify_field(l2_metadata.bd_stats_idx, stats_idx); + modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV6); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); + modify_field(l3_metadata.lkp_ip_version, inner_ipv6.version); + modify_field(l3_metadata.lkp_ip_tc, inner_ipv6.trafficClass); + modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); modify_field(multicast_metadata.ipv6_multicast_enabled, ipv6_multicast_enabled); @@ -274,19 +262,15 @@ action terminate_tunnel_inner_ipv6(vrf, rmac_group, modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(l3_metadata.vrf, vrf); modify_field(qos_metadata.outer_dscp, l3_metadata.lkp_ip_tc); + modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); + modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); + modify_field(l3_metadata.rmac_group, rmac_group); + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV6); - modify_field(ipv6_metadata.lkp_ipv6_sa, inner_ipv6.srcAddr); - modify_field(ipv6_metadata.lkp_ipv6_da, inner_ipv6.dstAddr); modify_field(l3_metadata.lkp_ip_version, inner_ipv6.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv6.nextHdr); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv6.hopLimit); modify_field(l3_metadata.lkp_ip_tc, inner_ipv6.trafficClass); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); - modify_field(ipv6_metadata.ipv6_unicast_enabled, ipv6_unicast_enabled); - modify_field(ipv6_metadata.ipv6_urpf_mode, ipv6_urpf_mode); - modify_field(l3_metadata.rmac_group, rmac_group); modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); modify_field(multicast_metadata.ipv6_multicast_enabled, @@ -297,15 +281,6 @@ action terminate_tunnel_inner_ipv6(vrf, rmac_group, action tunnel_lookup_miss() { } -table tunnel_miss { - actions { - tunnel_lookup_miss; - } -} - -/*****************************************************************************/ -/* Ingress tunnel processing */ -/*****************************************************************************/ table tunnel { reads { tunnel_metadata.tunnel_vni : exact; @@ -314,6 +289,7 @@ table tunnel { inner_ipv6 : valid; } actions { + nop; tunnel_lookup_miss; terminate_tunnel_inner_non_ip; #ifndef IPV4_DISABLE @@ -329,7 +305,72 @@ table tunnel { } #endif /* TUNNEL_DISABLE */ +action ipv4_tunnel_lookup_miss() { + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ipv4_metadata.lkp_ipv4_sa, ipv4.srcAddr); + modify_field(ipv4_metadata.lkp_ipv4_da, ipv4.dstAddr); + modify_field(l3_metadata.lkp_ip_proto, ipv4.protocol); + modify_field(l3_metadata.lkp_ip_ttl, ipv4.ttl); + modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_outer_l4_sport); + modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_outer_l4_dport); + modify_field(intrinsic_mcast_grp, 0); +} + +action ipv6_tunnel_lookup_miss() { + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(ipv6_metadata.lkp_ipv6_sa, ipv6.srcAddr); + modify_field(ipv6_metadata.lkp_ipv6_da, ipv6.dstAddr); + modify_field(l3_metadata.lkp_ip_proto, ipv6.nextHdr); + modify_field(l3_metadata.lkp_ip_ttl, ipv6.hopLimit); + modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_outer_l4_sport); + modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_outer_l4_dport); + modify_field(intrinsic_mcast_grp, 0); +} + +action non_ip_tunnel_lookup_miss() { + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); + modify_field(intrinsic_mcast_grp, 0); +} + +table tunnel_miss { + reads { + ipv4 : valid; + ipv6 : valid; + } + actions { + non_ip_tunnel_lookup_miss; + ipv4_tunnel_lookup_miss; +#ifndef IPV6_DISABLE + ipv6_tunnel_lookup_miss; +#endif /* IPV6_DISABLE */ + } +} + +table tunnel_lookup_miss { + reads { + ipv4 : valid; + ipv6 : valid; + } + actions { + non_ip_tunnel_lookup_miss; + ipv4_tunnel_lookup_miss; +#ifndef IPV6_DISABLE + ipv6_tunnel_lookup_miss; +#endif /* IPV6_DISABLE */ + } +} + +/*****************************************************************************/ +/* Ingress tunnel processing */ +/*****************************************************************************/ control process_tunnel { + + /* ingress fabric processing */ + process_ingress_fabric(); + #ifndef TUNNEL_DISABLE if (tunnel_metadata.ingress_tunnel_type != INGRESS_TUNNEL_TYPE_NONE) { @@ -346,9 +387,11 @@ control process_tunnel { process_ipv6_vtep(); } else { /* check for mpls tunnel termination */ +#ifndef MPLS_DISABLE if (valid(mpls[0])) { process_mpls(); } +#endif } } } @@ -362,7 +405,11 @@ control process_tunnel { (multicast_metadata.mcast_rpf_group == 0)) or ((multicast_metadata.outer_mcast_mode == MCAST_MODE_BIDIR) and (multicast_metadata.mcast_rpf_group != 0))))) { - apply(tunnel); + apply(tunnel) { + tunnel_lookup_miss { + apply(tunnel_lookup_miss); + } + } } else { apply(tunnel_miss); } @@ -423,10 +470,8 @@ control validate_mpls_header { action terminate_eompls(bd, tunnel_type) { modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(tunnel_metadata.ingress_tunnel_type, tunnel_type); - modify_field(ingress_metadata.bd, bd); - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); } @@ -434,8 +479,7 @@ action terminate_vpls(bd, tunnel_type) { modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(tunnel_metadata.ingress_tunnel_type, tunnel_type); modify_field(ingress_metadata.bd, bd); - modify_field(l2_metadata.lkp_mac_sa, inner_ethernet.srcAddr); - modify_field(l2_metadata.lkp_mac_da, inner_ethernet.dstAddr); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); } @@ -443,17 +487,14 @@ action terminate_vpls(bd, tunnel_type) { action terminate_ipv4_over_mpls(vrf, tunnel_type) { modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(tunnel_metadata.ingress_tunnel_type, tunnel_type); - modify_field(l3_metadata.vrf, vrf); + + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV4); - modify_field(ipv4_metadata.lkp_ipv4_sa, inner_ipv4.srcAddr); - modify_field(ipv4_metadata.lkp_ipv4_da, inner_ipv4.dstAddr); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); modify_field(l3_metadata.lkp_ip_version, inner_ipv4.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv4.protocol); modify_field(l3_metadata.lkp_ip_tc, inner_ipv4.diffserv); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv4.ttl); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); } #endif /* IPV4_DISABLE */ @@ -461,28 +502,31 @@ action terminate_ipv4_over_mpls(vrf, tunnel_type) { action terminate_ipv6_over_mpls(vrf, tunnel_type) { modify_field(tunnel_metadata.tunnel_terminate, TRUE); modify_field(tunnel_metadata.ingress_tunnel_type, tunnel_type); - modify_field(l3_metadata.vrf, vrf); + + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV6); - modify_field(ipv6_metadata.lkp_ipv6_sa, inner_ipv6.srcAddr); - modify_field(ipv6_metadata.lkp_ipv6_da, inner_ipv6.dstAddr); + modify_field(l2_metadata.lkp_mac_type, inner_ethernet.etherType); modify_field(l3_metadata.lkp_ip_version, inner_ipv6.version); - modify_field(l3_metadata.lkp_ip_proto, inner_ipv6.nextHdr); modify_field(l3_metadata.lkp_ip_tc, inner_ipv6.trafficClass); - modify_field(l3_metadata.lkp_ip_ttl, inner_ipv6.hopLimit); - modify_field(l3_metadata.lkp_l4_sport, l3_metadata.lkp_inner_l4_sport); - modify_field(l3_metadata.lkp_l4_dport, l3_metadata.lkp_inner_l4_dport); } #endif /* IPV6_DISABLE */ action terminate_pw(ifindex) { modify_field(ingress_metadata.egress_ifindex, ifindex); + + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); } action forward_mpls(nexthop_index) { modify_field(l3_metadata.fib_nexthop, nexthop_index); modify_field(l3_metadata.fib_nexthop_type, NEXTHOP_TYPE_SIMPLE); modify_field(l3_metadata.fib_hit, TRUE); + + modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); + modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); } table mpls { @@ -514,7 +558,7 @@ control process_mpls { } -#ifndef TUNNEL_DISABLE +#ifndef TUNNEL_DISABLE /*****************************************************************************/ /* Tunnel decap (strip tunnel header) */ /*****************************************************************************/ @@ -568,6 +612,7 @@ action decap_genv_inner_non_ip() { remove_header(ipv6); } +#ifndef NVGRE_DISABLE action decap_nvgre_inner_ipv4() { copy_header(ethernet, inner_ethernet); copy_header(ipv4, inner_ipv4); @@ -595,8 +640,9 @@ action decap_nvgre_inner_non_ip() { remove_header(ipv4); remove_header(ipv6); } +#endif -action decap_ip_inner_ipv4() { +action decap_gre_inner_ipv4() { copy_header(ipv4, inner_ipv4); remove_header(gre); remove_header(ipv6); @@ -604,7 +650,7 @@ action decap_ip_inner_ipv4() { modify_field(ethernet.etherType, ETHERTYPE_IPV4); } -action decap_ip_inner_ipv6() { +action decap_gre_inner_ipv6() { copy_header(ipv6, inner_ipv6); remove_header(gre); remove_header(ipv4); @@ -612,6 +658,27 @@ action decap_ip_inner_ipv6() { modify_field(ethernet.etherType, ETHERTYPE_IPV6); } +action decap_gre_inner_non_ip() { + modify_field(ethernet.etherType, gre.proto); + remove_header(gre); + remove_header(ipv4); + remove_header(inner_ipv6); +} + +action decap_ip_inner_ipv4() { + copy_header(ipv4, inner_ipv4); + remove_header(ipv6); + remove_header(inner_ipv4); + modify_field(ethernet.etherType, ETHERTYPE_IPV4); +} + +action decap_ip_inner_ipv6() { + copy_header(ipv6, inner_ipv6); + remove_header(ipv4); + remove_header(inner_ipv6); + modify_field(ethernet.etherType, ETHERTYPE_IPV6); +} + #ifndef MPLS_DISABLE action decap_mpls_inner_ipv4_pop1() { remove_header(mpls[0]); @@ -750,9 +817,14 @@ table tunnel_decap_process_outer { decap_genv_inner_ipv4; decap_genv_inner_ipv6; decap_genv_inner_non_ip; +#ifndef NVGRE_DISABLE decap_nvgre_inner_ipv4; decap_nvgre_inner_ipv6; decap_nvgre_inner_non_ip; +#endif + decap_gre_inner_ipv4; + decap_gre_inner_ipv6; + decap_gre_inner_non_ip; decap_ip_inner_ipv4; decap_ip_inner_ipv6; #ifndef MPLS_DISABLE @@ -863,6 +935,7 @@ action inner_ipv4_udp_rewrite() { modify_field(egress_metadata.payload_length, ipv4.totalLen); remove_header(udp); remove_header(ipv4); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV4); } action inner_ipv4_tcp_rewrite() { @@ -871,6 +944,7 @@ action inner_ipv4_tcp_rewrite() { modify_field(egress_metadata.payload_length, ipv4.totalLen); remove_header(tcp); remove_header(ipv4); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV4); } action inner_ipv4_icmp_rewrite() { @@ -879,12 +953,14 @@ action inner_ipv4_icmp_rewrite() { modify_field(egress_metadata.payload_length, ipv4.totalLen); remove_header(icmp); remove_header(ipv4); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV4); } action inner_ipv4_unknown_rewrite() { copy_header(inner_ipv4, ipv4); modify_field(egress_metadata.payload_length, ipv4.totalLen); remove_header(ipv4); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV4); } action inner_ipv6_udp_rewrite() { @@ -892,6 +968,7 @@ action inner_ipv6_udp_rewrite() { copy_header(inner_udp, udp); add(egress_metadata.payload_length, ipv6.payloadLen, 40); remove_header(ipv6); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV6); } action inner_ipv6_tcp_rewrite() { @@ -900,6 +977,7 @@ action inner_ipv6_tcp_rewrite() { add(egress_metadata.payload_length, ipv6.payloadLen, 40); remove_header(tcp); remove_header(ipv6); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV6); } action inner_ipv6_icmp_rewrite() { @@ -908,12 +986,14 @@ action inner_ipv6_icmp_rewrite() { add(egress_metadata.payload_length, ipv6.payloadLen, 40); remove_header(icmp); remove_header(ipv6); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV6); } action inner_ipv6_unknown_rewrite() { copy_header(inner_ipv6, ipv6); add(egress_metadata.payload_length, ipv6.payloadLen, 40); remove_header(ipv6); + modify_field(tunnel_metadata.inner_ip_proto, IP_PROTOCOLS_IPV6); } action inner_non_ip_rewrite() { @@ -1028,6 +1108,7 @@ action ipv6_genv_rewrite() { modify_field(ethernet.etherType, ETHERTYPE_IPV6); } +#ifndef NVGRE_DISABLE action f_insert_nvgre_header() { copy_header(inner_ethernet, ethernet); add_header(gre); @@ -1063,6 +1144,7 @@ action ipv6_nvgre_rewrite() { add(ipv6.payloadLen, egress_metadata.payload_length, 22); modify_field(ethernet.etherType, ETHERTYPE_IPV6); } +#endif action f_insert_gre_header() { add_header(gre); @@ -1072,39 +1154,27 @@ action ipv4_gre_rewrite() { f_insert_gre_header(); modify_field(gre.proto, ethernet.etherType); f_insert_ipv4_header(IP_PROTOCOLS_GRE); - add(ipv4.totalLen, egress_metadata.payload_length, 38); + add(ipv4.totalLen, egress_metadata.payload_length, 24); modify_field(ethernet.etherType, ETHERTYPE_IPV4); } action ipv6_gre_rewrite() { f_insert_gre_header(); - modify_field(gre.proto, ETHERTYPE_IPV4); + modify_field(gre.proto, ethernet.etherType); f_insert_ipv6_header(IP_PROTOCOLS_GRE); - add(ipv6.payloadLen, egress_metadata.payload_length, 18); + add(ipv6.payloadLen, egress_metadata.payload_length, 4); modify_field(ethernet.etherType, ETHERTYPE_IPV6); } -action ipv4_ipv4_rewrite() { - f_insert_ipv4_header(IP_PROTOCOLS_IPV4); +action ipv4_ip_rewrite() { + f_insert_ipv4_header(tunnel_metadata.inner_ip_proto); add(ipv4.totalLen, egress_metadata.payload_length, 20); modify_field(ethernet.etherType, ETHERTYPE_IPV4); } -action ipv4_ipv6_rewrite() { - f_insert_ipv4_header(IP_PROTOCOLS_IPV6); - add(ipv4.totalLen, egress_metadata.payload_length, 40); - modify_field(ethernet.etherType, ETHERTYPE_IPV4); -} - -action ipv6_ipv4_rewrite() { - f_insert_ipv6_header(IP_PROTOCOLS_IPV4); - add(ipv6.payloadLen, egress_metadata.payload_length, 20); - modify_field(ethernet.etherType, ETHERTYPE_IPV6); -} - -action ipv6_ipv6_rewrite() { - f_insert_ipv6_header(IP_PROTOCOLS_IPV6); - add(ipv6.payloadLen, egress_metadata.payload_length, 40); +action ipv6_ip_rewrite() { + f_insert_ipv6_header(tunnel_metadata.inner_ip_proto); + modify_field(ipv6.payloadLen, egress_metadata.payload_length); modify_field(ethernet.etherType, ETHERTYPE_IPV6); } @@ -1184,16 +1254,18 @@ table tunnel_encap_process_outer { nop; ipv4_vxlan_rewrite; ipv4_genv_rewrite; +#ifndef NVGRE_DISABLE ipv4_nvgre_rewrite; +#endif ipv4_gre_rewrite; - ipv4_ipv4_rewrite; - ipv4_ipv6_rewrite; - ipv6_ipv4_rewrite; + ipv4_ip_rewrite; ipv4_erspan_t3_rewrite; #ifndef TUNNEL_OVER_IPV6_DISABLE - ipv6_ipv6_rewrite; ipv6_gre_rewrite; + ipv6_ip_rewrite; +#ifndef NVGRE_DISABLE ipv6_nvgre_rewrite; +#endif ipv6_vxlan_rewrite; ipv6_genv_rewrite; ipv6_erspan_t3_rewrite; diff --git a/switchapi/Doxyfile b/switchapi/Doxyfile index b619e24..550f2c5 100644 --- a/switchapi/Doxyfile +++ b/switchapi/Doxyfile @@ -52,7 +52,7 @@ PROJECT_LOGO = # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = doc +OUTPUT_DIRECTORY = switchapi-doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output @@ -329,22 +329,6 @@ INLINE_SIMPLE_STRUCTS = NO TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the @@ -668,8 +652,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = main.dox \ - inc/switchapi +INPUT = switchapi/main.dox \ + switchapi/inc/switchapi # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/switchapi/README.md b/switchapi/README.md index 0d4870a..e5c8500 100644 --- a/switchapi/README.md +++ b/switchapi/README.md @@ -29,7 +29,7 @@ Supported Features 4. L3 Multicast (Sparse mode, SSM and Bidir) 5. LAG 6. ECMP -7. Tunneling: VXLAN and NVGRE (including L2/L3 Gateway), Geneve, and GRE +7. Tunneling: VXLAN and NVGRE (including L2/L3 Gateway), Geneve, GRE and IPinIP 8. Basic ACL: MAC and IP ACLs 9. Unicast RPF check 10. MPLS: LER, LSR, IPVPN @@ -48,8 +48,8 @@ Upcoming Features Documentation ------------- -To generate doxygen documentation for switchapi +To generate doxygen documentation for switchapi (from switch directory) - make doc + make doxygen-doc -or view a hosted version at http://p4lang.github.io/switchapi +or view a hosted version at http://p4lang.github.io/switch/switchapi-doc/html/ diff --git a/switchapi/configure.ac b/switchapi/configure.ac index ecb9df8..84c03fb 100644 --- a/switchapi/configure.ac +++ b/switchapi/configure.ac @@ -23,7 +23,6 @@ AC_ARG_ENABLE([bmv2], \ esac], []) AM_CONDITIONAL(TARGET_BMV2, [test "x$p4target" = "xbmv2"]) -AM_CONDITIONAL(TARGET_TOFINO, [test "x$p4target" = "xtofino"]) # Checks for programs. CFLAGS="-g -Wall -Wextra -Wno-unused-parameter" diff --git a/switchapi/inc/switchapi/switch_acl.h b/switchapi/inc/switchapi/switch_acl.h index 6d1951a..5dc79db 100644 --- a/switchapi/inc/switchapi/switch_acl.h +++ b/switchapi/inc/switchapi/switch_acl.h @@ -428,10 +428,10 @@ typedef union switch_acl_action_params_ { } redirect; /**< port redirect struct */ struct { uint16_t reason_code; /**< cpu reason code */ - } cpu_redirect; + } cpu_redirect; /**< cpu redirect struct */ struct { uint8_t reason_code; /**< drop reason code */ - } drop; + } drop; /**< drop action struct */ } switch_acl_action_params_t; /** Acl optional action parameters */ @@ -443,7 +443,7 @@ typedef struct switch_acl_opt_action_params_ { switch_handle_t counter_handle; /**< counter handle */ } switch_acl_opt_action_params_t; -/** Egress port ACL */ +/** Egress ACL field enum */ typedef enum switch_acl_egr_field_ { SWITCH_ACL_EGR_DEST_PORT, SWITCH_ACL_EGR_DEFLECT, @@ -451,20 +451,20 @@ typedef enum switch_acl_egr_field_ { SWITCH_ACL_EGR_FIELD_MAX } switch_acl_egr_field_t; -/** Egress port value */ +/** Egress ACL match value */ typedef union switch_acl_egr_value_ { - switch_handle_t egr_port; - bool deflection_flag; - unsigned short l3_mtu_check; + switch_handle_t egr_port; /**< egress port */ + bool deflection_flag; /**< deflection flag */ + unsigned short l3_mtu_check; /**< L3 MTU check */ } switch_acl_egr_value_t; -/** Egress acl port mask */ +/** Egress ACL match mask */ typedef union switch_acl_egr_mask_ { unsigned type:1; /**< acl mask type */ union { uint64_t mask; /**< mask value */ unsigned int start, end; /**< mask range */ - } u; /**< ip mask union */ + } u; /**< mask union */ } switch_acl_egr_mask_t; /** Egress acl key value pair */ @@ -526,7 +526,8 @@ switch_status_t switch_api_acl_list_delete(switch_device_t device, switch_handle @param key_value_count - key value pair count @param acl_kvp - pointer to multiple key value pair @param action - Acl action (permit/drop/redirect to cpu) - @param action_params - optional action parameters + @param action_params - action parameters + @param opt_action_params - optional action parameters @param ace_handle - returned handle for the rule */ switch_status_t switch_api_acl_rule_create(switch_device_t device, switch_handle_t acl_handle, diff --git a/switchapi/inc/switchapi/switch_base_types.h b/switchapi/inc/switchapi/switch_base_types.h index 41d39d8..71d646d 100644 --- a/switchapi/inc/switchapi/switch_base_types.h +++ b/switchapi/inc/switchapi/switch_base_types.h @@ -79,11 +79,11 @@ typedef enum { /** 128 bit field */ typedef struct uint128_t { union { - uint8_t addr8[16]; - uint16_t addr16[8]; - uint16_t addr32[4]; - } u; -} uint128_t; + uint8_t addr8[16]; /** 16x8bit */ + uint16_t addr16[8]; /** 8x16bit */ + uint32_t addr32[4]; /** 4x32bit */ + } u; /**< union */ +} uint128_t; /**< 128-bit value */ /** Mac address declaration for use in API */ typedef struct switch_mac_addr { diff --git a/switchapi/inc/switchapi/switch_hostif.h b/switchapi/inc/switchapi/switch_hostif.h index d29fd52..38f952a 100644 --- a/switchapi/inc/switchapi/switch_hostif.h +++ b/switchapi/inc/switchapi/switch_hostif.h @@ -109,7 +109,6 @@ typedef struct switch_hostif_packet_ { /** host interface */ typedef struct switch_hostif_ { - switch_handle_t handle; /**< front panel port id */ char intf_name[SWITCH_HOSTIF_NAME_SIZE]; /**< interface name */ } switch_hostif_t; @@ -198,6 +197,67 @@ switch_api_hostif_delete(switch_device_t device, switch_handle_t hostif_handle); switch_handle_t switch_api_cpu_nhop_get(switch_hostif_reason_code_t rcode); +typedef enum switch_packet_vlan_action { + SWITCH_PACKET_VLAN_NONE = 0x0, + SWITCH_PACKET_VLAN_ADD = 0x1, + SWITCH_PACKET_VLAN_REMOVE = 0x2, + SWITCH_PACKET_VLAN_SWAP = 0x3 +} switch_packet_vlan_action_t; + +typedef struct switch_packet_rx_key_ { + bool port_valid; + switch_handle_t port_handle; /**< port handle */ + bool port_lag_valid; + switch_handle_t port_lag_handle; /**< port or lag handle */ + bool handle_valid; + switch_handle_t handle; /**< bd or interface handle */ + bool reason_code_valid; + switch_hostif_reason_code_t reason_code; /**< reason code */ + uint32_t priority; +} switch_packet_rx_key_t; + +typedef struct switch_packet_rx_action_ { + switch_handle_t hostif_handle; + switch_vlan_t vlan_id; + switch_packet_vlan_action_t vlan_action; +} switch_packet_rx_action_t; + +typedef struct switch_packet_tx_key_ { + bool handle_valid; + switch_handle_t hostif_handle; + bool vlan_valid; + switch_vlan_t vlan_id; + uint32_t priority; +} switch_packet_tx_key_t; + +typedef struct switch_packet_tx_action_ { + switch_handle_t handle; /**< bd or interface handle */ + bool tx_bypass; /**< tx bypass */ + switch_handle_t port_handle; /**< egress port */ +} switch_packet_tx_action_t; + +switch_status_t +switch_api_packet_net_filter_tx_create( + switch_device_t device, + switch_packet_tx_key_t *tx_key, + switch_packet_tx_action_t *tx_action); + +switch_status_t +switch_api_packet_net_filter_tx_delete( + switch_device_t device, + switch_packet_tx_key_t *tx_key); + +switch_status_t +switch_api_packet_net_filter_rx_create( + switch_device_t device, + switch_packet_rx_key_t *rx_key, + switch_packet_rx_action_t *rx_action); + +switch_status_t +switch_api_packet_net_filter_rx_delete( + switch_device_t device, + switch_packet_rx_key_t *rx_key); + /** @} */ // end of Host Interface API #ifdef __cplusplus diff --git a/switchapi/inc/switchapi/switch_interface.h b/switchapi/inc/switchapi/switch_interface.h index 7e457c6..be4a167 100644 --- a/switchapi/inc/switchapi/switch_interface.h +++ b/switchapi/inc/switchapi/switch_interface.h @@ -270,6 +270,24 @@ switch_status_t switch_api_interface_get_type(switch_handle_t intf_handle, switch_interface_type_t *type); +switch_status_t +switch_api_l3_interface_bd_stats_enable( + switch_device_t device, + switch_handle_t intf_handle); + +switch_status_t +switch_api_l3_interface_bd_stats_disable( + switch_device_t device, + switch_handle_t intf_handle); + +switch_status_t +switch_api_l3_interface_stats_get( + switch_device_t device, + switch_handle_t intf_handle, + uint8_t count, + switch_bd_stats_id_t *counter_ids, + switch_counter_t *counters); + /** Dump interface table */ diff --git a/switchapi/inc/switchapi/switch_lag.h b/switchapi/inc/switchapi/switch_lag.h index 3dc637c..db4869c 100644 --- a/switchapi/inc/switchapi/switch_lag.h +++ b/switchapi/inc/switchapi/switch_lag.h @@ -40,13 +40,13 @@ extern "C" { /**< LACP Key */ typedef unsigned int lacp_key_t; - + /** type of LAG */ typedef enum switch_lag_type_ { SWITCH_API_LAG_SIMPLE, /**< simple hash */ SWITCH_API_LAG_RESILIENT /**< weighted/resilient hash */ } switch_lag_type_t; - + // Simple LAG API /** @@ -54,7 +54,7 @@ typedef enum switch_lag_type_ { @param device device to use */ switch_handle_t switch_api_lag_create(switch_device_t device); - + /** Link Aggregation Group deletion @param device device to use @@ -81,12 +81,12 @@ switch_status_t switch_api_lag_member_add(switch_device_t device, switch_handle_ */ switch_status_t switch_api_lag_member_delete(switch_device_t device, switch_handle_t lag_handle, switch_direction_t side, switch_port_t port); - + /** Link Aggregation Group member add by handle @param device device to use @param lag_handle handle of group returned on creation - @param side allow rx and rx member add separately + @param direction allow rx and rx member add separately @param port port in the same device on which lag_handle was created */ switch_handle_t diff --git a/switchapi/inc/switchapi/switch_mcast.h b/switchapi/inc/switchapi/switch_mcast.h index b92ab38..351a90b 100644 --- a/switchapi/inc/switchapi/switch_mcast.h +++ b/switchapi/inc/switchapi/switch_mcast.h @@ -91,7 +91,7 @@ switch_status_t switch_api_multicast_member_get(switch_device_t device, Add a (S,G) or (*, G) entry to MFIB. @param device - device that programs the tree @param mgid_handle - Handle that uniquely identifies multicast tree - @param vrf_handle - VRF handle + @param vlan_vrf_handle - VLAN/VRF handle @param src_ip - Source IP address @param grp_ip - Group IP address @param mc_mode - Multicast mode to indicate PIM SM/PIM BIDIR diff --git a/switchapi/inc/switchapi/switch_meter.h b/switchapi/inc/switchapi/switch_meter.h index afb4046..45605a4 100644 --- a/switchapi/inc/switchapi/switch_meter.h +++ b/switchapi/inc/switchapi/switch_meter.h @@ -27,7 +27,7 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -/** @defgroup Switching Meters Switching API +/** @defgroup Meters Meters Switching API * API functions listed to configure meters * @{ */ // begin of meters @@ -54,7 +54,7 @@ typedef enum switch_meter_type_ { SWITCH_METER_TYPE_BYTES = 2, } switch_meter_type_t; -/* Meter color */ +/** Meter color */ typedef enum switch_meter_color_ { SWITCH_METER_COLOR_GREEN, SWITCH_METER_COLOR_YELLOW, @@ -62,6 +62,7 @@ typedef enum switch_meter_color_ { SWITCH_METER_COLOR_MAX } switch_meter_color_t; +/** Meter stats */ typedef enum switch_meter_stats_ { SWITCH_METER_STATS_GREEEN, SWITCH_METER_STATS_YELLOW, diff --git a/switchapi/inc/switchapi/switch_mirror.h b/switchapi/inc/switchapi/switch_mirror.h index 68e818b..22e51d8 100644 --- a/switchapi/inc/switchapi/switch_mirror.h +++ b/switchapi/inc/switchapi/switch_mirror.h @@ -30,7 +30,7 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + /** * @defgroup Mirror Mirroring API * API functions define and manipulate Access lists @@ -41,55 +41,58 @@ extern "C" { /** Mirror ID */ typedef unsigned int switch_mirror_id_t; -/** Mirror Session type */ +/** Mirror Session Type */ typedef enum { SWITCH_MIRROR_SESSION_TYPE_SIMPLE, /**< Simple Mirror session */ SWITCH_MIRROR_SESSION_TYPE_TRUNCATE, /**< Truncate packet in session */ SWITCH_MIRROR_SESSION_TYPE_COALESCE /**< Coalesce mirrorred packets */ } switch_mirror_session_type_t; +/** Mirror Type */ typedef enum { - SWITCH_MIRROR_TYPE_NONE = 0, - SWITCH_MIRROR_TYPE_LOCAL = 1, - SWITCH_MIRROR_TYPE_REMOTE = 2, - SWITCH_MIRROR_TYPE_ENHANCED_REMOTE = 3 + SWITCH_MIRROR_TYPE_NONE = 0, /**< None */ + SWITCH_MIRROR_TYPE_LOCAL = 1, /**< Local */ + SWITCH_MIRROR_TYPE_REMOTE = 2, /**< RSPAN */ + SWITCH_MIRROR_TYPE_ENHANCED_REMOTE = 3 /**< ERSPAN */ } switch_mirror_type_t; +/** Mirror Session Info */ typedef struct switch_api_mirror_info_ { - switch_mirror_type_t mirror_type; - switch_mirror_id_t session_id; - switch_mirror_session_type_t session_type; - switch_handle_t egress_port; - switch_direction_t direction; - switch_cos_t cos; - switch_vlan_t vlan_id; - uint16_t vlan_tpid; - uint8_t vlan_priority; - bool tunnel_create; - bool vlan_create; - switch_encap_type_t encap_type; - switch_tunnel_info_t tunnel_info; - switch_mac_addr_t src_mac; - switch_mac_addr_t dst_mac; - uint32_t max_pkt_len; - switch_handle_t nhop_handle; - bool enable; - uint32_t extract_len; - uint32_t timeout_usec; + switch_mirror_type_t mirror_type; /**< Mirror type */ + switch_mirror_id_t session_id; /**< Session id */ + switch_mirror_session_type_t session_type; /**< Session type */ + switch_handle_t egress_port; /**< Egress port */ + switch_direction_t direction; /**< Direction - tx/rx */ + switch_cos_t cos; /**< VLAN CoS */ + switch_vlan_t vlan_id; /**< VLAN ID */ + uint16_t vlan_tpid; /**< VLAN Ethertype */ + uint8_t vlan_priority; /**< VLAN priority */ + bool tunnel_create; /**< Create tunnel? */ + bool vlan_create; /**< Create VLAN? */ + switch_encap_type_t encap_type; /**< Encap type */ + switch_tunnel_info_t tunnel_info; /**< Tunnel info */ + switch_mac_addr_t src_mac; /**< Source MAC */ + switch_mac_addr_t dst_mac; /**< Destination MAC */ + uint32_t max_pkt_len; /**< Max packet length */ + switch_handle_t nhop_handle; /**< Nexthop handle */ + bool enable; /**< Enable? */ + uint32_t extract_len; /**< Extract len */ + uint32_t timeout_usec; /**< Timeout in micro secs */ } switch_api_mirror_info_t; -/* +/** * MAX mirroring sessions supported */ #define SWITCH_MAX_MIRROR_SESSIONS 1024 + /** -* ID for cpu mirror session -*/ + * ID for cpu mirror session + */ #define SWITCH_CPU_MIRROR_SESSION_ID 250 /** -* ID for negative mirror session -*/ + * ID for negative mirror session + */ #define SWITCH_NEGATIVE_MIRROR_SESSION_ID 1015 /** @@ -111,21 +114,32 @@ switch_status_t switch_api_mirror_session_update(switch_device_t device, switch_handle_t mirror_handle, switch_api_mirror_info_t *api_mirror_info); /** - delete the mirror session + Delete the mirror session @param device device @param mirror_handle mirror handle */ switch_status_t switch_api_mirror_session_delete(switch_device_t device, - switch_handle_t mirror_handle); + switch_handle_t mirror_handle); +/** + Create nexthop for mirror session + @param device device + @param mirror_handle mirror handle + @param nhop_hdl nexthop handle +*/ switch_status_t switch_mirror_nhop_create(switch_device_t device, switch_handle_t mirror_handle, switch_handle_t nhop_hdl); +/** + Delete nexthop for mirror session + @param device device + @param mirror_handle mirror handle +*/ switch_status_t switch_mirror_nhop_delete(switch_device_t device, switch_handle_t mirror_handle); -/** @} */ // end of ACL API +/** @} */ // end of Mirror API #ifdef __cplusplus } diff --git a/switchapi/inc/switchapi/switch_protocol.h b/switchapi/inc/switchapi/switch_protocol.h index 950c608..aa1d44b 100644 --- a/switchapi/inc/switchapi/switch_protocol.h +++ b/switchapi/inc/switchapi/switch_protocol.h @@ -37,7 +37,8 @@ typedef enum switch_encap_type_ { SWITCH_API_ENCAP_TYPE_GRE=4, /**< GRE encapsulation */ SWITCH_API_ENCAP_TYPE_NVGRE=5, /**< NVGRE encapsulation */ SWITCH_API_ENCAP_TYPE_GENEVE=6, /**< Geneve encapsulation */ - SWITCH_API_ENCAP_TYPE_ERSPAN_T3=7 /**< ERSPAN type III encapsulation */ + SWITCH_API_ENCAP_TYPE_ERSPAN_T3=7, /**< ERSPAN type III encapsulation */ + SWITCH_API_ENCAP_TYPE_IPIP=8, /**< IP in IP encapsulation */ } switch_encap_type_t; /** UDP fields that are relevant */ @@ -205,8 +206,8 @@ typedef struct switch_encap_info_ { } u; /**< union */ } switch_encap_info_t; -/** @} */ // end of Protocol - +/** @} */ // end of Protocol + #ifdef __cplusplus } #endif diff --git a/switchapi/inc/switchapi/switch_tunnel.h b/switchapi/inc/switchapi/switch_tunnel.h index 1e11c7c..b3799d6 100644 --- a/switchapi/inc/switchapi/switch_tunnel.h +++ b/switchapi/inc/switchapi/switch_tunnel.h @@ -69,6 +69,8 @@ typedef enum switch_tunnel_type_egress_ { SWITCH_EGRESS_TUNNEL_TYPE_FABRIC = 15, SWITCH_EGRESS_TUNNEL_TYPE_CPU = 16, SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN_GPE = 17, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_IP = 18, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_IP = 19, } switch_tunnel_type_egress_t; /** Tunnel Ingress type */ @@ -76,7 +78,7 @@ typedef enum switch_tunnel_type_ingress_ { SWITCH_INGRESS_TUNNEL_TYPE_NONE = 0, SWITCH_INGRESS_TUNNEL_TYPE_VXLAN = 1, SWITCH_INGRESS_TUNNEL_TYPE_GRE = 2, - SWITCH_INGRESS_TUNNEL_TYPE_IP_IN_IP = 3, + SWITCH_INGRESS_TUNNEL_TYPE_IPIP = 3, SWITCH_INGRESS_TUNNEL_TYPE_GENEVE = 4, SWITCH_INGRESS_TUNNEL_TYPE_NVGRE = 5, SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_1 = 6, @@ -93,7 +95,7 @@ typedef enum switch_tunnel_type_ingress_ { /** Mpls ipv6 explicit null label */ #define SWITCH_MPLS_IPV6_EXPLICIT_NULL 2 - + /** Tunnel creation After tunnel creation another interface need to be created to offer @@ -105,7 +107,7 @@ typedef enum switch_tunnel_type_ingress_ { switch_handle_t switch_api_tunnel_interface_create(switch_device_t device, switch_direction_t direction, switch_tunnel_info_t *tunnel_info); - + /** Tunnel deletion No services should be configured on the tunnel when the tunnel is @@ -115,7 +117,7 @@ switch_handle_t switch_api_tunnel_interface_create(switch_device_t device, */ switch_status_t switch_api_tunnel_interface_delete(switch_device_t device, switch_handle_t tunnel_handle); - + /** Add member to logical network @param device device @@ -123,7 +125,7 @@ switch_status_t switch_api_tunnel_interface_delete(switch_device_t device, @param interface_handle Handle of access port ot Tunnel interface */ switch_status_t switch_api_logical_network_member_add(switch_device_t device, - switch_handle_t network_handle, + switch_handle_t network_handle, switch_handle_t interface_handle); /** @@ -150,7 +152,7 @@ switch_status_t switch_api_mpls_tunnel_transit_create(switch_device_t device, sw */ switch_status_t switch_api_mpls_tunnel_transit_delete(switch_device_t device, switch_mpls_encap_t *mpls_encap); /** @} */ // end of Tunnel API - + #ifdef __cplusplus } #endif diff --git a/switchapi/inc/switchapi/switch_vlan.h b/switchapi/inc/switchapi/switch_vlan.h index 263e6f3..22d9be9 100644 --- a/switchapi/inc/switchapi/switch_vlan.h +++ b/switchapi/inc/switchapi/switch_vlan.h @@ -87,28 +87,29 @@ typedef enum switch_ln_attr_ SWITCH_LN_ATTR_MAC_LEARNING } switch_ln_attr_t; -typedef enum _switch_vlan_stats_t +typedef enum _switch_bd_stats_t { - SWITCH_VLAN_STATS_IN_UCAST, - SWITCH_VLAN_STATS_IN_MCAST, - SWITCH_VLAN_STATS_IN_BCAST, - SWITCH_VLAN_STATS_IN_DROP, - SWITCH_VLAN_STATS_OUT_UCAST, - SWITCH_VLAN_STATS_OUT_MCAST, - SWITCH_VLAN_STATS_OUT_BCAST, - SWITCH_VLAN_STATS_OUT_DROP, - SWITCH_VLAN_STATS_MAX, -} switch_vlan_stats_t; - -/** vlan port info */ + SWITCH_BD_STATS_IN_UCAST, + SWITCH_BD_STATS_IN_MCAST, + SWITCH_BD_STATS_IN_BCAST, + SWITCH_BD_STATS_IN_DROP, + SWITCH_BD_STATS_OUT_UCAST, + SWITCH_BD_STATS_OUT_MCAST, + SWITCH_BD_STATS_OUT_BCAST, + SWITCH_BD_STATS_OUT_DROP, + SWITCH_BD_STATS_MAX, +} switch_bd_stats_id_t; + +/** Vlan Port info */ typedef struct switch_vlan_port_ { switch_handle_t handle; /**< port or interface handle */ switch_vlan_tagging_mode_t tagging_mode; /**< tagging mode */ } switch_vlan_port_t; +/** Vlan Interface info */ typedef struct switch_vlan_interface_ { - switch_handle_t vlan_handle; - switch_handle_t intf_handle; + switch_handle_t vlan_handle; /**< vlan handle */ + switch_handle_t intf_handle; /**< interface handle */ } switch_vlan_interface_t; /** Logical Network information */ @@ -453,6 +454,7 @@ switch_status_t switch_api_vlan_stats_disable(switch_device_t device, switch_han /** Get vlan statistics + @param device device to be programmed @param vlan_handle Vlan handle that identifies vlan uniquely @param count number of counter ids @param counter_ids list of counter ids @@ -462,7 +464,7 @@ switch_status_t switch_api_vlan_stats_get( switch_device_t device, switch_handle_t vlan_handle, uint8_t count, - switch_vlan_stats_t *counter_ids, + switch_bd_stats_id_t *counter_ids, switch_counter_t *counters); /** @} */ // end of VLAN diff --git a/switchapi/src/switch_api.thrift b/switchapi/src/switch_api.thrift index c38c5ee..803544a 100644 --- a/switchapi/src/switch_api.thrift +++ b/switchapi/src/switch_api.thrift @@ -389,8 +389,7 @@ struct switcht_api_hostif_rcode_info_t { } struct switcht_hostif_t { - 1: switcht_handle_t handle; - 2: string intf_name; + 1: string intf_name; } struct switcht_acl_action_cpu_redirect { diff --git a/switchapi/src/switch_api_rpc_server.cpp b/switchapi/src/switch_api_rpc_server.cpp index 26b5b48..d238c76 100644 --- a/switchapi/src/switch_api_rpc_server.cpp +++ b/switchapi/src/switch_api_rpc_server.cpp @@ -41,10 +41,10 @@ limitations under the License. #define SWITCH_API_RPC_SERVER_PORT (9091) -using namespace ::apache::thrift; -using namespace ::apache::thrift::protocol; -using namespace ::apache::thrift::transport; -using namespace ::apache::thrift::server; +using namespace ::thrift_provider; +using namespace ::thrift_provider::protocol; +using namespace ::thrift_provider::transport; +using namespace ::thrift_provider::server; using boost::shared_ptr; @@ -402,10 +402,10 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { printf("switcht_api_vlan_ingress_stats_get\n"); std::vector::const_iterator it = counter_ids.begin(); switcht_counter_t _counter; - switch_vlan_stats_t *counter_id_list = (switch_vlan_stats_t *) malloc(sizeof(switch_vlan_stats_t) * counter_ids.size()); + switch_bd_stats_id_t *counter_id_list = (switch_bd_stats_id_t *) malloc(sizeof(switch_bd_stats_id_t) * counter_ids.size()); switch_counter_t *counters = (switch_counter_t *) malloc(sizeof(switch_counter_t) * counter_ids.size()); for(uint32_t i = 0; i < counter_ids.size(); i++, it++) { - counter_id_list[i] = (switch_vlan_stats_t) *it; + counter_id_list[i] = (switch_bd_stats_id_t) *it; } printf("\nnumber of counterids %d\n", (int)(counter_ids.size())); switch_api_vlan_stats_get(device, vlan_handle, counter_ids.size(), counter_id_list, counters); @@ -1489,7 +1489,6 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { switcht_handle_t switcht_api_hostif_create(const switcht_device_t device, const switcht_hostif_t& hostif) { printf("switcht_api_hostif_create\n"); switch_hostif_t lhostif; - lhostif.handle = hostif.handle; memcpy(lhostif.intf_name, hostif.intf_name.c_str(), SWITCH_HOSTIF_NAME_SIZE); return switch_api_hostif_create(device, &lhostif); } diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index 7cd43be..b16ac77 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -719,14 +719,10 @@ switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char { switch_cpu_header_t *cpu_header = NULL; switch_hostif_rcode_info_t *rcode_info = NULL; - switch_interface_info_t *intf_info = NULL; void *temp = NULL; switch_hostif_packet_t hostif_packet; - switch_handle_t intf_handle = 0; - switch_handle_t hostif_handle = 0; - switch_hostif_info_t *hostif_info = NULL; - switch_handle_t port_handle = 0; - switch_port_info_t *port_info = NULL; + switch_handle_t bd_handle = 0; + switch_bd_info_t *bd_info = NULL; memset(&hostif_packet, 0, sizeof(switch_hostif_packet_t)); cpu_header = &packet_header->cpu_header; @@ -741,18 +737,22 @@ switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char cpu_header->ingress_ifindex); rcode_info = (switch_hostif_rcode_info_t *) (*(unsigned long *)temp); + + bd_handle = id_to_handle(SWITCH_HANDLE_TYPE_BD, cpu_header->ingress_bd); + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("received packet on invalid bd %x", cpu_header->ingress_bd); + return SWITCH_STATUS_INVALID_HANDLE; + } + if ((rcode_info->rcode_api_info.reason_code == SWITCH_HOSTIF_REASON_CODE_NONE) || (rcode_info->rcode_api_info.channel == SWITCH_HOSTIF_CHANNEL_CB)) { hostif_packet.reason_code = cpu_header->reason_code; hostif_packet.pkt = packet; hostif_packet.pkt_size = packet_size; + hostif_packet.handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, + cpu_header->ingress_port); - intf_handle = switch_api_interface_get_from_ifindex(cpu_header->ingress_ifindex); - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - hostif_packet.handle = intf_info->api_intf_info.u.port_lag_handle; if (SWITCH_IS_LAG_IFINDEX(cpu_header->ingress_ifindex)) { hostif_packet.is_lag = TRUE; } @@ -761,25 +761,11 @@ switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char rx_packet(&hostif_packet); } } + if ((rcode_info->rcode_api_info.reason_code == SWITCH_HOSTIF_REASON_CODE_NONE) || (rcode_info->rcode_api_info.channel == SWITCH_HOSTIF_CHANNEL_NETDEV)) { - intf_handle = switch_api_interface_get_from_ifindex(cpu_header->ingress_ifindex); - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - port_handle = SWITCH_INTF_PORT_HANDLE(intf_info); - port_info = switch_api_port_get_internal(port_handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - hostif_handle = port_info->hostif_handle; - hostif_info = switch_hostif_get(hostif_handle); - if (!hostif_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } SWITCH_API_TRACE("Sending packet through netdev\n"); - switch_packet_tx_to_host(hostif_info, packet, packet_size); + switch_packet_tx_to_host(packet_header, packet, packet_size); } return SWITCH_STATUS_SUCCESS; } @@ -811,37 +797,11 @@ switch_api_hostif_tx_packet(switch_device_t device, switch_hostif_packet_t *host fabric_header->packet_type = SWITCH_FABRIC_HEADER_TYPE_CPU; fabric_header->ether_type = SWITCH_FABRIC_HEADER_ETHTYPE; cpu_header->tx_bypass = hostif_packet->tx_bypass; + cpu_header->reason_code = 0xFFFF; switch_packet_tx_to_hw(&packet_header, hostif_packet->pkt, hostif_packet->pkt_size); return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_hostif_rx_packet_from_host(switch_hostif_info_t *hostif_info, char *packet, int packet_size) -{ - switch_packet_header_t packet_header; - switch_fabric_header_t *fabric_header = NULL; - switch_cpu_header_t *cpu_header = NULL; - switch_device_t device = 0; - switch_port_info_t *port_info = NULL; - - SWITCH_API_TRACE("Received packet from host port %lx through netdev\n", - hostif_info->hostif.handle); - - fabric_header = &packet_header.fabric_header; - cpu_header = &packet_header.cpu_header; - fabric_header->dst_device = device; - port_info = switch_api_port_get_internal(hostif_info->hostif.handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - fabric_header->packet_type = SWITCH_FABRIC_HEADER_TYPE_CPU; - fabric_header->ether_type = SWITCH_FABRIC_HEADER_ETHTYPE; - fabric_header->dst_port_or_group = SWITCH_PORT_ID(port_info); - cpu_header->tx_bypass = TRUE; - switch_packet_tx_to_hw(&packet_header, packet, packet_size); - return SWITCH_STATUS_SUCCESS; -} - switch_handle_t switch_hostif_create() { @@ -872,9 +832,6 @@ switch_api_hostif_create(switch_device_t device, switch_hostif_t *hostif) switch_handle_t hostif_handle = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_hostif_info_t *hostif_info = NULL; - switch_handle_type_t handle_type = 0; - switch_port_info_t *port_info = NULL; - switch_interface_info_t *intf_info = NULL; hostif_handle = switch_hostif_create(); hostif_info = switch_hostif_get(hostif_handle); @@ -885,26 +842,7 @@ switch_api_hostif_create(switch_device_t device, switch_hostif_t *hostif) switch_hostif_delete(hostif_handle); return SWITCH_API_INVALID_HANDLE; } - handle_type = switch_handle_get_type(hostif->handle); - switch (handle_type) { - case SWITCH_HANDLE_TYPE_PORT: - port_info = switch_api_port_get_internal(hostif->handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - port_info->hostif_handle = hostif_handle; - break; - case SWITCH_HANDLE_TYPE_INTERFACE: - //TODO: Add support for RIF - intf_info = switch_api_interface_get(hostif->handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - intf_info->hostif_handle = hostif_handle; - break; - default: - break; - } + SWITCH_API_TRACE("Host interface created %lu\n", hostif_handle); return hostif_handle; } @@ -924,6 +862,7 @@ switch_api_hostif_delete(switch_device_t device, switch_handle_t hostif_handle) } switch_packet_hostif_delete(device, hostif_info); switch_hostif_delete(hostif_handle); + SWITCH_API_TRACE("Host interface deleted %lu\n", hostif_handle); return SWITCH_STATUS_SUCCESS; } @@ -982,11 +921,11 @@ switch_api_cpu_interface_create(switch_device_t device) return status; } intf_handle = hostif_nhop[SWITCH_HOSTIF_REASON_CODE_NONE].intf_handle; + port_info = switch_api_port_get_internal(CPU_PORT_ID); if (!port_info) { return SWITCH_STATUS_INVALID_PORT_NUMBER; } - port_info->intf_handle = intf_handle; status = switch_pd_rewrite_table_fabric_add_entry(device, SWITCH_EGRESS_TUNNEL_TYPE_CPU, handle_to_id(intf_handle), diff --git a/switchapi/src/switch_hostif_int.h b/switchapi/src/switch_hostif_int.h index 5381c3f..d107049 100644 --- a/switchapi/src/switch_hostif_int.h +++ b/switchapi/src/switch_hostif_int.h @@ -35,6 +35,7 @@ typedef struct switch_hostif_rcode_info_ { typedef struct switch_hostif_info_ { switch_hostif_t hostif; + switch_handle_t intf_handle; int intf_fd; } switch_hostif_info_t; @@ -98,7 +99,11 @@ switch_api_hostif_rx_packet_from_host(switch_hostif_info_t *hostif_info, char *p switch_hostif_info_t * switch_hostif_get(switch_handle_t hostif_handle); void -switch_packet_tx_to_host(switch_hostif_info_t *hostif_info, char *packet, int packet_size); +switch_packet_tx_to_host( + switch_packet_header_t *packet_header, + char *packet, + int packet_size); + switch_status_t switch_api_cpu_interface_create(switch_device_t device); diff --git a/switchapi/src/switch_id.c b/switchapi/src/switch_id.c index f38ab3a..37b6a24 100644 --- a/switchapi/src/switch_id.c +++ b/switchapi/src/switch_id.c @@ -95,7 +95,9 @@ switch_api_id_allocator_allocate(switch_api_id_allocator *allocator) void switch_api_id_allocator_release(switch_api_id_allocator *allocator, unsigned int id) { - id = id > 0 ? id - 1 : 0; + if (allocator->zero_based != true) { + id = id > 0 ? id - 1 : 0; + } allocator->data[id >> 5] &= ~(1 << (31 - id)); } diff --git a/switchapi/src/switch_init.c b/switchapi/src/switch_init.c index 33e6280..5bc8dbd 100644 --- a/switchapi/src/switch_init.c +++ b/switchapi/src/switch_init.c @@ -72,6 +72,7 @@ switch_api_lib_init(switch_device_t device) switch_hostif_init(device); switch_capability_init(device); switch_meter_init(device); + switch_packet_init(device); return SWITCH_STATUS_SUCCESS; } diff --git a/switchapi/src/switch_interface.c b/switchapi/src/switch_interface.c index bf8fe3c..afa2ef7 100644 --- a/switchapi/src/switch_interface.c +++ b/switchapi/src/switch_interface.c @@ -117,34 +117,37 @@ switch_api_interface_get_vlan_handle(switch_handle_t intf_handle, } switch_handle_t -switch_api_interface_get_from_ifindex(switch_ifindex_t ifindex) +switch_api_interface_get_from_ifindex( + switch_ifindex_t ifindex, + switch_handle_t bd_handle) { - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; switch_handle_t intf_handle = 0; - switch_handle_t lag_handle = 0; - switch_handle_t port_handle = 0; + switch_handle_t port_lag_handle = 0; uint16_t tunnel_id = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; - if (SWITCH_IS_LAG_IFINDEX(ifindex)) { - lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_LAG, SWITCH_LAG_ID_FROM_IFINDEX(ifindex)); - lag_info = switch_api_lag_get_internal(lag_handle); - if(lag_info) { - intf_handle = lag_info->intf_handle; - } else { - return 0; - } - intf_handle = lag_info->intf_handle; - } else if (SWITCH_INTF_IS_TUNNEL_IFINDEX(ifindex)) { + if (SWITCH_INTF_IS_TUNNEL_IFINDEX(ifindex)) { tunnel_id = SWITCH_INTF_TUNNEL_ID(ifindex); intf_handle = id_to_handle(SWITCH_HANDLE_TYPE_INTERFACE, tunnel_id); } else { - port_handle = ifindex - 1; - port_info = switch_api_port_get_internal(port_handle); - if(port_info) - intf_handle = port_info->intf_handle; - else - return 0; + if (SWITCH_IS_LAG_IFINDEX(ifindex)) { + port_lag_handle = id_to_handle( + SWITCH_HANDLE_TYPE_LAG, + SWITCH_LAG_ID_FROM_IFINDEX(ifindex)); + } else { + port_lag_handle = id_to_handle( + SWITCH_HANDLE_TYPE_PORT, + (ifindex - 1)); + } + + status = switch_interface_handle_get( + port_lag_handle, + bd_handle, + &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("interface handle get failed for port_lag_handle %lx", + port_lag_handle); + } } return intf_handle; } @@ -155,31 +158,53 @@ switch_api_interface_create_l2(switch_device_t device, switch_handle_t intf_hand { switch_port_info_t *port_info = NULL; switch_lag_info_t *lag_info = NULL; - switch_handle_t port_handle = 0; + switch_handle_t port_lag_handle = 0; + switch_handle_t tmp_intf_handle = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; UNUSED(device); if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_PORT_VLAN) { - port_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); + port_lag_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); } else { - port_handle = SWITCH_INTF_PORT_HANDLE(intf_info); + port_lag_handle = SWITCH_INTF_PORT_HANDLE(intf_info); } - if (SWITCH_HANDLE_IS_LAG(port_handle)) { - lag_info = switch_api_lag_get_internal(port_handle); + if (SWITCH_HANDLE_IS_LAG(port_lag_handle)) { + lag_info = switch_api_lag_get_internal(port_lag_handle); if (!lag_info) { return SWITCH_STATUS_INVALID_HANDLE; } intf_info->ifindex = lag_info->ifindex; - lag_info->intf_handle = intf_handle; } else { port_info = switch_api_port_get_internal(SWITCH_INTF_PORT_HANDLE(intf_info)); if (!port_info) { return SWITCH_STATUS_INVALID_PORT_NUMBER; } - port_info->intf_handle = intf_handle; + port_lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, port_lag_handle); intf_info->ifindex = port_info->ifindex; } SWITCH_INTF_FLOOD_ENABLED(intf_info) = TRUE; + + if (handle_to_id(port_lag_handle) != CPU_PORT_ID) { + status = switch_interface_handle_get( + port_lag_handle, + 0x0, + &tmp_intf_handle); + if (status != SWITCH_STATUS_ITEM_NOT_FOUND) { + status = SWITCH_STATUS_INVALID_PARAMETER; + SWITCH_API_ERROR("interface create failed. " + "one interface per l2 port is allowed"); + return status; + } + + status = switch_interface_array_insert( + port_lag_handle, + intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("interface array insert failed"); + return status; + } + } + // TODO: should we add the l2 port to default vlan ? // TODO: Will the application remove the port from // default vlan when adding it to new vlan ? @@ -198,7 +223,7 @@ switch_status_t switch_api_interface_create_l3(switch_device_t device, switch_handle_t intf_handle, switch_interface_info_t *intf_info) { - switch_handle_t port_handle = 0; + switch_handle_t port_lag_handle = 0; switch_logical_network_t ln_info_tmp; switch_logical_network_t *ln_info = NULL; switch_port_info_t *port_info = NULL; @@ -206,6 +231,7 @@ switch_api_interface_create_l3(switch_device_t device, switch_handle_t intf_hand switch_lag_info_t *lag_info = NULL; switch_api_interface_info_t *api_intf_info = NULL; switch_vlan_t vlan_id = 0; + switch_handle_t tmp_intf_handle = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; tommy_list_init(&(intf_info->ip_addr)); @@ -213,34 +239,55 @@ switch_api_interface_create_l3(switch_device_t device, switch_handle_t intf_hand switch (SWITCH_INTF_TYPE(intf_info)) { case SWITCH_API_INTERFACE_L3: - port_handle = SWITCH_INTF_PORT_HANDLE(intf_info); vlan_id = 0; + port_lag_handle = SWITCH_INTF_PORT_HANDLE(intf_info); break; case SWITCH_API_INTERFACE_L3_PORT_VLAN: vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); + port_lag_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); break; default: SWITCH_API_ERROR("%s:%d: unsupported interface type!", __FUNCTION__, __LINE__); return SWITCH_STATUS_UNSUPPORTED_TYPE; } - port_handle = SWITCH_INTF_PORT_HANDLE(intf_info); - if (SWITCH_HANDLE_IS_LAG(port_handle)) { - lag_info = switch_api_lag_get_internal(port_handle); + + if (SWITCH_HANDLE_IS_LAG(port_lag_handle)) { + lag_info = switch_api_lag_get_internal(port_lag_handle); if (!lag_info) { return SWITCH_STATUS_INVALID_HANDLE; } intf_info->ifindex = lag_info->ifindex; - lag_info->intf_handle = intf_handle; } else { port_info = switch_api_port_get_internal(SWITCH_INTF_PORT_HANDLE(intf_info)); if (!port_info) { return SWITCH_STATUS_INVALID_PORT_NUMBER; } - port_info->intf_handle = intf_handle; + port_lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, port_lag_handle); intf_info->ifindex = port_info->ifindex; } + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3) { + status = switch_interface_handle_get( + port_lag_handle, + 0x0, + &tmp_intf_handle); + if (status != SWITCH_STATUS_ITEM_NOT_FOUND) { + status = SWITCH_STATUS_INVALID_PARAMETER; + SWITCH_API_ERROR("interface create failed. " + "one interface per l3 port is allowed\n"); + return status; + } + } + + status = switch_interface_array_insert( + port_lag_handle, + intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("interface array insert failed"); + return status; + } + ln_info = &ln_info_tmp; memset(ln_info, 0, sizeof(switch_logical_network_t)); ln_info->type = SWITCH_LOGICAL_NETWORK_TYPE_L3; @@ -289,6 +336,8 @@ switch_api_interface_create_l3(switch_device_t device, switch_handle_t intf_hand } } + bd_info->l3_intf_handle = intf_handle; + return status; } @@ -333,6 +382,9 @@ switch_api_interface_create_vlan_interface(switch_device_t device, intf_info->bd_handle = bd_handle; intf_info->ifindex = SWITCH_VLAN_INTERFACE_COMPUTE_IFINDEX(intf_handle); switch_api_logical_network_update(device, bd_handle, ln_info); + + bd_info->l3_intf_handle = intf_handle; + return status; } @@ -389,6 +441,44 @@ switch_api_interface_create(switch_device_t device, switch_api_interface_info_t return intf_handle; } +switch_status_t +switch_api_interface_handle_reset( + switch_device_t device, + switch_handle_t intf_handle) +{ + switch_handle_t port_lag_handle = 0; + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + port_lag_handle = SWITCH_INTF_PORT_HANDLE(intf_info); + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_PORT_VLAN) { + port_lag_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); + } + + + if (!(SWITCH_HANDLE_IS_LAG(port_lag_handle))) { + port_lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, port_lag_handle); + } + + status = switch_interface_array_delete( + port_lag_handle, + intf_handle); + return status; +} + +switch_status_t +switch_api_interface_delete_l2( + switch_device_t device, + switch_handle_t intf_handle) +{ + return switch_api_interface_handle_reset(device, intf_handle); +} + switch_status_t switch_api_interface_delete_vlan_interface(switch_device_t device, switch_handle_t intf_handle) @@ -414,8 +504,9 @@ switch_api_interface_delete_vlan_interface(switch_device_t device, ln_info->rmac_handle = 0; status = switch_pd_bd_table_update_entry(device, handle_to_id(intf_info->bd_handle), - bd_info, - bd_info->bd_entry); + bd_info); + bd_info->l3_intf_handle = 0; + return status; } @@ -458,6 +549,11 @@ switch_api_interface_delete_l3_interface(switch_device_t device, status = switch_api_router_mac_group_delete(device, api_intf_info->rmac_handle); } + + switch_api_interface_handle_reset(device, intf_handle); + + bd_info->l3_intf_handle = 0; + return status; } @@ -478,6 +574,11 @@ switch_api_interface_delete(switch_device_t device, switch_handle_t handle) switch(SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + case SWITCH_API_INTERFACE_L2_VLAN_TRUNK: + case SWITCH_API_INTERFACE_L2_PORT_VLAN: + switch_api_interface_delete_l2(device, handle); + case SWITCH_API_INTERFACE_L3: case SWITCH_API_INTERFACE_L3_PORT_VLAN: switch_api_interface_delete_l3_interface(device, handle); @@ -851,6 +952,165 @@ switch_api_interface_native_vlan_get(switch_handle_t intf_handle, uint64_t *valu return SWITCH_STATUS_SUCCESS; } +switch_status_t +switch_interface_array_insert( + switch_handle_t port_lag_handle, + switch_handle_t intf_handle) +{ + switch_handle_type_t handle_type = 0; + switch_port_info_t *port_info = NULL; + switch_lag_info_t *lag_info = NULL; + void **array = NULL; + void *temp = NULL; + switch_interface_info_t *intf_info = NULL; + + handle_type = switch_handle_get_type(port_lag_handle); + + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + port_info = switch_api_port_get_internal(port_lag_handle); + if (!port_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + array = &port_info->intf_array; + break; + + case SWITCH_HANDLE_TYPE_LAG: + lag_info = switch_api_lag_get_internal(port_lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + array = &lag_info->intf_array; + break; + + default: + return SWITCH_STATUS_INVALID_HANDLE; + } + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("intf array insert failed. invalid interface handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + JLI(temp, *array, intf_handle); + *(unsigned long *) temp = (unsigned long) intf_handle; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t +switch_interface_array_delete( + switch_handle_t port_lag_handle, + switch_handle_t intf_handle) +{ + switch_handle_type_t handle_type = 0; + switch_port_info_t *port_info = NULL; + switch_lag_info_t *lag_info = NULL; + void **array = NULL; + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + handle_type = switch_handle_get_type(port_lag_handle); + + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + port_info = switch_api_port_get_internal(port_lag_handle); + if (!port_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + array = &port_info->intf_array; + break; + + case SWITCH_HANDLE_TYPE_LAG: + lag_info = switch_api_lag_get_internal(port_lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + array = &lag_info->intf_array; + break; + + default: + return SWITCH_STATUS_INVALID_HANDLE; + } + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("intf array insert failed. invalid interface handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + JLD(status, *array, intf_handle); + return status; +} + +switch_status_t +switch_interface_handle_get( + switch_handle_t port_lag_handle, + switch_handle_t bd_handle, + switch_handle_t *intf_handle) +{ + switch_handle_type_t handle_type = 0; + switch_port_info_t *port_info = NULL; + switch_lag_info_t *lag_info = NULL; + void **array = NULL; + void *temp = NULL; + switch_handle_t tmp_intf_handle = 0; + switch_interface_info_t *intf_info = NULL; + + *intf_handle = 0; + + handle_type = switch_handle_get_type(port_lag_handle); + + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + port_info = switch_api_port_get_internal(port_lag_handle); + if (!port_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + array = &port_info->intf_array; + break; + + case SWITCH_HANDLE_TYPE_LAG: + lag_info = switch_api_lag_get_internal(port_lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + array = &lag_info->intf_array; + break; + + default: + return SWITCH_STATUS_INVALID_HANDLE; + } + + JLF(temp, *array, tmp_intf_handle); + while (temp) { + intf_info = switch_api_interface_get(tmp_intf_handle); + if (intf_info) { + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + case SWITCH_API_INTERFACE_L2_VLAN_TRUNK: + case SWITCH_API_INTERFACE_L2_PORT_VLAN: + *intf_handle = tmp_intf_handle; + return SWITCH_STATUS_SUCCESS; + case SWITCH_API_INTERFACE_L3: + *intf_handle = tmp_intf_handle; + return SWITCH_STATUS_SUCCESS; + case SWITCH_API_INTERFACE_L3_PORT_VLAN: + if (bd_handle == intf_info->bd_handle) { + *intf_handle = tmp_intf_handle; + return SWITCH_STATUS_SUCCESS; + } + break; + default: + break; + } + } + JLN(temp, *array, tmp_intf_handle); + } + + return SWITCH_STATUS_ITEM_NOT_FOUND; +} + switch_status_t switch_api_interface_l3_ifs_get(switch_l3_interfaces_iterator_fn iterator_fn) { @@ -927,6 +1187,77 @@ switch_api_interface_print_all(void) return SWITCH_STATUS_SUCCESS; } +switch_status_t +switch_api_l3_interface_bd_stats_enable( + switch_device_t device, + switch_handle_t intf_handle) +{ + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + status = switch_api_bd_stats_enable(device, intf_info->bd_handle); + return status; +} + +switch_status_t +switch_api_l3_interface_bd_stats_disable( + switch_device_t device, + switch_handle_t intf_handle) +{ + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + status = switch_api_bd_stats_disable(device, intf_info->bd_handle); + return status; +} + +switch_status_t +switch_api_l3_interface_stats_get( + switch_device_t device, + switch_handle_t intf_handle, + uint8_t count, + switch_bd_stats_id_t *counter_ids, + switch_counter_t *counters) +{ + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + status = switch_api_bd_stats_get( + device, + intf_info->bd_handle, + count, + counter_ids, + counters); + return status; +} + #ifdef SWITCH_INTERFACE_TEST int _switch_interface_main (int argc, char **argv) { diff --git a/switchapi/src/switch_interface_int.h b/switchapi/src/switch_interface_int.h index a179c9b..8cb637e 100644 --- a/switchapi/src/switch_interface_int.h +++ b/switchapi/src/switch_interface_int.h @@ -49,6 +49,8 @@ typedef struct switch_interface_info_ { switch_handle_t ln_bd_handle; /**< Logical network BD Handle */ switch_handle_t nhop_handle; switch_handle_t hostif_handle; + void *vlan_array; + uint16_t vlan_count; #ifdef SWITCH_PD p4_pd_entry_hdl_t nhop_type_entry; p4_pd_entry_hdl_t lag_group_entry; @@ -136,7 +138,12 @@ typedef struct switch_interface_info_ { // Internal Interface API's switch_interface_info_t *switch_api_interface_get(switch_handle_t handle); -switch_handle_t switch_api_interface_get_from_ifindex(switch_ifindex_t ifindex); + +switch_handle_t +switch_api_interface_get_from_ifindex( + switch_ifindex_t ifindex, + switch_handle_t bd_handle); + switch_status_t switch_interface_init(switch_device_t device); switch_status_t switch_interface_free(switch_device_t device); switch_status_t switch_api_interface_create_l2(switch_device_t device, switch_handle_t intf_handle, @@ -144,6 +151,22 @@ switch_status_t switch_api_interface_create_l2(switch_device_t device, switch_ha switch_status_t switch_api_interface_create_l3(switch_device_t device, switch_handle_t intf_handle, switch_interface_info_t *intf_info); +switch_status_t +switch_interface_array_insert( + switch_handle_t port_lag_handle, + switch_handle_t intf_handle); + +switch_status_t +switch_interface_array_delete( + switch_handle_t port_lag_handle, + switch_handle_t intf_handle); + +switch_status_t +switch_interface_handle_get( + switch_handle_t port_lag_handle, + switch_handle_t bd_handle, + switch_handle_t *intf_handle); + #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_l2.c b/switchapi/src/switch_l2.c index bc8d041..1265ad0 100644 --- a/switchapi/src/switch_l2.c +++ b/switchapi/src/switch_l2.c @@ -312,7 +312,9 @@ switch_mac_learn_notify_cb(p4_pd_sess_hdl_t sess_hdl, continue; } - intf_handle = switch_api_interface_get_from_ifindex(learn_entry->ingress_metadata_ifindex); + intf_handle = switch_api_interface_get_from_ifindex( + learn_entry->ingress_metadata_ifindex, + mac_entry.vlan_handle); if (!intf_handle) { SWITCH_API_TRACE("%s:%d: Ignoring the mac. invalid ifindex!", __FUNCTION__, __LINE__); continue; @@ -526,7 +528,10 @@ switch_api_mac_table_entry_add(switch_device_t device, switch(handle_type) { case SWITCH_HANDLE_TYPE_PORT: case SWITCH_HANDLE_TYPE_LAG: - status = switch_intf_handle_get(mac_entry->vlan_handle, mac_entry->handle, &intf_handle); + status = switch_interface_handle_get( + mac_entry->handle, + 0x0, + &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { goto cleanup; } @@ -695,7 +700,10 @@ switch_api_mac_table_entry_update(switch_device_t device, switch(handle_type) { case SWITCH_HANDLE_TYPE_PORT: case SWITCH_HANDLE_TYPE_LAG: - status = switch_intf_handle_get(mac_entry->vlan_handle, mac_entry->handle, &intf_handle); + status = switch_interface_handle_get( + mac_entry->handle, + 0x0, + &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { goto cleanup; } @@ -835,8 +843,10 @@ switch_api_mac_table_entry_delete(switch_device_t device, switch(handle_type) { case SWITCH_HANDLE_TYPE_PORT: case SWITCH_HANDLE_TYPE_LAG: - status = switch_intf_handle_get(mac_entry->vlan_handle, handle, - &intf_handle); + status = switch_interface_handle_get( + handle, + 0x0, + &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { goto cleanup; } @@ -1006,8 +1016,6 @@ switch_api_mac_table_entries_delete_by_interface(switch_device_t device, void *temp = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_handle_t intf_handle = 0; - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; switch_handle_type_t handle_type = 0; if (!SWITCH_PORT_HANDLE_VALID(handle) && @@ -1019,21 +1027,16 @@ switch_api_mac_table_entries_delete_by_interface(switch_device_t device, handle_type = switch_handle_get_type(handle); intf_handle = handle; - if (handle_type == SWITCH_HANDLE_TYPE_PORT) { - port_info = switch_api_port_get_internal((switch_port_t)handle); - if (!port_info) { - status = SWITCH_STATUS_INVALID_PORT_NUMBER; - goto cleanup; - } - intf_handle = port_info->intf_handle; - } - if (handle_type == SWITCH_HANDLE_TYPE_LAG) { - lag_info = switch_api_lag_get_internal(handle); - if (!lag_info) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + status = switch_interface_handle_get( + handle, + 0x0, + &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("mac table delete by interface failed"); + return status; } - intf_handle = lag_info->intf_handle; } JLG(temp, intf_mac_hdl_array, intf_handle); @@ -1072,8 +1075,6 @@ switch_api_mac_table_entries_delete_by_interface_vlan(switch_device_t device, void *temp = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_handle_t intf_handle = 0; - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; switch_handle_type_t handle_type = 0; if (!SWITCH_PORT_HANDLE_VALID(handle) && @@ -1096,21 +1097,16 @@ switch_api_mac_table_entries_delete_by_interface_vlan(switch_device_t device, handle_type = switch_handle_get_type(handle); intf_handle = handle; - if (handle_type == SWITCH_HANDLE_TYPE_PORT) { - port_info = switch_api_port_get_internal((switch_port_t)handle); - if (!port_info) { - status = SWITCH_STATUS_INVALID_PORT_NUMBER; - goto cleanup; - } - intf_handle = port_info->intf_handle; - } - if (handle_type == SWITCH_HANDLE_TYPE_LAG) { - lag_info = switch_api_lag_get_internal(handle); - if (!lag_info) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + status = switch_interface_handle_get( + handle, + 0x0, + &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("mac table delete by vlan failed"); + return status; } - intf_handle = lag_info->intf_handle; } mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); diff --git a/switchapi/src/switch_lag.c b/switchapi/src/switch_lag.c index de86887..3256c1e 100644 --- a/switchapi/src/switch_lag.c +++ b/switchapi/src/switch_lag.c @@ -257,7 +257,8 @@ switch_api_lag_member_add(switch_device_t device, switch_handle_t lag_handle, status = switch_pd_ingress_port_mapping_table_add_entry(device, port, lag_info->ifindex, port_info->port_type, - &port_info->hw_entry); + port_info->hw_entry); + port_info->lag_handle = lag_handle; if (status != SWITCH_STATUS_SUCCESS) { return status; } @@ -358,7 +359,8 @@ switch_api_lag_member_delete(switch_device_t device, switch_handle_t lag_handle, status = switch_pd_ingress_port_mapping_table_add_entry(device, port, port_info->ifindex, port_info->port_type, - &port_info->hw_entry); + port_info->hw_entry); + port_info->lag_handle = 0; if (status != SWITCH_STATUS_SUCCESS) { return status; } diff --git a/switchapi/src/switch_lag_int.h b/switchapi/src/switch_lag_int.h index 1ef806c..5ccc508 100644 --- a/switchapi/src/switch_lag_int.h +++ b/switchapi/src/switch_lag_int.h @@ -48,7 +48,7 @@ typedef struct switch_lag_member_ { typedef struct { switch_lag_type_t type; /**< weighted or otherwise */ switch_ifindex_t ifindex; /**< LAG Ifindex */ - switch_handle_t intf_handle; + void *intf_array; bool lacp; /**< LACP enabled? */ lacp_key_t key; /**< LACP key */ tommy_list ingress; /**< Ingress port list */ diff --git a/switchapi/src/switch_mcast.c b/switchapi/src/switch_mcast.c index d8a1303..f2ffe4c 100644 --- a/switchapi/src/switch_mcast.c +++ b/switchapi/src/switch_mcast.c @@ -41,11 +41,13 @@ static void *switch_mcast_array; static tommy_hashtable switch_rid_hash_table; static tommy_hashtable switch_mcast_group_hash_table; static switch_api_id_allocator *switch_rid_allocator; +static void *rid_array; switch_status_t switch_mcast_init(switch_device_t device) { switch_mcast_array = NULL; + rid_array = NULL; switch_handle_type_init(SWITCH_HANDLE_TYPE_MGID, SWITCH_MGID_TABLE_SIZE); tommy_hashtable_init(&switch_rid_hash_table, SWITCH_RID_HASH_TABLE_SIZE); tommy_hashtable_init(&switch_mcast_group_hash_table, SWTICH_MCAST_GROUP_HASH_TABLE_SIZE); @@ -504,13 +506,15 @@ switch_mcast_update_mcast_info(switch_mcast_info_t *mcast_info, uint16_t mbr_count, switch_vlan_interface_t *mbrs, bool add) { - for (int i = 0; i < mbr_count; i++) { + int i = 0, j = 0; + + for (i = 0; i < mbr_count; i++) { switch_vlan_interface_t *mbr = &mbrs[i]; int found = -1; - for (int i = 0; i < mcast_info->mbr_count; i++) { - if (memcmp(&(mcast_info->mbrs[i]), mbr, + for (j = 0; j < mcast_info->mbr_count; j++) { + if (memcmp(&(mcast_info->mbrs[j]), mbr, sizeof(switch_vlan_interface_t)) == 0) { - found = i; + found = j; break; } } @@ -586,11 +590,18 @@ switch_api_multicast_member_add(switch_device_t device, switch_interface_info_t *intf_info = NULL; switch_handle_t bd_handle = 0; switch_handle_t intf_handle = 0; + switch_handle_t handle = 0; switch_handle_type_t handle_type; uint16_t rid = 0; bool inner_replica = TRUE; - bool new_rid_node = FALSE; + bool new_node = FALSE; int index = 0; + switch_ip_encap_t *ip_encap = NULL; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + uint8_t tunnel_type = 0; + uint16_t tunnel_index = 0; + void *temp = NULL; + switch_rid_info_t *rid_info = NULL; mcast_info = switch_mcast_tree_get(mgid_handle); if (!mcast_info) { @@ -611,12 +622,15 @@ switch_api_multicast_member_add(switch_device_t device, } } + handle = mbrs[index].intf_handle; intf_handle = mbrs[index].intf_handle; handle_type = switch_handle_get_type(intf_handle); if ((handle_type == SWITCH_HANDLE_TYPE_PORT) || (handle_type == SWITCH_HANDLE_TYPE_LAG)) { - status = switch_intf_handle_get(bd_handle, intf_handle, - &intf_handle); + status = switch_interface_handle_get( + handle, + bd_handle, + &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("%s:%d: invalid interface %lx", __FUNCTION__, __LINE__, @@ -647,7 +661,37 @@ switch_api_multicast_member_add(switch_device_t device, continue; } - new_rid_node = FALSE; + JLG(temp, rid_array, rid); + if (!temp) { + rid_info = switch_malloc(sizeof(switch_rid_info_t), 1); + rid_info->ref_count = 0; + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); + tunnel_type = switch_tunnel_get_egress_tunnel_type( + encap_type, + ip_encap); + tunnel_index = handle_to_id(intf_handle); + } + status = switch_pd_rid_table_add_entry( + device, + rid, + handle_to_id(bd_handle), + inner_replica, + tunnel_type, + tunnel_index, + &rid_info->rid_hw_entry); + JLI(temp, rid_array, rid); + *(unsigned long *) temp = (unsigned long) rid_info; + SWITCH_API_TRACE("%s:%d: new l1 node allocated with rid %x", + __FUNCTION__, __LINE__, rid); + } + + rid_info = (switch_rid_info_t *) (*(unsigned long *)temp); + rid_info->ref_count++; + + new_node = FALSE; mcast_node = switch_mcast_find_node(mcast_info, SWITCH_NODE_TYPE_SINGLE, rid); @@ -658,7 +702,7 @@ switch_api_multicast_member_add(switch_device_t device, } memset(mcast_node, 0, sizeof(switch_mcast_node_t)); SWITCH_MCAST_NODE_RID(mcast_node) = rid; - new_rid_node = TRUE; + new_node = TRUE; tommy_list_insert_head(&mcast_info->node_list, &(mcast_node->node), mcast_node); } @@ -666,29 +710,12 @@ switch_api_multicast_member_add(switch_device_t device, status = switch_mcast_update_port_map(mcast_node, intf_handle, TRUE); // Create a L1 Node - if (new_rid_node) { - switch_ip_encap_t *ip_encap = NULL; - switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; - uint8_t tunnel_type = 0; - uint16_t tunnel_index = 0; + if (new_node) { status = switch_pd_mcast_add_entry(device, mcast_node); //Associate L1 Node to multicast tree status = switch_pd_mcast_mgid_table_add_entry(device, mcast_info->mgrp_hdl, mcast_node); - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); - ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); - tunnel_type = switch_tunnel_get_egress_tunnel_type(encap_type, - ip_encap); - tunnel_index = handle_to_id(intf_handle); - } - status = switch_pd_rid_table_add_entry(device, rid, - handle_to_id(bd_handle), - inner_replica, tunnel_type, tunnel_index, - &(SWITCH_MCAST_NODE_RID_HW_ENTRY(mcast_node))); - SWITCH_API_TRACE("%s:%d: new l1 node allocated with rid %x", - __FUNCTION__, __LINE__, rid); } else { status = switch_pd_mcast_update_entry(device, mcast_node); } @@ -709,12 +736,15 @@ switch_api_multicast_member_delete(switch_device_t device, switch_bd_info_t *bd_info = NULL; switch_handle_t bd_handle = 0; switch_handle_t intf_handle = 0; + switch_handle_t handle = 0; switch_interface_info_t *intf_info = NULL; switch_handle_type_t handle_type; switch_status_t status = SWITCH_STATUS_SUCCESS; uint16_t rid = 0; int index = 0; bool delete_mcast_node = FALSE; + void *temp = NULL; + switch_rid_info_t *rid_info = NULL; mcast_info = switch_mcast_tree_get(mgid_handle); if (!mcast_info) { @@ -733,12 +763,15 @@ switch_api_multicast_member_delete(switch_device_t device, } } + handle = mbrs[index].intf_handle; intf_handle = mbrs[index].intf_handle; handle_type = switch_handle_get_type(intf_handle); if ((handle_type == SWITCH_HANDLE_TYPE_PORT) || (handle_type == SWITCH_HANDLE_TYPE_LAG)) { - status = switch_intf_handle_get(bd_handle, intf_handle, - &intf_handle); + status = switch_interface_handle_get( + handle, + bd_handle, + &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("%s:%d: invalid interface %lx", __FUNCTION__, __LINE__, @@ -776,6 +809,30 @@ switch_api_multicast_member_delete(switch_device_t device, return SWITCH_STATUS_ITEM_NOT_FOUND; } + JLG(temp, rid_array, rid); + if (!temp) { + SWITCH_API_ERROR("mcast member delete failed. " + "rid not found for bd %lx intf %lx\n", + bd_handle, + intf_handle); + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + rid_info = (switch_rid_info_t *) (*(unsigned long *)temp); + rid_info->ref_count--; + if (rid_info->ref_count == 0) { + status = switch_pd_rid_table_delete_entry( + device, + rid_info->rid_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("rid entry delete failed for bd %lx intf %lx", + bd_handle, + intf_handle); + } + JLD(status, rid_array, rid); + switch_free(rid_info); + } + status = switch_mcast_update_port_map(mcast_node, intf_handle, FALSE); delete_mcast_node = switch_mcast_node_empty(mcast_node); @@ -783,8 +840,6 @@ switch_api_multicast_member_delete(switch_device_t device, status = switch_pd_mcast_mgid_table_delete_entry( device, mcast_info->mgrp_hdl, mcast_node); status = switch_pd_mcast_delete_entry(device, mcast_node); - status = switch_pd_rid_table_delete_entry(device, - SWITCH_MCAST_NODE_RID_HW_ENTRY(mcast_node)); mcast_node = tommy_list_remove_existing(&mcast_info->node_list, &(mcast_node->node)); switch_free(mcast_node); diff --git a/switchapi/src/switch_mcast_int.h b/switchapi/src/switch_mcast_int.h index 4b4213b..2788f89 100644 --- a/switchapi/src/switch_mcast_int.h +++ b/switchapi/src/switch_mcast_int.h @@ -90,6 +90,11 @@ typedef struct switch_mcast_node_info_ { p4_pd_entry_hdl_t rid_hw_entry; } switch_mcast_node_info_t; +typedef struct switch_rid_info_ { + p4_pd_entry_hdl_t rid_hw_entry; + uint16_t ref_count; +} switch_rid_info_t; + typedef struct switch_mcast_node_ { tommy_node node; switch_mcast_node_type_t node_type; diff --git a/switchapi/src/switch_meter.c b/switchapi/src/switch_meter.c index a97f01d..0a3f850 100644 --- a/switchapi/src/switch_meter.c +++ b/switchapi/src/switch_meter.c @@ -200,7 +200,7 @@ switch_api_meter_stats_get(switch_device_t device, switch_meter_info_t *meter_info = NULL; switch_meter_stats_info_t *stats_info = NULL; int index = 0; - switch_vlan_stats_t counter_id = 0; + switch_bd_stats_id_t counter_id = 0; meter_info = switch_meter_info_get(meter_handle); if (!meter_info) { diff --git a/switchapi/src/switch_neighbor.c b/switchapi/src/switch_neighbor.c index 70c3351..f1b48cd 100644 --- a/switchapi/src/switch_neighbor.c +++ b/switchapi/src/switch_neighbor.c @@ -32,12 +32,12 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + static void *switch_neighbor_array=NULL; static tommy_hashtable switch_dmac_rewrite_table; static tommy_hashtable switch_neighbor_dmac_table; switch_api_id_allocator *dmac_rewrite_index_allocator = NULL; - + switch_status_t switch_neighbor_init(switch_device_t device) { @@ -248,7 +248,7 @@ switch_neighbor_dmac_delete_hash(switch_device_t device, switch_handle_t bd_hand switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash); neighbor_dmac = tommy_hashtable_remove(&switch_neighbor_dmac_table, switch_neighbor_dmac_hash_cmp, key, hash); switch_free(neighbor_dmac); - return status; + return status; } switch_status_t @@ -374,7 +374,7 @@ switch_api_neighbor_entry_add_tunnel_rewrite(switch_device_t device, return status; } - + switch_handle_t switch_api_neighbor_entry_add(switch_device_t device, switch_api_neighbor_t *neighbor) { diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index abdee6d..c14f70d 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -31,11 +31,18 @@ limitations under the License. #include #include "switch_packet_int.h" #include "switch_hostif_int.h" +#include "switch_interface_int.h" +#include "switch_vlan_int.h" +#include "switch_port_int.h" +#include "switch_lag_int.h" #include "switch_log.h" #include #include +#include "switchapi/switch_utils.h" pthread_t packet_driver_thread; +static tommy_list packet_rx_list; +static tommy_list packet_tx_list; static char *cpu_intf_name = "veth251"; static uint32_t cpu_ifindex = 0; @@ -43,6 +50,24 @@ static int cpu_sock_fd = -1; static void *switch_intf_fd_array; static int pipe_fd[2]; +switch_status_t +switch_packet_init( + switch_device_t device) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + tommy_list_init(&packet_rx_list); + tommy_list_init(&packet_tx_list); + return status; +} + +switch_status_t +switch_packet_done( + switch_device_t device) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + return status; +} + static void switch_packet_create_pipe() { int ret = 0; @@ -96,6 +121,11 @@ switch_packet_tx_to_hw(switch_packet_header_t *packet_header, char *packet, int fabric_header->ether_type = htons(fabric_header->ether_type); fabric_header->dst_port_or_group = htons(fabric_header->dst_port_or_group); + + /* + * TODO: bypass system acl for all cpu packets + */ + cpu_header->reason_code |= 0x20; cpu_header->reason_code = htons(cpu_header->reason_code); memcpy(out_packet, packet, SWITCH_PACKET_HEADER_OFFSET); @@ -156,15 +186,84 @@ switch_packet_rx_from_hw() } void -switch_packet_tx_to_host(switch_hostif_info_t *hostif_info, char *packet, int packet_size) +switch_packet_tx_to_host( + switch_packet_header_t *packet_header, + char *packet, + int packet_size) { - int intf_fd = hostif_info->intf_fd; - if (write(intf_fd, packet, packet_size) < 0) { + static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + switch_cpu_header_t *cpu_header = NULL; + switch_packet_rx_entry_t rx_entry; + switch_packet_rx_info_t *rx_info = NULL; + int intf_fd = 0; + switch_ethernet_header_t *eth_header = NULL; + switch_vlan_header_t *vlan_header = NULL; + uint16_t offset = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + cpu_header = &packet_header->cpu_header; + + memset(&rx_entry, 0x0, sizeof(rx_entry)); + rx_entry.port = cpu_header->ingress_port; + rx_entry.ifindex = cpu_header->ingress_ifindex; + rx_entry.bd = cpu_header->ingress_bd; + rx_entry.reason_code = cpu_header->reason_code; + + status = switch_packet_rx_info_get( + &rx_entry, + &rx_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to find fd. dropping packet"); + return; + } + + if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) { + memcpy(in_packet, packet, packet_size); + eth_header = (switch_ethernet_header_t *) packet; + if (ntohs(eth_header->ether_type) != SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { + offset = 2 * ETH_LEN; + memcpy(in_packet, packet, offset); + vlan_header = (switch_vlan_header_t *) (in_packet + offset); + vlan_header->tpid = htons(SWITCH_ETHERTYPE_DOT1Q); + uint16_t *vlan_h = (uint16_t *) (vlan_header) + 1; + *vlan_h = htons(rx_info->vlan_id); + /* + vlan_header->pcp = 0; + vlan_header->dei = 0; + vlan_header->vid = htons(vid); + */ + + memcpy(in_packet + offset + sizeof(switch_vlan_header_t), + packet + offset, + packet_size - offset); + packet_size += sizeof(switch_vlan_header_t); + } + } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_REMOVE) { + memcpy(in_packet, packet, packet_size); + eth_header = (switch_ethernet_header_t *) packet; + if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { + offset = 2 * ETH_LEN; + memcpy(in_packet, packet, offset); + memcpy(in_packet, packet + offset, packet_size - offset); + packet_size -= sizeof(switch_vlan_header_t); + } + } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_SWAP) { + memcpy(in_packet, packet, packet_size); + eth_header = (switch_ethernet_header_t *) packet; + if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { + offset = 2 * ETH_LEN; + vlan_header = (switch_vlan_header_t *) (in_packet + offset); + vlan_header->vid = htons(rx_info->vlan_id); + } + } else { + memcpy(in_packet, packet, packet_size); + } + intf_fd = rx_info->intf_fd; + + if (write(intf_fd, in_packet, packet_size) < 0) { perror("sendto host interface failed"); return; } -// SWITCH_API_TRACE("Sent packet to host interface %lu\n", -// hostif_info->hostif.handle); return; } @@ -172,12 +271,30 @@ void switch_packet_rx_from_host(int intf_fd) { switch_hostif_info_t *hostif_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; int packet_size = 0; + int in_packet_size = 0; static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; void *temp = NULL; + switch_packet_header_t packet_header; + switch_fabric_header_t *fabric_header = NULL; + switch_cpu_header_t *cpu_header = NULL; + switch_device_t device = 0; + switch_ethernet_header_t *eth_header = NULL; + switch_vlan_header_t *vlan_header = NULL; + switch_vlan_t vlan_id1 = 0; + switch_vlan_t vlan_id2 = 0; + switch_packet_tx_entry_t tx_entry; + switch_packet_tx_info_t *tx_info = NULL; + uint16_t ether_type = 0; + uint16_t offset = 0; + uint16_t vlan_offset = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + memset(in_packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE); + memset(packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE); - while ((packet_size = read(intf_fd, in_packet, sizeof(in_packet))) > 0) { + while ((in_packet_size = read(intf_fd, in_packet, sizeof(in_packet))) > 0) { JLG(temp, switch_intf_fd_array, intf_fd); hostif_info = (switch_hostif_info_t *) (*(unsigned long *)temp); @@ -185,12 +302,82 @@ switch_packet_rx_from_host(int intf_fd) perror("invalid hostif fd"); return; } -// SWITCH_API_TRACE("Received packet from host interface %lu\n", -// hostif_info->hostif.handle); - status = switch_api_hostif_rx_packet_from_host(hostif_info, in_packet, - packet_size); + SWITCH_API_TRACE("Received packet from host port %s through netdev\n", + hostif_info->hostif.intf_name); + + eth_header = (switch_ethernet_header_t *) in_packet; + if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { + vlan_header = (switch_vlan_header_t *) (in_packet + 2 * ETH_LEN); + uint16_t *vlan_h = (uint16_t *) (vlan_header) + 1; + vlan_id1 = ntohs(*vlan_h); + } + + tx_entry.intf_fd = intf_fd; + tx_entry.vlan_id = vlan_id1; + status = switch_packet_tx_info_get( + &tx_entry, + &tx_info); if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("net filter tx not found. dropping packet"); + continue; } + + memset(&packet_header, 0x0, sizeof(packet_header)); + cpu_header = &packet_header.cpu_header; + fabric_header = &packet_header.fabric_header; + + if (tx_info->tx_bypass) { + cpu_header->tx_bypass = TRUE; + cpu_header->reason_code = 0xFFFF; + fabric_header->dst_port_or_group = tx_info->port; + memcpy(packet, in_packet, in_packet_size); + packet_size = in_packet_size; + } else { + cpu_header->tx_bypass = FALSE; + cpu_header->reason_code = 0x0; + vlan_id1 = tx_info->bd & 0xFFF; + vlan_id2 = (tx_info->bd & 0xF000) >> 12; + + eth_header = (switch_ethernet_header_t *) in_packet; + ether_type = htons(eth_header->ether_type); + + if (ether_type != SWITCH_ETHERTYPE_DOT1Q) { + vlan_offset += sizeof(switch_vlan_header_t); + } + + if (vlan_id2) { + vlan_offset += sizeof(switch_vlan_header_t); + } + + memcpy(packet, in_packet, 2 * ETH_LEN); + memcpy(packet + 2 * ETH_LEN + vlan_offset, + in_packet + 2 * ETH_LEN, + (in_packet_size - 2 * ETH_LEN)); + packet_size = in_packet_size; + packet_size += vlan_offset; + + vlan_header = (switch_vlan_header_t *) (packet + 2 * ETH_LEN); + vlan_header->vid = ntohs(vlan_id1); + vlan_header->tpid = ntohs(SWITCH_ETHERTYPE_DOT1Q); + vlan_header->dei = 0; + vlan_header->pcp = 0; + + if (vlan_id2) { + offset = 2 * ETH_LEN + sizeof(switch_vlan_header_t); + vlan_header = (switch_vlan_header_t *) (packet + offset); + vlan_header->vid = ntohs(vlan_id2); + vlan_header->tpid = ntohs(SWITCH_ETHERTYPE_DOT1Q); + vlan_header->dei = 0; + vlan_header->pcp = 0; + } + } + + fabric_header = &packet_header.fabric_header; + cpu_header = &packet_header.cpu_header; + fabric_header->dst_device = device; + fabric_header->packet_type = SWITCH_FABRIC_HEADER_TYPE_CPU; + fabric_header->ether_type = SWITCH_FABRIC_HEADER_ETHTYPE; + switch_packet_tx_to_hw(&packet_header, packet, packet_size); } } @@ -410,3 +597,415 @@ int start_switch_api_packet_driver() switch_packet_driver_thread, NULL); return SWITCH_STATUS_SUCCESS; } + +int32_t +switch_packet_tx_compare( + const void *key1, + const void *key2) +{ + switch_packet_tx_entry_t *tx_entry1 = NULL; + switch_packet_tx_entry_t *tx_entry2 = NULL; + + if (!key1 || !key2) { + return 0; + } + + tx_entry1 = (switch_packet_tx_entry_t *) key1; + tx_entry2 = (switch_packet_tx_entry_t *) key2; + + if (tx_entry1->priority == tx_entry2->priority) { + return 0; + } else if (tx_entry1->priority > tx_entry2->priority) { + return 1; + } else { + return -1; + } +} + +switch_status_t +switch_api_packet_net_filter_tx_create( + switch_device_t device, + switch_packet_tx_key_t *tx_key, + switch_packet_tx_action_t *tx_action) +{ + switch_packet_tx_entry_t tx_entry; + switch_packet_tx_info_t *tx_info = NULL; + switch_hostif_info_t *hostif_info = NULL; + switch_handle_t bd_handle = 0; + switch_interface_info_t *intf_info = NULL; + switch_handle_type_t handle_type = 0; + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + hostif_info = switch_hostif_get(tx_key->hostif_handle); + if (!hostif_info) { + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + memset(&tx_entry, 0x0, sizeof(tx_entry)); + tx_entry.intf_fd = hostif_info->intf_fd; + tx_entry.fd_valid = tx_key->handle_valid; + tx_entry.vlan_id = tx_key->vlan_id; + tx_entry.vlan_valid = tx_key->vlan_valid; + + tx_info = switch_malloc(sizeof(switch_packet_tx_info_t), 0x1); + if (!tx_info) { + SWITCH_API_ERROR("hif %lx vlan %x malloc failure", + tx_key->hostif_handle, + tx_key->vlan_id); + return SWITCH_STATUS_NO_MEMORY; + } + + if (!tx_action->tx_bypass) { + bd_handle = tx_action->handle; + + handle_type = switch_handle_get_type(tx_action->handle); + if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { + intf_info = switch_api_interface_get(tx_action->handle); + if (!intf_info) { + SWITCH_API_ERROR("intf_handle %lx is invalid", tx_action->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + SWITCH_API_ERROR("intf_handle %lx is not l3", tx_action->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + bd_handle = intf_info->bd_handle; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("hif %lx vlan %x invalid bd", + tx_key->hostif_handle, + tx_key->vlan_id); + return SWITCH_STATUS_INVALID_HANDLE; + } + } + + memcpy(&tx_info->tx_entry, &tx_entry, sizeof(tx_entry)); + tx_info->bd = handle_to_id(bd_handle); + tx_info->tx_bypass = tx_action->tx_bypass; + tx_info->port = handle_to_id(tx_action->port_handle); + + tommy_list_insert_head(&packet_tx_list, &(tx_info->node), tx_info); + tommy_list_sort(&packet_tx_list, switch_packet_tx_compare); + return status; +} + +switch_status_t +switch_api_packet_net_filter_tx_delete( + switch_device_t device, + switch_packet_tx_key_t *tx_key) +{ + switch_packet_tx_entry_t *tmp_tx_entry = NULL; + switch_packet_tx_info_t *tmp_tx_info = NULL; + switch_packet_tx_entry_t tx_entry; + switch_packet_tx_info_t *tx_info = NULL; + tommy_node *node = NULL; + switch_hostif_info_t *hostif_info = NULL; + bool node_found = FALSE; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + hostif_info = switch_hostif_get(tx_key->hostif_handle); + if (!hostif_info) { + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + memset(&tx_entry, 0x0, sizeof(tx_entry)); + tx_entry.intf_fd = hostif_info->intf_fd; + tx_entry.vlan_id = tx_key->vlan_id; + tx_entry.priority = tx_key->priority; + + node = tommy_list_head(&packet_tx_list); + while (node) { + tmp_tx_info = (switch_packet_tx_info_t *) node->data; + tmp_tx_entry = &tmp_tx_info->tx_entry; + if (tmp_tx_entry->intf_fd == tx_key->vlan_id && + tmp_tx_entry->vlan_id == hostif_info->intf_fd && + tmp_tx_entry->priority == tx_key->priority) { + node_found = TRUE; + break; + } + node = node->next; + } + + if (!node_found) { + SWITCH_API_ERROR("tx filter delete failed. node find failed"); + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + tommy_list_remove_existing(&packet_tx_list, node); + switch_free(tx_info); + return status; +} + +int32_t +switch_packet_rx_compare( + const void *key1, + const void *key2) +{ + switch_packet_rx_entry_t *rx_entry1 = NULL; + switch_packet_rx_entry_t *rx_entry2 = NULL; + + if (!key1 || !key2) { + return 0; + } + + rx_entry1 = (switch_packet_rx_entry_t *) key1; + rx_entry2 = (switch_packet_rx_entry_t *) key2; + + if (rx_entry1->priority == rx_entry2->priority) { + return 0; + } else if (rx_entry1->priority > rx_entry2->priority) { + return 1; + } else { + return -1; + } +} + +switch_status_t +switch_api_packet_net_filter_rx_create( + switch_device_t device, + switch_packet_rx_key_t *rx_key, + switch_packet_rx_action_t *rx_action) +{ + switch_hostif_info_t *hostif_info = NULL; + switch_lag_info_t *lag_info = NULL; + switch_port_info_t *port_info = NULL; + switch_packet_rx_entry_t rx_entry; + switch_packet_rx_info_t *rx_info = NULL; + switch_handle_type_t handle_type = 0; + switch_interface_info_t *intf_info = NULL; + switch_handle_t bd_handle = 0; + switch_bd_info_t *bd_info = NULL; + switch_ifindex_t ifindex = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + memset(&rx_entry, 0x0, sizeof(rx_entry)); + + if (rx_key->port_lag_valid) { + handle_type = switch_handle_get_type(rx_key->port_lag_handle); + if (handle_type == SWITCH_HANDLE_TYPE_LAG) { + lag_info = switch_api_lag_get_internal(rx_key->port_lag_handle); + if (!lag_info) { + SWITCH_API_ERROR("invalid lag handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + ifindex = lag_info->ifindex; + } else { + port_info = switch_api_port_get_internal(rx_key->port_lag_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + ifindex = port_info->ifindex; + } + rx_entry.ifindex_valid = TRUE; + } + + if (rx_key->handle_valid) { + bd_handle = rx_key->handle; + handle_type = switch_handle_get_type(rx_key->handle); + if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { + intf_info = switch_api_interface_get(rx_key->handle); + if (!intf_info) { + SWITCH_API_ERROR("intf_handle %lx is invalid", rx_key->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + SWITCH_API_ERROR("intf_handle %lx is not l3", rx_key->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + bd_handle = intf_info->bd_handle; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("bd derivation failed %lx", rx_key->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + rx_entry.bd_valid = TRUE; + } + + hostif_info = switch_hostif_get(rx_action->hostif_handle); + if (!hostif_info) { + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + rx_entry.bd = handle_to_id(bd_handle); + rx_entry.ifindex = ifindex; + rx_entry.port = handle_to_id(rx_key->port_handle); + rx_entry.port_valid = rx_key->port_valid; + rx_entry.reason_code = rx_key->reason_code; + rx_entry.reason_code_valid = rx_key->reason_code_valid; + rx_entry.priority = rx_key->priority; + + rx_info = switch_malloc(sizeof(switch_packet_rx_info_t), 0x1); + if (!rx_info) { + SWITCH_API_ERROR("port %lx port_lag %lx handle %lx malloc failed", + rx_key->port_handle, + rx_key->port_lag_handle, + rx_key->handle); + return SWITCH_STATUS_NO_MEMORY; + } + + memset(rx_info, 0x0, sizeof(switch_packet_rx_info_t)); + memcpy(&rx_info->rx_entry, &rx_entry, sizeof(rx_entry)); + rx_info->vlan_id = rx_action->vlan_id; + rx_info->vlan_action = rx_action->vlan_action; + rx_info->intf_fd = hostif_info->intf_fd; + + tommy_list_insert_head(&packet_rx_list, &(rx_info->node), rx_info); + tommy_list_sort(&packet_rx_list, switch_packet_rx_compare); + return status; +} + +switch_status_t +switch_api_packet_net_filter_rx_delete( + switch_device_t device, + switch_packet_rx_key_t *rx_key) +{ + switch_lag_info_t *lag_info = NULL; + switch_port_info_t *port_info = NULL; + switch_packet_rx_entry_t *tmp_rx_entry = NULL; + switch_packet_rx_info_t *tmp_rx_info = NULL; + switch_packet_rx_info_t *rx_info = NULL; + switch_handle_type_t handle_type = 0; + switch_interface_info_t *intf_info = NULL; + switch_handle_t bd_handle = 0; + switch_bd_info_t *bd_info = NULL; + switch_ifindex_t ifindex = 0; + tommy_node *node = NULL; + bool node_found = FALSE; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + handle_type = switch_handle_get_type(rx_key->port_lag_handle); + if (handle_type == SWITCH_HANDLE_TYPE_LAG) { + lag_info = switch_api_lag_get_internal(rx_key->port_lag_handle); + if (!lag_info) { + SWITCH_API_ERROR("invalid lag handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + ifindex = lag_info->ifindex; + } else { + port_info = switch_api_port_get_internal(rx_key->port_lag_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + ifindex = port_info->ifindex; + } + + bd_handle = rx_key->handle; + handle_type = switch_handle_get_type(rx_key->handle); + if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { + intf_info = switch_api_interface_get(rx_key->handle); + if (!intf_info) { + SWITCH_API_ERROR("intf_handle %lx is invalid", rx_key->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + SWITCH_API_ERROR("intf_handle %lx is not l3", rx_key->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + bd_handle = intf_info->bd_handle; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("bd derivation failed %lx", rx_key->handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + + node = tommy_list_head(&packet_rx_list); + while (node) { + tmp_rx_info = (switch_packet_rx_info_t *) node->data; + tmp_rx_entry = &tmp_rx_info->rx_entry; + if (tmp_rx_entry->bd == handle_to_id(bd_handle) && + tmp_rx_entry->ifindex == ifindex && + tmp_rx_entry->port == handle_to_id(rx_key->port_handle) && + tmp_rx_entry->reason_code == rx_key->reason_code && + tmp_rx_entry->priority == rx_key->priority) { + node_found = TRUE; + break; + } + node = node->next; + } + + if (!node_found) { + SWITCH_API_ERROR("tx filter delete failed. node find failed"); + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + tommy_list_remove_existing(&packet_rx_list, node); + + switch_free(rx_info); + return status; +} + +switch_status_t +switch_packet_rx_info_get( + switch_packet_rx_entry_t *rx_entry, + switch_packet_rx_info_t **rx_info) +{ + switch_packet_rx_info_t *tmp_rx_info = NULL; + tommy_node *node = NULL; + switch_packet_rx_entry_t *tmp_rx_entry = NULL; + switch_status_t status = SWITCH_STATUS_ITEM_NOT_FOUND; + + *rx_info = NULL; + + node = tommy_list_head(&packet_rx_list); + while (node) { + tmp_rx_info = (switch_packet_rx_info_t *) node->data; + tmp_rx_entry = &tmp_rx_info->rx_entry; + if (((tmp_rx_entry->port_valid && tmp_rx_entry->port == rx_entry->port) || + !tmp_rx_entry->port_valid) && + ((tmp_rx_entry->ifindex_valid && tmp_rx_entry->ifindex == rx_entry->ifindex) || + !tmp_rx_entry->ifindex_valid) && + ((tmp_rx_entry->bd_valid && tmp_rx_entry->bd == rx_entry->bd) || + !tmp_rx_entry->bd_valid) && + ((tmp_rx_entry->reason_code_valid && tmp_rx_entry->reason_code == rx_entry->reason_code) || + !tmp_rx_entry->reason_code_valid)) { + *rx_info = tmp_rx_info; + status = SWITCH_STATUS_SUCCESS; + break; + } + node = node->next; + } + + return status; +} + +switch_status_t +switch_packet_tx_info_get( + switch_packet_tx_entry_t *tx_entry, + switch_packet_tx_info_t **tx_info) +{ + switch_packet_tx_info_t *tmp_tx_info = NULL; + tommy_node *node = NULL; + switch_packet_tx_entry_t *tmp_tx_entry = NULL; + switch_status_t status = SWITCH_STATUS_ITEM_NOT_FOUND; + + *tx_info = NULL; + + node = tommy_list_head(&packet_tx_list); + while (node) { + tmp_tx_info = (switch_packet_tx_info_t *) node->data; + tmp_tx_entry = &tmp_tx_info->tx_entry; + if (((tmp_tx_entry->fd_valid && tmp_tx_entry->intf_fd == tx_entry->intf_fd) || + !tmp_tx_entry->fd_valid) && + ((tmp_tx_entry->vlan_valid && tmp_tx_entry->vlan_id == tx_entry->vlan_id) || + !tmp_tx_entry->vlan_valid)) { + *tx_info = tmp_tx_info; + status = SWITCH_STATUS_SUCCESS; + break; + } + node = node->next; + } + + return status; +} diff --git a/switchapi/src/switch_packet_int.h b/switchapi/src/switch_packet_int.h index a8449f5..490c04b 100644 --- a/switchapi/src/switch_packet_int.h +++ b/switchapi/src/switch_packet_int.h @@ -27,6 +27,63 @@ extern "C" { #define SWITCH_PACKET_MAX_BUFFER_SIZE 10000 +#define SWITCH_PACKET_TX_HASH_TABLE_SIZE 1024 +#define SWITCH_PACKET_RX_HASH_TABLE_SIZE 1024 + +typedef struct switch_packet_rx_entry_ { + switch_port_t port; + bool port_valid; + switch_ifindex_t ifindex; + bool ifindex_valid; + uint16_t bd; + bool bd_valid; + switch_hostif_reason_code_t reason_code; + bool reason_code_valid; + uint32_t priority; +} switch_packet_rx_entry_t; + +typedef struct switch_packet_rx_info_ { + switch_packet_rx_entry_t rx_entry; + tommy_node node; + int intf_fd; + switch_vlan_t vlan_id; + switch_packet_vlan_action_t vlan_action; +} switch_packet_rx_info_t; + +typedef struct switch_packet_tx_entry_ { + int32_t intf_fd; + bool fd_valid; + switch_vlan_t vlan_id; + bool vlan_valid; + uint32_t priority; +} switch_packet_tx_entry_t; + +typedef struct switch_packet_tx_info_ { + switch_packet_tx_entry_t tx_entry; + tommy_node node; + uint16_t bd; + bool tx_bypass; + switch_port_t port; +} switch_packet_tx_info_t; + +typedef struct __attribute__((__packed__)) switch_ethernet_header_ { + uint8_t dst_mac[ETH_LEN]; + uint8_t src_mac[ETH_LEN]; + uint16_t ether_type; +} switch_ethernet_header_t; + +#define SWITCH_ETHERTYPE_DOT1Q 0x8100 + +typedef struct __attribute__((__packed__)) switch_vlan_header_ { + uint16_t tpid; + uint16_t vid:12; + uint16_t dei:1; + uint16_t pcp:3; +} switch_vlan_header_t; + +#define SWITCH_PACKET_TX_HASH_KEY_SIZE sizeof(switch_packet_tx_hash_entry_t) +#define SWITCH_PACKET_RX_HASH_KEY_SIZE sizeof(switch_packet_rx_hash_entry_t) + void switch_packet_tx_to_hw(switch_packet_header_t *packet_header, char *packet, int packet_size); switch_status_t @@ -34,6 +91,23 @@ switch_packet_hostif_create(switch_device_t device, switch_hostif_info_t *hostif switch_status_t switch_packet_hostif_delete(switch_device_t device, switch_hostif_info_t *hostif_info); +switch_status_t +switch_packet_init( + switch_device_t device); + +switch_status_t +switch_packet_free( + switch_device_t device); + +switch_status_t +switch_packet_rx_info_get( + switch_packet_rx_entry_t *rx_entry, + switch_packet_rx_info_t **rx_info); + +switch_status_t +switch_packet_tx_info_get( + switch_packet_tx_entry_t *tx_entry, + switch_packet_tx_info_t **tx_info); #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_pd.c b/switchapi/src/switch_pd.c index f184a06..f82f8de 100644 --- a/switchapi/src/switch_pd.c +++ b/switchapi/src/switch_pd.c @@ -22,10 +22,16 @@ limitations under the License. #include "switch_defines.h" #include "switch_mirror_int.h" #include "switch_tunnel_int.h" -//#include "model_flags.h" #include "switch_config_int.h" #include +#define ingress_input_port standard_metadata_ingress_port +#define ingress_egress_port standard_metadata_egress_spec +#define egress_egress_port standard_metadata_egress_port +#define egress_egress_port_mask standard_metadata_egress_port_mask +#define intrinsic_mcast_grp intrinsic_metadata_mcast_grp +#define egress_egress_rid intrinsic_metadata_egress_rid + #define SWITCH_MAX_TXN_SZ 10 p4_pd_sess_hdl_t g_sess_hdl = 0; @@ -854,7 +860,7 @@ switch_pd_outer_rmac_table_add_entry(switch_device_t device, memset(&match_spec, 0, sizeof(p4_pd_dc_rmac_match_spec_t)); match_spec.l3_metadata_rmac_group = rmac_group; - memcpy(match_spec.l2_metadata_lkp_mac_da, mac, ETH_LEN); + memcpy(match_spec.ethernet_dstAddr, mac, ETH_LEN); p4_pd_dc_outer_rmac_table_add_with_outer_rmac_hit(g_sess_hdl, p4_pd_device, @@ -902,7 +908,9 @@ switch_pd_src_vtep_table_add_entry(switch_device_t device, memset(&v4_action_spec, 0, sizeof(p4_pd_dc_src_vtep_hit_action_spec_t)); v4_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); - v4_match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap); + v4_match_spec.ipv4_srcAddr = SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap); + v4_match_spec.tunnel_metadata_ingress_tunnel_type = + switch_tunnel_get_ingress_tunnel_type(ip_encap); v4_action_spec.action_ifindex = ifindex; status = p4_pd_dc_ipv4_src_vtep_table_add_with_src_vtep_hit( @@ -921,8 +929,10 @@ switch_pd_src_vtep_table_add_entry(switch_device_t device, memset(&v6_action_spec, 0, sizeof(p4_pd_dc_src_vtep_hit_action_spec_t)); v6_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_sa, + memcpy(&v6_match_spec.ipv6_srcAddr, SWITCH_IP_ENCAP_IPV6_SRC_IP(ip_encap), 16); + v6_match_spec.tunnel_metadata_ingress_tunnel_type = + switch_tunnel_get_ingress_tunnel_type(ip_encap); v6_action_spec.action_ifindex = ifindex; status = p4_pd_dc_ipv6_src_vtep_table_add_with_src_vtep_hit( @@ -980,8 +990,7 @@ switch_pd_dest_vtep_table_add_entry(switch_device_t device, p4_pd_dc_ipv4_dest_vtep_match_spec_t v4_match_spec; memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_dest_vtep_match_spec_t)); v4_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); - v4_match_spec.ipv4_metadata_lkp_ipv4_da = - SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap); + v4_match_spec.ipv4_dstAddr = SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap); v4_match_spec.tunnel_metadata_ingress_tunnel_type = switch_tunnel_get_ingress_tunnel_type(ip_encap); status = p4_pd_dc_ipv4_dest_vtep_table_add_with_set_tunnel_termination_flag( @@ -995,7 +1004,7 @@ switch_pd_dest_vtep_table_add_entry(switch_device_t device, p4_pd_dc_ipv6_dest_vtep_match_spec_t v6_match_spec; memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_dest_vtep_match_spec_t)); v6_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_da, + memcpy(&v6_match_spec.ipv6_dstAddr, SWITCH_IP_ENCAP_IPV6_DST_IP(ip_encap), 16); v6_match_spec.tunnel_metadata_ingress_tunnel_type = switch_tunnel_get_ingress_tunnel_type(ip_encap); @@ -1208,6 +1217,9 @@ switch_pd_tunnel_table_add_entry(switch_device_t device, case SWITCH_API_ENCAP_TYPE_ERSPAN_T3: ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GRE; break; + case SWITCH_API_ENCAP_TYPE_IPIP: + ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IPIP; + break; default: return SWITCH_STATUS_INVALID_TUNNEL_TYPE; } @@ -1531,6 +1543,7 @@ switch_pd_tunnel_decap_tables_init_entry(switch_device_t device) &o_match_spec, &entry_hdl); +#ifndef P4_NVGRE_DISABLE /* nvgre, inner ipv4 */ memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_outer_match_spec_t)); o_match_spec.tunnel_metadata_ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NVGRE; @@ -1561,6 +1574,60 @@ switch_pd_tunnel_decap_tables_init_entry(switch_device_t device) p4_pd_device, &o_match_spec, &entry_hdl); +#endif + + /* gre, inner ipv4 */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GRE; + o_match_spec.inner_ipv4_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_gre_inner_ipv4( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + +#ifndef P4_IPV6_DISABLE + /* gre, inner ipv6 */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GRE; + o_match_spec.inner_ipv6_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_gre_inner_ipv6( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); +#endif /* P4_IPV6_DISABLE */ + + /* gre, inner non ip */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GRE; + status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_gre_inner_non_ip( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + + /* ipip, inner ipv4 */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IPIP; + o_match_spec.inner_ipv4_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_ip_inner_ipv4( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + +#ifndef P4_IPV6_DISABLE + /* ipip, inner ipv6 */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IPIP; + o_match_spec.inner_ipv6_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_ip_inner_ipv6( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); +#endif /* P4_IPV6_DISABLE */ #ifndef P4_MPLS_DISABLE /* mpls, inner_ipv4, pop 1 */ @@ -1859,6 +1926,7 @@ switch_pd_tunnel_encap_tables_init_entry(switch_device_t device) &o_match_spec, &entry_hdl); +#ifndef TUNNEL_OVER_IPV6_DISABLE /* ipv6 vxlan */ memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; @@ -1876,6 +1944,7 @@ switch_pd_tunnel_encap_tables_init_entry(switch_device_t device) p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* ipv4 geneve */ memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); @@ -1895,6 +1964,7 @@ switch_pd_tunnel_encap_tables_init_entry(switch_device_t device) &o_match_spec, &entry_hdl); +#ifndef TUNNEL_OVER_IPV6_DISABLE /* ipv6 geneve */ memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; @@ -1912,7 +1982,9 @@ switch_pd_tunnel_encap_tables_init_entry(switch_device_t device) p4_pd_device, &o_match_spec, &entry_hdl); +#endif +#ifndef P4_NVGRE_DISABLE /* ipv4 nvgre */ memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; @@ -1948,6 +2020,83 @@ switch_pd_tunnel_encap_tables_init_entry(switch_device_t device) p4_pd_device, &o_match_spec, &entry_hdl); +#endif + + /* ipv4 gre */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GRE; + o_match_spec.multicast_metadata_replica = false; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_gre_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GRE; + o_match_spec.multicast_metadata_replica = true; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_gre_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + +#ifndef TUNNEL_OVER_IPV6_DISABLE + /* ipv6 gre */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GRE; + o_match_spec.multicast_metadata_replica = false; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_gre_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GRE; + o_match_spec.multicast_metadata_replica = true; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_gre_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); +#endif + + /* ipv4 ip */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_IP; + o_match_spec.multicast_metadata_replica = false; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_ip_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_IP; + o_match_spec.multicast_metadata_replica = true; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_ip_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + +#ifndef TUNNEL_OVER_IPV6_DISABLE + /* ipv6 ip */ + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_IP; + o_match_spec.multicast_metadata_replica = false; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_ip_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); + memset(&o_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + o_match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_IP; + o_match_spec.multicast_metadata_replica = true; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_ip_rewrite( + g_sess_hdl, + p4_pd_device, + &o_match_spec, + &entry_hdl); +#endif #ifndef P4_MPLS_DISABLE /* mpls, ethernet, push 1 */ @@ -2275,9 +2424,7 @@ switch_pd_tunnel_dst_rewrite_table_delete_entry(switch_device_t device, p4_pd_status_t switch_pd_bd_table_add_entry(switch_device_t device, - uint16_t bd, - switch_bd_info_t *bd_info, - p4_pd_mbr_hdl_t *entry_hdl) + uint16_t bd, switch_bd_info_t *bd_info) { p4_pd_status_t status = 0; p4_pd_dev_target_t p4_pd_device; @@ -2329,10 +2476,7 @@ switch_pd_bd_table_add_entry(switch_device_t device, } status = p4_pd_dc_bd_action_profile_add_member_with_set_bd_properties( - g_sess_hdl, - p4_pd_device, - &action_spec, - entry_hdl); + g_sess_hdl, p4_pd_device, &action_spec, &(bd_info->bd_entry)); #ifndef P4_MULTICAST_DISABLE /* Unknown unicast flood */ @@ -2345,11 +2489,8 @@ switch_pd_bd_table_add_entry(switch_device_t device, flood_match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UUC; flood_action_spec.action_mc_index = handle_to_id(bd_info->uuc_mc_index); status = p4_pd_dc_bd_flood_table_add_with_set_bd_flood_mc_index( - g_sess_hdl, - p4_pd_device, - &flood_match_spec, - &flood_action_spec, - &bd_info->uuc_entry); + g_sess_hdl, p4_pd_device, &flood_match_spec, &flood_action_spec, + &bd_info->uuc_entry); /* Unknown multicast flood */ memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); @@ -2359,11 +2500,8 @@ switch_pd_bd_table_add_entry(switch_device_t device, flood_match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; flood_action_spec.action_mc_index = handle_to_id(bd_info->umc_mc_index); status = p4_pd_dc_bd_flood_table_add_with_set_bd_flood_mc_index( - g_sess_hdl, - p4_pd_device, - &flood_match_spec, - &flood_action_spec, - &bd_info->umc_entry); + g_sess_hdl, p4_pd_device, &flood_match_spec, &flood_action_spec, + &bd_info->umc_entry); /* Unknown broadcast flood */ memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); @@ -2373,21 +2511,35 @@ switch_pd_bd_table_add_entry(switch_device_t device, flood_match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_BCAST; flood_action_spec.action_mc_index = handle_to_id(bd_info->bcast_mc_index); status = p4_pd_dc_bd_flood_table_add_with_set_bd_flood_mc_index( - g_sess_hdl, - p4_pd_device, - &flood_match_spec, - &flood_action_spec, - &bd_info->bcast_entry); + g_sess_hdl, p4_pd_device, &flood_match_spec, &flood_action_spec, + &bd_info->bcast_entry); #endif + + p4_pd_dc_port_vlan_mapping_match_spec_t pv_match_spec; + memset(&pv_match_spec, 0, sizeof(pv_match_spec)); + pv_match_spec.ingress_metadata_ifindex = 0x41; + int vlan_id0 = bd & 0xFFF; + int vlan_id1 = (bd & 0xF000) >> 12; + if (vlan_id0) { + pv_match_spec.vlan_tag__0__valid = TRUE; + pv_match_spec.vlan_tag__0__vid = vlan_id0; + } + if (vlan_id1) { + pv_match_spec.vlan_tag__1__valid = TRUE; + pv_match_spec.vlan_tag__1__vid = vlan_id1; + } + status = p4_pd_dc_port_vlan_mapping_add_entry(g_sess_hdl, p4_pd_device, + &pv_match_spec, + bd_info->bd_entry, + &(bd_info->cpu_entry)); + p4_pd_complete_operations(g_sess_hdl); return status; } p4_pd_status_t -switch_pd_bd_table_update_entry(switch_device_t device, - uint16_t bd, - switch_bd_info_t *bd_info, - p4_pd_mbr_hdl_t entry_hdl) +switch_pd_bd_table_update_entry(switch_device_t device, uint16_t bd, + switch_bd_info_t *bd_info) { p4_pd_status_t status = 0; switch_logical_network_t *ln_info = NULL; @@ -2436,10 +2588,7 @@ switch_pd_bd_table_update_entry(switch_device_t device, } status = p4_pd_dc_bd_action_profile_modify_member_with_set_bd_properties( - g_sess_hdl, - device, - entry_hdl, - &action_spec); + g_sess_hdl, device, bd_info->bd_entry, &action_spec); #ifndef P4_MULTICAST_DISABLE /* Unknown unicast flood */ @@ -2448,30 +2597,21 @@ switch_pd_bd_table_update_entry(switch_device_t device, sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); flood_action_spec.action_mc_index = handle_to_id(bd_info->uuc_mc_index); status = p4_pd_dc_bd_flood_table_modify_with_set_bd_flood_mc_index( - g_sess_hdl, - device, - bd_info->uuc_entry, - &flood_action_spec); + g_sess_hdl, device, bd_info->uuc_entry, &flood_action_spec); /* Unknown multicast flood */ memset(&flood_action_spec, 0, sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); flood_action_spec.action_mc_index = handle_to_id(bd_info->umc_mc_index); status = p4_pd_dc_bd_flood_table_modify_with_set_bd_flood_mc_index( - g_sess_hdl, - device, - bd_info->umc_entry, - &flood_action_spec); + g_sess_hdl, device, bd_info->umc_entry, &flood_action_spec); /* Unknown broadcast flood */ memset(&flood_action_spec, 0, sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); flood_action_spec.action_mc_index = handle_to_id(bd_info->bcast_mc_index); status = p4_pd_dc_bd_flood_table_modify_with_set_bd_flood_mc_index( - g_sess_hdl, - device, - bd_info->bcast_entry, - &flood_action_spec); + g_sess_hdl, device, bd_info->bcast_entry, &flood_action_spec); #endif p4_pd_complete_operations(g_sess_hdl); @@ -2496,6 +2636,9 @@ switch_pd_bd_table_delete_entry(switch_device_t device, bd_info->bcast_entry); #endif + status = p4_pd_dc_port_vlan_mapping_table_delete(g_sess_hdl, device, + bd_info->cpu_entry); + p4_pd_complete_operations(g_sess_hdl); return status; } @@ -2665,11 +2808,9 @@ switch_pd_port_vlan_mapping_table_add_entry(switch_device_t device, match_spec.vlan_tag__1__vid = vlan_id1; } - status = p4_pd_dc_port_vlan_mapping_add_entry(g_sess_hdl, - p4_pd_device, - &match_spec, - bd_hdl, - entry_hdl); + status = p4_pd_dc_port_vlan_mapping_add_entry(g_sess_hdl, p4_pd_device, + &match_spec, bd_hdl, + entry_hdl); p4_pd_complete_operations(g_sess_hdl); return status; } @@ -2680,9 +2821,8 @@ switch_pd_port_vlan_mapping_table_delete_entry(switch_device_t device, { p4_pd_status_t status = 0; - status = p4_pd_dc_port_vlan_mapping_table_delete(g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_port_vlan_mapping_table_delete(g_sess_hdl, device, + entry_hdl); p4_pd_complete_operations(g_sess_hdl); return status; } @@ -2741,36 +2881,42 @@ switch_pd_ingress_port_mapping_table_add_entry(switch_device_t device, switch_port_type_t port_type, p4_pd_entry_hdl_t *entry_hdl) { - p4_pd_dc_ingress_port_mapping_match_spec_t match_spec; - p4_pd_dc_set_ifindex_action_spec_t action_spec; - p4_pd_status_t status = 0; - bool modify = FALSE; - p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_ingress_port_mapping_match_spec_t match1_spec; + p4_pd_dc_ingress_port_properties_match_spec_t match2_spec; + p4_pd_dc_set_ifindex_action_spec_t action1_spec; + p4_pd_dc_set_ingress_port_properties_action_spec_t action2_spec; + p4_pd_status_t status = 0; + bool modify = FALSE; + p4_pd_dev_target_t p4_pd_device; p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_ingress_port_mapping_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_set_ifindex_action_spec_t)); + memset(&match1_spec, 0, sizeof(match1_spec)); + memset(&action1_spec, 0, sizeof(action1_spec)); + memset(&match2_spec, 0, sizeof(match2_spec)); + memset(&action2_spec, 0, sizeof(action2_spec)); - match_spec.standard_metadata_ingress_port = port_id; - action_spec.action_ifindex = ifindex; - action_spec.action_if_label = port_id; - action_spec.action_port_type = port_type; + match1_spec.ingress_input_port = port_id; + action1_spec.action_ifindex = ifindex; + action1_spec.action_port_type = port_type; - modify = (*entry_hdl != SWITCH_HW_INVALID_HANDLE) ? TRUE : FALSE; + match2_spec.ingress_input_port = port_id; + action2_spec.action_if_label = port_id; + + modify = (entry_hdl[0] != SWITCH_HW_INVALID_HANDLE) ? TRUE : FALSE; if (modify) { status = p4_pd_dc_ingress_port_mapping_table_modify_with_set_ifindex( - g_sess_hdl, 0, - *entry_hdl, - &action_spec); + g_sess_hdl, 0, entry_hdl[0], &action1_spec); + status = p4_pd_dc_ingress_port_properties_table_modify_with_set_ingress_port_properties( + g_sess_hdl, 0, entry_hdl[1], &action2_spec); } else { status = p4_pd_dc_ingress_port_mapping_table_add_with_set_ifindex( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); + g_sess_hdl, p4_pd_device, &match1_spec, &action1_spec, + &entry_hdl[0]); + status = p4_pd_dc_ingress_port_properties_table_add_with_set_ingress_port_properties( + g_sess_hdl, p4_pd_device, &match2_spec, &action2_spec, + &entry_hdl[1]); } p4_pd_complete_operations(g_sess_hdl); @@ -2779,13 +2925,15 @@ switch_pd_ingress_port_mapping_table_add_entry(switch_device_t device, p4_pd_status_t switch_pd_ingress_port_mapping_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) + p4_pd_entry_hdl_t *entry_hdl) { p4_pd_status_t status = 0; - status = p4_pd_dc_ingress_port_mapping_table_delete(g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_ingress_port_mapping_table_delete( + g_sess_hdl, device, entry_hdl[0]); + status = p4_pd_dc_ingress_port_properties_table_delete( + g_sess_hdl, device, entry_hdl[1]); + p4_pd_complete_operations(g_sess_hdl); return status; } @@ -2805,16 +2953,16 @@ switch_pd_egress_port_mapping_table_add_entry(switch_device_t device, p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_ingress_port_mapping_match_spec_t)); - match_spec.standard_metadata_egress_port = port_id; + memset(&match_spec, 0, sizeof(match_spec)); modify = (*entry_hdl != SWITCH_HW_INVALID_HANDLE) ? TRUE : FALSE; if (!modify) { + match_spec.egress_egress_port = port_id; if (port_type == SWITCH_PORT_TYPE_NORMAL) { p4_pd_dc_egress_port_type_normal_action_spec_t action_spec; memset(&action_spec, 0, sizeof(action_spec)); action_spec.action_ifindex = ifindex; - p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_normal( + status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_normal( g_sess_hdl, p4_pd_device, &match_spec, @@ -2824,7 +2972,7 @@ switch_pd_egress_port_mapping_table_add_entry(switch_device_t device, p4_pd_dc_egress_port_type_fabric_action_spec_t action_spec; memset(&action_spec, 0, sizeof(action_spec)); action_spec.action_ifindex = ifindex; - p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_fabric( + status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_fabric( g_sess_hdl, p4_pd_device, &match_spec, @@ -2834,7 +2982,7 @@ switch_pd_egress_port_mapping_table_add_entry(switch_device_t device, p4_pd_dc_egress_port_type_cpu_action_spec_t action_spec; memset(&action_spec, 0, sizeof(action_spec)); action_spec.action_ifindex = ifindex; - p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_cpu( + status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_cpu( g_sess_hdl, p4_pd_device, &match_spec, @@ -2984,6 +3132,20 @@ switch_pd_rewrite_table_tunnel_rewrite_add_entry(switch_device_t device, tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3; } break; + case SWITCH_API_ENCAP_TYPE_IPIP: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_IP; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_IP; + } + break; + case SWITCH_API_ENCAP_TYPE_GRE: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GRE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GRE; + } + break; default: status = SWITCH_STATUS_INVALID_TUNNEL_TYPE; return status; @@ -3096,6 +3258,20 @@ switch_pd_rewrite_table_tunnel_rewrite_update_entry(switch_device_t device, tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3; } break; + case SWITCH_API_ENCAP_TYPE_IPIP: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_IP; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_IP; + } + break; + case SWITCH_API_ENCAP_TYPE_GRE: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GRE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GRE; + } + break; default: status = SWITCH_STATUS_INVALID_TUNNEL_TYPE; return status; @@ -3341,7 +3517,7 @@ switch_pd_rid_table_add_entry(switch_device_t device, p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; memset(&match_spec, 0, sizeof(p4_pd_dc_rid_match_spec_t)); - match_spec.intrinsic_metadata_egress_rid = rid; + match_spec.egress_egress_rid = rid; if (!inner_replica) { p4_pd_dc_outer_replica_from_rid_action_spec_t action_spec; @@ -3968,13 +4144,16 @@ switch_pd_system_acl_table_add_entry(switch_device_t device, #ifndef BMV2 p4_pd_dc_negative_mirror_action_spec_t action_spec; action_spec.action_session_id = handle_to_id(opt_action_params->mirror_handle); -#endif +#endif /* BMV2 */ status = p4_pd_dc_system_acl_table_add_with_negative_mirror( - g_sess_hdl, p4_pd_device, &match_spec, priority, + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, #ifndef BMV2 - &action_spec, -#endif - entry_hdl); + &action_spec, +#endif /* BMV2 */ + entry_hdl); } break; case SWITCH_ACL_ACTION_DROP: @@ -5202,9 +5381,9 @@ switch_pd_egr_acl_table_add_entry(switch_device_t device, switch(egr_acl[i].field) { case SWITCH_ACL_EGR_DEST_PORT: { - match_spec.standard_metadata_egress_port = + match_spec.egress_egress_port_mask = 0xFFFF; + match_spec.egress_egress_port = handle_to_id(egr_acl[i].value.egr_port); - match_spec.standard_metadata_egress_port_mask = 0xFFFF; } break; case SWITCH_ACL_EGR_DEFLECT: @@ -5427,14 +5606,18 @@ switch_pd_ip_mcast_add_default_entry(switch_device_t device) status = p4_pd_dc_outer_ipv4_multicast_star_g_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_TUNNEL_DISABLE */ +#ifndef P4_L2_MULTICAST_DISABLE status = p4_pd_dc_ipv4_multicast_bridge_set_default_action_on_miss( g_sess_hdl, p4_pd_device, &entry_hdl); status = p4_pd_dc_ipv4_multicast_bridge_star_g_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L2_MULTICAST_DISABLE */ +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_ipv4_multicast_route_set_default_action_on_miss( g_sess_hdl, p4_pd_device, &entry_hdl); status = p4_pd_dc_ipv4_multicast_route_star_g_set_default_action_multicast_route_star_g_miss( g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L3_MULTICAST_DISABLE */ #endif /* P4_IPV4_DISABLE */ #ifndef P4_IPV6_DISABLE @@ -5444,14 +5627,18 @@ switch_pd_ip_mcast_add_default_entry(switch_device_t device) status = p4_pd_dc_outer_ipv6_multicast_star_g_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_TUNNEL_DISABLE */ +#ifndef P4_L2_MULTICAST_DISABLE status = p4_pd_dc_ipv6_multicast_bridge_set_default_action_on_miss( g_sess_hdl, p4_pd_device, &entry_hdl); status = p4_pd_dc_ipv6_multicast_bridge_star_g_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L2_MULTICAST_DISABLE */ +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_ipv6_multicast_route_set_default_action_on_miss( g_sess_hdl, p4_pd_device, &entry_hdl); status = p4_pd_dc_ipv6_multicast_route_star_g_set_default_action_multicast_route_star_g_miss( g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L3_MULTICAST_DISABLE */ #endif /* P4_IPV6_DISABLE */ #endif /* P4_MULTICAST_DISABLE */ @@ -5513,8 +5700,8 @@ switch_pd_validate_outer_ip_add_default_entry(switch_device_t device) sizeof(p4_pd_dc_validate_outer_ipv4_packet_match_spec_t)); memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t)); - match_spec.ipv4_metadata_lkp_ipv4_sa = 0x7f000000; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xff000000; + match_spec.ipv4_srcAddr = 0x7f000000; + match_spec.ipv4_srcAddr_mask = 0xff000000; action_spec.action_drop_reason = DROP_OUTER_IP_SRC_LOOPBACK; status = p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_malformed_outer_ipv4_packet( g_sess_hdl, @@ -5529,8 +5716,8 @@ switch_pd_validate_outer_ip_add_default_entry(switch_device_t device) sizeof(p4_pd_dc_validate_outer_ipv4_packet_match_spec_t)); memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t)); - match_spec.ipv4_metadata_lkp_ipv4_sa = 0xe0000000; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xf0000000; + match_spec.ipv4_srcAddr = 0xe0000000; + match_spec.ipv4_srcAddr_mask = 0xf0000000; action_spec.action_drop_reason = DROP_OUTER_IP_SRC_MULTICAST; status = p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_malformed_outer_ipv4_packet( g_sess_hdl, @@ -5545,7 +5732,7 @@ switch_pd_validate_outer_ip_add_default_entry(switch_device_t device) sizeof(p4_pd_dc_validate_outer_ipv4_packet_match_spec_t)); memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t)); - match_spec.l3_metadata_lkp_ip_ttl_mask = 0xff; + match_spec.ipv4_ttl_mask = 0xff; action_spec.action_drop_reason = DROP_OUTER_IP_TTL_ZERO; status = p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_malformed_outer_ipv4_packet( g_sess_hdl, @@ -5601,8 +5788,8 @@ switch_pd_validate_outer_ip_add_default_entry(switch_device_t device) sizeof(p4_pd_dc_validate_outer_ipv6_packet_match_spec_t)); memset(&v6_action_spec, 0, sizeof(p4_pd_dc_set_malformed_outer_ipv6_packet_action_spec_t)); - v6_match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xff; - v6_match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xff; + v6_match_spec.ipv6_srcAddr[0] = 0xff; + v6_match_spec.ipv6_srcAddr_mask[0] = 0xff; v6_action_spec.action_drop_reason = DROP_OUTER_IP_SRC_MULTICAST; status = p4_pd_dc_validate_outer_ipv6_packet_table_add_with_set_malformed_outer_ipv6_packet( g_sess_hdl, @@ -5617,7 +5804,7 @@ switch_pd_validate_outer_ip_add_default_entry(switch_device_t device) sizeof(p4_pd_dc_validate_outer_ipv6_packet_match_spec_t)); memset(&v6_action_spec, 0, sizeof(p4_pd_dc_set_malformed_outer_ipv6_packet_action_spec_t)); - v6_match_spec.l3_metadata_lkp_ip_ttl_mask = 0xff; + v6_match_spec.ipv6_hopLimit_mask = 0xff; v6_action_spec.action_drop_reason = DROP_OUTER_IP_TTL_ZERO; status = p4_pd_dc_validate_outer_ipv6_packet_table_add_with_set_malformed_outer_ipv6_packet( g_sess_hdl, @@ -5804,9 +5991,7 @@ switch_pd_port_vlan_mapping_table_add_default_entry(switch_device_t device) p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; status = p4_pd_dc_bd_action_profile_add_member_with_port_vlan_mapping_miss( - g_sess_hdl, - p4_pd_device, - &mbr_hdl); + g_sess_hdl, p4_pd_device, &mbr_hdl); status = p4_pd_dc_port_vlan_mapping_set_default_entry(g_sess_hdl, p4_pd_device, mbr_hdl, @@ -6224,8 +6409,8 @@ switch_pd_egress_filter_table_add_default_entry(switch_device_t device) { p4_pd_status_t status = 0; #ifdef EGRESS_FILTER - p4_pd_entry_hdl_t entry_hdl; p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; @@ -6234,7 +6419,7 @@ switch_pd_egress_filter_table_add_default_entry(switch_device_t device) g_sess_hdl, p4_pd_device, &entry_hdl); - status = p4_pd_dc_egress_filter_drop_set_default_action_egress_filter_drop( + status = p4_pd_dc_egress_filter_drop_set_default_action_set_egress_filter_drop( g_sess_hdl, p4_pd_device, &entry_hdl); @@ -6441,8 +6626,14 @@ switch_pd_rewrite_multicast_table_add_default_entry(switch_device_t device) p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + (void) entry_hdl; + (void) p4_pd_device; + (void) entry_hdl; + +#ifndef P4_MULTICAST_DISABLE status = p4_pd_dc_rewrite_multicast_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_MULTICAST_DISABLE */ p4_pd_complete_operations(g_sess_hdl); return status; @@ -6553,8 +6744,62 @@ switch_pd_tunnel_table_add_default_entry(switch_device_t device) status = p4_pd_dc_tunnel_set_default_action_tunnel_lookup_miss( g_sess_hdl, p4_pd_device, &entry_hdl); - status = p4_pd_dc_tunnel_miss_set_default_action_tunnel_lookup_miss( + status = p4_pd_dc_tunnel_miss_set_default_action_non_ip_tunnel_lookup_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_tunnel_lookup_miss_set_default_action_non_ip_tunnel_lookup_miss( g_sess_hdl, p4_pd_device, &entry_hdl); + + p4_pd_dc_tunnel_match_spec_t match_spec; + int tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_1; + while (tunnel_type <= SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_3) { + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.tunnel_metadata_tunnel_vni = 0; + match_spec.tunnel_metadata_ingress_tunnel_type = tunnel_type; + match_spec.inner_ipv4_valid = 0; + match_spec.inner_ipv6_valid = 0; + status = p4_pd_dc_tunnel_table_add_with_nop(g_sess_hdl, p4_pd_device, + &match_spec, &entry_hdl); + match_spec.tunnel_metadata_tunnel_vni = 0; + match_spec.tunnel_metadata_ingress_tunnel_type = tunnel_type; + match_spec.inner_ipv4_valid = 1; + match_spec.inner_ipv6_valid = 0; + status = p4_pd_dc_tunnel_table_add_with_nop(g_sess_hdl, p4_pd_device, + &match_spec, &entry_hdl); + match_spec.tunnel_metadata_tunnel_vni = 0; + match_spec.tunnel_metadata_ingress_tunnel_type = tunnel_type; + match_spec.inner_ipv4_valid = 0; + match_spec.inner_ipv6_valid = 1; + status = p4_pd_dc_tunnel_table_add_with_nop(g_sess_hdl, p4_pd_device, + &match_spec, &entry_hdl); + tunnel_type++; + } + + p4_pd_dc_tunnel_miss_match_spec_t match1_spec; + memset(&match1_spec, 0, sizeof(match1_spec)); + match1_spec.ipv4_valid = true; + status = p4_pd_dc_tunnel_miss_table_add_with_ipv4_tunnel_lookup_miss( + g_sess_hdl, p4_pd_device, &match1_spec, &entry_hdl); + +#ifndef P4_IPV6_DISABLE + memset(&match1_spec, 0, sizeof(match1_spec)); + match1_spec.ipv6_valid = true; + status = p4_pd_dc_tunnel_miss_table_add_with_ipv6_tunnel_lookup_miss( + g_sess_hdl, p4_pd_device, &match1_spec, &entry_hdl); +#endif + + p4_pd_dc_tunnel_lookup_miss_match_spec_t match2_spec; + memset(&match2_spec, 0, sizeof(match2_spec)); + match2_spec.ipv4_valid = true; + status = p4_pd_dc_tunnel_lookup_miss_table_add_with_ipv4_tunnel_lookup_miss( + g_sess_hdl, p4_pd_device, &match2_spec, &entry_hdl); + +#ifndef P4_IPV6_DISABLE + memset(&match2_spec, 0, sizeof(match2_spec)); + match2_spec.ipv6_valid = true; + status = p4_pd_dc_tunnel_lookup_miss_table_add_with_ipv6_tunnel_lookup_miss( + g_sess_hdl, p4_pd_device, &match2_spec, &entry_hdl); +#endif + #endif /* P4_TUNNEL_DISABLE */ p4_pd_complete_operations(g_sess_hdl); return status; @@ -6948,94 +7193,55 @@ switch_pd_validate_outer_ethernet_table_init_entry(switch_device_t device) sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); memset(&action_spec, 0, sizeof(p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t)); - match_spec.l2_metadata_lkp_mac_sa_mask[0] = 0xff; - match_spec.l2_metadata_lkp_mac_sa_mask[1] = 0xff; - match_spec.l2_metadata_lkp_mac_sa_mask[2] = 0xff; - match_spec.l2_metadata_lkp_mac_sa_mask[3] = 0xff; - match_spec.l2_metadata_lkp_mac_sa_mask[4] = 0xff; - match_spec.l2_metadata_lkp_mac_sa_mask[5] = 0xff; + memset(match_spec.ethernet_srcAddr_mask, 0xff, + sizeof(match_spec.ethernet_srcAddr_mask)); action_spec.action_drop_reason = DROP_OUTER_SRC_MAC_ZERO; status = p4_pd_dc_validate_outer_ethernet_table_add_with_malformed_outer_ethernet_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - 10, - &action_spec, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 10, &action_spec, &entry_hdl); /* mac sa is multicast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); memset(&action_spec, 0, sizeof(p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t)); - match_spec.l2_metadata_lkp_mac_sa[0] = 0x01; - match_spec.l2_metadata_lkp_mac_sa_mask[0] = 0x01; + match_spec.ethernet_srcAddr[0] = 0x01; + match_spec.ethernet_srcAddr_mask[0] = 0x01; action_spec.action_drop_reason = DROP_OUTER_SRC_MAC_MULTICAST; status = p4_pd_dc_validate_outer_ethernet_table_add_with_malformed_outer_ethernet_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - 11, - &action_spec, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 11, &action_spec, &entry_hdl); /* mac da is zeros */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); memset(&action_spec, 0, sizeof(p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t)); - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[5] = 0xff; + memset(match_spec.ethernet_dstAddr_mask, 0xff, + sizeof(match_spec.ethernet_dstAddr_mask)); action_spec.action_drop_reason = DROP_OUTER_DST_MAC_ZERO; status = p4_pd_dc_validate_outer_ethernet_table_add_with_malformed_outer_ethernet_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - 12, - &action_spec, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 12, &action_spec, &entry_hdl); /* double tagged broadcast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da[5] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[5] = 0xff; + memset(match_spec.ethernet_dstAddr, 0xff, + sizeof(match_spec.ethernet_dstAddr)); + memset(match_spec.ethernet_dstAddr_mask, 0xff, + sizeof(match_spec.ethernet_dstAddr_mask)); match_spec.vlan_tag__0__valid = 1; match_spec.vlan_tag__1__valid = 1; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_broadcast_packet_double_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1000, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 1000, &entry_hdl); /* double tagged multicast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0x01; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; + match_spec.ethernet_dstAddr[0] = 0x01; + match_spec.ethernet_dstAddr_mask[0] = 0x01; match_spec.vlan_tag__0__valid = 1; match_spec.vlan_tag__1__valid = 1; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_multicast_packet_double_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1001, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 1001, &entry_hdl); /* double tagged unicast */ memset(&match_spec, 0, @@ -7043,49 +7249,29 @@ switch_pd_validate_outer_ethernet_table_init_entry(switch_device_t device) match_spec.vlan_tag__0__valid = 1; match_spec.vlan_tag__1__valid = 1; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_unicast_packet_double_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1002, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 1002, &entry_hdl); /* single tagged broadcast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da[5] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[5] = 0xff; + memset(match_spec.ethernet_dstAddr, 0xff, + sizeof(match_spec.ethernet_dstAddr)); + memset(match_spec.ethernet_dstAddr_mask, 0xff, + sizeof(match_spec.ethernet_dstAddr_mask)); match_spec.vlan_tag__0__valid = 1; match_spec.vlan_tag__1__valid = 0; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_broadcast_packet_single_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 2000, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 2000, &entry_hdl); /* single tagged multicast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0x01; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; + match_spec.ethernet_dstAddr[0] = 0x01; + match_spec.ethernet_dstAddr_mask[0] = 0x01; match_spec.vlan_tag__0__valid = 1; match_spec.vlan_tag__1__valid = 0; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_multicast_packet_single_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 2001, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 2001, &entry_hdl); /* single tagged unicast */ memset(&match_spec, 0, @@ -7093,49 +7279,29 @@ switch_pd_validate_outer_ethernet_table_init_entry(switch_device_t device) match_spec.vlan_tag__0__valid = 1; match_spec.vlan_tag__1__valid = 0; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_unicast_packet_single_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 2002, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 2002, &entry_hdl); /* untagged packet broadcast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da[5] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[1] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[2] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[3] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[4] = 0xff; - match_spec.l2_metadata_lkp_mac_da_mask[5] = 0xff; + memset(match_spec.ethernet_dstAddr, 0xff, + sizeof(match_spec.ethernet_dstAddr)); + memset(match_spec.ethernet_dstAddr_mask, 0xff, + sizeof(match_spec.ethernet_dstAddr_mask)); match_spec.vlan_tag__0__valid = 0; match_spec.vlan_tag__1__valid = 0; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_broadcast_packet_untagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 3000, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 3000, &entry_hdl); /* untagged packet multicast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0x01; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; + match_spec.ethernet_dstAddr[0] = 0x01; + match_spec.ethernet_dstAddr_mask[0] = 0x01; match_spec.vlan_tag__0__valid = 0; match_spec.vlan_tag__1__valid = 0; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_multicast_packet_untagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 3001, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 3001, &entry_hdl); /* untagged packet unicast */ memset(&match_spec, 0, @@ -7143,11 +7309,7 @@ switch_pd_validate_outer_ethernet_table_init_entry(switch_device_t device) match_spec.vlan_tag__0__valid = 0; match_spec.vlan_tag__1__valid = 0; status = p4_pd_dc_validate_outer_ethernet_table_add_with_set_valid_outer_unicast_packet_untagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - 3002, - &entry_hdl); + g_sess_hdl, p4_pd_device, &match_spec, 3002, &entry_hdl); p4_pd_complete_operations(g_sess_hdl); return status; @@ -7366,7 +7528,9 @@ switch_pd_rewrite_multicast_table_init_entry(switch_device_t device) p4_pd_status_t status = 0; p4_pd_entry_hdl_t entry_hdl; p4_pd_dev_target_t p4_pd_device; +#ifndef P4_MULTICAST_DISABLE p4_pd_dc_rewrite_multicast_match_spec_t match_spec; +#endif /* P4_MULTICAST_DISABLE */ p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; @@ -7380,7 +7544,7 @@ switch_pd_rewrite_multicast_table_init_entry(switch_device_t device) status = p4_pd_dc_rewrite_multicast_table_add_with_rewrite_ipv4_multicast( g_sess_hdl, p4_pd_device, &match_spec, 100, &entry_hdl); #else - (void)entry_hdl; (void)p4_pd_device; (void)match_spec; + (void)entry_hdl; (void)p4_pd_device; #endif #if !defined(P4_IPV6_DISABLE) && !defined(P4_MULTICAST_DISABLE) @@ -7408,33 +7572,34 @@ switch_pd_l3_rewrite_table_init_entry(switch_device_t device) p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -#ifndef P4_MULTICAST_DISABLE +#ifndef P4_L3_MULTICAST_DISABLE memset(&match_spec, 0, sizeof(match_spec)); match_spec.ipv4_valid = 0x1; match_spec.ipv4_dstAddr = 0xe0000000; match_spec.ipv4_dstAddr_mask = 0xf0000000; status = p4_pd_dc_l3_rewrite_table_add_with_ipv4_multicast_rewrite( g_sess_hdl, p4_pd_device, &match_spec, 100, &entry_hdl); -#endif /* P4_MULTICAST_DISABLE */ +#endif /* P4_L3_MULTICAST_DISABLE */ memset(&match_spec, 0, sizeof(match_spec)); match_spec.ipv4_valid = 0x1; status = p4_pd_dc_l3_rewrite_table_add_with_ipv4_unicast_rewrite( g_sess_hdl, p4_pd_device, &match_spec, 101, &entry_hdl); -#if !defined(P4_IPV6_DISABLE) && !defined(P4_MULTICAST_DISABLE) +#if !defined(P4_IPV6_DISABLE) memset(&match_spec, 0, sizeof(match_spec)); match_spec.ipv6_valid = 0x1; match_spec.ipv6_dstAddr[0] = 0xff; match_spec.ipv6_dstAddr_mask[0] = 0xff; +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_l3_rewrite_table_add_with_ipv6_multicast_rewrite( g_sess_hdl, p4_pd_device, &match_spec, 200, &entry_hdl); - +#endif /* P4_L3_MULTICAST_DISABLE */ memset(&match_spec, 0, sizeof(match_spec)); match_spec.ipv6_valid = 0x1; status = p4_pd_dc_l3_rewrite_table_add_with_ipv6_unicast_rewrite( g_sess_hdl, p4_pd_device, &match_spec, 201, &entry_hdl); -#endif /* !P4_IPV6_DISABLE && !P4_MULTICAST_DISABLE */ +#endif /* !P4_IPV6_DISABLE */ #ifndef P4_MPLS_DISABLE memset(&match_spec, 0, sizeof(match_spec)); @@ -7448,7 +7613,7 @@ switch_pd_l3_rewrite_table_init_entry(switch_device_t device) } p4_pd_status_t -switch_pd_vlan_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats) +switch_pd_bd_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats) { p4_pd_status_t status = 0; #ifndef P4_STATS_DISABLE @@ -7459,7 +7624,7 @@ switch_pd_vlan_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_s p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - for (index = 0; index < SWITCH_VLAN_STATS_OUT_UCAST; index++) { + for (index = 0; index < SWITCH_BD_STATS_OUT_UCAST; index++) { counter = p4_pd_dc_counter_read_ingress_bd_stats( g_sess_hdl, p4_pd_device, @@ -7474,7 +7639,7 @@ switch_pd_vlan_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_s } p4_pd_status_t -switch_pd_vlan_egress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats) +switch_pd_bd_egress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats) { p4_pd_status_t status = 0; #ifndef P4_STATS_DISABLE @@ -7491,8 +7656,8 @@ switch_pd_vlan_egress_stats_get(switch_device_t device, switch_bd_stats_t *bd_st p4_pd_device, bd_stats->stats_hw_entry[index], COUNTER_READ_HW_SYNC); - bd_stats->counters[index + SWITCH_VLAN_STATS_OUT_UCAST].num_packets = counter.packets; - bd_stats->counters[index + SWITCH_VLAN_STATS_OUT_UCAST].num_bytes = counter.bytes; + bd_stats->counters[index + SWITCH_BD_STATS_OUT_UCAST].num_packets = counter.packets; + bd_stats->counters[index + SWITCH_BD_STATS_OUT_UCAST].num_bytes = counter.bytes; } #endif /* P4_STATS_DISABLE */ p4_pd_complete_operations(g_sess_hdl); @@ -7573,6 +7738,7 @@ switch_pd_storm_control_stats_get(switch_device_t device, switch_meter_info_t *m stats_info = meter_info->stats_info; +#ifndef P4_STORM_CONTROL_DISABLE for (index = 0; index < SWITCH_METER_STATS_MAX; index++) { counter = p4_pd_dc_counter_read_storm_control_stats( g_sess_hdl, @@ -7582,6 +7748,7 @@ switch_pd_storm_control_stats_get(switch_device_t device, switch_meter_info_t *m stats_info->counters[index].num_packets = counter.packets; stats_info->counters[index].num_bytes = counter.bytes; } +#endif #endif /* P4_STATS_DISABLE */ p4_pd_complete_operations(g_sess_hdl); return status; @@ -8538,7 +8705,7 @@ switch_pd_storm_control_table_add_entry( match_spec.l2_metadata_lkp_pkt_type = pkt_type; match_spec.l2_metadata_lkp_pkt_type_mask = 0xFF; - match_spec.ingress_metadata_ingress_port = port; + match_spec.ingress_input_port = port; action_spec.action_meter_idx = meter_idx; @@ -9204,12 +9371,13 @@ switch_pd_stats_update(switch_device_t device) p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +#ifndef P4_STORM_CONTROL_DISABLE status = p4_pd_dc_counter_hw_sync_storm_control_stats( g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); - +#endif status = p4_pd_dc_counter_hw_sync_acl_stats( g_sess_hdl, p4_pd_device, diff --git a/switchapi/src/switch_pd.h b/switchapi/src/switch_pd.h index e6c203e..5e45abd 100644 --- a/switchapi/src/switch_pd.h +++ b/switchapi/src/switch_pd.h @@ -286,15 +286,11 @@ switch_pd_tunnel_dmac_rewrite_table_delete_entry(switch_device_t device, p4_pd_status_t switch_pd_bd_table_add_entry(switch_device_t device, - uint16_t bd, - switch_bd_info_t *bd_info, - p4_pd_mbr_hdl_t *entry_hdl); + uint16_t bd, switch_bd_info_t *bd_info); p4_pd_status_t switch_pd_bd_table_update_entry(switch_device_t device, - uint16_t outer_bd, - switch_bd_info_t *bd_info, - p4_pd_mbr_hdl_t entry_hdl); + uint16_t bd, switch_bd_info_t *bd_info); p4_pd_status_t switch_pd_bd_table_delete_entry(switch_device_t device, @@ -327,9 +323,10 @@ switch_pd_port_vlan_mapping_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t -switch_pd_egress_vlan_xlate_table_add_entry(switch_device_t device, switch_ifindex_t ifindex, - uint16_t egress_bd, switch_vlan_t vlan_id, - p4_pd_entry_hdl_t *entry_hdl); +switch_pd_egress_vlan_xlate_table_add_entry( + switch_device_t device, switch_ifindex_t ifindex, + uint16_t egress_bd, switch_vlan_t vlan_id, + p4_pd_entry_hdl_t *entry_hdl); p4_pd_status_t switch_pd_egress_vlan_xlate_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl); @@ -343,6 +340,17 @@ switch_pd_ingress_port_mapping_table_add_entry(switch_device_t device, p4_pd_status_t switch_pd_ingress_port_mapping_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t +switch_pd_egress_port_mapping_table_add_entry(switch_device_t device, + switch_port_t port_id, + switch_ifindex_t ifindex, + switch_port_type_t port_type, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t +switch_pd_egress_port_mapping_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t @@ -701,10 +709,10 @@ switch_pd_egr_acl_table_delete_entry( p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t -switch_pd_vlan_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats); +switch_pd_bd_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats); p4_pd_status_t -switch_pd_vlan_egress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats);; +switch_pd_bd_egress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats);; p4_pd_status_t switch_pd_drop_stats_get(switch_device_t device, int num_counters, diff --git a/switchapi/src/switch_pd_mcast.c b/switchapi/src/switch_pd_mcast.c index 8798784..23e7085 100644 --- a/switchapi/src/switch_pd_mcast.c +++ b/switchapi/src/switch_pd_mcast.c @@ -53,8 +53,8 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv4_mcast_key_type = SWITCH_MCAST_KEY_TYPE_VRF; match_spec.multicast_metadata_ipv4_mcast_key = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + match_spec.ipv4_srcAddr = SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key); + match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -73,8 +73,8 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv4_mcast_key_type = SWITCH_MCAST_KEY_TYPE_BD; match_spec.multicast_metadata_ipv4_mcast_key = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + match_spec.ipv4_srcAddr = SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key); + match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -96,9 +96,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv6_mcast_key_type = SWITCH_MCAST_KEY_TYPE_VRF; match_spec.multicast_metadata_ipv6_mcast_key = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_sa), + memcpy(&(match_spec.ipv6_srcAddr), &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + memcpy(&(match_spec.ipv6_dstAddr), &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); #ifdef OUTER_MULTICAST_TREE_ENABLED @@ -118,9 +118,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv6_mcast_key_type = SWITCH_MCAST_KEY_TYPE_BD; match_spec.multicast_metadata_ipv6_mcast_key = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_sa), + memcpy(&(match_spec.ipv6_srcAddr), &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + memcpy(&(match_spec.ipv6_dstAddr), &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); #ifdef OUTER_MULTICAST_TREE_ENABLED @@ -146,8 +146,8 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv4_mcast_key_type = SWITCH_MCAST_KEY_TYPE_VRF; match_spec.multicast_metadata_ipv4_mcast_key = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0xffffffff; + match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + match_spec.ipv4_dstAddr_mask = 0xffffffff; #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -166,8 +166,8 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv4_mcast_key_type = SWITCH_MCAST_KEY_TYPE_VRF; match_spec.multicast_metadata_ipv4_mcast_key = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0xffffffff; + match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + match_spec.ipv4_dstAddr_mask = 0xffffffff; #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -187,8 +187,8 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv4_mcast_key_type = SWITCH_MCAST_KEY_TYPE_BD; match_spec.multicast_metadata_ipv4_mcast_key = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0xffffffff; + match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + match_spec.ipv4_dstAddr_mask = 0xffffffff; #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -211,9 +211,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv6_mcast_key_type = SWITCH_MCAST_KEY_TYPE_VRF; match_spec.multicast_metadata_ipv6_mcast_key = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + memcpy(&(match_spec.ipv6_dstAddr), &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - memset(&(match_spec.ipv6_metadata_lkp_ipv6_da_mask), 0xff, 16); + memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -232,9 +232,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv6_mcast_key_type = SWITCH_MCAST_KEY_TYPE_VRF; match_spec.multicast_metadata_ipv6_mcast_key = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + memcpy(&(match_spec.ipv6_dstAddr), &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - memset(&(match_spec.ipv6_metadata_lkp_ipv6_da_mask), 0xff, 16); + memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -254,9 +254,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, match_spec.multicast_metadata_ipv6_mcast_key_type = SWITCH_MCAST_KEY_TYPE_BD; match_spec.multicast_metadata_ipv6_mcast_key = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + memcpy(&(match_spec.ipv6_dstAddr), &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - memset(&(match_spec.ipv6_metadata_lkp_ipv6_da_mask), 0xff, 16); + memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); #ifdef OUTER_MULTICAST_TREE_ENABLED action_spec.action_mc_index = mgid_index; @@ -276,6 +276,7 @@ switch_pd_mcast_table_add_entry(switch_device_t device, if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE p4_pd_dc_ipv4_multicast_route_match_spec_t match_spec; p4_pd_dc_multicast_route_s_g_hit_action_spec_t action_spec; @@ -291,7 +292,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, status = p4_pd_dc_ipv4_multicast_route_table_add_with_multicast_route_s_g_hit( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE p4_pd_dc_ipv4_multicast_bridge_match_spec_t match_spec; p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t action_spec; @@ -306,11 +309,13 @@ switch_pd_mcast_table_add_entry(switch_device_t device, status = p4_pd_dc_ipv4_multicast_bridge_table_add_with_multicast_bridge_s_g_hit( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV4_DISABLE */ } else { #ifndef P4_IPV6_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE p4_pd_dc_ipv6_multicast_route_match_spec_t match_spec; p4_pd_dc_multicast_route_s_g_hit_action_spec_t action_spec; @@ -328,7 +333,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, status = p4_pd_dc_ipv6_multicast_route_table_add_with_multicast_route_s_g_hit( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE p4_pd_dc_ipv6_multicast_bridge_match_spec_t match_spec; p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t action_spec; @@ -345,6 +352,7 @@ switch_pd_mcast_table_add_entry(switch_device_t device, status = p4_pd_dc_ipv6_multicast_bridge_table_add_with_multicast_bridge_s_g_hit( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV6_DISABLE */ } @@ -352,6 +360,7 @@ switch_pd_mcast_table_add_entry(switch_device_t device, if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) { p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t match_spec; p4_pd_dc_multicast_route_sm_star_g_hit_action_spec_t action_spec; @@ -383,7 +392,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); } +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE p4_pd_dc_ipv4_multicast_bridge_star_g_match_spec_t match_spec; p4_pd_dc_multicast_bridge_star_g_hit_action_spec_t action_spec; @@ -397,11 +408,13 @@ switch_pd_mcast_table_add_entry(switch_device_t device, status = p4_pd_dc_ipv4_multicast_bridge_star_g_table_add_with_multicast_bridge_star_g_hit( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV4_DISABLE */ } else { #ifndef P4_IPV6_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) { p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t match_spec; p4_pd_dc_multicast_route_sm_star_g_hit_action_spec_t action_spec; @@ -435,7 +448,9 @@ switch_pd_mcast_table_add_entry(switch_device_t device, g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); } +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE p4_pd_dc_ipv6_multicast_bridge_star_g_match_spec_t match_spec; p4_pd_dc_multicast_bridge_star_g_hit_action_spec_t action_spec; @@ -450,6 +465,7 @@ switch_pd_mcast_table_add_entry(switch_device_t device, status = p4_pd_dc_ipv6_multicast_bridge_star_g_table_add_with_multicast_bridge_star_g_hit( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &(group_info->inner_hw_entry)); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV6_DISABLE */ } @@ -507,21 +523,29 @@ switch_pd_mcast_table_delete_entry(switch_device_t device, if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_ipv4_multicast_route_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE status = p4_pd_dc_ipv4_multicast_bridge_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV4_DISABLE */ } else { #ifndef P4_IPV6_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_ipv6_multicast_route_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE status = p4_pd_dc_ipv6_multicast_bridge_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV6_DISABLE */ } @@ -529,21 +553,29 @@ switch_pd_mcast_table_delete_entry(switch_device_t device, if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_ipv4_multicast_route_star_g_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE status = p4_pd_dc_ipv4_multicast_bridge_star_g_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV4_DISABLE */ } else { #ifndef P4_IPV6_DISABLE if (vrf_entry) { +#ifndef P4_L3_MULTICAST_DISABLE status = p4_pd_dc_ipv6_multicast_route_star_g_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L3_MULTICAST_DISABLE */ } else { +#ifndef P4_L2_MULTICAST_DISABLE status = p4_pd_dc_ipv6_multicast_bridge_star_g_table_delete( g_sess_hdl, device, group_info->inner_hw_entry); +#endif /* P4_L2_MULTICAST_DISABLE */ } #endif /* P4_IPV6_DISABLE */ } diff --git a/switchapi/src/switch_port.c b/switchapi/src/switch_port.c index 123a983..dab72a4 100644 --- a/switchapi/src/switch_port.c +++ b/switchapi/src/switch_port.c @@ -39,17 +39,20 @@ switch_port_init(switch_device_t device) if (index == CPU_PORT_ID) { port_info->port_type = SWITCH_PORT_TYPE_CPU; } + port_info->lag_handle = 0; + #ifdef SWITCH_PD switch_pd_lag_group_table_add_entry(device, port_info->ifindex, SWITCH_PORT_ID(port_info), &(port_info->mbr_hdl), &(port_info->lg_entry)); - port_info->hw_entry = SWITCH_HW_INVALID_HANDLE; + port_info->hw_entry[0] = SWITCH_HW_INVALID_HANDLE; + port_info->hw_entry[1] = SWITCH_HW_INVALID_HANDLE; switch_pd_ingress_port_mapping_table_add_entry(device, SWITCH_PORT_ID(port_info), port_info->ifindex, port_info->port_type, - &(port_info->hw_entry)); + port_info->hw_entry); port_info->eg_port_entry = SWITCH_HW_INVALID_HANDLE; switch_pd_egress_port_mapping_table_add_entry(device, SWITCH_PORT_ID(port_info), @@ -59,13 +62,6 @@ switch_port_init(switch_device_t device) port_info->port_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, index); #endif } - memset(&dummy_port_info, 0, sizeof(dummy_port_info)); - dummy_port_info.port_type = SWITCH_PORT_TYPE_NORMAL; - - memset(&null_port_info, 0, sizeof(null_port_info)); - null_port_info.ifindex = NULL_PORT_ID; - null_port_info.port_type = SWITCH_PORT_TYPE_NORMAL; - return SWITCH_STATUS_SUCCESS; } @@ -113,13 +109,14 @@ switch_api_port_delete(switch_device_t device, uint16_t port_number) { switch_status_t status = SWITCH_STATUS_SUCCESS; switch_port_info_t *port_info = switch_api_port_get_internal(port_number); - if(port_info) { - status = switch_pd_lag_group_table_delete_entry(device, port_info->hw_entry); - return status; - } - return SWITCH_STATUS_FAILURE; + status = switch_pd_lag_group_table_delete_entry( + device, port_info->lg_entry); + status = switch_pd_ingress_port_mapping_table_delete_entry( + device, port_info->hw_entry); + return status; } + switch_status_t switch_api_port_print_entry(switch_port_t port) { @@ -207,7 +204,7 @@ switch_api_storm_control_stats_get(switch_device_t device, switch_meter_info_t *meter_info = NULL; switch_meter_stats_info_t *stats_info = NULL; int index = 0; - switch_vlan_stats_t counter_id = 0; + switch_bd_stats_id_t counter_id = 0; meter_info = switch_meter_info_get(meter_handle); if (!meter_info) { diff --git a/switchapi/src/switch_port_int.h b/switchapi/src/switch_port_int.h index d50451c..4a9e4fc 100644 --- a/switchapi/src/switch_port_int.h +++ b/switchapi/src/switch_port_int.h @@ -39,17 +39,17 @@ typedef enum switch_port_type_ { typedef struct switch_port_info_ { switch_api_port_info_t api_port_info; switch_ifindex_t ifindex; - switch_handle_t intf_handle; + void *intf_array; switch_handle_t port_handle; - switch_handle_t hostif_handle; switch_port_type_t port_type; switch_handle_t meter_handle[SWITCH_PACKET_TYPE_MAX]; + switch_handle_t lag_handle; #ifdef SWITCH_PD - p4_pd_entry_hdl_t hw_entry; /* port mapping entry */ + p4_pd_entry_hdl_t hw_entry[2]; /* port mapping entry */ p4_pd_entry_hdl_t lg_entry; /* Lag group entry */ p4_pd_entry_hdl_t ls_entry; /* Lag select entry */ p4_pd_mbr_hdl_t mbr_hdl; /* Lag action profile entry */ - p4_pd_entry_hdl_t eg_port_entry; /* egress lag entry */ + p4_pd_entry_hdl_t eg_port_entry; /* egress port entry */ p4_pd_entry_hdl_t rw_entry; /* fabric rewrite entry */ p4_pd_entry_hdl_t tunnel_rw_entry; /* tunnel rewrite entry */ p4_pd_entry_hdl_t meter_pd_hdl[SWITCH_PACKET_TYPE_MAX]; /* meter pd hdl */ diff --git a/switchapi/src/switch_stp.c b/switchapi/src/switch_stp.c index 121851c..6675b3d 100644 --- a/switchapi/src/switch_stp.c +++ b/switchapi/src/switch_stp.c @@ -20,6 +20,7 @@ limitations under the License. #include "switchapi/switch_interface.h" #include "switch_stp_int.h" #include "switch_pd.h" +#include "switch_log.h" #include #ifdef __cplusplus @@ -161,10 +162,8 @@ switch_api_stp_group_vlans_add(switch_device_t device, vlan_entry->bd_handle = bd_handle; bd_info->stp_handle = stg_handle; - switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); tommy_list_insert_head(&(stp_info->vlan_list), &(vlan_entry->node), vlan_entry); @@ -215,10 +214,8 @@ switch_api_stp_group_vlans_remove(switch_device_t device, } bd_info->stp_handle = 0; - switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); vlan_entry = tommy_list_remove_existing(&(stp_info->vlan_list), node); switch_free(vlan_entry); @@ -235,8 +232,6 @@ switch_api_stp_port_state_set(switch_device_t device, switch_handle_t stg_handle switch_stp_port_entry_t *port_entry = NULL; tommy_node *node = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; switch_handle_t intf_handle; switch_handle_type_t handle_type = 0; bool new_entry = FALSE; @@ -258,19 +253,16 @@ switch_api_stp_port_state_set(switch_device_t device, switch_handle_t stg_handle handle_type = switch_handle_get_type(handle); intf_handle = handle; - if (handle_type == SWITCH_HANDLE_TYPE_PORT) { - port_info = switch_api_port_get_internal((switch_port_t)handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - intf_handle = port_info->intf_handle; - } - if (handle_type == SWITCH_HANDLE_TYPE_LAG) { - lag_info = switch_api_lag_get_internal(handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + status = switch_interface_handle_get( + handle, + 0x0, + &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("stp port state set failed"); + return status; } - intf_handle = lag_info->intf_handle; } intf_info = switch_api_interface_get(intf_handle); @@ -341,10 +333,9 @@ switch_api_stp_port_state_get(switch_device_t device, switch_handle_t stg_handle switch_interface_info_t *intf_info = NULL; switch_stp_port_entry_t *port_entry = NULL; tommy_node *node = NULL; - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; switch_handle_t intf_handle = 0; switch_handle_type_t handle_type = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { return SWITCH_STATUS_INVALID_HANDLE; @@ -363,19 +354,16 @@ switch_api_stp_port_state_get(switch_device_t device, switch_handle_t stg_handle handle_type = switch_handle_get_type(handle); intf_handle = handle; - if (handle_type == SWITCH_HANDLE_TYPE_PORT) { - port_info = switch_api_port_get_internal((switch_port_t)handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - intf_handle = port_info->intf_handle; - } - if (handle_type == SWITCH_HANDLE_TYPE_LAG) { - lag_info = switch_api_lag_get_internal(handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + status = switch_interface_handle_get( + handle, + 0x0, + &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("stp port state get failed"); + return status; } - intf_handle = lag_info->intf_handle; } intf_info = switch_api_interface_get(intf_handle); @@ -413,8 +401,6 @@ switch_api_stp_port_state_clear(switch_device_t device, switch_handle_t stg_hand switch_stp_port_entry_t *port_entry = NULL; tommy_node *node = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; switch_handle_t intf_handle = 0; switch_handle_type_t handle_type = 0; @@ -435,19 +421,16 @@ switch_api_stp_port_state_clear(switch_device_t device, switch_handle_t stg_hand handle_type = switch_handle_get_type(handle); intf_handle = handle; - if (handle_type == SWITCH_HANDLE_TYPE_PORT) { - port_info = switch_api_port_get_internal((switch_port_t)handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - intf_handle = port_info->intf_handle; - } - if (handle_type == SWITCH_HANDLE_TYPE_LAG) { - lag_info = switch_api_lag_get_internal(handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + status = switch_interface_handle_get( + handle, + 0x0, + &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("stp port state clear failed"); + return status; } - intf_handle = lag_info->intf_handle; } intf_info = switch_api_interface_get(intf_handle); diff --git a/switchapi/src/switch_tunnel.c b/switchapi/src/switch_tunnel.c index cc7671a..b46ec83 100644 --- a/switchapi/src/switch_tunnel.c +++ b/switchapi/src/switch_tunnel.c @@ -63,20 +63,22 @@ switch_tunnel_free(switch_device_t device) static void switch_tunnel_vtep_hash_key_init(uchar *key, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, uint32_t *len, - uint32_t *hash) + switch_ip_addr_t *ip_addr, + uint32_t *len, uint32_t *hash) { - *len=0; + (*len) = 0; memset(key, 0, SWITCH_VTEP_HASH_KEY_SIZE); - *(unsigned int *)(&key[0]) = (unsigned int)handle_to_id(vrf); - key[4] = ip_addr->type; + *(unsigned int *)(&key[(*len)]) = (unsigned int)handle_to_id(vrf); + (*len) += 4; + key[(*len)] = ip_addr->type; + (*len)++; if(ip_addr->type == SWITCH_API_IP_ADDR_V4) { - *(unsigned int *)(&key[5]) = ip_addr->ip.v4addr; - *len = 9; + *(unsigned int *)(&key[(*len)]) = ip_addr->ip.v4addr; + (*len) += 4; } else { - memcpy(&key[5], ip_addr->ip.v6addr, 4*sizeof(unsigned int)); - *len = 21; + memcpy(&key[(*len)], ip_addr->ip.v6addr, 4*sizeof(unsigned int)); + (*len) += 16; } key[*len] = ip_addr->prefix_len; (*len)++; @@ -90,7 +92,8 @@ switch_vtep_hash_cmp(const void *key1, const void *key2) } static uint16_t -switch_tunnel_src_vtep_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +switch_tunnel_src_vtep_insert_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { switch_vtep_entry_t *vtep_entry = NULL; unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; @@ -103,6 +106,7 @@ switch_tunnel_src_vtep_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add if (!vtep_entry) { return src_vtep_index; } + memset(vtep_entry, 0, sizeof(switch_vtep_entry_t)); src_vtep_index = switch_api_id_allocator_allocate(src_vtep_index_allocator); vtep_entry->vrf = vrf; memcpy(&vtep_entry->ip_addr, ip_addr, sizeof(switch_ip_addr_t)); @@ -113,7 +117,8 @@ switch_tunnel_src_vtep_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add } static switch_status_t -switch_tunnel_src_vtep_delete_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +switch_tunnel_src_vtep_delete_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { switch_vtep_entry_t *vtep_entry = NULL; unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; @@ -128,11 +133,12 @@ switch_tunnel_src_vtep_delete_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add } switch_api_id_allocator_release(src_vtep_index_allocator, vtep_entry->entry_index); free(vtep_entry); - return status; + return status; } static uint16_t -switch_tunnel_src_vtep_search_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +switch_tunnel_src_vtep_search_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { switch_vtep_entry_t *vtep_entry = NULL; unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; @@ -150,7 +156,8 @@ switch_tunnel_src_vtep_search_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add } static uint16_t -switch_tunnel_dst_vtep_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +switch_tunnel_dst_vtep_insert_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { switch_vtep_entry_t *vtep_entry = NULL; unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; @@ -163,6 +170,7 @@ switch_tunnel_dst_vtep_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add if (!vtep_entry) { return dst_vtep_index; } + memset(vtep_entry, 0, sizeof(switch_vtep_entry_t)); dst_vtep_index = switch_api_id_allocator_allocate(dst_vtep_index_allocator); vtep_entry->vrf = vrf; memcpy(&vtep_entry->ip_addr, ip_addr, sizeof(switch_ip_addr_t)); @@ -173,7 +181,8 @@ switch_tunnel_dst_vtep_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add } static switch_status_t -switch_tunnel_dst_vtep_delete_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +switch_tunnel_dst_vtep_delete_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { switch_vtep_entry_t *vtep_entry = NULL; unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; @@ -188,11 +197,12 @@ switch_tunnel_dst_vtep_delete_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add } switch_api_id_allocator_release(dst_vtep_index_allocator, vtep_entry->entry_index); free(vtep_entry); - return status; + return status; } static uint16_t -switch_tunnel_dst_vtep_search_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +switch_tunnel_dst_vtep_search_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { switch_vtep_entry_t *vtep_entry = NULL; unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; @@ -210,12 +220,14 @@ switch_tunnel_dst_vtep_search_hash(switch_handle_t vrf, switch_ip_addr_t *ip_add } uint16_t -switch_tunnel_src_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr) { +switch_tunnel_src_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +{ return switch_tunnel_src_vtep_search_hash(vrf, ip_addr); } uint16_t -switch_tunnel_dst_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr) { +switch_tunnel_dst_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr) +{ return switch_tunnel_dst_vtep_search_hash(vrf, ip_addr); } @@ -232,56 +244,71 @@ switch_tunnel_ip_encap_table_add_entries(switch_device_t device, ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); ip_encap_hdl = &intf_info->ip_encap_hdl; + /* * Allocate Src Vtep Rewrite Index */ - src_vtep_index = switch_tunnel_src_vtep_search_hash(ip_encap->vrf_handle, &ip_encap->src_ip); + src_vtep_index = switch_tunnel_src_vtep_search_hash(ip_encap->vrf_handle, + &ip_encap->src_ip); if (!src_vtep_index) { - src_vtep_index = switch_tunnel_src_vtep_insert_hash(ip_encap->vrf_handle, &ip_encap->src_ip); + src_vtep_index = switch_tunnel_src_vtep_insert_hash( + ip_encap->vrf_handle, &ip_encap->src_ip); +#ifdef SWITCH_PD + status = switch_pd_tunnel_src_rewrite_table_add_entry( + device, src_vtep_index, ip_encap, &ip_encap_hdl->src_rw_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: unable to add src rewrite entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); + goto cleanup; + } +#endif /* SWITCH_PD */ } + /* * Allocate Dst Vtep Rewrite Index */ - dst_vtep_index = switch_tunnel_dst_vtep_search_hash(ip_encap->vrf_handle, &ip_encap->dst_ip); + dst_vtep_index = switch_tunnel_dst_vtep_search_hash(ip_encap->vrf_handle, + &ip_encap->dst_ip); if (!dst_vtep_index) { - dst_vtep_index = switch_tunnel_dst_vtep_insert_hash(ip_encap->vrf_handle, &ip_encap->dst_ip); - } + dst_vtep_index = switch_tunnel_dst_vtep_insert_hash( + ip_encap->vrf_handle, &ip_encap->dst_ip); #ifdef SWITCH_PD - status = switch_pd_src_vtep_table_add_entry(device, ip_encap, - intf_info->ifindex, &ip_encap_hdl->src_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add src vtep entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); - goto cleanup; - } - - status = switch_pd_dest_vtep_table_add_entry(device, ip_encap, &ip_encap_hdl->dst_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add dest vtep entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); - goto cleanup; + status = switch_pd_tunnel_dst_rewrite_table_add_entry( + device, dst_vtep_index, ip_encap, &ip_encap_hdl->dst_rw_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: unable to add dst rewrite entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); + goto cleanup; + } +#endif /* SWITCH_PD */ } - status = switch_pd_tunnel_src_rewrite_table_add_entry(device, - src_vtep_index, ip_encap, - &ip_encap_hdl->src_rw_hw_entry); +#ifdef SWITCH_PD + status = switch_pd_src_vtep_table_add_entry( + device, ip_encap, intf_info->ifindex, &ip_encap_hdl->src_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add src rewrite entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); + SWITCH_API_ERROR("%s:%d: unable to add src vtep entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); goto cleanup; } - status = switch_pd_tunnel_dst_rewrite_table_add_entry(device, - dst_vtep_index, ip_encap, - &ip_encap_hdl->dst_rw_hw_entry); + status = switch_pd_dest_vtep_table_add_entry( + device, ip_encap, &ip_encap_hdl->dst_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add dst rewrite entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); + SWITCH_API_ERROR("%s:%d: unable to add dest vtep entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); goto cleanup; } #endif /* SWITCH_PD */ - SWITCH_API_TRACE("%s:%d: Tunnel interface %lx created [%d : %d]", __FUNCTION__, __LINE__, - intf_handle, src_vtep_index, dst_vtep_index); + + SWITCH_API_TRACE("%s:%d: Tunnel interface %lx created [%d : %d]", + __FUNCTION__, __LINE__, + intf_handle, src_vtep_index, dst_vtep_index); + cleanup: return status; } @@ -297,34 +324,56 @@ switch_tunnel_ip_encap_table_delete_entries(switch_device_t device, ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); ip_encap_hdl = &intf_info->ip_encap_hdl; - status = switch_tunnel_src_vtep_delete_hash(ip_encap->vrf_handle, &ip_encap->src_ip); - status = switch_tunnel_dst_vtep_delete_hash(ip_encap->vrf_handle, &ip_encap->dst_ip); + + status = switch_tunnel_src_vtep_delete_hash(ip_encap->vrf_handle, + &ip_encap->src_ip); #ifdef SWITCH_PD - status = switch_pd_src_vtep_table_delete_entry(device, ip_encap, ip_encap_hdl->src_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete src vtep entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); - goto cleanup; + if (status == SWITCH_STATUS_SUCCESS) { + status = switch_pd_tunnel_src_rewrite_table_delete_entry( + device, ip_encap_hdl->src_rw_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: unable to delete src rewrite entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); + goto cleanup; + } } - status = switch_pd_dest_vtep_table_delete_entry(device, ip_encap, ip_encap_hdl->dst_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete dst vtep entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); - goto cleanup; +#endif /* SWITCH_PD */ + + status = switch_tunnel_dst_vtep_delete_hash(ip_encap->vrf_handle, + &ip_encap->dst_ip); +#ifdef SWITCH_PD + if (status == SWITCH_STATUS_SUCCESS) { + status = switch_pd_tunnel_dst_rewrite_table_delete_entry( + device, ip_encap_hdl->dst_rw_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: unable to delete dst rewrite entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); + goto cleanup; + } } - status = switch_pd_tunnel_src_rewrite_table_delete_entry(device, ip_encap_hdl->src_rw_hw_entry); +#endif /* SWITCH_PD */ + +#ifdef SWITCH_PD + status = switch_pd_src_vtep_table_delete_entry( + device, ip_encap, ip_encap_hdl->src_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete src rewrite entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); + SWITCH_API_ERROR("%s:%d: unable to delete src vtep entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); goto cleanup; } - status = switch_pd_tunnel_dst_rewrite_table_delete_entry(device, ip_encap_hdl->dst_rw_hw_entry); + status = switch_pd_dest_vtep_table_delete_entry( + device, ip_encap, ip_encap_hdl->dst_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete dst rewrite entry for interface %lx", - __FUNCTION__, __LINE__, intf_handle); + SWITCH_API_ERROR("%s:%d: unable to delete dst vtep entry for " + "interface %lx", __FUNCTION__, __LINE__, + intf_handle); goto cleanup; } #endif /* SWITCH_PD */ + cleanup: return status; } @@ -563,6 +612,7 @@ switch_api_logical_network_member_add_basic(switch_device_t device, if (!ln_member) { return SWITCH_STATUS_NO_MEMORY; } + memset(ln_member, 0, sizeof(switch_ln_member_t)); ln_member->member = intf_handle; ln_member->rid = switch_mcast_rid_allocate(); tommy_list_insert_head(&(bd_info->members), &(ln_member->node), ln_member); @@ -678,6 +728,7 @@ switch_api_logical_network_member_add_enhanced(switch_device_t device, if (!ln_member) { return SWITCH_STATUS_NO_MEMORY; } + memset(ln_member, 0, sizeof(switch_ln_member_t)); ln_member->member = intf_handle; ln_member->rid = switch_mcast_rid_allocate(); tommy_list_insert_head(&(bd_info->members), &(ln_member->node), ln_member); @@ -1014,7 +1065,7 @@ switch_tunnel_get_ingress_tunnel_type(switch_ip_encap_t *ip_encap) { case IPPROTO_IPIP: case IPPROTO_IPV6: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IP_IN_IP; + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IPIP; break; case IPPROTO_GRE: { switch (ip_encap->u.gre.protocol) { diff --git a/switchapi/src/switch_tunnel_int.h b/switchapi/src/switch_tunnel_int.h index 8b67879..b7a5ca6 100644 --- a/switchapi/src/switch_tunnel_int.h +++ b/switchapi/src/switch_tunnel_int.h @@ -21,8 +21,8 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - -#define SWITCH_VTEP_HASH_KEY_SIZE 21 + +#define SWITCH_VTEP_HASH_KEY_SIZE 32 #define SWITCH_SRC_VTEP_HASH_TABLE_SIZE 4096 #define SWITCH_DST_VTEP_HASH_TABLE_SIZE 4096 @@ -43,8 +43,11 @@ typedef struct switch_mpls_info_ { switch_status_t switch_tunnel_init(switch_device_t device); switch_status_t switch_tunnel_free(switch_device_t device); -uint16_t switch_tunnel_src_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr); -uint16_t switch_tunnel_dst_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr); +uint16_t +switch_tunnel_src_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr); + +uint16_t +switch_tunnel_dst_vtep_index_get(switch_handle_t vrf, switch_ip_addr_t *ip_addr); switch_status_t switch_api_logical_network_member_add_basic(switch_device_t device, @@ -66,7 +69,7 @@ switch_api_logical_network_member_remove_enhanced(switch_device_t device, switch_handle_t bd_handle, switch_handle_t intf_handle); -uint16_t switch_tunnel_get_tunnel_vni(switch_encap_info_t *encap_info); +uint16_t switch_tunnel_get_tunnel_vni(switch_encap_info_t *encap_info); switch_tunnel_type_ingress_t switch_tunnel_get_ingress_tunnel_type(switch_ip_encap_t *ip_encap); diff --git a/switchapi/src/switch_vlan.c b/switchapi/src/switch_vlan.c index f164645..06c5d12 100644 --- a/switchapi/src/switch_vlan.c +++ b/switchapi/src/switch_vlan.c @@ -156,7 +156,7 @@ switch_api_logical_network_create(switch_device_t device, switch_logical_network #ifdef SWITCH_PD status = switch_pd_bd_table_add_entry(device, handle_to_id(handle), - bd_info, &bd_info->bd_entry); + bd_info); if (status != SWITCH_STATUS_SUCCESS) { return SWITCH_API_INVALID_HANDLE; } @@ -226,8 +226,7 @@ switch_api_logical_network_update(switch_device_t device, #ifdef SWITCH_PD status = switch_pd_bd_table_update_entry(device, handle_to_id(network_handle), - bd_info, - bd_info->bd_entry); + bd_info); if (status != SWITCH_STATUS_SUCCESS) { return status; } @@ -413,10 +412,8 @@ switch_api_vlan_flood_type_set(switch_handle_t vlan_handle, uint64_t value) ln_info = &bd_info->ln_info; ln_info->flood_type = (switch_vlan_flood_type_t) value; switch_logical_network_mc_index_allocate(device, bd_info); - status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), + bd_info); return status; } @@ -480,10 +477,8 @@ switch_api_vlan_vrf_handle_set(switch_handle_t vlan_handle, uint64_t value) ln_info = &bd_info->ln_info; ln_info->vrf_handle = (switch_handle_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), + bd_info); return status; } @@ -515,10 +510,8 @@ switch_api_ln_network_type_set(switch_handle_t ln_handle, uint64_t value) } SWITCH_LN_NETWORK_TYPE(bd_info) = (switch_handle_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(ln_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(ln_handle), + bd_info); return status; } @@ -548,10 +541,8 @@ switch_bd_ipv4_unicast_enabled_set(switch_handle_t bd_handle, uint64_t value) } SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -593,10 +584,8 @@ switch_bd_ipv6_unicast_enabled_set(switch_handle_t bd_handle, uint64_t value) } SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -638,10 +627,8 @@ switch_bd_ipv4_multicast_enabled_set(switch_handle_t bd_handle, uint64_t value) } SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -686,10 +673,8 @@ switch_bd_ipv6_multicast_enabled_set(switch_handle_t bd_handle, uint64_t value) } SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -734,10 +719,8 @@ switch_bd_ipv4_urpf_mode_set(switch_handle_t bd_handle, uint64_t value) } bd_info->ipv4_urpf_mode = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -767,10 +750,8 @@ switch_bd_ipv6_urpf_mode_set(switch_handle_t bd_handle, uint64_t value) } bd_info->ipv6_urpf_mode = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -800,10 +781,8 @@ switch_api_vlan_learning_enabled_set(switch_handle_t vlan_handle, uint64_t value } SWITCH_LN_LEARN_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), + bd_info); return status; } @@ -834,10 +813,8 @@ switch_api_vlan_igmp_snooping_enabled_set(switch_handle_t vlan_handle, } SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), + bd_info); return status; } @@ -869,10 +846,8 @@ switch_api_vlan_mld_snooping_enabled_set(switch_handle_t vlan_handle, } SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), + bd_info); return status; } @@ -904,7 +879,7 @@ switch_api_vlan_mrpf_group_set(switch_handle_t vlan_handle, uint64_t value) bd_info->ln_info.mrpf_group = value; status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), - bd_info, bd_info->bd_entry); + bd_info); return status; } @@ -944,99 +919,40 @@ switch_status_t switch_api_vlan_handle_to_id_get(switch_handle_t vlan_handle, return SWITCH_STATUS_SUCCESS; } -static inline void -switch_vlan_port_hash_key_init(uchar *key, switch_vlan_port_key_t *vlan_port_key, - uint32_t *len, uint32_t *hash) -{ - *len = 0; - memset(key, 0, SWITCH_VLAN_PORT_HASH_KEY_SIZE); - - memcpy(key, &(vlan_port_key->vlan_handle), sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); - - memcpy((key + *len), &(vlan_port_key->port_lag_handle), sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); - - *hash = MurmurHash2(key, *len, 0x98761234); -} - -static inline int -switch_vlan_port_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_VLAN_PORT_HASH_KEY_SIZE); -} - -static switch_status_t -switch_vlan_port_key_insert_hash(switch_vlan_port_key_t *vlan_port_key, switch_handle_t intf_handle) -{ - switch_vlan_port_info_t *vlan_port_info = NULL; - unsigned char key[SWITCH_VLAN_PORT_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_vlan_port_hash_key_init(key, vlan_port_key, &len, &hash); - vlan_port_info = switch_malloc(sizeof(switch_vlan_port_info_t), 1); - if (!vlan_port_info) { - return SWITCH_STATUS_NO_MEMORY; - } - memcpy(&vlan_port_info->vlan_port_key, vlan_port_key, sizeof(switch_vlan_port_key_t)); - vlan_port_info->intf_handle = intf_handle; - tommy_hashtable_insert(&switch_vlan_port_hash_table, - &(vlan_port_info->node), - vlan_port_info, hash); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t -switch_vlan_port_key_delete_hash(switch_vlan_port_key_t *vlan_port_key) +bool +switch_vlan_interface_check( + switch_handle_t vlan_handle, + switch_handle_t intf_handle) { - switch_vlan_port_info_t *vlan_port_info = NULL; - unsigned char key[SWITCH_VLAN_PORT_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; + switch_interface_info_t *intf_info = NULL; + void *temp = NULL; + switch_handle_t tmp_vlan_handle = 0; - switch_vlan_port_hash_key_init(key, vlan_port_key, &len, &hash); - vlan_port_info= tommy_hashtable_remove(&switch_vlan_port_hash_table, - switch_vlan_port_hash_cmp, - key, hash); - if (!vlan_port_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return FALSE; } - switch_free(vlan_port_info); - return SWITCH_STATUS_SUCCESS; -} - -static switch_vlan_port_info_t * -switch_vlan_port_key_search_hash(switch_vlan_port_key_t *vlan_port_key) -{ - switch_vlan_port_info_t *vlan_port_info = NULL; - unsigned char key[SWITCH_VLAN_PORT_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - switch_vlan_port_hash_key_init(key, vlan_port_key, &len, &hash); - vlan_port_info = tommy_hashtable_search(&switch_vlan_port_hash_table, - switch_vlan_port_hash_cmp, - key, hash); - return vlan_port_info; -} + JLF(temp, intf_info->vlan_array, tmp_vlan_handle); + while (temp) { + tmp_vlan_handle = *((switch_handle_t *) temp); + if (tmp_vlan_handle == vlan_handle) { + SWITCH_API_ERROR("intf_handle %lx is already member of vlan_handle %lx", + intf_handle, + tmp_vlan_handle); + return FALSE; + } -switch_status_t switch_intf_handle_get(switch_handle_t vlan_handle, - switch_handle_t port_lag_handle, - switch_handle_t *intf_handle) -{ - switch_vlan_port_info_t *vlan_port_info = NULL; - switch_vlan_port_key_t vlan_port_key; + if (SWITCH_INTF_IS_PORT_L2_ACCESS(intf_info)) { + SWITCH_API_ERROR("access intf_handle %lx is already member of vlan_handle %lx", + intf_handle, + tmp_vlan_handle); + return FALSE; + } - vlan_port_key.vlan_handle = vlan_handle; - vlan_port_key.port_lag_handle = port_lag_handle; - vlan_port_info = switch_vlan_port_key_search_hash(&vlan_port_key); - if (!vlan_port_info) { - *intf_handle = 0; - return SWITCH_STATUS_ITEM_NOT_FOUND; + JLN(temp, intf_info->vlan_array, tmp_vlan_handle); } - *intf_handle = vlan_port_info->intf_handle; - return SWITCH_STATUS_SUCCESS; + return TRUE; } switch_status_t @@ -1053,7 +969,10 @@ switch_api_vlan_ports_add(switch_device_t device, switch_vlan_t vlan_id = 0; switch_handle_type_t handle_type = 0; switch_api_interface_info_t api_intf_info; - switch_vlan_port_key_t vlan_port_key; + switch_handle_t handle = 0; + switch_handle_t port_lag_handle = 0; + switch_port_info_t *port_info = NULL; + void *temp = NULL; int count = 0; if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { @@ -1065,39 +984,86 @@ switch_api_vlan_ports_add(switch_device_t device, return SWITCH_STATUS_INVALID_VLAN_ID; } - while (count < port_count) { + for (count = 0; count < port_count; count++) { + handle = vlan_port[count].handle; intf_handle = vlan_port[count].handle; - if ((!SWITCH_PORT_HANDLE_VALID(intf_handle)) && - (!SWITCH_LAG_HANDLE_VALID(intf_handle)) && - (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle))) { + port_lag_handle = 0; + + if ((!SWITCH_PORT_HANDLE_VALID(handle)) && + (!SWITCH_LAG_HANDLE_VALID(handle)) && + (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { return SWITCH_STATUS_INVALID_HANDLE; } - intf_handle = vlan_port[count].handle; - handle_type = switch_handle_get_type(vlan_port[count].handle); + handle_type = switch_handle_get_type(handle); if (handle_type == SWITCH_HANDLE_TYPE_PORT || handle_type == SWITCH_HANDLE_TYPE_LAG) { - if (vlan_port[count].tagging_mode == SWITCH_VLAN_PORT_UNTAGGED) { - api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_ACCESS; - } else if (vlan_port[count].tagging_mode == SWITCH_VLAN_PORT_TAGGED) { - api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_TRUNK; + + port_lag_handle = handle; + + if (handle_type == SWITCH_HANDLE_TYPE_PORT) { + port_info = switch_api_port_get_internal(handle); + if (!port_info) { + SWITCH_API_ERROR("vlan ports add failed. " + "invalid port handle %lx", + handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (port_info->lag_handle) { + port_lag_handle = port_info->lag_handle; + } } - api_intf_info.u.port_lag_handle = vlan_port[count].handle; - intf_handle = switch_api_interface_create(device, &api_intf_info); - if (intf_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_ERROR("%s:%d: unable to create interface for vlan %d", - __FUNCTION__, __LINE__, vlan_id); - return SWITCH_STATUS_FAILURE; + + status = switch_interface_handle_get( + port_lag_handle, + 0x0, + &intf_handle); + if (status != SWITCH_STATUS_ITEM_NOT_FOUND && + status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("vlan ports add failed. " + "interface handle get failed\n"); + continue; + } + + if (!intf_handle) { + memset(&api_intf_info, 0x0, sizeof(api_intf_info)); + api_intf_info.u.port_lag_handle = port_lag_handle; + api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_TRUNK; + if (vlan_port[count].tagging_mode == SWITCH_VLAN_PORT_UNTAGGED) { + api_intf_info.native_vlan = vlan_handle; + } + intf_handle = switch_api_interface_create(device, &api_intf_info); + } else { + vlan_member = switch_api_logical_network_search_member(vlan_handle, intf_handle); + if (vlan_member) { + SWITCH_API_TRACE("intf_handle %lx is already a member of vlan handle %lx\n", + intf_handle, vlan_handle); + continue; + } } - vlan_port_key.vlan_handle = vlan_handle; - vlan_port_key.port_lag_handle = vlan_port[count].handle; - switch_vlan_port_key_insert_hash(&vlan_port_key, intf_handle); } + intf_info = switch_api_interface_get(intf_handle); if (!intf_info) { return SWITCH_STATUS_INVALID_INTERFACE; } + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + intf_info->vlan_count++; + } + + if (!switch_vlan_interface_check(vlan_handle, intf_handle)) { + SWITCH_API_ERROR("failed to add vlan %lx to interface %lx", + vlan_handle, + intf_handle); + continue; + } + + JLI(temp, intf_info->vlan_array, vlan_handle); + *(unsigned long *) temp = vlan_handle; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { if (SWITCH_INTF_IS_PORT_L2_ACCESS(intf_info)) { vlan_id = 0; @@ -1143,7 +1109,6 @@ switch_api_vlan_ports_add(switch_device_t device, return status; } #endif - count++; } return status; @@ -1160,11 +1125,13 @@ switch_api_vlan_ports_remove(switch_device_t device, switch_ln_member_t *vlan_member = NULL; tommy_node *node = NULL; switch_handle_t intf_handle = 0; + switch_handle_t port_lag_handle = 0; int count = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_vlan_t vlan_id = 0; switch_handle_type_t handle_type = 0; - switch_vlan_port_key_t vlan_port_key; + switch_handle_t handle = 0; + switch_port_info_t *port_info = NULL; if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { return SWITCH_STATUS_INVALID_HANDLE; @@ -1176,7 +1143,10 @@ switch_api_vlan_ports_remove(switch_device_t device, } for(count = 0; count < port_count; count++) { + + handle = vlan_port[count].handle; intf_handle = vlan_port[count].handle; + if ((!SWITCH_PORT_HANDLE_VALID(intf_handle)) && (!SWITCH_LAG_HANDLE_VALID(intf_handle)) && (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle))) { @@ -1185,10 +1155,34 @@ switch_api_vlan_ports_remove(switch_device_t device, handle_type = switch_handle_get_type(vlan_port[count].handle); if (handle_type == SWITCH_HANDLE_TYPE_PORT || handle_type == SWITCH_HANDLE_TYPE_LAG) { - status = switch_intf_handle_get(vlan_handle, vlan_port[count].handle, &intf_handle); + port_lag_handle = handle; + if (handle_type == SWITCH_HANDLE_TYPE_PORT) { + port_info = switch_api_port_get_internal(handle); + if (!port_info) { + SWITCH_API_ERROR("vlan ports delete failed. " + "invalid port handle %lx\n", + handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (port_info->lag_handle) { + port_lag_handle = port_info->lag_handle; + } + } + + status = switch_interface_handle_get( + port_lag_handle, + 0x0, + &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d unable to get interface!\n", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; + SWITCH_API_ERROR("vlan ports delete failed. " + "interface handle get failed\n"); + continue; + } + + vlan_member = switch_api_logical_network_search_member(vlan_handle, intf_handle); + if (!vlan_member) { + continue; } } @@ -1196,6 +1190,9 @@ switch_api_vlan_ports_remove(switch_device_t device, if (!intf_info) { return SWITCH_STATUS_INVALID_INTERFACE; } + + JLD(status, intf_info->vlan_array, vlan_handle); + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { if (SWITCH_INTF_IS_PORT_L2_ACCESS(intf_info)) { vlan_id = 0; @@ -1245,13 +1242,13 @@ switch_api_vlan_ports_remove(switch_device_t device, if (handle_type == SWITCH_HANDLE_TYPE_PORT|| handle_type == SWITCH_HANDLE_TYPE_LAG) { - status = switch_api_interface_delete(device, intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - return status; + intf_info->vlan_count--; + if (intf_info->vlan_count == 0) { + status = switch_api_interface_delete(device, intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } } - vlan_port_key.vlan_handle = vlan_handle; - vlan_port_key.port_lag_handle = vlan_port[count].handle; - switch_vlan_port_key_delete_hash(&vlan_port_key); } } } @@ -1315,10 +1312,8 @@ switch_bd_router_mac_handle_set(switch_handle_t bd_handle, switch_handle_t rmac_ ln_info = &bd_info->ln_info; ln_info->rmac_handle = rmac_handle; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(bd_handle), - bd_info, - bd_info->bd_entry); + status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), + bd_info); return status; } @@ -1477,7 +1472,7 @@ switch_api_vlan_print_all(void) } switch_status_t -switch_api_vlan_stats_enable(switch_device_t device, switch_handle_t vlan_handle) +switch_api_bd_stats_enable(switch_device_t device, switch_handle_t bd_handle) { switch_bd_info_t *bd_info = NULL; switch_logical_network_t *ln_info = NULL; @@ -1487,7 +1482,7 @@ switch_api_vlan_stats_enable(switch_device_t device, switch_handle_t vlan_handle int index = 0; uint16_t bd_stats_start_idx = 0; - bd_info = switch_bd_get(vlan_handle); + bd_info = switch_bd_get(bd_handle); if (!bd_info) { return SWITCH_STATUS_INVALID_VLAN_ID; } @@ -1506,28 +1501,25 @@ switch_api_vlan_stats_enable(switch_device_t device, switch_handle_t vlan_handle } memset(bd_info->egress_bd_stats, 0, sizeof(switch_bd_stats_t)); ingress_bd_stats = bd_info->ingress_bd_stats; - bd_stats_start_idx = switch_api_id_allocator_allocate_contiguous(bd_stats_index, SWITCH_VLAN_STATS_MAX); - for (index = 0; index < SWITCH_VLAN_STATS_MAX; index++) { + bd_stats_start_idx = switch_api_id_allocator_allocate_contiguous(bd_stats_index, SWITCH_BD_STATS_MAX); + for (index = 0; index < SWITCH_BD_STATS_MAX; index++) { ingress_bd_stats->stats_idx[index] = bd_stats_start_idx; bd_stats_start_idx++; } if (bd_info->bd_entry != SWITCH_HW_INVALID_HANDLE) { status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + handle_to_id(bd_handle), + bd_info); } egress_bd_stats = bd_info->egress_bd_stats; status = switch_pd_egress_bd_stats_table_add_entry( - device, - handle_to_id(vlan_handle), - egress_bd_stats->stats_hw_entry); + device, handle_to_id(bd_handle), egress_bd_stats->stats_hw_entry); } return status; } switch_status_t -switch_api_vlan_stats_disable(switch_device_t device, switch_handle_t vlan_handle) +switch_api_bd_stats_disable(switch_device_t device, switch_handle_t bd_handle) { switch_bd_info_t *bd_info = NULL; switch_logical_network_t *ln_info = NULL; @@ -1536,7 +1528,7 @@ switch_api_vlan_stats_disable(switch_device_t device, switch_handle_t vlan_handl switch_bd_stats_t *egress_bd_stats = NULL; int index = 0; - bd_info = switch_bd_get(vlan_handle); + bd_info = switch_bd_get(bd_handle); if (!bd_info) { return SWITCH_STATUS_INVALID_VLAN_ID; } @@ -1545,15 +1537,14 @@ switch_api_vlan_stats_disable(switch_device_t device, switch_handle_t vlan_handl if (ln_info->flags.stats_enabled) { ln_info->flags.stats_enabled = FALSE; ingress_bd_stats = bd_info->ingress_bd_stats; - for (index = 0; index < SWITCH_VLAN_STATS_MAX; index++) { + for (index = 0; index < SWITCH_BD_STATS_MAX; index++) { switch_api_id_allocator_release(bd_stats_index, ingress_bd_stats->stats_idx[index]); ingress_bd_stats->stats_idx[index] = 0; } if (bd_info->bd_entry != SWITCH_HW_INVALID_HANDLE) { status = switch_pd_bd_table_update_entry(device, - handle_to_id(vlan_handle), - bd_info, - bd_info->bd_entry); + handle_to_id(bd_handle), + bd_info); } switch_free(bd_info->ingress_bd_stats); egress_bd_stats = bd_info->egress_bd_stats; @@ -1566,11 +1557,11 @@ switch_api_vlan_stats_disable(switch_device_t device, switch_handle_t vlan_handl } switch_status_t -switch_api_vlan_stats_get( +switch_api_bd_stats_get( switch_device_t device, - switch_handle_t vlan_handle, + switch_handle_t bd_handle, uint8_t count, - switch_vlan_stats_t *counter_ids, + switch_bd_stats_id_t *counter_ids, switch_counter_t *counters) { switch_bd_info_t *bd_info = NULL; @@ -1579,9 +1570,9 @@ switch_api_vlan_stats_get( switch_bd_stats_t *ingress_bd_stats = NULL; switch_bd_stats_t *egress_bd_stats = NULL; int index = 0; - switch_vlan_stats_t counter_id = 0; + switch_bd_stats_id_t counter_id = 0; - bd_info = switch_bd_get(vlan_handle); + bd_info = switch_bd_get(bd_handle); if (!bd_info) { return SWITCH_STATUS_INVALID_VLAN_ID; } @@ -1590,19 +1581,19 @@ switch_api_vlan_stats_get( if (ln_info->flags.stats_enabled) { ingress_bd_stats = bd_info->ingress_bd_stats; egress_bd_stats = bd_info->egress_bd_stats; - status = switch_pd_vlan_ingress_stats_get(device, ingress_bd_stats); - status = switch_pd_vlan_egress_stats_get(device, egress_bd_stats); + status = switch_pd_bd_ingress_stats_get(device, ingress_bd_stats); + status = switch_pd_bd_egress_stats_get(device, egress_bd_stats); for (index = 0; index < count; index++) { counter_id = counter_ids[index]; switch (counter_id) { - case SWITCH_VLAN_STATS_IN_UCAST: - case SWITCH_VLAN_STATS_IN_MCAST: - case SWITCH_VLAN_STATS_IN_BCAST: + case SWITCH_BD_STATS_IN_UCAST: + case SWITCH_BD_STATS_IN_MCAST: + case SWITCH_BD_STATS_IN_BCAST: counters[index] = ingress_bd_stats->counters[counter_id]; break; - case SWITCH_VLAN_STATS_OUT_UCAST: - case SWITCH_VLAN_STATS_OUT_MCAST: - case SWITCH_VLAN_STATS_OUT_BCAST: + case SWITCH_BD_STATS_OUT_UCAST: + case SWITCH_BD_STATS_OUT_MCAST: + case SWITCH_BD_STATS_OUT_BCAST: counters[index] = egress_bd_stats->counters[counter_id]; break; default: @@ -1613,6 +1604,38 @@ switch_api_vlan_stats_get( return status; } +switch_status_t +switch_api_vlan_stats_enable( + switch_device_t device, + switch_handle_t vlan_handle) +{ + return switch_api_bd_stats_enable(device, vlan_handle); +} + +switch_status_t +switch_api_vlan_stats_disable( + switch_device_t device, + switch_handle_t vlan_handle) +{ + return switch_api_bd_stats_disable(device, vlan_handle); +} + +switch_status_t +switch_api_vlan_stats_get( + switch_device_t device, + switch_handle_t vlan_handle, + uint8_t count, + switch_bd_stats_id_t *counter_ids, + switch_counter_t *counters) +{ + return switch_api_bd_stats_get( + device, + vlan_handle, + count, + counter_ids, + counters); +} + #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_vlan_int.h b/switchapi/src/switch_vlan_int.h index ff9c0f7..c26f0b3 100644 --- a/switchapi/src/switch_vlan_int.h +++ b/switchapi/src/switch_vlan_int.h @@ -46,10 +46,10 @@ typedef struct { } switch_ln_member_t; typedef struct switch_bd_stats_ { - uint16_t stats_idx[SWITCH_VLAN_STATS_MAX]; - switch_counter_t counters[SWITCH_VLAN_STATS_MAX]; + uint16_t stats_idx[SWITCH_BD_STATS_MAX]; + switch_counter_t counters[SWITCH_BD_STATS_MAX]; #ifdef SWITCH_PD - p4_pd_entry_hdl_t stats_hw_entry[SWITCH_VLAN_STATS_MAX]; + p4_pd_entry_hdl_t stats_hw_entry[SWITCH_BD_STATS_MAX]; #endif } switch_bd_stats_t; @@ -69,12 +69,16 @@ typedef struct switch_bd_info_ { uint16_t bd_label; switch_bd_stats_t *ingress_bd_stats; switch_bd_stats_t *egress_bd_stats; + + switch_handle_t l3_intf_handle; + #ifdef SWITCH_PD - p4_pd_mbr_hdl_t bd_entry; /**< hw bd table entry */ - p4_pd_entry_hdl_t egress_bd_entry; /**< hw bd table entry */ + p4_pd_mbr_hdl_t bd_entry; /**< hw bd mbr hdl entry */ + p4_pd_entry_hdl_t egress_bd_entry; /**< hw egress bd table entry */ p4_pd_entry_hdl_t uuc_entry; /**< hw uuc entry */ p4_pd_entry_hdl_t umc_entry; /**< hw umc entry */ p4_pd_entry_hdl_t bcast_entry; /**< hw bcast entry */ + p4_pd_entry_hdl_t cpu_entry; /**< hw cpu entry */ switch_ip_encap_pd_hdl_t ip_encap_hdl; #endif } switch_bd_info_t; @@ -153,8 +157,24 @@ switch_status_t switch_api_vlan_xlate_remove(switch_device_t device, switch_hand switch_handle_t intf_handle, switch_vlan_t vlan_id); switch_ln_member_t * switch_api_logical_network_search_member(switch_handle_t bd_handle, switch_handle_t intf_handle); -switch_status_t switch_intf_handle_get(switch_handle_t vlan_handle, switch_handle_t port_lag_handle, - switch_handle_t *intf_handle); + +switch_status_t +switch_api_bd_stats_enable( + switch_device_t device, + switch_handle_t bd_handle); + +switch_status_t +switch_api_bd_stats_disable( + switch_device_t device, + switch_handle_t bd_handle); + +switch_status_t +switch_api_bd_stats_get( + switch_device_t device, + switch_handle_t bd_handle, + uint8_t count, + switch_bd_stats_id_t *counter_ids, + switch_counter_t *counters); #ifdef __cplusplus } diff --git a/switchapi/src/thrift_cache.h b/switchapi/src/thrift_cache.h index f7b8581..42def3d 100644 --- a/switchapi/src/thrift_cache.h +++ b/switchapi/src/thrift_cache.h @@ -18,9 +18,18 @@ limitations under the License. * thrift precompiled header cache */ +#ifdef P4THRIFT +#include +#include +#include +#include + +namespace thrift_provider = p4::thrift; +#else #include #include #include #include - +namespace thrift_provider = apache::thrift; +#endif // P4THRIFT diff --git a/switchlink/src/switchlink_db.c b/switchlink/src/switchlink_db.c index 003a705..5652d76 100644 --- a/switchlink/src/switchlink_db.c +++ b/switchlink/src/switchlink_db.c @@ -39,6 +39,18 @@ static switchlink_db_port_obj_t switchlink_db_port_map[] = { {"swp2", 1}, {"swp3", 2}, {"swp4", 3}, + {"swp5", 4}, + {"swp6", 5}, + {"swp7", 6}, + {"swp8", 7}, + {"swp9", 8}, + {"swp10", 9}, + {"swp11", 10}, + {"swp12", 11}, + {"swp13", 12}, + {"swp14", 13}, + {"swp15", 14}, + {"swp16", 15}, {SWITCHLINK_CPU_INTERFACE_NAME, 64}, }; diff --git a/switchlink/src/switchlink_main.c b/switchlink/src/switchlink_main.c index 18adc40..4edd8ac 100644 --- a/switchlink/src/switchlink_main.c +++ b/switchlink/src/switchlink_main.c @@ -29,7 +29,7 @@ static struct nl_sock *g_nlsk = NULL; static pthread_t switchlink_thread; uint8_t g_log_level = SWITCHLINK_LOG_ERR; -static enum { +enum { SWITCHLINK_MSG_LINK, SWITCHLINK_MSG_ADDR, SWITCHLINK_MSG_NETCONF, diff --git a/switchlink/src/switchlink_neigh.c b/switchlink/src/switchlink_neigh.c index 6d8f3ae..0bc6d8f 100644 --- a/switchlink/src/switchlink_neigh.c +++ b/switchlink/src/switchlink_neigh.c @@ -220,15 +220,8 @@ switchlink_linux_mac_update(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h, switchlink_handle_t intf_h, bool create) { switchlink_db_status_t status; - uint32_t vlan_ifindex; uint32_t ifindex; - status = switchlink_db_bridge_get_ifindex(bridge_h, &vlan_ifindex); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - assert(false); - return; - } - if (!create) { status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &intf_h); if (status != SWITCHLINK_DB_STATUS_SUCCESS) { diff --git a/switchlink/src/switchlink_route.c b/switchlink/src/switchlink_route.c index 5716a4e..7477b6f 100644 --- a/switchlink/src/switchlink_route.c +++ b/switchlink/src/switchlink_route.c @@ -447,15 +447,15 @@ process_route_msg(struct nlmsghdr *nlmsg, int type) { if (!ip_multicast) { if (type == RTM_NEWROUTE) { - if (!oif_valid) { - return; - } - switchlink_db_status_t status; - status = switchlink_db_interface_get_info(oif, &ifinfo); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - NL_LOG_DEBUG(("route: switchlink_db_interface_get_info " - "(unicast) failed\n")); - return; + memset(&ifinfo, 0, sizeof(ifinfo)); + if (oif_valid) { + switchlink_db_status_t status; + status = switchlink_db_interface_get_info(oif, &ifinfo); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + NL_LOG_DEBUG(("route: switchlink_db_interface_get_info " + "(unicast) failed\n")); + return; + } } route_create(g_default_vrf_h, (dst_valid ? &dst_addr : NULL), (gateway_valid ? &gateway_addr : NULL), diff --git a/switchlink/src/switchlink_sai.c b/switchlink/src/switchlink_sai.c index 0d957c5..b182a76 100644 --- a/switchlink/src/switchlink_sai.c +++ b/switchlink/src/switchlink_sai.c @@ -144,13 +144,14 @@ on_fdb_event(uint32_t count, sai_fdb_event_notification_data_t *data) { switchlink_handle_t bridge_h; switchlink_handle_t intf_h; bool create = false; + uint32_t i = 0; memcpy(mac_addr, data->fdb_entry.mac_address, ETH_ALEN); bridge_h = data->fdb_entry.vlan_id; intf_h = 0; if (data->event_type == SAI_FDB_EVENT_LEARNED) { - for(int i = 0; i < data->attr_count; i++) { + for(i = 0; i < data->attr_count; i++) { if (data->attr[i].id == SAI_FDB_ENTRY_ATTR_PORT_ID) { intf_h = data->attr[i].value.oid; break; @@ -334,7 +335,7 @@ switchlink_interface_create(switchlink_db_interface_info_t *intf, attr_list[ac].value.oid = intf->vrf_h; ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; - attr_list[ac].value.u8 = SAI_ROUTER_INTERFACE_TYPE_PORT; + attr_list[ac].value.s32 = SAI_ROUTER_INTERFACE_TYPE_PORT; ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID; attr_list[ac].value.oid = get_port_object(intf->port_id); @@ -355,11 +356,11 @@ switchlink_interface_create(switchlink_db_interface_info_t *intf, attr_list[ac].value.booldata = intf->flags.ipv6_multicast_enabled; ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE; - attr_list[ac].value.u8 = + attr_list[ac].value.s32 = switchlink_to_sai_urpf_mode(intf->flags.ipv4_urpf_mode); ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE; - attr_list[ac].value.u8 = + attr_list[ac].value.s32 = switchlink_to_sai_urpf_mode(intf->flags.ipv6_urpf_mode); ac++; @@ -372,7 +373,7 @@ switchlink_interface_create(switchlink_db_interface_info_t *intf, attr_list[ac].value.oid = intf->vrf_h; ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; - attr_list[ac].value.u8 = SAI_ROUTER_INTERFACE_TYPE_VLAN; + attr_list[ac].value.s32 = SAI_ROUTER_INTERFACE_TYPE_VLAN; ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_VLAN_ID; attr_list[ac].value.oid = intf->bridge_h; @@ -393,11 +394,11 @@ switchlink_interface_create(switchlink_db_interface_info_t *intf, attr_list[ac].value.booldata = intf->flags.ipv6_multicast_enabled; ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE; - attr_list[ac].value.u8 = + attr_list[ac].value.s32 = switchlink_to_sai_urpf_mode(intf->flags.ipv4_urpf_mode); ac++; attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE; - attr_list[ac].value.u8 = + attr_list[ac].value.s32 = switchlink_to_sai_urpf_mode(intf->flags.ipv6_urpf_mode); ac++; @@ -453,7 +454,7 @@ switchlink_interface_urpf_mode_update(switchlink_handle_t intf_h, int af, } else { attr.id = SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE; } - attr.value.u8 = value; + attr.value.s32 = value; status = rintf_api->set_router_interface_attribute(intf_h, &attr); return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); } @@ -587,11 +588,11 @@ switchlink_mac_create(switchlink_mac_addr_t mac_addr, sai_attribute_t attr_list[3]; memset(&attr_list, 0, sizeof(attr_list)); attr_list[0].id = SAI_FDB_ENTRY_ATTR_TYPE; - attr_list[0].value.u8 = SAI_FDB_ENTRY_STATIC; + attr_list[0].value.s32 = SAI_FDB_ENTRY_STATIC; attr_list[1].id = SAI_FDB_ENTRY_ATTR_PORT_ID; attr_list[1].value.oid = intf_h; attr_list[2].id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; - attr_list[2].value.u8 = SAI_PACKET_ACTION_FORWARD; + attr_list[2].value.s32 = SAI_PACKET_ACTION_FORWARD; status = fdb_api->create_fdb_entry(&fdb_entry, 3, attr_list); return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); @@ -636,7 +637,7 @@ switchlink_nexthop_create(switchlink_db_neigh_info_t *neigh_info) { sai_attribute_t attr_list[3]; memset(attr_list, 0, sizeof(attr_list)); attr_list[0].id = SAI_NEXT_HOP_ATTR_TYPE; - attr_list[0].value.u8 = SAI_NEXT_HOP_IP; + attr_list[0].value.s32 = SAI_NEXT_HOP_IP; attr_list[1].id = SAI_NEXT_HOP_ATTR_IP; if (neigh_info->ip_addr.family == AF_INET) { attr_list[1].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; @@ -709,7 +710,7 @@ switchlink_ecmp_create(switchlink_db_ecmp_info_t *ecmp_info) { sai_attribute_t attr_list[3]; memset(attr_list, 0, sizeof(attr_list)); attr_list[0].id = SAI_NEXT_HOP_GROUP_ATTR_TYPE; - attr_list[0].value.u8 = SAI_NEXT_HOP_GROUP_ECMP; + attr_list[0].value.s32 = SAI_NEXT_HOP_GROUP_ECMP; attr_list[1].id = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT; attr_list[1].value.u32 = ecmp_info->num_nhops; attr_list[2].id = SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST; @@ -933,7 +934,7 @@ switchlink_send_packet(char *buf, uint32_t buf_size, uint16_t port_id) { return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); } -static sai_status_t +sai_status_t create_ip_acl(sai_object_id_t *table_id) { sai_status_t status = SAI_STATUS_SUCCESS; sai_attribute_t attr_list[2]; diff --git a/switchsai/src/sai_bmlib.c b/switchsai/src/sai_bmlib.c index a193224..893aa22 100644 --- a/switchsai/src/sai_bmlib.c +++ b/switchsai/src/sai_bmlib.c @@ -14,23 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -#ifdef SAI_BMLIB - #include "saiinternal.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ static unsigned int initialized = 0; -static int log_level = P4_LOG_LEVEL_NONE; -static bmi_port_mgr_t *port_mgr; static sai_api_t api_id = SAI_API_UNSPECIFIED; - -extern int start_switch_api_packet_driver(void); - const char * sai_profile_get_value(_In_ sai_switch_profile_id_t profile_id, _In_ const char* variable) @@ -57,6 +44,20 @@ const service_method_table_t sai_services = { .profile_get_next_value = sai_profile_get_next_value }; +#ifdef SAI_BMLIB + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static int log_level = P4_LOG_LEVEL_NONE; +static bmi_port_mgr_t *port_mgr; + +extern int start_switch_api_packet_driver(void); + static void sai_log_packet( _In_ int port_num, _In_ const char *buffer, @@ -188,4 +189,24 @@ sai_api_uninitialize(void) { } #endif /* __cplusplus */ +#else +extern int bmv2_model_init(); + +sai_status_t +sai_api_initialize(uint64_t flags, + const service_method_table_t* services) { + sai_status_t status = SAI_STATUS_SUCCESS; + unsigned int num_ports = 32; + UNUSED(services); + if(!initialized) { + SAI_LOG_WARN("Initializing device"); + initialized = 1; + bmv2_model_init(); + sai_initialize(); + } + + services = &sai_services; + return status; +} + #endif /* SAI_BMLIB */ diff --git a/switchsai/src/saiacl.c b/switchsai/src/saiacl.c index 5cddf31..60cfd6a 100644 --- a/switchsai/src/saiacl.c +++ b/switchsai/src/saiacl.c @@ -159,15 +159,22 @@ static sai_status_t sai_acl_match_table_type_get( for (index2 = 0; index2 < attr_count; index2++) { // skip ports and VLAN attributes on check switch(attr_list[index2].id) { + case SAI_ACL_TABLE_ATTR_STAGE: + case SAI_ACL_TABLE_ATTR_PRIORITY: + case SAI_ACL_TABLE_ATTR_SIZE: + case SAI_ACL_TABLE_ATTR_GROUP_ID: case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS: case SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORTS: case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT: case SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID: case SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID: break; + // ignore above for matching fields default: - if (table[attr_list[index2].id - SAI_ACL_TABLE_ATTR_FIELD_START] == -1) { - table_matched = FALSE; + if (attr_list[index2].id >= SAI_ACL_TABLE_ATTR_FIELD_START && attr_list[index2].id <= SAI_ACL_TABLE_ATTR_FIELD_END) { + if (table[attr_list[index2].id - SAI_ACL_TABLE_ATTR_FIELD_START] == -1) { + table_matched = FALSE; + } } break; } @@ -555,7 +562,7 @@ sai_status_t sai_create_acl_entry( break; case SAI_ACL_ENTRY_ATTR_PACKET_ACTION: acl_action = 0; - packet_action = attr_list[index1].value.aclfield.data.u8; + packet_action = attr_list[index1].value.aclfield.data.s32; if (packet_action == SAI_PACKET_ACTION_DROP) { acl_action = SWITCH_ACL_ACTION_DROP; } else if (packet_action == SAI_PACKET_ACTION_FORWARD) { diff --git a/switchsai/src/saifdb.c b/switchsai/src/saifdb.c index a0616df..cbe59da 100644 --- a/switchsai/src/saifdb.c +++ b/switchsai/src/saifdb.c @@ -57,7 +57,7 @@ static void sai_fdb_entry_attribute_parse( attribute = &attr_list[i]; switch (attribute->id) { case SAI_FDB_ENTRY_ATTR_TYPE: - switch (attribute->value.u8) { + switch (attribute->value.s32) { case SAI_FDB_ENTRY_DYNAMIC: mac_entry->entry_type = SWITCH_MAC_ENTRY_DYNAMIC; break; @@ -73,7 +73,7 @@ static void sai_fdb_entry_attribute_parse( break; case SAI_FDB_ENTRY_ATTR_PACKET_ACTION: - action = (switch_mac_action_t) attribute->value.u8; + action = (switch_mac_action_t) attribute->value.s32; switch (action) { case SAI_PACKET_ACTION_DROP: mac_entry->mac_action = SWITCH_MAC_ACTION_DROP; @@ -333,7 +333,7 @@ sai_status_t sai_flush_fdb_entries( vlan_valid = true; break; case SAI_FDB_FLUSH_ATTR_ENTRY_TYPE: - entry_type = attribute->value.u8; + entry_type = attribute->value.s32; switch (entry_type) { case SAI_FDB_FLUSH_ENTRY_DYNAMIC: case SAI_FDB_FLUSH_ENTRY_STATIC: @@ -397,11 +397,11 @@ sai_mac_learn_notify_cb(switch_api_mac_entry_t *mac_entry) sai_attribute_t attr_list[3]; memset(attr_list, 0, sizeof(attr_list)); attr_list[0].id = SAI_FDB_ENTRY_ATTR_TYPE; - attr_list[0].value.u8 = SAI_FDB_ENTRY_DYNAMIC; + attr_list[0].value.s32 = SAI_FDB_ENTRY_DYNAMIC; attr_list[1].id = SAI_FDB_ENTRY_ATTR_PORT_ID; attr_list[1].value.oid = intf_h; attr_list[2].id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION; - attr_list[2].value.u8 = SAI_PACKET_ACTION_FORWARD; + attr_list[2].value.s32 = SAI_PACKET_ACTION_FORWARD; fdb_event.attr = attr_list; fdb_event.attr_count = 3; sai_switch_notifications.on_fdb_event(1, &fdb_event); diff --git a/switchsai/src/saimirror.c b/switchsai/src/saimirror.c index 5136884..9684952 100644 --- a/switchsai/src/saimirror.c +++ b/switchsai/src/saimirror.c @@ -63,7 +63,7 @@ static void sai_mirror_session_attribute_parse( switch (attribute->id) { case SAI_MIRROR_SESSION_ATTR_TYPE: api_mirror_info->mirror_type = - sai_session_to_switch_session(attribute->value.u8); + sai_session_to_switch_session(attribute->value.s32); break; case SAI_MIRROR_SESSION_ATTR_MONITOR_PORT: api_mirror_info->egress_port = attribute->value.oid; @@ -82,7 +82,7 @@ static void sai_mirror_session_attribute_parse( break; case SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE: tunnel_info->encap_info.encap_type = - sai_erspan_encap_to_switch_erspan_encap(attribute->value.u8); + sai_erspan_encap_to_switch_erspan_encap(attribute->value.s32); break; case SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION: break; diff --git a/switchsai/src/sainexthop.c b/switchsai/src/sainexthop.c index a03a847..ede5778 100644 --- a/switchsai/src/sainexthop.c +++ b/switchsai/src/sainexthop.c @@ -61,7 +61,7 @@ sai_status_t sai_create_next_hop_entry( attribute = &attr_list[index]; switch (attribute->id) { case SAI_NEXT_HOP_ATTR_TYPE: - nhtype = attribute->value.u8; + nhtype = attribute->value.s32; break; case SAI_NEXT_HOP_ATTR_IP: assert(nhtype == SAI_NEXT_HOP_IP); @@ -113,7 +113,10 @@ sai_status_t sai_remove_next_hop_entry( sai_status_t status = SAI_STATUS_SUCCESS; switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(next_hop_id) == SAI_OBJECT_TYPE_NEXT_HOP); + if (sai_object_type_query(next_hop_id) != SAI_OBJECT_TYPE_NEXT_HOP) { + SAI_LOG_ERROR("nexthop remove failed: invalid nexthop handle %lx\n", next_hop_id); + return SAI_STATUS_INVALID_PARAMETER; + } switch_status = switch_api_nhop_delete(device, (switch_handle_t) next_hop_id); status = sai_switch_status_to_sai_status(switch_status); diff --git a/switchsai/src/sainexthopgroup.c b/switchsai/src/sainexthopgroup.c index 9fda27d..3a18d56 100644 --- a/switchsai/src/sainexthopgroup.c +++ b/switchsai/src/sainexthopgroup.c @@ -16,7 +16,9 @@ limitations under the License. #include #include "saiinternal.h" +#include #include +#include static sai_api_t api_id = SAI_API_NEXT_HOP_GROUP; @@ -84,7 +86,7 @@ sai_status_t sai_create_next_hop_group_entry( case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT: break; case SAI_NEXT_HOP_GROUP_ATTR_TYPE: - nhgroup_type = attribute.value.u8; + nhgroup_type = attribute.value.s32; break; case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST: nhop_list = attribute.value.objlist.list; @@ -221,7 +223,7 @@ sai_status_t sai_get_next_hop_group_entry_attribute( for (index = 0; index < attr_count; index++) { switch(attr_list[index].id) { case SAI_NEXT_HOP_GROUP_ATTR_TYPE: { - attr_list[index].value.u8 = + attr_list[index].value.s32 = sai_get_next_hop_group_type(next_hop_group_id); break; } diff --git a/switchsai/src/saipolicer.c b/switchsai/src/saipolicer.c index 066985a..9003018 100644 --- a/switchsai/src/saipolicer.c +++ b/switchsai/src/saipolicer.c @@ -71,15 +71,15 @@ sai_status_t sai_policer_attr_parse( switch (attribute->id) { case SAI_POLICER_ATTR_METER_TYPE: api_meter_info->meter_type = - sai_meter_type_to_switch_meter_type(attribute->value.u8); + sai_meter_type_to_switch_meter_type(attribute->value.s32); break; case SAI_POLICER_ATTR_MODE: api_meter_info->meter_mode = - sai_meter_mode_to_switch_meter_mode(attribute->value.u8); + sai_meter_mode_to_switch_meter_mode(attribute->value.s32); break; case SAI_POLICER_ATTR_COLOR_SOURCE: api_meter_info->color_source = - sai_color_source_to_switch_color_source(attribute->value.u8); + sai_color_source_to_switch_color_source(attribute->value.s32); break; case SAI_POLICER_ATTR_CBS: api_meter_info->cbs = attribute->value.u64; @@ -95,15 +95,15 @@ sai_status_t sai_policer_attr_parse( break; case SAI_POLICER_ATTR_GREEN_PACKET_ACTION: api_meter_info->action[SWITCH_METER_COLOR_GREEN] = - sai_packet_action_to_switch_packet_action(attribute->value.u8); + sai_packet_action_to_switch_packet_action(attribute->value.s32); break; case SAI_POLICER_ATTR_YELLOW_PACKET_ACTION: api_meter_info->action[SWITCH_METER_COLOR_YELLOW] = - sai_packet_action_to_switch_packet_action(attribute->value.u8); + sai_packet_action_to_switch_packet_action(attribute->value.s32); break; case SAI_POLICER_ATTR_RED_PACKET_ACTION: api_meter_info->action[SWITCH_METER_COLOR_RED] = - sai_packet_action_to_switch_packet_action(attribute->value.u8); + sai_packet_action_to_switch_packet_action(attribute->value.s32); break; } } diff --git a/switchsai/src/saiport.c b/switchsai/src/saiport.c index e7082d9..9502d73 100644 --- a/switchsai/src/saiport.c +++ b/switchsai/src/saiport.c @@ -41,7 +41,6 @@ sai_status_t sai_set_port_attribute( sai_status_t status = SAI_STATUS_SUCCESS; switch_status_t switch_status = SWITCH_STATUS_SUCCESS; switch_handle_t vlan_handle = SWITCH_API_INVALID_HANDLE; - switch_vlan_port_t switch_port; if (!attr) { status = SAI_STATUS_INVALID_PARAMETER; @@ -59,15 +58,8 @@ sai_status_t sai_set_port_attribute( sai_status_to_string(status)); return status; } - switch_port.handle = (switch_handle_t)port_id; - switch_port.tagging_mode = SWITCH_VLAN_PORT_UNTAGGED; - switch_status = switch_api_vlan_ports_add(device, vlan_handle, 1, &switch_port); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to add port %d to default vlan: %s", - port_id, sai_status_to_string(status)); - return status; - } + /* TBD: Default BD */ + break; default: break; diff --git a/switchsai/src/sairouterintf.c b/switchsai/src/sairouterintf.c index b7f3d48..4f7d364 100644 --- a/switchsai/src/sairouterintf.c +++ b/switchsai/src/sairouterintf.c @@ -87,7 +87,7 @@ sai_status_t sai_create_router_interface( intf_info.vrf_handle = (switch_handle_t) attribute->value.oid; break; case SAI_ROUTER_INTERFACE_ATTR_TYPE: - sai_intf_type = attribute->value.u8; + sai_intf_type = attribute->value.s32; break; case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_PORT); @@ -117,11 +117,11 @@ sai_status_t sai_create_router_interface( break; case SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE: intf_info.ipv4_urpf_mode = - sai_to_switch_urpf_mode(attribute->value.u8); + sai_to_switch_urpf_mode(attribute->value.s32); break; case SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE: intf_info.ipv6_urpf_mode = - sai_to_switch_urpf_mode(attribute->value.u8); + sai_to_switch_urpf_mode(attribute->value.s32); break; default: return SAI_STATUS_INVALID_PARAMETER; @@ -226,11 +226,11 @@ sai_status_t sai_set_router_interface_attribute( break; case SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE: switch_status = switch_api_interface_ipv4_urpf_mode_set( - rif_id, sai_to_switch_urpf_mode(attr->value.u8)); + rif_id, sai_to_switch_urpf_mode(attr->value.s32)); break; case SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE: switch_status = switch_api_interface_ipv6_urpf_mode_set( - rif_id, sai_to_switch_urpf_mode(attr->value.u8)); + rif_id, sai_to_switch_urpf_mode(attr->value.s32)); break; default: return SAI_STATUS_INVALID_PARAMETER; diff --git a/switchsai/src/switch_sai.thrift b/switchsai/src/switch_sai.thrift index 7fbc7c0..0696e63 100644 --- a/switchsai/src/switch_sai.thrift +++ b/switchsai/src/switch_sai.thrift @@ -161,6 +161,9 @@ struct sai_thrift_attribute_list_t { } service switch_sai_rpc { + //port API + sai_thrift_status_t sai_thrift_set_port_attribute(1: sai_thrift_object_id_t port_id, 2: sai_thrift_attribute_t thrift_attr); + //fdb API sai_thrift_status_t sai_thrift_create_fdb_entry(1: sai_thrift_fdb_entry_t thrift_fdb_entry, 2: list thrift_attr_list); sai_thrift_status_t sai_thrift_delete_fdb_entry(1: sai_thrift_fdb_entry_t thrift_fdb_entry); @@ -199,7 +202,7 @@ service switch_sai_rpc { sai_thrift_status_t sai_thrift_remove_next_hop_from_group(1: sai_thrift_object_id_t next_hop_group_id, 2: list thrift_nexthops); //lag API - sai_thrift_object_id_t sai_thrift_create_lag(); + sai_thrift_object_id_t sai_thrift_create_lag(1: list thrift_attr_list); sai_thrift_status_t sai_thrift_remove_lag(1: sai_thrift_object_id_t lag_id); sai_thrift_object_id_t sai_thrift_create_lag_member(1: list thrift_attr_list); sai_thrift_status_t sai_thrift_remove_lag_member(1: sai_thrift_object_id_t lag_member_id); diff --git a/switchsai/src/switch_sai_rpc_server.cpp b/switchsai/src/switch_sai_rpc_server.cpp index 0319648..dffdb29 100644 --- a/switchsai/src/switch_sai_rpc_server.cpp +++ b/switchsai/src/switch_sai_rpc_server.cpp @@ -20,10 +20,23 @@ limitations under the License. #include #include "switch_sai_rpc.h" + +#ifdef P4THRIFT +#include +#include +#include +#include + +namespace thrift_provider = p4::thrift; +#else #include #include #include #include + +namespace thrift_provider = apache::thrift; +#endif + #include #ifdef __cplusplus @@ -45,10 +58,10 @@ extern "C" { #include "arpa/inet.h" -using namespace ::apache::thrift; -using namespace ::apache::thrift::protocol; -using namespace ::apache::thrift::transport; -using namespace ::apache::thrift::server; +using namespace ::thrift_provider; +using namespace ::thrift_provider::protocol; +using namespace ::thrift_provider::transport; +using namespace ::thrift_provider::server; using boost::shared_ptr; @@ -149,6 +162,25 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { sai_thrift_string_to_mac(thrift_fdb_entry.mac_address, fdb_entry->mac_address); } + void sai_thrift_parse_port_attributes(const std::vector &thrift_attr_list, sai_attribute_t *attr_list) { + std::vector::const_iterator it = thrift_attr_list.begin(); + sai_thrift_attribute_t attribute; + for(uint32_t i = 0; i < thrift_attr_list.size(); i++, it++) { + attribute = (sai_thrift_attribute_t)*it; + attr_list[i].id = attribute.id; + switch (attribute.id) { + case SAI_PORT_ATTR_ADMIN_STATE: + attr_list[i].value.booldata = attribute.value.booldata; + break; + case SAI_PORT_ATTR_PORT_VLAN_ID: + attr_list[i].value.u16 = attribute.value.u16; + break; + default: + break; + } + } + } + void sai_thrift_parse_unicast_route_entry(const sai_thrift_unicast_route_entry_t &thrift_unicast_route_entry, sai_unicast_route_entry_t *unicast_route_entry) { unicast_route_entry->vr_id = (sai_object_id_t) thrift_unicast_route_entry.vr_id; sai_thrift_parse_ip_prefix(thrift_unicast_route_entry.destination, &unicast_route_entry->destination); @@ -167,13 +199,13 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].id = attribute.id; switch (attribute.id) { case SAI_FDB_ENTRY_ATTR_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_FDB_ENTRY_ATTR_PORT_ID: attr_list[i].value.oid = attribute.value.oid; break; case SAI_FDB_ENTRY_ATTR_PACKET_ACTION: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; default: break; @@ -195,7 +227,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].value.u16 = attribute.value.u16; break; case SAI_FDB_FLUSH_ATTR_ENTRY_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; } } @@ -247,7 +279,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].value.oid = attribute.value.oid; break; case SAI_ROUTER_INTERFACE_ATTR_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: attr_list[i].value.u16 = attribute.value.u16; @@ -273,7 +305,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].id = attribute.id; switch (attribute.id) { case SAI_NEXT_HOP_ATTR_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_NEXT_HOP_ATTR_IP: sai_thrift_parse_ip_address(attribute.value.ipaddr, &attr_list[i].value.ipaddr); @@ -293,7 +325,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].id = attribute.id; switch (attribute.id) { case SAI_NEXT_HOP_GROUP_ATTR_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT: attr_list[i].value.u32 = attribute.value.u32; @@ -394,7 +426,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].id = attribute.id; switch (attribute.id) { case SAI_HOSTIF_ATTR_TYPE: - attr_list[i].value.u32 = attribute.value.u32; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_HOSTIF_ATTR_RIF_OR_PORT_ID: attr_list[i].value.oid = attribute.value.oid; @@ -468,6 +500,21 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { } } + int32_t sai_thrift_set_port_attribute(const sai_thrift_object_id_t port_id, const sai_thrift_attribute_t &thrift_attr) { + printf("sai_thrift_set_port\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_port_api_t *port_api; + status = sai_api_query(SAI_API_PORT, (void **) &port_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + std::vector thrift_attr_list; + thrift_attr_list.push_back(thrift_attr); + sai_attribute_t attr; + sai_thrift_parse_port_attributes(thrift_attr_list, &attr); + status = port_api->set_port_attribute((sai_object_id_t)port_id, &attr); + return status; + } int32_t sai_thrift_create_fdb_entry(const sai_thrift_fdb_entry_t& thrift_fdb_entry, const std::vector & thrift_attr_list) { printf("sai_thrift_create_fdb_entry\n"); @@ -787,7 +834,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return status; } - sai_thrift_object_id_t sai_thrift_create_lag() { + sai_thrift_object_id_t sai_thrift_create_lag(const std::vector & thrift_attr_list) { printf("sai_thrift_create_lag\n"); sai_status_t status = SAI_STATUS_SUCCESS; sai_lag_api_t *lag_api; @@ -1210,7 +1257,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].value.aclfield.data.oid = attribute.value.aclfield.data.oid; break; case SAI_ACL_ENTRY_ATTR_PACKET_ACTION: - attr_list[i].value.aclfield.data.u8 = attribute.value.aclfield.data.u8; + attr_list[i].value.aclfield.data.s32 = attribute.value.aclfield.data.s32; break; default: break; @@ -1398,7 +1445,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].id = attribute.id; switch (attribute.id) { case SAI_MIRROR_SESSION_ATTR_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_MIRROR_SESSION_ATTR_MONITOR_PORT: attr_list[i].value.oid = attribute.value.oid; @@ -1416,7 +1463,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].value.u8 = attribute.value.u8; break; case SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION: attr_list[i].value.u8 = attribute.value.u8; @@ -1484,13 +1531,13 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].id = attribute.id; switch (attribute.id) { case SAI_POLICER_ATTR_METER_TYPE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_POLICER_ATTR_MODE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_POLICER_ATTR_COLOR_SOURCE: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_POLICER_ATTR_CBS: attr_list[i].value.u64 = attribute.value.u64; @@ -1505,13 +1552,13 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attr_list[i].value.u64 = attribute.value.u64; break; case SAI_POLICER_ATTR_GREEN_PACKET_ACTION: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_POLICER_ATTR_YELLOW_PACKET_ACTION: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; case SAI_POLICER_ATTR_RED_PACKET_ACTION: - attr_list[i].value.u8 = attribute.value.u8; + attr_list[i].value.s32 = attribute.value.s32; break; } } diff --git a/tests/ptf-tests/api-tests/switch.py b/tests/ptf-tests/api-tests/switch.py index a8e1a71..c00a293 100644 --- a/tests/ptf-tests/api-tests/switch.py +++ b/tests/ptf-tests/api-tests/switch.py @@ -661,10 +661,8 @@ def runTest(self): dst_ip += 1 print 'L2LagTest:', count - #setting the hash to 60% for bmv2 - hash_factor = 0.6 for i in range(0, 4): - self.assertTrue((count[i] >= ((max_itrs / 4) * hash_factor)), + self.assertTrue((count[i] >= ((max_itrs / 4) * 0.9)), "Not all paths are equally balanced") pkt = simple_tcp_packet(eth_src='00:11:11:11:11:11', @@ -792,7 +790,7 @@ def runTest(self): class L3IPv4HostTest(api_base_tests.ThriftInterfaceDataPlane): def runTest(self): print - print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.10.10.1 [id = 101])" + print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.10.10.1 [id = 105])" self.client.switcht_api_init(device) vrf = self.client.switcht_api_vrf_create(device, swports[1]) @@ -957,11 +955,114 @@ def runTest(self): ############################################################################### @group('l3') @group('ipv4') +@group('maxsizes') +class L3IPv4SubIntfHostTest(api_base_tests.ThriftInterfaceDataPlane): + def runTest(self): + print + print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.10.10.1 [id = 105])" + self.client.switcht_api_init(device) + vrf = self.client.switcht_api_vrf_create(device, swports[1]) + + rmac = self.client.switcht_api_router_mac_group_create(device) + self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') + + iu1 = interface_union(port_lag_handle = swports[1]) + i_info1 = switcht_interface_info_t(device=0, type=4, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if1 = self.client.switcht_api_interface_create(device, i_info1) + i_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) + + pv = switcht_port_vlan_t(port_lag_handle = swports[2], vlan_id=10) + iu2 = interface_union(port_vlan=pv) + i_info2 = switcht_interface_info_t(device=0, type=6, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if2 = self.client.switcht_api_interface_create(device, i_info2) + i_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) + + # Add a static route + i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + nhop1 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=1) + neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) + self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop1) + + i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='20.20.20.1', prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if1, ip_addr_valid=0) + nhop2 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if1, mac_addr='00:11:22:33:44:56', ip_addr=i_ip4, rw_type=1) + neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) + self.client.switcht_api_l3_route_add(device, vrf, i_ip4, nhop2) + + # send the test packet(s) + try: + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:22:22:22:22:22', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64) + exp_pkt = simple_tcp_packet( + eth_dst='00:11:22:33:44:55', + eth_src='00:77:66:55:44:33', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + dl_vlan_enable=True, + vlan_vid=10, + pktlen=104, + ip_ttl=63) + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [swports[2]]) + + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:11:11:11:11:11', + ip_dst='20.20.20.1', + ip_src='10.0.0.1', + dl_vlan_enable=True, + vlan_vid=10, + pktlen=104, + ip_id=105, + ip_ttl=64) + exp_pkt = simple_tcp_packet( + eth_dst='00:11:22:33:44:56', + eth_src='00:77:66:55:44:33', + ip_dst='20.20.20.1', + ip_src='10.0.0.1', + ip_id=105, + ip_ttl=63) + send_packet(self, swports[2], str(pkt)) + verify_packets(self, exp_pkt, [swports[1]]) + + finally: + self.client.switcht_api_neighbor_entry_remove(device, neighbor1) + self.client.switcht_api_l3_route_delete(device, vrf, i_ip3, nhop1) + self.client.switcht_api_nhop_delete(device, nhop1) + + self.client.switcht_api_neighbor_entry_remove(device, neighbor2) + self.client.switcht_api_l3_route_delete(device, vrf, i_ip4, nhop2) + self.client.switcht_api_nhop_delete(device, nhop2) + + self.client.switcht_api_l3_interface_address_delete(device, if1, vrf, i_ip1) + self.client.switcht_api_l3_interface_address_delete(device, if2, vrf, i_ip2) + + self.client.switcht_api_interface_delete(device, if1) + self.client.switcht_api_interface_delete(device, if2) + + self.client.switcht_api_router_mac_delete(device, rmac, '00:77:66:55:44:33') + self.client.switcht_api_router_mac_group_delete(device, rmac) + self.client.switcht_api_vrf_delete(device, vrf) + + +############################################################################### +@group('l3') +@group('ipv4') +@group('maxsizes') class L3IPv4HostModifyTest(api_base_tests.ThriftInterfaceDataPlane): def runTest(self): print - print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.10.10.1 [id = 101] route add)" - print "Sending packet port %d" % swports[1], " -> port %d" % swports[3], " (192.168.0.1 -> 10.10.10.1 [id = 101] route update)" + print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.10.10.1 [id = 105] route add)" + print "Sending packet port %d" % swports[1], " -> port %d" % swports[3], " (192.168.0.1 -> 10.10.10.1 [id = 105] route update)" self.client.switcht_api_init(device) vrf = self.client.switcht_api_vrf_create(device, 1) @@ -1062,7 +1163,7 @@ def runTest(self): class L3IPv4LpmTest(api_base_tests.ThriftInterfaceDataPlane): def runTest(self): print - print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.0.0.1 [id = 101])" + print "Sending packet port %d" % swports[1], " -> port %d" % swports[2], " (192.168.0.1 -> 10.0.0.1 [id = 105])" self.client.switcht_api_init(device) vrf = self.client.switcht_api_vrf_create(device, 1) @@ -3579,12 +3680,12 @@ def runTest(self): self.client.switcht_api_init(device) vrf = self.client.switcht_api_vrf_create(device, 2) - pv1 = switcht_port_vlan_t(port_lag_handle=1, vlan_id=10) + pv1 = switcht_port_vlan_t(port_lag_handle=swports[1], vlan_id=10) iu1 = interface_union(port_vlan = pv1) i_info1 = switcht_interface_info_t(device=0, type=9, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) - pv2 = switcht_port_vlan_t(port_lag_handle=2, vlan_id=20) + pv2 = switcht_port_vlan_t(port_lag_handle=swports[2], vlan_id=20) iu2 = interface_union(port_vlan = pv2) i_info2 = switcht_interface_info_t(device=0, type=9, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) @@ -4834,7 +4935,6 @@ def runTest(self): # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) - #encap_type 3 is vxlan ln_flags = switcht_ln_flags(ipv4_unicast_enabled=1) lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf, rmac_handle=rmac, flags=ln_flags) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) @@ -4844,6 +4944,7 @@ def runTest(self): src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) + #encap_type 3 is vxlan encap_info = switcht_encap_info_t(encap_type=3) ip_encap = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip, dst_ip=dst_ip, ttl=60, proto=17, u=udp_tcp) tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) @@ -8945,3 +9046,636 @@ def tearDown(self): self.client.switcht_api_vrf_delete(device, self.vrf) api_base_tests.ThriftInterfaceDataPlane.tearDown(self) + +############################################################################### +@group('tunnel') +class IPinIPTest(api_base_tests.ThriftInterfaceDataPlane): + def setUp(self): + print + print 'Configuring device for IPinIP packet test cases' + api_base_tests.ThriftInterfaceDataPlane.setUp(self) + self.client.switcht_api_init(device) + + self.vrf = self.client.switcht_api_vrf_create(device, 2) + self.rmac = self.client.switcht_api_router_mac_group_create(device) + self.client.switcht_api_router_mac_add(device, self.rmac, + '00:77:66:55:44:33') + + iu1 = interface_union(port_lag_handle = swports[0]) + i_info1 = switcht_interface_info_t(device=0, type=4, u=iu1, + mac='00:77:66:55:44:33', label=0, + vrf_handle=self.vrf, + rmac_handle=self.rmac) + self.if1 = self.client.switcht_api_interface_create(device, i_info1) + + iu2 = interface_union(port_lag_handle = swports[1]) + i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, + mac='00:77:66:55:44:33', label=0, + vrf_handle=self.vrf, + rmac_handle=self.rmac) + self.if2 = self.client.switcht_api_interface_create(device, i_info2) + + # Create an GRE IPv4 tunnel interface (encap_type = 4) + src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.100.1.1', + prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.200.1.3', + prefix_length=32) + encap_info = switcht_encap_info_t(encap_type=4) + ip_encap = switcht_ip_encap_t(vrf=self.vrf, src_ip=src_ip, + dst_ip=dst_ip, ttl=64, proto=47) + tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) + iu3 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, + encap_info=encap_info, out_if=self.if2) + self.ift1 = self.client.switcht_api_tunnel_interface_create(device, + 0, iu3) + + # Create nexthop over GRE IPv4 tunnel interface + nhop_key = switcht_nhop_key_t(intf_handle=self.ift1, ip_addr_valid=0) + self.nhop1 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop1, + interface_handle=self.ift1, + mac_addr='00:44:44:44:44:44', + rw_type=1, neigh_type=7) + self.neigh1 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, + interface_handle=self.ift1, + mac_addr='00:55:55:55:55:55', + ip_addr=dst_ip) + self.neigh2 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + + # Create an GRE IPv6 tunnel interface (encap_type = 4) + src_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::1', + prefix_length=128) + dst_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::2', + prefix_length=128) + encap_info = switcht_encap_info_t(encap_type=4) + ip_encap = switcht_ip_encap_t(vrf=self.vrf, src_ip=src_ip, + dst_ip=dst_ip, ttl=64, proto=47) + tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) + iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, + encap_info=encap_info, out_if=self.if2) + self.ift2 = self.client.switcht_api_tunnel_interface_create(device, + 0, iu4) + + # Create nexthop over GRE IPv6 tunnel interface + nhop_key = switcht_nhop_key_t(intf_handle=self.ift2, ip_addr_valid=0) + self.nhop2 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop2, + interface_handle=self.ift2, + mac_addr='00:44:44:44:44:44', + rw_type=1, neigh_type=8) + self.neigh3 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, + interface_handle=self.ift2, + mac_addr='00:55:55:55:55:55', + ip_addr=dst_ip) + self.neigh4 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + + # Create an IPv4 tunnel interface (encap_type = 8) + src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.100.1.1', + prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.200.1.3', + prefix_length=32) + encap_info = switcht_encap_info_t(encap_type=8) + ip_encap = switcht_ip_encap_t(vrf=self.vrf, src_ip=src_ip, + dst_ip=dst_ip, ttl=64, proto=4) + tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) + iu5 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, + encap_info=encap_info, out_if=self.if2) + self.ift3 = self.client.switcht_api_tunnel_interface_create(device, + 0, iu5) + + # Create nexthop over IPv4 tunnel interface + nhop_key = switcht_nhop_key_t(intf_handle=self.ift3, ip_addr_valid=0) + self.nhop3 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop3, + interface_handle=self.ift3, + mac_addr='00:44:44:44:44:44', + rw_type=1, neigh_type=7) + self.neigh5 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, + interface_handle=self.ift3, + mac_addr='00:55:55:55:55:55', + ip_addr=dst_ip) + self.neigh6 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + + # Create an IPv6 tunnel interface (encap_type = 8) + src_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::1', + prefix_length=128) + dst_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::2', + prefix_length=128) + encap_info = switcht_encap_info_t(encap_type=8) + ip_encap = switcht_ip_encap_t(vrf=self.vrf, src_ip=src_ip, + dst_ip=dst_ip, ttl=64, proto=41) + tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) + iu6 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, + encap_info=encap_info, out_if=self.if2) + self.ift4 = self.client.switcht_api_tunnel_interface_create(device, + 0, iu6) + + # Create nexthop over GRE IPv6 tunnel interface + nhop_key = switcht_nhop_key_t(intf_handle=self.ift4, ip_addr_valid=0) + self.nhop4 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop4, + interface_handle=self.ift4, + mac_addr='00:44:44:44:44:44', + rw_type=1, neigh_type=8) + self.neigh7 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, + interface_handle=self.ift4, + mac_addr='00:55:55:55:55:55', + ip_addr=dst_ip) + self.neigh8 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + + # Add route 10.10.10.1/32 => GRE IPv4 tunnel ift1 + self.ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', + prefix_length=32) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip1, self.nhop1) + # Add route 2ffe::1/128 => GRE IPV4 tunnel ift1 + self.ip2 = switcht_ip_addr_t(addr_type=1, ipaddr='2ffe::1', + prefix_length=128) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip2, self.nhop1) + + # Add route 10.10.10.2/32 => GRE IPv6 tunnel ift2 + self.ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.2', + prefix_length=32) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip3, self.nhop2) + # Add route 2ffe::2/128 => GRE IPV6 tunnel ift2 + self.ip4 = switcht_ip_addr_t(addr_type=1, ipaddr='2ffe::2', + prefix_length=128) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip4, self.nhop2) + + # Add route 10.10.10.3/32 => IPv4 tunnel ift3 + self.ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.3', + prefix_length=32) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip5, self.nhop3) + # Add route 2ffe::3/128 => IPV4 tunnel ift3 + self.ip6 = switcht_ip_addr_t(addr_type=1, ipaddr='2ffe::3', + prefix_length=128) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip6, self.nhop3) + + # Add route 10.10.10.4/32 => IPv6 tunnel ift4 + self.ip7 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.4', + prefix_length=32) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip7, self.nhop4) + # Add route 2ffe::4/128 => IPV6 tunnel ift4 + self.ip8 = switcht_ip_addr_t(addr_type=1, ipaddr='2ffe::4', + prefix_length=128) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip8, self.nhop4) + + # Create a logical network + bt = switcht_bridge_type(tunnel_vni=0) + encap = switcht_encap_info_t(u=bt) + ln_flags = switcht_ln_flags(ipv4_unicast_enabled=1) + ln_info = switcht_logical_network_t(type=4, encap_info=encap, + age_interval=1800, vrf=self.vrf, + rmac_handle=self.rmac, + flags=ln_flags) + self.ln1 = self.client.switcht_api_logical_network_create(device, + ln_info) + self.client.switcht_api_logical_network_member_add(device, + self.ln1, self.ift1) + self.client.switcht_api_logical_network_member_add(device, + self.ln1, self.ift3) + + # Create nexthop over normal interface + nhop_key = switcht_nhop_key_t(intf_handle=self.if1, ip_addr_valid=0) + self.nhop5 = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop5, + interface_handle=self.if1, + mac_addr='00:11:11:11:11:11', + rw_type=1, neigh_type=0) + self.neigh9 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + + # Add route 10.20.10.1/32 => if1 + self.ip9 = switcht_ip_addr_t(addr_type=0, ipaddr='10.20.10.1', + prefix_length=32) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip9, self.nhop5) + # Add route 2000::1/128 => ift1 + self.ip10 = switcht_ip_addr_t(addr_type=1, ipaddr='2000::1', + prefix_length=128) + self.client.switcht_api_l3_route_add(device, self.vrf, + self.ip10, self.nhop5) + + def runTest(self): + try: + print "Verifying GRE 4in4 (encap)" + pkt1 = simple_tcp_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ip_dst='10.10.10.1', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=64) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ip_dst='10.10.10.1', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=63) + ipip_pkt = simple_gre_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt2['IP']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying GRE 6in4 (encap)" + pkt1 = simple_tcpv6_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2ffe::1', + ipv6_src='2000::1', + ipv6_hlim=64) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ipv6_dst='2ffe::1', + ipv6_src='2000::1', + ipv6_hlim=63) + ipip_pkt = simple_gre_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt2['IPv6']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying GRE 4in6 (encap)" + pkt1 = simple_tcp_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ip_dst='10.10.10.2', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=64) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ip_dst='10.10.10.2', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=63) + ipip_pkt = simple_grev6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt2['IP']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying GRE 6in6 (encap)" + pkt1 = simple_tcpv6_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2ffe::2', + ipv6_src='2000::1', + ipv6_hlim=64) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ipv6_dst='2ffe::2', + ipv6_src='2000::1', + ipv6_hlim=63) + ipip_pkt = simple_grev6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt2['IPv6']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying 4in4 (encap)" + pkt1 = simple_tcp_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ip_dst='10.10.10.3', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=64) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ip_dst='10.10.10.3', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=63) + ipip_pkt = simple_ipv4ip_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt2['IP']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying 6in4 (encap)" + pkt1 = simple_tcpv6_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2ffe::3', + ipv6_src='2000::1', + ipv6_hlim=64) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ipv6_dst='2ffe::3', + ipv6_src='2000::1', + ipv6_hlim=63) + ipip_pkt = simple_ipv4ip_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt2['IPv6']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying 4in6 (encap)" + pkt1 = simple_tcp_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ip_dst='10.10.10.4', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=64) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ip_dst='10.10.10.4', + ip_src='10.20.10.1', + ip_id=108, + ip_ttl=63) + ipip_pkt = simple_ipv6ip_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt2['IP']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying 6in6 (encap)" + pkt1 = simple_tcpv6_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2ffe::4', + ipv6_src='2000::1', + ipv6_hlim=64) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:44:44:44:44:44', + ipv6_dst='2ffe::4', + ipv6_src='2000::1', + ipv6_hlim=63) + ipip_pkt = simple_ipv6ip_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:55:55:55:55:55', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt2['IPv6']) + send_packet(self, swports[0], str(pkt1)) + verify_packets(self, ipip_pkt, [swports[1]]) + + print "Verifying GRE 4in4 (decap)" + pkt1 = simple_tcp_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=64) + ipip_pkt = simple_gre_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt1['IP']) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying GRE 6in4 (decap)" + pkt1 = simple_tcpv6_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=64) + ipip_pkt = simple_gre_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt1['IPv6']) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying GRE 4in6 (decap)" + pkt1 = simple_tcp_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=64) + ipip_pkt = simple_grev6_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt1['IP']) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying GRE 6in6 (decap)" + pkt1 = simple_tcpv6_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=64) + ipip_pkt = simple_grev6_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt1['IPv6']) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying 4in4 (decap)" + pkt1 = simple_tcp_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=64) + ipip_pkt = simple_ipv4ip_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt1['IP']) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying 6in4 (decap)" + pkt1 = simple_tcpv6_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=64) + ipip_pkt = simple_ipv4ip_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ip_id=0, + ip_dst='10.200.1.3', + ip_src='10.100.1.1', + ip_ttl=64, + inner_frame=pkt1['IPv6']) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying 4in6 (decap)" + pkt1 = simple_tcp_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=64) + ipip_pkt = simple_ipv6ip_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt1['IP']) + pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ip_dst='10.20.10.1', + ip_src='10.10.10.1', + ip_id=108, + ip_ttl=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + print "Verifying 6in6 (decap)" + pkt1 = simple_tcpv6_packet(eth_src='00:44:44:44:44:44', + eth_dst='00:77:66:55:44:33', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=64) + ipip_pkt = simple_ipv6ip_packet(eth_src='00:55:55:55:55:55', + eth_dst='00:77:66:55:44:33', + ipv6_dst='3ffe::2', + ipv6_src='3ffe::1', + ipv6_hlim=64, + inner_frame=pkt1['IPv6']) + pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ipv6_dst='2000::1', + ipv6_src='2ffe::1', + ipv6_hlim=63) + send_packet(self, swports[1], str(ipip_pkt)) + verify_packets(self, pkt2, [swports[0]]) + + finally: + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip1, self.nhop1) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip2, self.nhop1) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip3, self.nhop2) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip4, self.nhop2) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip5, self.nhop3) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip6, self.nhop3) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip7, self.nhop4) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip8, self.nhop4) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip9, self.nhop5) + self.client.switcht_api_l3_route_delete(device, self.vrf, + self.ip10, self.nhop5) + + self.client.switcht_api_neighbor_entry_remove(device, self.neigh1) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh2) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh3) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh4) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh5) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh6) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh7) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh8) + self.client.switcht_api_neighbor_entry_remove(device, self.neigh9) + self.client.switcht_api_nhop_delete(device, self.nhop1) + self.client.switcht_api_nhop_delete(device, self.nhop2) + self.client.switcht_api_nhop_delete(device, self.nhop3) + self.client.switcht_api_nhop_delete(device, self.nhop4) + self.client.switcht_api_nhop_delete(device, self.nhop5) + + self.client.switcht_api_logical_network_member_remove(device, + self.ln1, + self.ift1) + self.client.switcht_api_logical_network_member_remove(device, + self.ln1, + self.ift3) + self.client.switcht_api_logical_network_delete(device, self.ln1) + + self.client.switcht_api_tunnel_interface_delete(device, self.ift1) + self.client.switcht_api_tunnel_interface_delete(device, self.ift2) + self.client.switcht_api_tunnel_interface_delete(device, self.ift3) + self.client.switcht_api_tunnel_interface_delete(device, self.ift4) + + self.client.switcht_api_interface_delete(device, self.if1) + self.client.switcht_api_interface_delete(device, self.if2) + + self.client.switcht_api_router_mac_delete(device, self.rmac, + '00:77:66:55:44:33') + self.client.switcht_api_router_mac_group_delete(device, self.rmac) + self.client.switcht_api_vrf_delete(device, self.vrf) + diff --git a/tests/ptf-tests/api-tests/switch_acl.py b/tests/ptf-tests/api-tests/switch_acl.py index f0fdf03..953c80b 100644 --- a/tests/ptf-tests/api-tests/switch_acl.py +++ b/tests/ptf-tests/api-tests/switch_acl.py @@ -84,7 +84,7 @@ def runTest(self): ip_src='192.168.0.1', ip_id=105, ip_ttl=64) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) exp_pkt = simple_tcp_packet( eth_dst='00:11:22:33:44:55', @@ -112,7 +112,7 @@ def runTest(self): action_params, opt_action_params) self.client.switcht_api_acl_reference(0, acl, if1) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) # check for absence of packet here! try: @@ -186,7 +186,7 @@ def runTest(self): ip_src='192.168.0.1', ip_id=105, ip_ttl=64) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) exp_pkt = simple_tcp_packet( eth_dst='00:11:22:33:44:55', @@ -200,7 +200,7 @@ def runTest(self): # create a mirror session minfo1 = switcht_mirror_info_t(session_id=1, direction=1, - egress_port=4, mirror_type=0, + egress_port=swports[4], mirror_type=0, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=0) @@ -224,7 +224,7 @@ def runTest(self): self.client.switcht_api_acl_reference(0, acl, if1) # send the test packet(s) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packet(self, exp_pkt, swports[2]) # verify mirrored packet verify_packet(self, pkt, swports[4]) @@ -234,7 +234,7 @@ def runTest(self): print "Delete Mirror ACL" self.client.switcht_api_mirror_session_delete(0, mirror1) # clean-up test, make sure pkt is not mirrored after session is deleted - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packet(self, exp_pkt, swports[2]) verify_no_other_packets(self) # ip_acl cleanup @@ -265,19 +265,19 @@ def runTest(self): self.client.switcht_api_init(0) print "create mirror sessions" minfo1 = switcht_mirror_info_t(session_id=1, direction=1, - egress_port=3, mirror_type=0, + egress_port=swports[3], mirror_type=0, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=0) mirror1 = self.client.switcht_api_mirror_session_create(0, minfo1) minfo2 = switcht_mirror_info_t(session_id=101, direction=2, - egress_port=3, mirror_type=0, + egress_port=swports[3], mirror_type=0, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=0) mirror2 = self.client.switcht_api_mirror_session_create(0, minfo2) minfo3 = switcht_mirror_info_t(session_id=201, direction=3, - egress_port=3, mirror_type=0, + egress_port=swports[3], mirror_type=0, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=0) @@ -344,18 +344,18 @@ def runTest(self): ip_ttl=63) # create a mirror session minfo1 = switcht_mirror_info_t(session_id=1, direction=2, - egress_port=4, mirror_type=0, + egress_port=swports[4], mirror_type=0, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=0) mirror1 = self.client.switcht_api_mirror_session_create(0, minfo1) # setup a egress Mirror acl - print "Create Egress Mirror ACL to mirror e2e from 2->4" + print "Create Egress Mirror ACL to mirror e2e from %d -> %d" % (swports[2], swports[4]) acl = self.client.switcht_api_acl_list_create(0, 6) # create kvp to match egress port and deflect bit kvp = [] - kvp_val = switcht_acl_value_t(value_num=2) + kvp_val = switcht_acl_value_t(value_num=swports[2]) kvp_mask = switcht_acl_value_t(value_num=0xff) kvp.append(switcht_acl_key_value_pair_t(0, kvp_val, kvp_mask)) #kvp.append(switcht_acl_egr_key_value_pair_t(field=0, value=2, mask=-1)) @@ -370,7 +370,7 @@ def runTest(self): action_params, opt_action_params) self.client.switcht_api_acl_reference(0, acl, if2) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packet(self, exp_pkt, swports[2]) # verify mirrored packet verify_packet(self, exp_pkt, swports[4]) @@ -379,19 +379,19 @@ def runTest(self): # update the mirror sesion to different port print "Update Egress Mirror Session's egr_port to 3 and test packet again" minfo1 = switcht_mirror_info_t(session_id=1, direction=2, - egress_port=3, mirror_type=0, + egress_port=swports[3], mirror_type=0, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=0) self.client.switcht_api_mirror_session_update(0, mirror1, minfo1) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packet(self, exp_pkt, swports[2]) verify_packet(self, exp_pkt, swports[3]) verify_no_other_packets(self) print "Delete Mirror Session" self.client.switcht_api_mirror_session_delete(0, mirror1) # clean-up test, make sure pkt is not mirrored after session is deleted - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packet(self, exp_pkt, swports[2]) verify_no_other_packets(self) # ip_acl cleanup @@ -508,7 +508,7 @@ def runTest(self): # create a mirror session minfo1 = switcht_mirror_info_t(session_id=85, direction=1, - egress_port=4, mirror_type=3, + egress_port=swports[4], mirror_type=3, session_type=0, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=nhop1) @@ -530,7 +530,7 @@ def runTest(self): self.client.switcht_api_acl_reference(0, acl, if1) # egress interface if4 - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) # verify mirrored packet exp_mirrored_pkt = ipv4_erspan_pkt(eth_dst='00:44:44:44:44:44', eth_src='00:77:66:55:44:33', @@ -551,7 +551,7 @@ def runTest(self): print "Delete Egress Mirror Session and test packet again" self.client.switcht_api_mirror_session_delete(0, mirror1) # clean-up test, make sure pkt is not mirrored after session is deleted - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packet(self, exp_pkt, swports[2]) verify_no_other_packets(self) # ip_acl cleanup @@ -669,7 +669,7 @@ def runTest(self): ip_id=105, ip_ttl=63, pktlen=pktlen) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) verify_packets(self, exp_pkt, [swports[2]]) num_bytes += pktlen num_packets += 1 @@ -693,7 +693,7 @@ def runTest(self): ip_id=105, ip_ttl=63, pktlen=pktlen) - send_packet(self, 1, str(pkt)) + send_packet(self, swports[1], str(pkt)) num_bytes += pktlen num_packets += 1 diff --git a/tests/ptf-tests/common/pd_utils.py b/tests/ptf-tests/common/pd_utils.py index 2ec25a2..e744b24 100644 --- a/tests/ptf-tests/common/pd_utils.py +++ b/tests/ptf-tests/common/pd_utils.py @@ -123,7 +123,9 @@ def populate_default_fabric_entries(client, sess_hdl, dev_tgt, ipv6_enabled=0, #client.storm_control_set_default_action_nop(sess_hdl, dev_tgt) client.egress_vlan_xlate_set_default_action_set_egress_packet_vlan_untagged( sess_hdl, dev_tgt) - client.egress_filter_set_default_action_set_egress_filter_drop( + client.egress_filter_set_default_action_egress_filter_check( + sess_hdl, dev_tgt) + client.egress_filter_drop_set_default_action_set_egress_filter_drop( sess_hdl, dev_tgt) if stats_enabled: client.ingress_bd_stats_set_default_action_update_ingress_bd_stats( @@ -163,7 +165,9 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) client.egress_vlan_xlate_set_default_action_set_egress_packet_vlan_untagged( sess_hdl, dev_tgt) - client.egress_filter_set_default_action_set_egress_filter_drop( + client.egress_filter_set_default_action_egress_filter_check( + sess_hdl, dev_tgt) + client.egress_filter_drop_set_default_action_set_egress_filter_drop( sess_hdl, dev_tgt) client.validate_packet_set_default_action_nop( sess_hdl, dev_tgt) @@ -188,8 +192,9 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) client.rewrite_set_default_action_set_l2_rewrite( sess_hdl, dev_tgt) + action_spec = dc_egress_port_type_normal_action_spec_t(action_ifindex=0) client.egress_port_mapping_set_default_action_egress_port_type_normal( - sess_hdl, dev_tgt) + sess_hdl, dev_tgt, action_spec) client.mtu_set_default_action_mtu_miss( sess_hdl, dev_tgt) @@ -567,6 +572,11 @@ def add_fabric_lag(client, sess_hdl, dev_tgt, src_device, port_list): grp_hdl, mbr_hdl) return grp_hdl +def enum(**enums): + return type('Enum', (), enums) + +PortType = enum(Normal=0, Fabric=1) + def program_ports(client, sess_hdl, dev_tgt, port_count): count = 1 ret = [] @@ -591,17 +601,17 @@ def program_ports(client, sess_hdl, dev_tgt, port_count): match_spec = dc_lag_group_match_spec_t( ingress_metadata_egress_ifindex=count) lag_hdl = client.lag_group_add_entry( - sess_hdl, dev_tgt, - match_spec, mbr_hdl) - ret.append({ 'port': port_hdl, 'mbr' : mbr_hdl, 'lag' : lag_hdl}) - - match_spec = dc_egress_lag_match_spec_t( - standard_metadata_egress_port=count) - action_spec = dc_set_egress_ifindex_action_spec_t( - action_egress_ifindex=count) - client.egress_lag_table_add_with_set_egress_ifindex( - sess_hdl, dev_tgt, match_spec, action_spec) - + sess_hdl, dev_tgt, + match_spec, mbr_hdl) + match_spec = dc_egress_port_mapping_match_spec_t( + standard_metadata_egress_port=count) + action_spec = dc_egress_port_type_normal_action_spec_t(action_ifindex=count) + egress_hdl = client.egress_port_mapping_table_add_with_egress_port_type_normal( + sess_hdl, + dev_tgt, + match_spec, + action_spec) + ret.append({ 'port': port_hdl, 'mbr' : mbr_hdl, 'lag' : lag_hdl, 'egress' : egress_hdl}) count = count + 1 return ret @@ -631,14 +641,18 @@ def program_emulation_ports(client, sess_hdl, dev_tgt, port_count): lag_hdl = client.lag_group_add_entry( sess_hdl, dev_tgt, match_spec, mbr_hdl) - ret.append({ 'port': port_hdl, 'mbr' : mbr_hdl, 'lag' : lag_hdl}) + match_spec = dc_egress_port_mapping_match_spec_t( + eg_intr_md_egress_port=count) + action_spec = dc_egress_port_type_normal_action_spec_t(action_ifindex=count) + egress_hdl = client.egress_port_mapping_table_add_with_egress_port_type_normal( + sess_hdl, + dev_tgt, + match_spec, + action_spec) + ret.append({ 'port': port_hdl, 'mbr' : mbr_hdl, 'lag' : lag_hdl, 'egress' : egress_hdl}) count = count + 1 return ret -def enum(**enums): - return type('Enum', (), enums) - -PortType = enum(Normal=0, Fabric=1) def add_ports(client, sess_hdl, dev_tgt, port_list, port_type, l2xid): #print port_list @@ -662,11 +676,14 @@ def add_ports(client, sess_hdl, dev_tgt, port_list, port_type, l2xid): match_spec = dc_egress_port_mapping_match_spec_t( standard_metadata_egress_port=i) if port_type == PortType.Normal: + action_spec = dc_egress_port_type_normal_action_spec_t(action_ifindex=ifindex) client.egress_port_mapping_table_add_with_egress_port_type_normal( - sess_hdl, dev_tgt, match_spec) + sess_hdl, dev_tgt, match_spec, action_spec) elif port_type == PortType.Fabric: + action_spec = dc_egress_port_type_fabric_action_spec_t(action_ifindex=ifindex) client.egress_port_mapping_table_add_with_egress_port_type_fabric( - sess_hdl, dev_tgt, match_spec) + sess_hdl, dev_tgt, match_spec, action_spec) + def delete_ports(client, sess_hdl, dev, port_count, ret_list): count = 0 @@ -679,6 +696,9 @@ def delete_ports(client, sess_hdl, dev, port_count, ret_list): ret_list[count]['mbr']) client.ingress_port_mapping_table_delete( sess_hdl, dev, ret_list[count]['port']) + client.egress_port_mapping_table_delete( + sess_hdl, dev, ret_list[count]['egress']) + count = count + 1 def program_bd(client, sess_hdl, dev_tgt, vlan, mc_index): @@ -1107,11 +1127,12 @@ def enable_learning(client, sess_hdl, dev_tgt): match_spec, 1000) def program_tunnel_ipv4_src_vtep(client, sess_hdl, dev_tgt, vrf, src_ip, - ifindex): + tunnel_type, ifindex): #Ingress Tunnel Decap - src vtep entry match_spec = dc_ipv4_src_vtep_match_spec_t( l3_metadata_vrf=vrf, - ipv4_metadata_lkp_ipv4_sa=src_ip) + ipv4_metadata_lkp_ipv4_sa=src_ip, + tunnel_metadata_ingress_tunnel_type=tunnel_type) action_spec = dc_src_vtep_hit_action_spec_t( action_ifindex=ifindex) hdl = client.ipv4_src_vtep_table_add_with_src_vtep_hit( @@ -1299,10 +1320,10 @@ def delete_egress_vni(client, sess_hdl, dev, hdl): sess_hdl, dev, hdl) -def program_egress_vlan_xlate(client, sess_hdl, dev_tgt, port, bd, +def program_egress_vlan_xlate(client, sess_hdl, dev_tgt, ifindex, bd, ctag=None, stag=None): match_spec = dc_egress_vlan_xlate_match_spec_t( - standard_metadata_egress_port=port, + egress_metadata_ifindex=ifindex, egress_metadata_bd=bd) if ((ctag is not None) and (stag is None)): action_spec = dc_set_egress_packet_vlan_tagged_action_spec_t( diff --git a/tests/ptf-tests/common/sai_utils.py b/tests/ptf-tests/common/sai_utils.py index 6676dec..4079053 100644 --- a/tests/ptf-tests/common/sai_utils.py +++ b/tests/ptf-tests/common/sai_utils.py @@ -42,7 +42,7 @@ def sai_thrift_create_fdb(client, vlan_id, mac, port, mac_action): fdb_entry = sai_thrift_fdb_entry_t(mac_address=mac, vlan_id=vlan_id) #value 0 represents static entry, id=0, represents entry type - fdb_attribute1_value = sai_thrift_attribute_value_t(u8=SAI_FDB_ENTRY_STATIC) + fdb_attribute1_value = sai_thrift_attribute_value_t(s32=SAI_FDB_ENTRY_STATIC) fdb_attribute1 = sai_thrift_attribute_t(id=SAI_FDB_ENTRY_ATTR_TYPE, value=fdb_attribute1_value) #value oid represents object id, id=1 represents port id @@ -50,7 +50,7 @@ def sai_thrift_create_fdb(client, vlan_id, mac, port, mac_action): fdb_attribute2 = sai_thrift_attribute_t(id=SAI_FDB_ENTRY_ATTR_PORT_ID, value=fdb_attribute2_value) #value oid represents object id, id=1 represents port id - fdb_attribute3_value = sai_thrift_attribute_value_t(u8=mac_action) + fdb_attribute3_value = sai_thrift_attribute_value_t(s32=mac_action) fdb_attribute3 = sai_thrift_attribute_t(id=SAI_FDB_ENTRY_ATTR_PACKET_ACTION, value=fdb_attribute3_value) fdb_attr_list = [fdb_attribute1, fdb_attribute2, fdb_attribute3] @@ -64,7 +64,7 @@ def sai_thrift_flush_fdb_by_vlan(client, vlan_id): fdb_attribute1_value = sai_thrift_attribute_value_t(u16=vlan_id) fdb_attribute1 = sai_thrift_attribute_t(id=SAI_FDB_FLUSH_ATTR_VLAN_ID, value=fdb_attribute1_value) - fdb_attribute2_value = sai_thrift_attribute_value_t(u8=SAI_FDB_FLUSH_ENTRY_STATIC) + fdb_attribute2_value = sai_thrift_attribute_value_t(s32=SAI_FDB_FLUSH_ENTRY_STATIC) fdb_attribute2 = sai_thrift_attribute_t(id=SAI_FDB_FLUSH_ATTR_ENTRY_TYPE, value=fdb_attribute2_value) fdb_attr_list = [fdb_attribute1, fdb_attribute2] @@ -92,7 +92,7 @@ def sai_thrift_create_router_interface(client, vr_id, is_port, port_id, vlan_id, rif_attr_list.append(rif_attribute1) if is_port: #port type and port id - rif_attribute2_value = sai_thrift_attribute_value_t(u8=SAI_ROUTER_INTERFACE_TYPE_PORT) + rif_attribute2_value = sai_thrift_attribute_value_t(s32=SAI_ROUTER_INTERFACE_TYPE_PORT) rif_attribute2 = sai_thrift_attribute_t(id=SAI_ROUTER_INTERFACE_ATTR_TYPE, value=rif_attribute2_value) rif_attr_list.append(rif_attribute2) @@ -102,7 +102,7 @@ def sai_thrift_create_router_interface(client, vr_id, is_port, port_id, vlan_id, rif_attr_list.append(rif_attribute3) else: #vlan type and vlan id - rif_attribute2_value = sai_thrift_attribute_value_t(u8=SAI_ROUTER_INTERFACE_TYPE_VLAN) + rif_attribute2_value = sai_thrift_attribute_value_t(s32=SAI_ROUTER_INTERFACE_TYPE_VLAN) rif_attribute2 = sai_thrift_attribute_t(id=SAI_ROUTER_INTERFACE_ATTR_TYPE, value=rif_attribute2_value) rif_attr_list.append(rif_attribute2) @@ -201,7 +201,7 @@ def sai_thrift_remove_neighbor(client, addr_family, rif_id, ip_addr, dmac): client.sai_thrift_remove_neighbor_entry(neighbor_entry) def sai_thrift_create_next_hop_group(client, nhop_list): - nhop_group_attribute1_value = sai_thrift_attribute_value_t(u8=SAI_NEXT_HOP_GROUP_ECMP) + nhop_group_attribute1_value = sai_thrift_attribute_value_t(s32=SAI_NEXT_HOP_GROUP_ECMP) nhop_group_attribute1 = sai_thrift_attribute_t(id=SAI_NEXT_HOP_GROUP_ATTR_TYPE, value=nhop_group_attribute1_value) nhop_objlist = sai_thrift_object_list_t(count=len(nhop_list), object_id_list=nhop_list) @@ -418,7 +418,7 @@ def sai_thrift_create_acl_entry(client, acl_table_id, #Drop attribute_value = sai_thrift_attribute_value_t( aclfield = sai_thrift_acl_field_data_t( - data = sai_thrift_acl_data_t(u8 = packet_action))) + data = sai_thrift_acl_data_t(s32 = packet_action))) attribute = sai_thrift_attribute_t( id = SAI_ACL_ENTRY_ATTR_PACKET_ACTION, value=attribute_value) @@ -495,7 +495,7 @@ def sai_thrift_create_mirror_session(client, mirror_type, port, mirror_attr_list = [] #Mirror type - attribute1_value = sai_thrift_attribute_value_t(u8=mirror_type) + attribute1_value = sai_thrift_attribute_value_t(s32=mirror_type) attribute1 = sai_thrift_attribute_t(id=SAI_MIRROR_SESSION_ATTR_TYPE, value=attribute1_value) mirror_attr_list.append(attribute1) @@ -531,7 +531,7 @@ def sai_thrift_create_mirror_session(client, mirror_type, port, mirror_attr_list.append(attribute5) elif mirror_type == SAI_MIRROR_TYPE_ENHANCED_REMOTE: #encap type - attribute3_value = sai_thrift_attribute_value_t(u8=encap_type) + attribute3_value = sai_thrift_attribute_value_t(s32=encap_type) attribute3 = sai_thrift_attribute_t(id=SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE, value=attribute3_value) mirror_attr_list.append(attribute3) @@ -647,17 +647,17 @@ def sai_thrift_create_policer( attr_list = [] - attribute1_value = sai_thrift_attribute_value_t(u8=meter_type) + attribute1_value = sai_thrift_attribute_value_t(s32=meter_type) attribute1 = sai_thrift_attribute_t(id=SAI_POLICER_ATTR_METER_TYPE, value=attribute1_value) attr_list.append(attribute1) - attribute2_value = sai_thrift_attribute_value_t(u8=meter_mode) + attribute2_value = sai_thrift_attribute_value_t(s32=meter_mode) attribute2 = sai_thrift_attribute_t(id=SAI_POLICER_ATTR_MODE, value=attribute2_value) attr_list.append(attribute2) - attribute3_value = sai_thrift_attribute_value_t(u8=color_source) + attribute3_value = sai_thrift_attribute_value_t(s32=color_source) attribute3 = sai_thrift_attribute_t(id=SAI_POLICER_ATTR_COLOR_SOURCE, value=attribute3_value) attr_list.append(attribute3) @@ -682,17 +682,17 @@ def sai_thrift_create_policer( value=attribute7_value) attr_list.append(attribute7) - attribute8_value = sai_thrift_attribute_value_t(u8=green_action) + attribute8_value = sai_thrift_attribute_value_t(s32=green_action) attribute8 = sai_thrift_attribute_t(id=SAI_POLICER_ATTR_GREEN_PACKET_ACTION, value=attribute8_value) attr_list.append(attribute8) - attribute9_value = sai_thrift_attribute_value_t(u8=yellow_action) + attribute9_value = sai_thrift_attribute_value_t(s32=yellow_action) attribute9 = sai_thrift_attribute_t(id=SAI_POLICER_ATTR_YELLOW_PACKET_ACTION, value=attribute9_value) attr_list.append(attribute9) - attribute10_value = sai_thrift_attribute_value_t(u8=red_action) + attribute10_value = sai_thrift_attribute_value_t(s32=red_action) attribute10 = sai_thrift_attribute_t(id=SAI_POLICER_ATTR_RED_PACKET_ACTION, value=attribute10_value) attr_list.append(attribute10) diff --git a/tests/ptf-tests/pd-tests/switch.py b/tests/ptf-tests/pd-tests/switch.py index 3b8a8e7..3b60365 100644 --- a/tests/ptf-tests/pd-tests/switch.py +++ b/tests/ptf-tests/pd-tests/switch.py @@ -480,7 +480,7 @@ def runTest(self): tun_dmac = program_tunnel_dst_mac_rewrite(self.client, sess_hdl, dev_tgt, dmac_index, '00:55:55:55:55:55') tun_l2 = program_tunnel_l2_unicast_rewrite(self.client, sess_hdl, dev_tgt, tunnel_index, tunnel_type, nhop, core_vlan) tun_rewrite = program_tunnel_rewrite(self.client, sess_hdl, dev_tgt, tunnel_index, sip_index, dip_index, smac_index, dmac_index, core_vlan) - tun_svtep = program_tunnel_ipv4_src_vtep(self.client, sess_hdl, dev_tgt, vrf, 0x0a0a0a02, 0) + tun_svtep = program_tunnel_ipv4_src_vtep(self.client, sess_hdl, dev_tgt, vrf, 0x0a0a0a02, 1, 0) tun_dvtep = program_tunnel_ipv4_dst_vtep(self.client, sess_hdl, dev_tgt, vrf, 0x0a0a0a01, 1) tun_vni = program_egress_vni(self.client, sess_hdl, dev_tgt, egress_tunnel_type, tenant_vlan, vnid) @@ -670,7 +670,7 @@ def runTest(self): tun_dmac = program_tunnel_dst_mac_rewrite(self.client, sess_hdl, dev_tgt, dmac_index, '00:55:55:55:55:55') tun_l3 = program_tunnel_l3_unicast_rewrite(self.client, sess_hdl, dev_tgt, tunnel_index, egress_tunnel_type, nhop2, tenant_vlan2, '00:22:22:22:22:22') tun_rewrite = program_tunnel_rewrite(self.client, sess_hdl, dev_tgt, tunnel_index, sip_index, dip_index, smac_index, dmac_index, core_vlan) - tun_svtep = program_tunnel_ipv4_src_vtep(self.client, sess_hdl, dev_tgt, vrf, 0x0a0a0a02, 0) + tun_svtep = program_tunnel_ipv4_src_vtep(self.client, sess_hdl, dev_tgt, vrf, 0x0a0a0a02, 1, 0) tun_dvtep = program_tunnel_ipv4_dst_vtep(self.client, sess_hdl, dev_tgt, vrf, 0x0a0a0a01, 1) tun_vni = program_egress_vni(self.client, sess_hdl, dev_tgt, egress_tunnel_type, tenant_vlan2, vnid) diff --git a/tests/ptf-tests/sai-tests/switch.py b/tests/ptf-tests/sai-tests/switch.py index 24dd176..6b40af6 100644 --- a/tests/ptf-tests/sai-tests/switch.py +++ b/tests/ptf-tests/sai-tests/switch.py @@ -303,7 +303,7 @@ def runTest(self): class L3IPv4HostTest(sai_base_test.ThriftInterfaceDataPlane): def runTest(self): print - print "Sending packet port 1 -> port 2 (192.168.0.1 -> 10.10.10.1 [id = 101])" + print "Sending packet port 2 -> port 1 (192.168.0.1 -> 10.10.10.1 [id = 101])" switch_init(self.client) port1 = port_list[1] port2 = port_list[2] @@ -457,7 +457,7 @@ class L3IPv6LpmTest(sai_base_test.ThriftInterfaceDataPlane): def runTest(self): print print "IPv6 Lpm Test" - print "Sending packet port 1 -> port 2 (2000::1 -> 3000::1, routing with 3000::0/120 route" + print "Sending packet port 2 -> port 1 (2000::1 -> 1234:5678:9abc:def0:4422:1133:5577:9900, routing with 1234:5678:9abc:def0:4422:1133:5577:9900/120 route" switch_init(self.client) port1 = port_list[1] port2 = port_list[2] @@ -471,7 +471,7 @@ def runTest(self): rif_id2 = sai_thrift_create_router_interface(self.client, vr_id, 1, port2, 0, v4_enabled, v6_enabled, mac) addr_family = SAI_IP_ADDR_FAMILY_IPV6 - ip_addr1 = '1234:5678:9abc:def0:4422:1133:5577:9900' + ip_addr1 = '0034:5678:9abc:def0:4422:1133:5577:9900' ip_mask1 = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00' dmac1 = '00:11:22:33:44:55' nhop_ip1 = '3000::1' @@ -482,13 +482,13 @@ def runTest(self): # send the test packet(s) pkt = simple_tcpv6_packet( eth_dst='00:77:66:55:44:33', eth_src='00:22:22:22:22:22', - ipv6_dst='1234:5678:9abc:def0:4422:1133:5577:99aa', + ipv6_dst='0034:5678:9abc:def0:4422:1133:5577:99aa', ipv6_src='2000::1', ipv6_hlim=64) exp_pkt = simple_tcpv6_packet( eth_dst='00:11:22:33:44:55', eth_src='00:77:66:55:44:33', - ipv6_dst='1234:5678:9abc:def0:4422:1133:5577:99aa', + ipv6_dst='0034:5678:9abc:def0:4422:1133:5577:99aa', ipv6_src='2000::1', ipv6_hlim=63) try: @@ -1007,7 +1007,7 @@ def runTest(self): self.client.sai_thrift_create_vlan(vlan_id) - lag_id1 = self.client.sai_thrift_create_lag() + lag_id1 = self.client.sai_thrift_create_lag([]) lag_member1 = sai_thrift_create_lag_member(self.client, lag_id1, port1) lag_member2 = sai_thrift_create_lag_member(self.client, lag_id1, port2) lag_member3 = sai_thrift_create_lag_member(self.client, lag_id1, port3) @@ -1087,6 +1087,105 @@ def runTest(self): self.client.sai_thrift_remove_lag(lag_id1) self.client.sai_thrift_delete_vlan(vlan_id) +class L2LagMemberTest(sai_base_test.ThriftInterfaceDataPlane): + def runTest(self): + switch_init(self.client) + vlan_id = 10 + port1 = port_list[1] + port2 = port_list[2] + port3 = port_list[3] + port4 = port_list[4] + port5 = port_list[5] + mac1 = '00:11:11:11:11:11' + mac2 = '00:22:22:22:22:22' + mac_action = SAI_PACKET_ACTION_FORWARD + + self.client.sai_thrift_create_vlan(vlan_id) + + lag_id1 = self.client.sai_thrift_create_lag([]) + lag_member1 = sai_thrift_create_lag_member(self.client, lag_id1, port1) + lag_member2 = sai_thrift_create_lag_member(self.client, lag_id1, port2) + lag_member3 = sai_thrift_create_lag_member(self.client, lag_id1, port3) + lag_member4 = sai_thrift_create_lag_member(self.client, lag_id1, port4) + + vlan_port1 = sai_thrift_vlan_port_t(port_id=port1, tagging_mode=SAI_VLAN_PORT_UNTAGGED) + vlan_port2 = sai_thrift_vlan_port_t(port_id=port2, tagging_mode=SAI_VLAN_PORT_UNTAGGED) + vlan_port3 = sai_thrift_vlan_port_t(port_id=port3, tagging_mode=SAI_VLAN_PORT_UNTAGGED) + vlan_port4 = sai_thrift_vlan_port_t(port_id=port4, tagging_mode=SAI_VLAN_PORT_UNTAGGED) + vlan_port5 = sai_thrift_vlan_port_t(port_id=port5, tagging_mode=SAI_VLAN_PORT_UNTAGGED) + self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2, vlan_port3, vlan_port4, vlan_port5]) + + sai_thrift_create_fdb(self.client, vlan_id, mac1, lag_id1, mac_action) + sai_thrift_create_fdb(self.client, vlan_id, mac2, port5, mac_action) + + try: + count = [0, 0, 0, 0] + dst_ip = int(socket.inet_aton('10.10.10.1').encode('hex'),16) + max_itrs = 200 + for i in range(0, max_itrs): + dst_ip_addr = socket.inet_ntoa(hex(dst_ip)[2:].zfill(8).decode('hex')) + pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:22:22:22:22:22', + ip_dst=dst_ip_addr, + ip_src='192.168.8.1', + ip_id=109, + ip_ttl=64) + + exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:22:22:22:22:22', + ip_dst=dst_ip_addr, + ip_src='192.168.8.1', + ip_id=109, + ip_ttl=64) + + send_packet(self, 5, str(pkt)) + rcv_idx = verify_any_packet_any_port(self, [exp_pkt], [1, 2, 3, 4]) + count[rcv_idx] += 1 + dst_ip += 1 + + print count + for i in range(0, 4): + self.assertTrue((count[i] >= ((max_itrs / 4) * 0.8)), + "Not all paths are equally balanced") + + pkt = simple_tcp_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:22:22:22:22:22', + ip_dst='10.0.0.1', + ip_id=109, + ip_ttl=64) + exp_pkt = simple_tcp_packet(eth_src='00:11:11:11:11:11', + eth_dst='00:22:22:22:22:22', + ip_dst='10.0.0.1', + ip_id=109, + ip_ttl=64) + print "Sending packet port 1 (lag member) -> port 1" + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [5]) + print "Sending packet port 2 (lag member) -> port 1" + send_packet(self, 2, str(pkt)) + verify_packets(self, exp_pkt, [5]) + print "Sending packet port 3 (lag member) -> port 1" + send_packet(self, 3, str(pkt)) + verify_packets(self, exp_pkt, [5]) + print "Sending packet port 4 (lag member) -> port 1" + send_packet(self, 4, str(pkt)) + verify_packets(self, exp_pkt, [5]) + finally: + + sai_thrift_delete_fdb(self.client, vlan_id, mac1, lag_id1) + sai_thrift_delete_fdb(self.client, vlan_id, mac2, port5) + + self.client.sai_thrift_remove_ports_from_vlan(vlan_id, + [vlan_port1, vlan_port2, vlan_port3, vlan_port4, vlan_port5]) + + self.client.sai_thrift_remove_lag_member(lag_member1) + self.client.sai_thrift_remove_lag_member(lag_member2) + self.client.sai_thrift_remove_lag_member(lag_member3) + self.client.sai_thrift_remove_lag_member(lag_member4) + + self.client.sai_thrift_remove_lag(lag_id1) + self.client.sai_thrift_delete_vlan(vlan_id) + class L3IPv4LagTest(sai_base_test.ThriftInterfaceDataPlane): def runTest(self): switch_init(self.client) @@ -1099,7 +1198,7 @@ def runTest(self): vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) - lag_id1 = self.client.sai_thrift_create_lag() + lag_id1 = self.client.sai_thrift_create_lag([]) lag_member1 = sai_thrift_create_lag_member(self.client, lag_id1, port1) lag_member2 = sai_thrift_create_lag_member(self.client, lag_id1, port2) @@ -1157,7 +1256,7 @@ def runTest(self): vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) - lag_id1 = self.client.sai_thrift_create_lag() + lag_id1 = self.client.sai_thrift_create_lag([]) lag_member1 = sai_thrift_create_lag_member(self.client, lag_id1, port1) lag_member2 = sai_thrift_create_lag_member(self.client, lag_id1, port2) @@ -1217,12 +1316,12 @@ def runTest(self): vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) - lag_id1 = self.client.sai_thrift_create_lag() + lag_id1 = self.client.sai_thrift_create_lag([]) lag_member11 = sai_thrift_create_lag_member(self.client, lag_id1, port1) lag_member12 = sai_thrift_create_lag_member(self.client, lag_id1, port2) lag_member13 = sai_thrift_create_lag_member(self.client, lag_id1, port3) - lag_id2 = self.client.sai_thrift_create_lag() + lag_id2 = self.client.sai_thrift_create_lag([]) lag_member21 = sai_thrift_create_lag_member(self.client, lag_id2, port4) lag_member22 = sai_thrift_create_lag_member(self.client, lag_id2, port5) @@ -1944,6 +2043,7 @@ def runTest(self): inner_frame=pkt); print "Sending packet port 1 -> port 2 and port 3 (erspan mirror)" + send_packet(self, 1, str(pkt)) verify_erspan3_packet(self, exp_mirrored_pkt, 3) verify_packets(self, exp_pkt, [2]) From acc51dbbc25c5fb02a0c55b7fb4aef47245ec8c1 Mon Sep 17 00:00:00 2001 From: krishna Date: Thu, 14 Apr 2016 11:53:36 -0700 Subject: [PATCH 2/4] sflow pd init --- switchapi/src/switch_init.c | 1 + switchapi/src/switch_pd.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/switchapi/src/switch_init.c b/switchapi/src/switch_init.c index e2452fa..982a748 100644 --- a/switchapi/src/switch_init.c +++ b/switchapi/src/switch_init.c @@ -144,6 +144,7 @@ switch_api_init_default_entries(switch_device_t device) // Setup INT tables switch_pd_int_tables_init(device); #endif + switch_pd_sflow_tables_init(device); return SWITCH_STATUS_SUCCESS; } diff --git a/switchapi/src/switch_pd.c b/switchapi/src/switch_pd.c index a1e86c2..cc3c77e 100644 --- a/switchapi/src/switch_pd.c +++ b/switchapi/src/switch_pd.c @@ -9048,12 +9048,12 @@ switch_pd_switch_config_params_table_init (switch_device_t device) return switch_pd_switch_config_params_update(device); } -#ifdef P4_SFLOW_ENABLE // sFlow APIs p4_pd_status_t switch_pd_sflow_tables_init(switch_device_t device) { switch_status_t status = SWITCH_STATUS_SUCCESS; +#ifdef P4_SFLOW_ENABLE p4_pd_dev_target_t p4_pd_device; p4_pd_entry_hdl_t entry_hdl; @@ -9066,9 +9066,14 @@ switch_pd_sflow_tables_init(switch_device_t device) p4_pd_dc_sflow_ing_take_sample_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); +#else + (void)device; + return status; +#endif return status; } +#ifdef P4_SFLOW_ENABLE switch_status_t switch_pd_sflow_ingress_table_add (switch_device_t device, switch_sflow_match_key_t *match_key, From a77d6cf168c69793635ce816d35926298da34d4f Mon Sep 17 00:00:00 2001 From: krishna Date: Thu, 14 Apr 2016 20:22:27 -0700 Subject: [PATCH 3/4] addressing code review comments --- switchapi/inc/switchapi/switch_hostif.h | 13 ++++++++++- switchapi/src/switch_hostif.c | 2 +- switchapi/src/switch_hostif_int.h | 4 +--- switchapi/src/switch_packet.c | 31 +++++++++++-------------- switchapi/src/switch_packet_int.h | 2 +- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/switchapi/inc/switchapi/switch_hostif.h b/switchapi/inc/switchapi/switch_hostif.h index 135d511..3c30382 100644 --- a/switchapi/inc/switchapi/switch_hostif.h +++ b/switchapi/inc/switchapi/switch_hostif.h @@ -205,6 +205,17 @@ typedef enum switch_packet_vlan_action { SWITCH_PACKET_VLAN_SWAP = 0x3 } switch_packet_vlan_action_t; +typedef enum switch_tx_bypass_flags_ { + SWITCH_BYPASS_NONE = 0x0, + SWITCH_BYPASS_L2 = 1 << 0, + SWITCH_BYPASS_L3 = 1 << 1, + SWITCH_BYPASS_ACL = 1 << 2, + SWITCH_BYPASS_QOS = 1 << 3, + SWITCH_BYPASS_METER = 1 << 4, + SWITCH_BYPASS_SYSTEM_ACL = 1 << 5, + SWITCH_BYPASS_ALL = 0xFFFF +} switch_tx_bypass_flags_t; + typedef struct switch_packet_rx_key_ { bool port_valid; switch_handle_t port_handle; /**< port handle */ @@ -233,7 +244,7 @@ typedef struct switch_packet_tx_key_ { typedef struct switch_packet_tx_action_ { switch_handle_t handle; /**< bd or interface handle */ - bool tx_bypass; /**< tx bypass */ + switch_tx_bypass_flags_t bypass_flags; /**< bypass flags */ switch_handle_t port_handle; /**< egress port */ } switch_packet_tx_action_t; diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index 2b664e2..8e0ca45 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -773,7 +773,7 @@ switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char if ((rcode_info->rcode_api_info.reason_code == SWITCH_HOSTIF_REASON_CODE_NONE) || (rcode_info->rcode_api_info.channel == SWITCH_HOSTIF_CHANNEL_NETDEV)) { SWITCH_API_TRACE("Sending packet through netdev\n"); - switch_packet_tx_to_host(packet_header, packet, packet_size); + switch_packet_rx_to_host(packet_header, packet, packet_size); } return SWITCH_STATUS_SUCCESS; } diff --git a/switchapi/src/switch_hostif_int.h b/switchapi/src/switch_hostif_int.h index d107049..340766e 100644 --- a/switchapi/src/switch_hostif_int.h +++ b/switchapi/src/switch_hostif_int.h @@ -94,12 +94,10 @@ switch_status_t switch_hostif_free(switch_device_t device); switch_status_t switch_packet_init(switch_device_t device); switch_status_t switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char *packet, int packet_size); -switch_status_t -switch_api_hostif_rx_packet_from_host(switch_hostif_info_t *hostif_info, char *packet, int packet_size); switch_hostif_info_t * switch_hostif_get(switch_handle_t hostif_handle); void -switch_packet_tx_to_host( +switch_packet_rx_to_host( switch_packet_header_t *packet_header, char *packet, int packet_size); diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index c14f70d..da93355 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -122,10 +122,7 @@ switch_packet_tx_to_hw(switch_packet_header_t *packet_header, char *packet, int fabric_header->ether_type = htons(fabric_header->ether_type); fabric_header->dst_port_or_group = htons(fabric_header->dst_port_or_group); - /* - * TODO: bypass system acl for all cpu packets - */ - cpu_header->reason_code |= 0x20; + cpu_header->reason_code |= SWITCH_BYPASS_SYSTEM_ACL; cpu_header->reason_code = htons(cpu_header->reason_code); memcpy(out_packet, packet, SWITCH_PACKET_HEADER_OFFSET); @@ -186,18 +183,18 @@ switch_packet_rx_from_hw() } void -switch_packet_tx_to_host( +switch_packet_rx_to_host( switch_packet_header_t *packet_header, char *packet, int packet_size) { - static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; switch_cpu_header_t *cpu_header = NULL; - switch_packet_rx_entry_t rx_entry; switch_packet_rx_info_t *rx_info = NULL; - int intf_fd = 0; switch_ethernet_header_t *eth_header = NULL; switch_vlan_header_t *vlan_header = NULL; + static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + switch_packet_rx_entry_t rx_entry; + int intf_fd = 0; uint16_t offset = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -268,7 +265,7 @@ switch_packet_tx_to_host( } void -switch_packet_rx_from_host(int intf_fd) +switch_packet_tx_from_host(int intf_fd) { switch_hostif_info_t *hostif_info = NULL; int packet_size = 0; @@ -326,15 +323,15 @@ switch_packet_rx_from_host(int intf_fd) cpu_header = &packet_header.cpu_header; fabric_header = &packet_header.fabric_header; - if (tx_info->tx_bypass) { + if (tx_info->bypass_flags == SWITCH_BYPASS_ALL) { cpu_header->tx_bypass = TRUE; - cpu_header->reason_code = 0xFFFF; + cpu_header->reason_code = tx_info->bypass_flags; fabric_header->dst_port_or_group = tx_info->port; memcpy(packet, in_packet, in_packet_size); packet_size = in_packet_size; } else { cpu_header->tx_bypass = FALSE; - cpu_header->reason_code = 0x0; + cpu_header->reason_code = tx_info->bypass_flags; vlan_id1 = tx_info->bd & 0xFFF; vlan_id2 = (tx_info->bd & 0xF000) >> 12; @@ -541,7 +538,7 @@ switch_packet_select_fd_get(fd_set *read_fds) } static void -switch_packet_rx_from_hosts(fd_set read_fds) +switch_packet_tx_from_hosts(fd_set read_fds) { switch_hostif_info_t *hostif_info = NULL; void *temp = NULL; @@ -552,7 +549,7 @@ switch_packet_rx_from_hosts(fd_set read_fds) hostif_info = (switch_hostif_info_t *) (*(unsigned long *) temp); if (FD_ISSET(hostif_info->intf_fd, &read_fds)) { - switch_packet_rx_from_host(hostif_info->intf_fd); + switch_packet_tx_from_host(hostif_info->intf_fd); } JLN(temp, switch_intf_fd_array, index); } @@ -585,7 +582,7 @@ switch_packet_driver_thread(void *args) } else if (FD_ISSET(pipe_fd[0], &read_fds)) { switch_packet_read_from_pipe(); } else { - switch_packet_rx_from_hosts(read_fds); + switch_packet_tx_from_hosts(read_fds); } } } @@ -657,7 +654,7 @@ switch_api_packet_net_filter_tx_create( return SWITCH_STATUS_NO_MEMORY; } - if (!tx_action->tx_bypass) { + if (tx_action->bypass_flags != SWITCH_BYPASS_ALL) { bd_handle = tx_action->handle; handle_type = switch_handle_get_type(tx_action->handle); @@ -685,7 +682,7 @@ switch_api_packet_net_filter_tx_create( memcpy(&tx_info->tx_entry, &tx_entry, sizeof(tx_entry)); tx_info->bd = handle_to_id(bd_handle); - tx_info->tx_bypass = tx_action->tx_bypass; + tx_info->bypass_flags = tx_action->bypass_flags; tx_info->port = handle_to_id(tx_action->port_handle); tommy_list_insert_head(&packet_tx_list, &(tx_info->node), tx_info); diff --git a/switchapi/src/switch_packet_int.h b/switchapi/src/switch_packet_int.h index 490c04b..4e06c80 100644 --- a/switchapi/src/switch_packet_int.h +++ b/switchapi/src/switch_packet_int.h @@ -62,7 +62,7 @@ typedef struct switch_packet_tx_info_ { switch_packet_tx_entry_t tx_entry; tommy_node node; uint16_t bd; - bool tx_bypass; + switch_tx_bypass_flags_t bypass_flags; switch_port_t port; } switch_packet_tx_info_t; From 4fdb7b1632b6a937eebfcaad936a9cd2a4b5d492 Mon Sep 17 00:00:00 2001 From: krishna Date: Fri, 15 Apr 2016 11:10:52 -0700 Subject: [PATCH 4/4] addressing code review comments --- switchapi/src/switch_packet.c | 76 ++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index da93355..d0821b9 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -41,8 +41,8 @@ limitations under the License. #include "switchapi/switch_utils.h" pthread_t packet_driver_thread; -static tommy_list packet_rx_list; -static tommy_list packet_tx_list; +static tommy_list packet_rx_filter_list; +static tommy_list packet_tx_filter_list; static char *cpu_intf_name = "veth251"; static uint32_t cpu_ifindex = 0; @@ -55,8 +55,8 @@ switch_packet_init( switch_device_t device) { switch_status_t status = SWITCH_STATUS_SUCCESS; - tommy_list_init(&packet_rx_list); - tommy_list_init(&packet_tx_list); + tommy_list_init(&packet_rx_filter_list); + tommy_list_init(&packet_tx_filter_list); return status; } @@ -215,7 +215,6 @@ switch_packet_rx_to_host( } if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) { - memcpy(in_packet, packet, packet_size); eth_header = (switch_ethernet_header_t *) packet; if (ntohs(eth_header->ether_type) != SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { offset = 2 * ETH_LEN; @@ -224,33 +223,31 @@ switch_packet_rx_to_host( vlan_header->tpid = htons(SWITCH_ETHERTYPE_DOT1Q); uint16_t *vlan_h = (uint16_t *) (vlan_header) + 1; *vlan_h = htons(rx_info->vlan_id); - /* - vlan_header->pcp = 0; - vlan_header->dei = 0; - vlan_header->vid = htons(vid); - */ - memcpy(in_packet + offset + sizeof(switch_vlan_header_t), packet + offset, packet_size - offset); packet_size += sizeof(switch_vlan_header_t); + } else { + memcpy(in_packet, packet, packet_size); } } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_REMOVE) { - memcpy(in_packet, packet, packet_size); eth_header = (switch_ethernet_header_t *) packet; if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { offset = 2 * ETH_LEN; memcpy(in_packet, packet, offset); memcpy(in_packet, packet + offset, packet_size - offset); packet_size -= sizeof(switch_vlan_header_t); + } else { + memcpy(in_packet, packet, packet_size); } } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_SWAP) { - memcpy(in_packet, packet, packet_size); eth_header = (switch_ethernet_header_t *) packet; if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { offset = 2 * ETH_LEN; vlan_header = (switch_vlan_header_t *) (in_packet + offset); vlan_header->vid = htons(rx_info->vlan_id); + } else { + memcpy(in_packet, packet, packet_size); } } else { memcpy(in_packet, packet, packet_size); @@ -332,6 +329,13 @@ switch_packet_tx_from_host(int intf_fd) } else { cpu_header->tx_bypass = FALSE; cpu_header->reason_code = tx_info->bypass_flags; + /* + * In order to perform a fastpath lookup, bd has to be + * added as vlan tag(s) to the packet from host. + * bd is a 16 bit field whereas the vlan id is a 12 bit field. + * packets has to be double tagged when the bd value is more + * than 12 bits. + */ vlan_id1 = tx_info->bd & 0xFFF; vlan_id2 = (tx_info->bd & 0xF000) >> 12; @@ -596,7 +600,7 @@ int start_switch_api_packet_driver() } int32_t -switch_packet_tx_compare( +switch_packet_tx_filter_priority_compare( const void *key1, const void *key2) { @@ -634,6 +638,11 @@ switch_api_packet_net_filter_tx_create( switch_bd_info_t *bd_info = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (!tx_key || !tx_action) { + SWITCH_API_ERROR("filter tx create failed. invalid params"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + hostif_info = switch_hostif_get(tx_key->hostif_handle); if (!hostif_info) { SWITCH_API_ERROR("invalid hostif handle"); @@ -685,8 +694,8 @@ switch_api_packet_net_filter_tx_create( tx_info->bypass_flags = tx_action->bypass_flags; tx_info->port = handle_to_id(tx_action->port_handle); - tommy_list_insert_head(&packet_tx_list, &(tx_info->node), tx_info); - tommy_list_sort(&packet_tx_list, switch_packet_tx_compare); + tommy_list_insert_head(&packet_tx_filter_list, &(tx_info->node), tx_info); + tommy_list_sort(&packet_tx_filter_list, switch_packet_tx_filter_priority_compare); return status; } @@ -704,6 +713,11 @@ switch_api_packet_net_filter_tx_delete( bool node_found = FALSE; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (!tx_key) { + SWITCH_API_ERROR("filter tx delete failed. invalid params"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + hostif_info = switch_hostif_get(tx_key->hostif_handle); if (!hostif_info) { SWITCH_API_ERROR("invalid hostif handle"); @@ -715,7 +729,7 @@ switch_api_packet_net_filter_tx_delete( tx_entry.vlan_id = tx_key->vlan_id; tx_entry.priority = tx_key->priority; - node = tommy_list_head(&packet_tx_list); + node = tommy_list_head(&packet_tx_filter_list); while (node) { tmp_tx_info = (switch_packet_tx_info_t *) node->data; tmp_tx_entry = &tmp_tx_info->tx_entry; @@ -733,7 +747,7 @@ switch_api_packet_net_filter_tx_delete( return SWITCH_STATUS_ITEM_NOT_FOUND; } - tommy_list_remove_existing(&packet_tx_list, node); + tommy_list_remove_existing(&packet_tx_filter_list, node); switch_free(tx_info); return status; } @@ -780,6 +794,11 @@ switch_api_packet_net_filter_rx_create( switch_ifindex_t ifindex = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (!rx_key || !rx_action) { + SWITCH_API_ERROR("filter rx create failed. invalid params"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + memset(&rx_entry, 0x0, sizeof(rx_entry)); if (rx_key->port_lag_valid) { @@ -855,8 +874,12 @@ switch_api_packet_net_filter_rx_create( rx_info->vlan_action = rx_action->vlan_action; rx_info->intf_fd = hostif_info->intf_fd; - tommy_list_insert_head(&packet_rx_list, &(rx_info->node), rx_info); - tommy_list_sort(&packet_rx_list, switch_packet_rx_compare); + /* + * Adding an element to the list results in sorting the list. + * tommy does not have a way to compare and insert the elements + */ + tommy_list_insert_head(&packet_rx_filter_list, &(rx_info->node), rx_info); + tommy_list_sort(&packet_rx_filter_list, switch_packet_rx_compare); return status; } @@ -879,6 +902,11 @@ switch_api_packet_net_filter_rx_delete( bool node_found = FALSE; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (!rx_key) { + SWITCH_API_ERROR("filter rx delete failed. invalid params"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + handle_type = switch_handle_get_type(rx_key->port_lag_handle); if (handle_type == SWITCH_HANDLE_TYPE_LAG) { lag_info = switch_api_lag_get_internal(rx_key->port_lag_handle); @@ -917,7 +945,7 @@ switch_api_packet_net_filter_rx_delete( return SWITCH_STATUS_INVALID_HANDLE; } - node = tommy_list_head(&packet_rx_list); + node = tommy_list_head(&packet_rx_filter_list); while (node) { tmp_rx_info = (switch_packet_rx_info_t *) node->data; tmp_rx_entry = &tmp_rx_info->rx_entry; @@ -937,7 +965,7 @@ switch_api_packet_net_filter_rx_delete( return SWITCH_STATUS_ITEM_NOT_FOUND; } - tommy_list_remove_existing(&packet_rx_list, node); + tommy_list_remove_existing(&packet_rx_filter_list, node); switch_free(rx_info); return status; @@ -955,7 +983,7 @@ switch_packet_rx_info_get( *rx_info = NULL; - node = tommy_list_head(&packet_rx_list); + node = tommy_list_head(&packet_rx_filter_list); while (node) { tmp_rx_info = (switch_packet_rx_info_t *) node->data; tmp_rx_entry = &tmp_rx_info->rx_entry; @@ -989,7 +1017,7 @@ switch_packet_tx_info_get( *tx_info = NULL; - node = tommy_list_head(&packet_tx_list); + node = tommy_list_head(&packet_tx_filter_list); while (node) { tmp_tx_info = (switch_packet_tx_info_t *) node->data; tmp_tx_entry = &tmp_tx_info->tx_entry;