From 3e1a53d0ba2f4afa61a93d59e8a587e82cb3352c Mon Sep 17 00:00:00 2001 From: Aniketa Date: Tue, 7 Mar 2017 16:16:21 -0800 Subject: [PATCH 1/2] Egress ACL logging support Signed-off-by: Aniketa --- p4src/acl.p4 | 10 ++++ switchapi/include/switchapi/switch_acl.h | 2 + switchapi/include/switchapi/switch_hostif.h | 2 + switchapi/src/switch_acl.c | 3 +- switchapi/src/switch_hostif.c | 48 +++++++++++++++++ switchapi/src/switch_pd.c | 58 +++++++++++++++++++++ 6 files changed, 122 insertions(+), 1 deletion(-) diff --git a/p4src/acl.p4 b/p4src/acl.p4 index 0327690..e8b6d2d 100644 --- a/p4src/acl.p4 +++ b/p4src/acl.p4 @@ -706,6 +706,13 @@ action egress_acl_permit(acl_copy_reason) { modify_field(fabric_metadata.reason_code, acl_copy_reason); } +action egress_acl_redirect_nexthop(nexthop_index, acl_copy_reason) { + modify_field(acl_metadata.acl_redirect, TRUE); + modify_field(acl_metadata.acl_nexthop, nexthop_index); + modify_field(acl_metadata.acl_nexthop_type, NEXTHOP_TYPE_SIMPLE); + modify_field(fabric_metadata.reason_code, acl_copy_reason); +} + /*****************************************************************************/ /* Egress Mac ACL */ /*****************************************************************************/ @@ -724,6 +731,7 @@ table egress_mac_acl { nop; egress_acl_deny; egress_acl_permit; + egress_acl_redirect_nexthop; } size : EGRESS_MAC_ACL_TABLE_SIZE; } @@ -748,6 +756,7 @@ table egress_ip_acl { nop; egress_acl_deny; egress_acl_permit; + egress_acl_redirect_nexthop; } size : EGRESS_IP_ACL_TABLE_SIZE; } @@ -772,6 +781,7 @@ table egress_ipv6_acl { nop; egress_acl_deny; egress_acl_permit; + egress_acl_redirect_nexthop; } size : EGRESS_IPV6_ACL_TABLE_SIZE; } diff --git a/switchapi/include/switchapi/switch_acl.h b/switchapi/include/switchapi/switch_acl.h index 1ab05ce..94dd941 100644 --- a/switchapi/include/switchapi/switch_acl.h +++ b/switchapi/include/switchapi/switch_acl.h @@ -414,6 +414,7 @@ typedef enum switch_acl_egr_field_ { SWITCH_ACL_EGR_DEFLECT, SWITCH_ACL_EGR_L3_MTU_CHECK, SWITCH_ACL_EGR_ACL_DENY, + SWITCH_ACL_EGR_REASON_CODE, SWITCH_ACL_EGR_FIELD_MAX } switch_acl_egr_field_t; @@ -423,6 +424,7 @@ typedef union switch_acl_egr_value_ { bool deflection_flag; /**< deflection flag */ unsigned short l3_mtu_check; /**< L3 MTU check */ bool acl_deny; /**< acl deny */ + uint16_t reason_code; /**< hostif reason code */ } switch_acl_egr_value_t; /** Egress ACL match mask */ diff --git a/switchapi/include/switchapi/switch_hostif.h b/switchapi/include/switchapi/switch_hostif.h index 52be1ec..3774314 100644 --- a/switchapi/include/switchapi/switch_hostif.h +++ b/switchapi/include/switchapi/switch_hostif.h @@ -42,6 +42,8 @@ typedef enum switch_hostif_reason_code_ { SWITCH_HOSTIF_REASON_CODE_DROP = 0x2, SWITCH_HOSTIF_REASON_CODE_NULL_DROP = 0x3, SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE = 0x4, + SWITCH_HOSTIF_REASON_CODE_ACL_LOG_INGRESS = 0x5, + SWITCH_HOSTIF_REASON_CODE_ACL_LOG_EGRESS = 0x6, /* L2 reason codes 0x100 - 0x1FF */ SWITCH_HOSTIF_REASON_CODE_L2_START = 0x100, diff --git a/switchapi/src/switch_acl.c b/switchapi/src/switch_acl.c index e65b208..d7a43e8 100644 --- a/switchapi/src/switch_acl.c +++ b/switchapi/src/switch_acl.c @@ -779,7 +779,8 @@ switch_status_t switch_api_acl_rule_create( node = node->next; } } else { - if ((acl_info->type == SWITCH_ACL_TYPE_SYSTEM)) { + if ((acl_info->type == SWITCH_ACL_TYPE_SYSTEM) || + (acl_info->type == SWITCH_ACL_TYPE_EGRESS_SYSTEM)) { // update system ACL H/W entries acl_hw_set(device, acl_info, p, NULL, 0, ace_handle); } diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index 0f96b13..f09ba9c 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -1016,6 +1016,48 @@ switch_status_t switch_api_hostif_reason_code_create( rcode_info->acl_handle = SWITCH_API_INVALID_HANDLE; break; } + case SWITCH_HOSTIF_REASON_CODE_ACL_LOG_INGRESS: { + // Reasoncode is installed as part of different ACLs, which are created + // when user configures an ACL, the acl_handle is not stored here. + acl_handle = SWITCH_API_INVALID_HANDLE; + system_acl_handle = SWITCH_API_INVALID_HANDLE; + system_ace_handle = SWITCH_API_INVALID_HANDLE; + break; + } + case SWITCH_HOSTIF_REASON_CODE_ACL_LOG_EGRESS: { + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); + switch_acl_egr_key_value_pair_t + system_acl_kvp[SWITCH_ACL_EGR_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_EGR_REASON_CODE; + system_acl_kvp[field_count].value.reason_code = + rcode_api_info->reason_code; + system_acl_kvp[field_count].mask.u.mask = 0xFFFF; + field_count++; + acl_action = rcode_api_info->action; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); + hostif_group_info = + switch_hostif_group_get(rcode_api_info->hostif_group_id); + if (hostif_group_info) { + opt_action_params.meter_handle = hostif_group_info->policer_handle; + opt_action_params.queue_id = hostif_group_info->queue_id; + } + + switch_api_acl_rule_create(device, + system_acl_handle, + priority, + field_count, + system_acl_kvp, + acl_action, + &action_params, + &opt_action_params, + &system_ace_handle); + break; + } default: status = SWITCH_STATUS_NOT_SUPPORTED; break; @@ -1102,6 +1144,8 @@ switch_status_t switch_api_hostif_reason_code_delete( case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: case SWITCH_HOSTIF_REASON_CODE_PIM: case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: + case SWITCH_HOSTIF_REASON_CODE_ACL_LOG_INGRESS: + case SWITCH_HOSTIF_REASON_CODE_ACL_LOG_EGRESS: status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, 0); status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); status = switch_api_acl_rule_delete( @@ -1154,6 +1198,10 @@ const char *switch_api_hostif_code_string( return "igmpv2-report"; case SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE: return "sflow-sample"; + case SWITCH_HOSTIF_REASON_CODE_ACL_LOG_INGRESS: + return "acl-log-ingress"; + case SWITCH_HOSTIF_REASON_CODE_ACL_LOG_EGRESS: + return "acl-log-egress"; default: return "unknown"; } diff --git a/switchapi/src/switch_pd.c b/switchapi/src/switch_pd.c index 542857c..f4ed7bd 100644 --- a/switchapi/src/switch_pd.c +++ b/switchapi/src/switch_pd.c @@ -4609,6 +4609,8 @@ p4_pd_status_t switch_pd_ipv4_acl_table_add_entry( case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { p4_pd_dc_acl_redirect_nexthop_action_spec_t action_spec; memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; action_spec.action_acl_meter_index = meter_index; action_spec.action_acl_stats_index = stats_index; action_spec.action_nexthop_index = @@ -4733,6 +4735,22 @@ p4_pd_status_t switch_pd_egress_ipv4_acl_table_add_entry( &action_spec, entry_hdl); } break; + case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { + p4_pd_dc_egress_acl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + status = + p4_pd_dc_egress_ip_acl_table_add_with_egress_acl_redirect_nexthop( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; default: break; } @@ -4893,6 +4911,8 @@ p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { p4_pd_dc_acl_redirect_nexthop_action_spec_t action_spec; memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; action_spec.action_acl_meter_index = meter_index; action_spec.action_acl_stats_index = stats_index; action_spec.action_nexthop_index = @@ -5018,6 +5038,22 @@ p4_pd_status_t switch_pd_egress_ipv6_acl_table_add_entry( &action_spec, entry_hdl); } break; + case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { + p4_pd_dc_egress_acl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + status = + p4_pd_dc_egress_ipv6_acl_table_add_with_egress_acl_redirect_nexthop( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; default: break; } @@ -5559,6 +5595,22 @@ p4_pd_status_t switch_pd_egress_mac_acl_table_add_entry( &action_spec, entry_hdl); } break; + case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { + p4_pd_dc_egress_acl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + status = + p4_pd_dc_egress_mac_acl_table_add_with_egress_acl_redirect_nexthop( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; default: break; } @@ -5631,6 +5683,12 @@ p4_pd_status_t switch_pd_egr_acl_table_add_entry( match_spec.acl_metadata_acl_deny = egr_acl[i].value.acl_deny; match_spec.acl_metadata_acl_deny_mask = 0xFF; } break; + case SWITCH_ACL_EGR_REASON_CODE: { + match_spec.fabric_metadata_reason_code = + egr_acl[i].value.reason_code; + match_spec.fabric_metadata_reason_code_mask = + egr_acl[i].mask.u.mask & 0xFFFF; + } break; default: break; } From 900cac26ebc0869324edfb90885ccf5f8a26cd44 Mon Sep 17 00:00:00 2001 From: Aniketa Date: Tue, 7 Mar 2017 16:59:49 -0800 Subject: [PATCH 2/2] Fixes for sFlow - Honor length provided during sflow session create and limit length of packets provided to callback - Add a new field 'ingress_ifindex' to the callback structure Signed-off-by: Aniketa --- switchapi/include/switchapi/switch_hostif.h | 1 + switchapi/src/switch_hostif.c | 18 ++++++++++++++++-- switchapi/src/switch_sflow_int.h | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/switchapi/include/switchapi/switch_hostif.h b/switchapi/include/switchapi/switch_hostif.h index 3774314..57466a8 100644 --- a/switchapi/include/switchapi/switch_hostif.h +++ b/switchapi/include/switchapi/switch_hostif.h @@ -118,6 +118,7 @@ typedef struct switch_hostif_packet_ { bool is_lag; /**< handle is lag or port. used in rx */ switch_handle_t handle; /**< port or lag. used in tx/rx */ switch_ifindex_t egress_ifindex; /**< egress ifindex */ + switch_ifindex_t ingress_ifindex;/**< ingress ifindex */ uint16_t sflow_session_id; /**< sflow session id */ bool tx_bypass; /**< tx type flag to skip pipeline */ void *pkt; /**< packet buffer rx/tx */ diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index f09ba9c..1a13f84 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -26,6 +26,7 @@ limitations under the License. #include "switch_hostif_int.h" #include "switch_packet_int.h" #include "switch_nhop_int.h" +#include "switch_sflow_int.h" #include #ifdef __cplusplus @@ -1215,8 +1216,10 @@ switch_status_t switch_api_hostif_rx_packet_from_hw( switch_cpu_header_t *cpu_header = NULL; switch_sflow_header_t *sflow_header = NULL; switch_hostif_rcode_info_t *rcode_info = NULL; + switch_sflow_info_t *sflow_info = NULL; void *temp = NULL; switch_hostif_packet_t hostif_packet; + int extract_length = 0; memset(&hostif_packet, 0, sizeof(switch_hostif_packet_t)); cpu_header = &packet_header->cpu_header; @@ -1243,11 +1246,16 @@ switch_status_t switch_api_hostif_rx_packet_from_hw( hostif_packet.pkt_size = packet_size; hostif_packet.handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, cpu_header->ingress_port); + hostif_packet.ingress_ifindex = cpu_header->ingress_ifindex; if (cpu_header->reason_code == SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE) { sflow_header = &opt_header->sflow_header; hostif_packet.sflow_session_id = sflow_header->sflow_session_id; hostif_packet.egress_ifindex = sflow_header->sflow_egress_ifindex; + + switch_handle_t sflow_handle = id_to_handle(SWITCH_HANDLE_TYPE_SFLOW, hostif_packet.sflow_session_id); + sflow_info = ((switch_sflow_info_t *) switch_sflow_info_get(sflow_handle)); + extract_length = sflow_info->api_info.extract_len; } if (SWITCH_IS_LAG_IFINDEX(cpu_header->ingress_ifindex)) { @@ -1260,8 +1268,14 @@ switch_status_t switch_api_hostif_rx_packet_from_hw( switch_packet_rx_transform( packet_header, in_packet, packet, &packet_size); - hostif_packet.pkt_size = packet_size; - hostif_packet.pkt = in_packet; + if((extract_length > 0) && (extract_length < packet_size)) { + memcpy(hostif_packet.pkt, in_packet, extract_length); + hostif_packet.pkt_size = extract_length; + } + else { + hostif_packet.pkt_size = packet_size; + hostif_packet.pkt = in_packet; + } rx_packet(&hostif_packet); } } diff --git a/switchapi/src/switch_sflow_int.h b/switchapi/src/switch_sflow_int.h index 7bfca41..111b2d8 100644 --- a/switchapi/src/switch_sflow_int.h +++ b/switchapi/src/switch_sflow_int.h @@ -36,4 +36,5 @@ typedef struct switch_sflow_info_ { } switch_sflow_info_t; void switch_sflow_init(switch_device_t device); +switch_sflow_info_t *switch_sflow_info_get(switch_handle_t sflow_handle); #endif /*_SWITCH_SFLOW_INT_H_*/