From ad877b02258af2b76f04e06265a8d7af13020276 Mon Sep 17 00:00:00 2001 From: Parag Bhide Date: Thu, 21 Apr 2016 14:32:36 -0700 Subject: [PATCH 1/7] Net Rx filter fixes: - group reason codes to use reason-code bit mask - add reason_code mask in the filter key - simplify filter compare code --- p4src/includes/headers.p4 | 2 +- switchapi/inc/switchapi/switch_hostif.h | 90 ++++++++++++++----------- switchapi/src/switch_init.c | 5 +- switchapi/src/switch_packet.c | 39 ++++------- switchapi/src/switch_packet_int.h | 1 + 5 files changed, 69 insertions(+), 68 deletions(-) diff --git a/p4src/includes/headers.p4 b/p4src/includes/headers.p4 index 28648ef..3c6c833 100644 --- a/p4src/includes/headers.p4 +++ b/p4src/includes/headers.p4 @@ -508,7 +508,7 @@ header_type fabric_header_mirror_t { } } -#define CPU_REASON_CODE_SFLOW 0x106 // must match switch_hostif.h reson_code +#define CPU_REASON_CODE_SFLOW 0x4 // must match switch_hostif.h reson_code header_type fabric_header_cpu_t { fields { diff --git a/switchapi/inc/switchapi/switch_hostif.h b/switchapi/inc/switchapi/switch_hostif.h index 3c30382..9dc0e0d 100644 --- a/switchapi/inc/switchapi/switch_hostif.h +++ b/switchapi/inc/switchapi/switch_hostif.h @@ -31,46 +31,57 @@ extern "C" { /** switch hostif reason code */ typedef enum switch_hostif_reason_code_ { + /* + * Reason code groups must start on power of 2 boundary since + * rx_net_filters are setup to use masks + */ + /* generic reason codes 0x0-0x0FF */ SWITCH_HOSTIF_REASON_CODE_NONE = 0x0, - SWITCH_HOSTIF_REASON_CODE_STP = 0x1, - SWITCH_HOSTIF_REASON_CODE_LACP = 0x2, - SWITCH_HOSTIF_REASON_CODE_EAPOL = 0x3, - SWITCH_HOSTIF_REASON_CODE_LLDP = 0x4, - SWITCH_HOSTIF_REASON_CODE_PVRST = 0x5, - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_QUERY = 0x6, - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_LEAVE = 0x7, - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V1_REPORT = 0x8, - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT = 0x9, - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V3_REPORT = 0xa, - SWITCH_HOSTIF_REASON_CODE_SAMPLEPACKET = 0xb, - SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST = 0xc, - SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE = 0xd, - SWITCH_HOSTIF_REASON_CODE_DHCP = 0xe, - SWITCH_HOSTIF_REASON_CODE_OSPF = 0xf, - SWITCH_HOSTIF_REASON_CODE_PIM = 0x10, - SWITCH_HOSTIF_REASON_CODE_VRRP = 0x11, - SWITCH_HOSTIF_REASON_CODE_BGP = 0x12, - SWITCH_HOSTIF_REASON_CODE_DHCPV6 = 0x13, - SWITCH_HOSTIF_REASON_CODE_OSPFV6 = 0x14, - SWITCH_HOSTIF_REASON_CODE_VRRPV6 = 0x15, - SWITCH_HOSTIF_REASON_CODE_BGPV6 = 0x16, - SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY = 0x17, - SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_V2 = 0x18, - SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_REPORT = 0x19, - SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_DONE = 0x1a, - SWITCH_HOSTIF_REASON_CODE_MLD_V2_REPORT = 0x1b, - SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR = 0x1c, - SWITCH_HOSTIF_REASON_CODE_TTL_ERROR = 0x1d, - - SWITCH_HOSTIF_REASON_CODE_CUSTOM = 0x100, - SWITCH_HOSTIF_REASON_CODE_GLEAN = 0x101, - SWITCH_HOSTIF_REASON_CODE_MYIP = 0x102, - SWITCH_HOSTIF_REASON_CODE_DROP = 0x103, - SWITCH_HOSTIF_REASON_CODE_NULL_DROP = 0x103, - SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT = 0x104, - SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL = 0x105, - SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE = 0x106, /* must match the value in headers.p4 */ - SWITCH_HOSTIF_REASON_CODE_MAX = 0x200, + SWITCH_HOSTIF_REASON_CODE_CUSTOM = 0x1, + SWITCH_HOSTIF_REASON_CODE_DROP = 0x2, + SWITCH_HOSTIF_REASON_CODE_NULL_DROP = 0x3, + SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE = 0x4, /* must match the value in headers.p4 */ + + /* L2 reason codes 0x100 - 0x1FF */ + SWITCH_HOSTIF_REASON_CODE_L2_START = 0x100, + SWITCH_HOSTIF_REASON_CODE_STP = SWITCH_HOSTIF_REASON_CODE_L2_START, + SWITCH_HOSTIF_REASON_CODE_LACP, /* 0x101 */ + SWITCH_HOSTIF_REASON_CODE_EAPOL, /* 0x102 */ + SWITCH_HOSTIF_REASON_CODE_LLDP, /* 0x103 */ + SWITCH_HOSTIF_REASON_CODE_PVRST, /* 0x104 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_QUERY, /* 0x105 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_LEAVE, /* 0x106 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V1_REPORT, /* 0x107 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT, /* 0x108 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V3_REPORT, /* 0x109 */ + + /* L3 reason codes 0x200-0x2FF */ + SWITCH_HOSTIF_REASON_CODE_L3_START = 0x200, + SWITCH_HOSTIF_REASON_CODE_SAMPLEPACKET = SWITCH_HOSTIF_REASON_CODE_L3_START, + SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST, /* 0x201 */ + SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE, /* 0x202 */ + SWITCH_HOSTIF_REASON_CODE_DHCP, /* 0x203 */ + SWITCH_HOSTIF_REASON_CODE_OSPF, /* 0x204 */ + SWITCH_HOSTIF_REASON_CODE_PIM, /* 0x205 */ + SWITCH_HOSTIF_REASON_CODE_VRRP, /* 0x206 */ + SWITCH_HOSTIF_REASON_CODE_BGP, /* 0x207 */ + SWITCH_HOSTIF_REASON_CODE_DHCPV6, /* 0x208 */ + SWITCH_HOSTIF_REASON_CODE_OSPFV6, /* 0x209 */ + SWITCH_HOSTIF_REASON_CODE_VRRPV6, /* 0x20a */ + SWITCH_HOSTIF_REASON_CODE_BGPV6, /* 0x20b */ + SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY, /* 0x20c */ + SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_V2, /* 0x20d */ + SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_REPORT, /* 0x20e */ + SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_DONE, /* 0x20f */ + SWITCH_HOSTIF_REASON_CODE_MLD_V2_REPORT, /* 0x210 */ + SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR, /* 0x211 */ + SWITCH_HOSTIF_REASON_CODE_TTL_ERROR, /* 0x212 */ + SWITCH_HOSTIF_REASON_CODE_GLEAN, /* 0x213 */ + SWITCH_HOSTIF_REASON_CODE_MYIP, /* 0x214 */ + SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT, /* 0x215 */ + SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL, /* 0x216 */ + + SWITCH_HOSTIF_REASON_CODE_MAX, } switch_hostif_reason_code_t; /** switch channel */ @@ -225,6 +236,7 @@ typedef struct switch_packet_rx_key_ { switch_handle_t handle; /**< bd or interface handle */ bool reason_code_valid; switch_hostif_reason_code_t reason_code; /**< reason code */ + uint32_t reason_code_mask; /**< reason code mask */ uint32_t priority; } switch_packet_rx_key_t; diff --git a/switchapi/src/switch_init.c b/switchapi/src/switch_init.c index 982a748..7abcdde 100644 --- a/switchapi/src/switch_init.c +++ b/switchapi/src/switch_init.c @@ -446,12 +446,13 @@ switch_api_init_default_acl_entries(switch_device_t device) acl_kvp[1].mask.u.mask = 0xFFFFFFFF; memset(&action_params, 0, sizeof(switch_acl_action_params_t)); action_params.cpu_redirect.reason_code = 0; - switch_api_acl_rule_create(device, acl_handle, priority++, 2, + switch_api_acl_rule_create(device, acl_handle, + 2000, /* keep priority lower than reason-codes */ + 2, acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, &action_params, &opt_action_params, &handle); - // egress l3_mtu_check acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_EGRESS_SYSTEM); diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index d0821b9..651fbf3 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -614,13 +614,7 @@ switch_packet_tx_filter_priority_compare( 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; - } + return (int32_t)tx_entry1->priority - (int32_t)tx_entry2->priority; } switch_status_t @@ -767,13 +761,7 @@ switch_packet_rx_compare( 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; - } + return (int32_t)rx_entry1->priority - (int32_t)rx_entry2->priority; } switch_status_t @@ -987,14 +975,14 @@ switch_packet_rx_info_get( 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)) { + + if ((!tmp_rx_entry->port_valid || tmp_rx_entry->port == rx_entry->port) && + (!tmp_rx_entry->ifindex_valid || tmp_rx_entry->ifindex == rx_entry->ifindex) && + (!tmp_rx_entry->bd_valid || tmp_rx_entry->bd == rx_entry->bd) && + (!tmp_rx_entry->reason_code_valid || + (tmp_rx_entry->reason_code & tmp_rx_entry->reason_code_mask) == + (rx_entry->reason_code & tmp_rx_entry->reason_code_mask))) { + *rx_info = tmp_rx_info; status = SWITCH_STATUS_SUCCESS; break; @@ -1021,10 +1009,9 @@ switch_packet_tx_info_get( 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)) { + if ((!tmp_tx_entry->fd_valid || tmp_tx_entry->intf_fd == tx_entry->intf_fd) && + (!tmp_tx_entry->vlan_valid || tmp_tx_entry->vlan_id == tx_entry->vlan_id)) { + *tx_info = tmp_tx_info; status = SWITCH_STATUS_SUCCESS; break; diff --git a/switchapi/src/switch_packet_int.h b/switchapi/src/switch_packet_int.h index 4e06c80..4db4c21 100644 --- a/switchapi/src/switch_packet_int.h +++ b/switchapi/src/switch_packet_int.h @@ -38,6 +38,7 @@ typedef struct switch_packet_rx_entry_ { uint16_t bd; bool bd_valid; switch_hostif_reason_code_t reason_code; + uint32_t reason_code_mask; bool reason_code_valid; uint32_t priority; } switch_packet_rx_entry_t; From a60a8ff0434038f9a0ae0e8e52a9256ee10e8187 Mon Sep 17 00:00:00 2001 From: Parag Bhide Date: Mon, 25 Apr 2016 08:07:33 -0700 Subject: [PATCH 2/7] Fixes for net filters: - Fixes filter delete code - Cleanup based on earlier comments, create filter match routines that can be shared between delete and lookup - Add L3_REDIRECT reason code to identify packets sent to cpu using fib_redirect action --- p4src/includes/drop_reasons.h | 8 ++ p4src/includes/headers.p4 | 2 - p4src/nexthop.p4 | 2 + switchapi/inc/switchapi/switch_hostif.h | 1 + switchapi/src/switch_hostif.c | 4 + switchapi/src/switch_packet.c | 168 +++++++++++++++--------- 6 files changed, 118 insertions(+), 67 deletions(-) diff --git a/p4src/includes/drop_reasons.h b/p4src/includes/drop_reasons.h index ee4964b..38ce55c 100644 --- a/p4src/includes/drop_reasons.h +++ b/p4src/includes/drop_reasons.h @@ -45,3 +45,11 @@ limitations under the License. #define DROP_URPF_CHECK_FAIL 62 #define DROP_IPSG_MISS 63 #define DROP_IFINDEX 64 + +/* + * other reason codes shared between P4 program and APIs + * Must match the definitions in switch_hostif.h file + */ + +#define CPU_REASON_CODE_SFLOW 0x4 +#define CPU_REASON_CODE_L3_REDIRECT 0x217 diff --git a/p4src/includes/headers.p4 b/p4src/includes/headers.p4 index 3c6c833..a412acf 100644 --- a/p4src/includes/headers.p4 +++ b/p4src/includes/headers.p4 @@ -508,8 +508,6 @@ header_type fabric_header_mirror_t { } } -#define CPU_REASON_CODE_SFLOW 0x4 // must match switch_hostif.h reson_code - header_type fabric_header_cpu_t { fields { egressQueue : 5; diff --git a/p4src/nexthop.p4 b/p4src/nexthop.p4 index c88e577..54dec82 100644 --- a/p4src/nexthop.p4 +++ b/p4src/nexthop.p4 @@ -68,6 +68,8 @@ action set_fib_redirect_action() { modify_field(nexthop_metadata.nexthop_type, l3_metadata.fib_nexthop_type); modify_field(l3_metadata.routed, TRUE); modify_field(intrinsic_mcast_grp, 0); + /* set the reason code incase packet is redirected to cpu */ + modify_field(fabric_metadata.reason_code, CPU_REASON_CODE_L3_REDIRECT); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); #endif /* FABRIC_ENABLE */ diff --git a/switchapi/inc/switchapi/switch_hostif.h b/switchapi/inc/switchapi/switch_hostif.h index 9dc0e0d..3fd1550 100644 --- a/switchapi/inc/switchapi/switch_hostif.h +++ b/switchapi/inc/switchapi/switch_hostif.h @@ -80,6 +80,7 @@ typedef enum switch_hostif_reason_code_ { SWITCH_HOSTIF_REASON_CODE_MYIP, /* 0x214 */ SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT, /* 0x215 */ SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL, /* 0x216 */ + SWITCH_HOSTIF_REASON_CODE_L3_REDIRECT, /* 0x217 */ SWITCH_HOSTIF_REASON_CODE_MAX, } switch_hostif_reason_code_t; diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index 8e0ca45..8532e6b 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -557,6 +557,10 @@ switch_api_hostif_reason_code_create(switch_device_t device, rcode_info->acl_handle = SWITCH_API_INVALID_HANDLE; break; } + case SWITCH_HOSTIF_REASON_CODE_L3_REDIRECT: { + rcode_info->acl_handle = SWITCH_API_INVALID_HANDLE; + break; + } default: status = SWITCH_STATUS_NOT_SUPPORTED; break; diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index 651fbf3..a255908 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -599,6 +599,21 @@ int start_switch_api_packet_driver() return SWITCH_STATUS_SUCCESS; } +static bool +switch_packet_tx_filter_match(switch_packet_tx_entry_t *tx_entry1, + switch_packet_tx_entry_t *tx_entry2) +{ + // entry1 is the one stored in the filter list + // entry2 represents incoming packet, therefore all the valid + // bits and masks are used from entry1 + if ((!tx_entry1->fd_valid || (tx_entry1->intf_fd == tx_entry2->intf_fd)) && + (!tx_entry1->vlan_valid || (tx_entry1->vlan_id == tx_entry2->vlan_id))){ + // priority is not be compared so matching entry can be found + return TRUE; + } + return FALSE; +} + int32_t switch_packet_tx_filter_priority_compare( const void *key1, @@ -648,6 +663,7 @@ switch_api_packet_net_filter_tx_create( 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_entry.priority = tx_key->priority; tx_info = switch_malloc(sizeof(switch_packet_tx_info_t), 0x1); if (!tx_info) { @@ -694,14 +710,12 @@ switch_api_packet_net_filter_tx_create( } switch_status_t -switch_api_packet_net_filter_tx_delete( - switch_device_t device, - switch_packet_tx_key_t *tx_key) +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; @@ -712,24 +726,26 @@ switch_api_packet_net_filter_tx_delete( return SWITCH_STATUS_INVALID_PARAMETER; } - 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)); + if (tx_key->handle_valid) { + hostif_info = switch_hostif_get(tx_key->hostif_handle); + if (!hostif_info) { + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + tx_entry.intf_fd = hostif_info->intf_fd; } - 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; + if (tx_key->vlan_valid) { + tx_entry.vlan_id = tx_key->vlan_id; + } 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; - 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) { + + if (switch_packet_tx_filter_match(tmp_tx_entry, &tx_entry)) { node_found = TRUE; break; } @@ -742,12 +758,12 @@ switch_api_packet_net_filter_tx_delete( } tommy_list_remove_existing(&packet_tx_filter_list, node); - switch_free(tx_info); + switch_free(tmp_tx_info); return status; } int32_t -switch_packet_rx_compare( +switch_packet_rx_filter_priority_compare( const void *key1, const void *key2) { @@ -764,6 +780,27 @@ switch_packet_rx_compare( return (int32_t)rx_entry1->priority - (int32_t)rx_entry2->priority; } +static bool +switch_packet_rx_filter_match(switch_packet_rx_entry_t *rx_entry1, + switch_packet_rx_entry_t *rx_entry2) +{ + // entry1 is the one stored in the filter list + // entry2 represents incoming packet, therefore all the valid + // bits and masks are used from entry1 + if ((!rx_entry1->port_valid || rx_entry1->port == rx_entry2->port) && + (!rx_entry1->ifindex_valid || rx_entry1->ifindex == rx_entry2->ifindex) && + (!rx_entry1->bd_valid || rx_entry1->bd == rx_entry2->bd) && + (!rx_entry1->reason_code_valid || + (rx_entry1->reason_code & rx_entry1->reason_code_mask) == + (rx_entry2->reason_code & rx_entry1->reason_code_mask))) { + // priority is not be compared so matching entry can be found + // use reason_code mask from entry1 + return TRUE; + } + return FALSE; + +} + switch_status_t switch_api_packet_net_filter_rx_create( switch_device_t device, @@ -841,10 +878,11 @@ switch_api_packet_net_filter_rx_create( 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.port = handle_to_id(rx_key->port_handle); rx_entry.reason_code_valid = rx_key->reason_code_valid; + rx_entry.reason_code = rx_key->reason_code; + rx_entry.reason_code_mask = rx_key->reason_code_mask; rx_entry.priority = rx_key->priority; rx_info = switch_malloc(sizeof(switch_packet_rx_info_t), 0x1); @@ -867,7 +905,7 @@ switch_api_packet_net_filter_rx_create( * 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); + tommy_list_sort(&packet_rx_filter_list, switch_packet_rx_filter_priority_compare); return status; } @@ -879,8 +917,8 @@ switch_api_packet_net_filter_rx_delete( 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_entry_t rx_entry; 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; @@ -895,53 +933,61 @@ switch_api_packet_net_filter_rx_delete( 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); - 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; + memset(&rx_entry, 0, sizeof(switch_packet_rx_entry_t)); + + if (rx_key->port_lag_valid && rx_key->port_lag_handle) { + 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; + } + rx_entry.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; + } + rx_entry.ifindex = port_info->ifindex; } - 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 (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; } - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - SWITCH_API_ERROR("intf_handle %lx is not l3", rx_key->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; } - bd_handle = intf_info->bd_handle; + rx_entry.bd = handle_to_id(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; + if (rx_entry.port_valid) { + rx_entry.port == handle_to_id(rx_key->port_handle); } + rx_entry.bd_valid = rx_key->handle_valid; + rx_entry.reason_code = rx_key->reason_code; 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; - 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) { + if (switch_packet_rx_filter_match(tmp_rx_entry, &rx_entry)) { node_found = TRUE; break; } @@ -955,7 +1001,7 @@ switch_api_packet_net_filter_rx_delete( tommy_list_remove_existing(&packet_rx_filter_list, node); - switch_free(rx_info); + switch_free(tmp_rx_info); return status; } @@ -976,13 +1022,7 @@ switch_packet_rx_info_get( 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->ifindex_valid || tmp_rx_entry->ifindex == rx_entry->ifindex) && - (!tmp_rx_entry->bd_valid || tmp_rx_entry->bd == rx_entry->bd) && - (!tmp_rx_entry->reason_code_valid || - (tmp_rx_entry->reason_code & tmp_rx_entry->reason_code_mask) == - (rx_entry->reason_code & tmp_rx_entry->reason_code_mask))) { - + if (switch_packet_rx_filter_match(tmp_rx_entry, rx_entry)) { *rx_info = tmp_rx_info; status = SWITCH_STATUS_SUCCESS; break; @@ -1009,9 +1049,7 @@ switch_packet_tx_info_get( 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->vlan_valid || tmp_tx_entry->vlan_id == tx_entry->vlan_id)) { - + if (switch_packet_tx_filter_match(tmp_tx_entry, tx_entry)) { *tx_info = tmp_tx_info; status = SWITCH_STATUS_SUCCESS; break; From b97681676cad86eeacbe77d27a42b73843c825fb Mon Sep 17 00:00:00 2001 From: Parag Bhide Date: Tue, 26 Apr 2016 17:46:48 -0700 Subject: [PATCH 3/7] Add apis to register external logger function. This allows switchapi logs to be integrated with customer's logging infra --- switchapi/{src => inc/switchapi}/switch_log.h | 22 +++++++---- switchapi/src/switch_config.c | 2 +- switchapi/src/switch_hostif.c | 8 +++- switchapi/src/switch_init.c | 3 +- switchapi/src/switch_interface.c | 2 +- switchapi/src/switch_l2.c | 2 +- switchapi/src/switch_l3.c | 2 +- switchapi/src/switch_lag.c | 2 +- switchapi/src/switch_log.c | 35 ++++++++++++++++- switchapi/src/switch_log_int.h | 38 +++++++++++++++++++ switchapi/src/switch_mcast.c | 2 +- switchapi/src/switch_meter.c | 2 +- switchapi/src/switch_mirror.c | 2 +- switchapi/src/switch_neighbor.c | 2 +- switchapi/src/switch_nhop.c | 2 +- switchapi/src/switch_packet.c | 21 ++++++++-- switchapi/src/switch_pd.c | 2 +- switchapi/src/switch_rmac.c | 2 +- switchapi/src/switch_stp.c | 2 +- switchapi/src/switch_tunnel.c | 2 +- switchapi/src/switch_vlan.c | 2 +- 21 files changed, 128 insertions(+), 29 deletions(-) rename switchapi/{src => inc/switchapi}/switch_log.h (54%) create mode 100644 switchapi/src/switch_log_int.h diff --git a/switchapi/src/switch_log.h b/switchapi/inc/switchapi/switch_log.h similarity index 54% rename from switchapi/src/switch_log.h rename to switchapi/inc/switchapi/switch_log.h index 23f7604..da04a63 100644 --- a/switchapi/src/switch_log.h +++ b/switchapi/inc/switchapi/switch_log.h @@ -1,5 +1,5 @@ /* -Copyright 2013-present Barefoot Networks, Inc. +Copyright 2016-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,14 +13,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +#ifndef _SWITCH_LOG_H_ +#define _SWITCH_LOG_H_ #include "p4features.h" #include -#define SWITCH_API_ERROR printf -#define SWITCH_API_WARN printf -#define SWITCH_API_INFO printf -#define SWITCH_API_VERBOSE printf -#define SWITCH_API_TRACE printf +typedef enum switch_api_log_levels_ { + SWITCH_API_LOG_NONE = 0, + SWITCH_API_LOG_ERROR, + SWITCH_API_LOG_WARN, + SWITCH_API_LOG_INFO, + SWITCH_API_LOG_VERBOSE, + SWITCH_API_LOG_TRACE, +} switch_api_log_level_t; -char * switch_print_error(switch_status_t status); +typedef int (switch_api_log_fn_t)(switch_api_log_level_t level, char *fmt, ...); +void switch_api_log_function_set(switch_api_log_fn_t *log_fn); + +#endif /* _SWITCH_LOG_H_ */ diff --git a/switchapi/src/switch_config.c b/switchapi/src/switch_config.c index 2f1eb55..3e3a929 100644 --- a/switchapi/src/switch_config.c +++ b/switchapi/src/switch_config.c @@ -16,7 +16,7 @@ limitations under the License. #include "p4features.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_lag_int.h" #include "switch_nhop_int.h" #include "switch_defines.h" diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index 8532e6b..c0b551d 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -21,7 +21,7 @@ limitations under the License. #include "switchapi/switch_nhop.h" #include "switchapi/switch_mirror.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_hostif_int.h" #include "switch_packet_int.h" #include "switch_nhop_int.h" @@ -741,6 +741,8 @@ switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char JLG(temp, switch_hostif_rcode_array, cpu_header->reason_code); if (!temp) { + SWITCH_API_ERROR("rx_packet w/ un-handled reason_code 0x%x\n", + cpu_header->reason_code); return SWITCH_STATUS_ITEM_NOT_FOUND; } @@ -749,13 +751,15 @@ 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); - + +#if 0 /* seems un-necessary check and failing for vlan 0 - checking it */ 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; } +#endif if ((rcode_info->rcode_api_info.reason_code == SWITCH_HOSTIF_REASON_CODE_NONE) || (rcode_info->rcode_api_info.channel == SWITCH_HOSTIF_CHANNEL_CB)) { diff --git a/switchapi/src/switch_init.c b/switchapi/src/switch_init.c index 7abcdde..9a58c57 100644 --- a/switchapi/src/switch_init.c +++ b/switchapi/src/switch_init.c @@ -26,7 +26,7 @@ limitations under the License. #include "switch_neighbor_int.h" #include "switch_lag_int.h" #include "switch_stp_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_port_int.h" #include "switch_tunnel_int.h" #include "switch_acl_int.h" @@ -52,6 +52,7 @@ static pthread_t stats_thread; switch_status_t switch_api_lib_init(switch_device_t device) { + switch_log_init(); SWITCH_API_TRACE("Initializing switch api!!"); switch_pd_client_init(device); switch_router_mac_init(device); diff --git a/switchapi/src/switch_interface.c b/switchapi/src/switch_interface.c index afa2ef7..cbc6add 100644 --- a/switchapi/src/switch_interface.c +++ b/switchapi/src/switch_interface.c @@ -26,7 +26,7 @@ limitations under the License. #include "switch_lag_int.h" #include "switch_pd.h" #include "switch_hostif_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_capability_int.h" #include diff --git a/switchapi/src/switch_l2.c b/switchapi/src/switch_l2.c index 1265ad0..858ac75 100644 --- a/switchapi/src/switch_l2.c +++ b/switchapi/src/switch_l2.c @@ -23,7 +23,7 @@ limitations under the License. #include "switch_nhop_int.h" #include "switch_neighbor_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include diff --git a/switchapi/src/switch_l3.c b/switchapi/src/switch_l3.c index 7bb6032..2c47ab9 100644 --- a/switchapi/src/switch_l3.c +++ b/switchapi/src/switch_l3.c @@ -24,7 +24,7 @@ limitations under the License. #include "switch_nhop_int.h" #include "switch_l3_int.h" #include "switch_hostif_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "arpa/inet.h" #include #include diff --git a/switchapi/src/switch_lag.c b/switchapi/src/switch_lag.c index 3256c1e..12defaf 100644 --- a/switchapi/src/switch_lag.c +++ b/switchapi/src/switch_lag.c @@ -19,7 +19,7 @@ limitations under the License. #include "switchapi/switch_port.h" #include "switch_lag_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include #ifdef __cplusplus diff --git a/switchapi/src/switch_log.c b/switchapi/src/switch_log.c index 7a4cf29..abc4104 100644 --- a/switchapi/src/switch_log.c +++ b/switchapi/src/switch_log.c @@ -15,7 +15,11 @@ limitations under the License. */ #include "p4features.h" -#include "switch_log.h" +#include "switch_log_int.h" +#include + +switch_api_log_fn_t *switch_api_client_log_fn = NULL; +switch_api_log_level_t switch_api_default_log_level = SWITCH_API_LOG_INFO; char * switch_print_error(switch_status_t status) { @@ -34,3 +38,32 @@ char * switch_print_error(switch_status_t status) break; } } + +int +switch_default_logger(switch_api_log_level_t level, char *fmt, ...) +{ + va_list args; + + if ((switch_api_default_log_level == SWITCH_API_LOG_NONE) || + (level > switch_api_default_log_level)) { + return 0; + } + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + return 1; +} + +void +switch_api_log_function_set(switch_api_log_fn_t *log_fn) +{ + switch_api_client_log_fn = log_fn; +} + +void +switch_log_init() +{ + switch_api_default_log_level = SWITCH_API_LOG_INFO; + switch_api_client_log_fn = switch_default_logger; +} diff --git a/switchapi/src/switch_log_int.h b/switchapi/src/switch_log_int.h new file mode 100644 index 0000000..784dd4d --- /dev/null +++ b/switchapi/src/switch_log_int.h @@ -0,0 +1,38 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _SWITCH_LOG_INT_H_ +#define _SWITCH_LOG_INT_H_ + +#include "p4features.h" +#include +#include + +void switch_log_init(); + +extern switch_api_log_fn_t *switch_api_client_log_fn; + +#define SWITCH_API_ERROR(...) \ + switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_ERROR, __VA_ARGS__); +#define SWITCH_API_WARN(...) \ + switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_WARN, __VA_ARGS__); +#define SWITCH_API_INFO(...) \ + switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_INFO, __VA_ARGS__); +#define SWITCH_API_VERBOSE(...) \ + switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_VERBOSE, __VA_ARGS__); +#define SWITCH_API_TRACE(...) \ + switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_TRACE, __VA_ARGS__); + +#endif /*_SWITCH_LOG_INT_H_ */ diff --git a/switchapi/src/switch_mcast.c b/switchapi/src/switch_mcast.c index f2ffe4c..17ee257 100644 --- a/switchapi/src/switch_mcast.c +++ b/switchapi/src/switch_mcast.c @@ -25,7 +25,7 @@ limitations under the License. #include "switch_lag_int.h" #include "switch_tunnel_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include #define SWITCH_MGID_TABLE_SIZE 16 * 1024 diff --git a/switchapi/src/switch_meter.c b/switchapi/src/switch_meter.c index 0a3f850..29366e8 100644 --- a/switchapi/src/switch_meter.c +++ b/switchapi/src/switch_meter.c @@ -18,7 +18,7 @@ limitations under the License. #include "switchapi/switch_status.h" #include "switch_meter_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" static void *switch_meter_array = NULL; diff --git a/switchapi/src/switch_mirror.c b/switchapi/src/switch_mirror.c index 45b3264..bc4e28f 100644 --- a/switchapi/src/switch_mirror.c +++ b/switchapi/src/switch_mirror.c @@ -20,7 +20,7 @@ limitations under the License. #include "switch_mirror_int.h" #include "switch_nhop_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_capability_int.h" static void *switch_mirror_array = NULL; diff --git a/switchapi/src/switch_neighbor.c b/switchapi/src/switch_neighbor.c index f1b48cd..122312a 100644 --- a/switchapi/src/switch_neighbor.c +++ b/switchapi/src/switch_neighbor.c @@ -25,7 +25,7 @@ limitations under the License. #include "switch_interface_int.h" #include "switch_nhop_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_defines.h" #include diff --git a/switchapi/src/switch_nhop.c b/switchapi/src/switch_nhop.c index df647b9..efae147 100644 --- a/switchapi/src/switch_nhop.c +++ b/switchapi/src/switch_nhop.c @@ -25,7 +25,7 @@ limitations under the License. #include "switch_neighbor_int.h" #include "switch_hostif_int.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #ifdef __cplusplus extern "C" { diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index a255908..64f7fa5 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -35,7 +35,7 @@ limitations under the License. #include "switch_vlan_int.h" #include "switch_port_int.h" #include "switch_lag_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #include #include #include "switchapi/switch_utils.h" @@ -214,6 +214,8 @@ switch_packet_rx_to_host( return; } + SWITCH_API_INFO("Rx packet reason_code 0x%x - send to fd %d, action %d\n", + rx_entry.reason_code, rx_info->intf_fd, rx_info->vlan_action); if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) { eth_header = (switch_ethernet_header_t *) packet; if (ntohs(eth_header->ether_type) != SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { @@ -431,8 +433,8 @@ switch_packet_hostif_create(switch_device_t device, switch_hostif_info_t *hostif int sock_flags = 0; char *intf_name = NULL; void *temp = NULL; - switch_api_capability_t api_switch_info; - switch_mac_addr_t mac; + switch_api_capability_t api_switch_info; + switch_mac_addr_t mac; switch_api_capability_get(device, &api_switch_info); @@ -704,6 +706,10 @@ 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); + SWITCH_API_INFO("net_filter_tx_create: hostif 0x%x, vlan_id = %d, fd 0x%x, bypass 0x%x\n", + tx_key->hostif_handle, tx_key->vlan_valid ? tx_key->vlan_id : 0xFFF, + tx_entry.intf_fd, tx_info->bypass_flags); + 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; @@ -900,6 +906,15 @@ switch_api_packet_net_filter_rx_create( rx_info->vlan_action = rx_action->vlan_action; rx_info->intf_fd = hostif_info->intf_fd; + SWITCH_API_INFO("net_filter_rx_create: port 0x%x, port_lag_hdl = 0x%x, " + "if_bd_hdl 0x%x, rcode 0x%x, rcode_mask 0x%x " + "vlan_id %d, fd %d, action %d\n", + rx_key->port_valid ? rx_key->port_handle : 0, + rx_key->port_lag_valid ? rx_key->port_lag_handle : 0, + rx_key->handle_valid ? rx_key->handle : 0, + rx_key->reason_code_valid ? rx_key->reason_code : 0, + rx_key->reason_code_mask, + rx_info->vlan_id, rx_info->vlan_action, rx_info->intf_fd); /* * Adding an element to the list results in sorting the list. * tommy does not have a way to compare and insert the elements diff --git a/switchapi/src/switch_pd.c b/switchapi/src/switch_pd.c index cc3c77e..4fe4008 100644 --- a/switchapi/src/switch_pd.c +++ b/switchapi/src/switch_pd.c @@ -16,7 +16,7 @@ limitations under the License. #include "p4features.h" #include "switch_pd.h" -#include "switch_log.h" +#include "switch_log_int.h" #include "switch_lag_int.h" #include "switch_nhop_int.h" #include "switch_defines.h" diff --git a/switchapi/src/switch_rmac.c b/switchapi/src/switch_rmac.c index f481fb9..177cce7 100644 --- a/switchapi/src/switch_rmac.c +++ b/switchapi/src/switch_rmac.c @@ -21,7 +21,7 @@ limitations under the License. #include "switchapi/switch_utils.h" #include "switch_pd.h" #include "switch_rmac_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #ifdef __cplusplus extern "C" { diff --git a/switchapi/src/switch_stp.c b/switchapi/src/switch_stp.c index 6675b3d..48a3727 100644 --- a/switchapi/src/switch_stp.c +++ b/switchapi/src/switch_stp.c @@ -20,7 +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 "switch_log_int.h" #include #ifdef __cplusplus diff --git a/switchapi/src/switch_tunnel.c b/switchapi/src/switch_tunnel.c index b46ec83..2115263 100644 --- a/switchapi/src/switch_tunnel.c +++ b/switchapi/src/switch_tunnel.c @@ -23,7 +23,7 @@ limitations under the License. #include "switch_pd.h" #include "switch_interface_int.h" #include "switch_tunnel_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #include #include diff --git a/switchapi/src/switch_vlan.c b/switchapi/src/switch_vlan.c index 06c5d12..1a65bef 100644 --- a/switchapi/src/switch_vlan.c +++ b/switchapi/src/switch_vlan.c @@ -22,7 +22,7 @@ limitations under the License. #include "switchapi/switch_utils.h" #include "switch_pd.h" #include "switch_lag_int.h" -#include "switch_log.h" +#include "switch_log_int.h" #ifdef __cplusplus extern "C" { From 8964d5da29d1c2f24b8461d58d4fbcaf151477b5 Mon Sep 17 00:00:00 2001 From: krishna Date: Wed, 31 Aug 2016 09:12:26 -0700 Subject: [PATCH 4/7] remove ocpsai repo references from switch --- .gitmodules | 3 --- switchsai/.gitmodules | 3 --- switchsai/submodules/ocpsai | 1 - 3 files changed, 7 deletions(-) delete mode 100644 switchsai/.gitmodules delete mode 160000 switchsai/submodules/ocpsai diff --git a/.gitmodules b/.gitmodules index d3cfc28..bcd6a83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "switchsai/submodules/SAI"] path = switchsai/submodules/SAI url = https://github.com/p4lang/SAI -[submodule "switchsai/submodules/ocpsai"] - path = switchsai/submodules/ocpsai - url = https://github.com/p4lang/ocpsai.git diff --git a/switchsai/.gitmodules b/switchsai/.gitmodules deleted file mode 100644 index 0b05a0b..0000000 --- a/switchsai/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "submodules/ocpsai"] - path = submodules/ocpsai - url = https://github.com/p4lang/ocpsai.git diff --git a/switchsai/submodules/ocpsai b/switchsai/submodules/ocpsai deleted file mode 160000 index 6a45573..0000000 --- a/switchsai/submodules/ocpsai +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a45573e1b4272e0e365e5018657fbb14f7854a7 From e05958957c60fe34792a066813dfbfff3f1cfb6a Mon Sep 17 00:00:00 2001 From: srikrishnagopu Date: Thu, 8 Sep 2016 17:55:43 -0700 Subject: [PATCH 5/7] Ops qos nat copp (#62) * qos, nat and copp support from p4lang * remove sflow header for cpu rx bound packets --- .clang-format | 8 + README.md | 6 +- p4src/.clang-format | 3 + p4src/acl.p4 | 265 +- p4src/fabric.p4 | 14 +- p4src/hashes.p4 | 4 + p4src/includes/cpu_reason_codes.h | 23 + p4src/includes/defines.p4 | 4 + p4src/includes/drop_reason_codes.h | 50 + p4src/includes/headers.p4 | 4 +- p4src/includes/intrinsic.p4 | 9 + p4src/includes/{sizes.p4 => p4_table_sizes.h} | 14 +- p4src/ipv4.p4 | 6 +- p4src/ipv6.p4 | 6 +- p4src/l2.p4 | 26 +- p4src/l3.p4 | 18 +- p4src/meter.p4 | 6 +- p4src/mirror.p4 | 6 + p4src/multicast.p4 | 16 +- p4src/nat.p4 | 246 + p4src/nexthop.p4 | 38 +- p4src/port.p4 | 34 +- p4src/qos.p4 | 163 + p4src/security.p4 | 11 +- p4src/sflow.p4 | 13 +- p4src/switch.p4 | 54 +- p4src/switch_config.p4 | 4 +- p4src/tunnel.p4 | 237 +- switchapi/Makefile.am | 78 +- switchapi/README.md | 9 +- switchapi/inc/switchapi/switch_INT.h | 55 - switchapi/inc/switchapi/switch_acl.h | 624 - switchapi/inc/switchapi/switch_capability.h | 121 - switchapi/inc/switchapi/switch_handle.h | 227 - switchapi/inc/switchapi/switch_hostif.h | 292 - switchapi/inc/switchapi/switch_interface.h | 302 - switchapi/inc/switchapi/switch_l3.h | 157 - switchapi/inc/switchapi/switch_mirror.h | 148 - switchapi/inc/switchapi/switch_port.h | 317 - switchapi/inc/switchapi/switch_porting.h | 123 - switchapi/inc/switchapi/switch_protocol.h | 215 - switchapi/inc/switchapi/switch_sflow.h | 96 - switchapi/inc/switchapi/switch_status.h | 186 - switchapi/inc/switchapi/switch_tunnel.h | 160 - switchapi/include/switchapi/switch_INT.h | 50 + switchapi/include/switchapi/switch_acl.h | 606 + .../switchapi/switch_base_types.h | 86 +- switchapi/include/switchapi/switch_buffer.h | 171 + .../include/switchapi/switch_capability.h | 127 + .../switchapi/switch_config.h | 4 +- switchapi/include/switchapi/switch_dox.h | 41 + switchapi/include/switchapi/switch_handle.h | 234 + switchapi/include/switchapi/switch_hostif.h | 343 + .../{inc => include}/switchapi/switch_id.h | 36 +- .../include/switchapi/switch_interface.h | 383 + .../{inc => include}/switchapi/switch_l2.h | 141 +- switchapi/include/switchapi/switch_l3.h | 210 + .../{inc => include}/switchapi/switch_lag.h | 56 +- .../{inc => include}/switchapi/switch_log.h | 16 +- .../{inc => include}/switchapi/switch_mcast.h | 105 +- .../{inc => include}/switchapi/switch_meter.h | 78 +- switchapi/include/switchapi/switch_mirror.h | 142 + switchapi/include/switchapi/switch_nat.h | 101 + .../switchapi/switch_neighbor.h | 63 +- .../{inc => include}/switchapi/switch_nhop.h | 60 +- switchapi/include/switchapi/switch_port.h | 509 + switchapi/include/switchapi/switch_porting.h | 121 + switchapi/include/switchapi/switch_protocol.h | 216 + switchapi/include/switchapi/switch_qos.h | 130 + switchapi/include/switchapi/switch_queue.h | 131 + .../{inc => include}/switchapi/switch_rmac.h | 21 +- .../include/switchapi/switch_scheduler.h | 159 + switchapi/include/switchapi/switch_sflow.h | 141 + switchapi/include/switchapi/switch_status.h | 185 + .../{inc => include}/switchapi/switch_stp.h | 53 +- switchapi/include/switchapi/switch_tunnel.h | 166 + .../{inc => include}/switchapi/switch_utils.h | 8 +- .../{inc => include}/switchapi/switch_vlan.h | 304 +- .../{inc => include}/switchapi/switch_vrf.h | 54 +- switchapi/src/switch_INT.c | 177 +- switchapi/src/switch_acl.c | 1620 +- switchapi/src/switch_acl_int.h | 26 +- switchapi/src/switch_api.thrift | 258 +- switchapi/src/switch_api_rpc_server.cpp | 691 +- switchapi/src/switch_buffer.c | 409 + switchapi/src/switch_buffer_int.h | 51 + switchapi/src/switch_capability.c | 122 +- switchapi/src/switch_capability_int.h | 19 +- switchapi/src/switch_config.c | 54 +- switchapi/src/switch_config_int.h | 18 +- switchapi/src/switch_defines.h | 74 +- switchapi/src/switch_handle.c | 199 +- switchapi/src/switch_hostif.c | 2255 ++- switchapi/src/switch_hostif_int.h | 113 +- switchapi/src/switch_id.c | 228 +- switchapi/src/switch_init.c | 985 +- switchapi/src/switch_interface.c | 2198 ++- switchapi/src/switch_interface_int.h | 167 +- switchapi/src/switch_l2.c | 2104 +- switchapi/src/switch_l2_int.h | 31 +- switchapi/src/switch_l3.c | 1220 +- switchapi/src/switch_l3_int.h | 56 +- switchapi/src/switch_lag.c | 827 +- switchapi/src/switch_lag_int.h | 80 +- switchapi/src/switch_log.c | 68 +- switchapi/src/switch_log.h | 26 + switchapi/src/switch_log_int.h | 29 +- switchapi/src/switch_lpm.c | 282 + switchapi/src/switch_lpm_int.h | 59 + switchapi/src/switch_mcast.c | 1992 +- switchapi/src/switch_mcast_int.h | 188 +- switchapi/src/switch_meter.c | 332 +- switchapi/src/switch_meter_int.h | 24 +- switchapi/src/switch_mirror.c | 587 +- switchapi/src/switch_mirror_int.h | 30 +- switchapi/src/switch_nat.c | 199 + switchapi/src/switch_nat_int.h | 90 + switchapi/src/switch_neighbor.c | 894 +- switchapi/src/switch_neighbor_int.h | 39 +- switchapi/src/switch_nhop.c | 1389 +- switchapi/src/switch_nhop_int.h | 72 +- switchapi/src/switch_packet.c | 1859 +- switchapi/src/switch_packet_int.h | 108 +- switchapi/src/switch_pd.c | 16347 ++++++++-------- switchapi/src/switch_pd.h | 1935 +- switchapi/src/switch_pd_buffer.c | 78 + switchapi/src/switch_pd_mcast.c | 1104 +- switchapi/src/switch_pd_nat.c | 324 + switchapi/src/switch_pd_ppg.c | 109 + switchapi/src/switch_pd_qos.c | 300 + switchapi/src/switch_pd_queue.c | 130 + switchapi/src/switch_pd_types.h | 32 + switchapi/src/switch_port.c | 812 +- switchapi/src/switch_port_int.h | 68 +- switchapi/src/switch_qos.c | 283 + switchapi/src/switch_qos_int.h | 54 + switchapi/src/switch_queue.c | 219 + switchapi/src/switch_queue_int.h | 47 + switchapi/src/switch_rmac.c | 673 +- switchapi/src/switch_rmac_int.h | 26 +- switchapi/src/switch_scheduler.c | 324 + switchapi/src/switch_scheduler_int.h | 33 + switchapi/src/switch_sflow.c | 675 +- switchapi/src/switch_sflow_int.h | 36 +- switchapi/src/switch_stp.c | 956 +- switchapi/src/switch_stp_int.h | 26 +- switchapi/src/switch_tunnel.c | 2268 ++- switchapi/src/switch_tunnel_int.h | 73 +- switchapi/src/switch_utils.c | 80 +- switchapi/src/switch_vlan.c | 2866 ++- switchapi/src/switch_vlan_int.h | 201 +- switchapi/src/switch_vrf.c | 202 +- switchapi/src/switch_vrf_int.h | 16 +- switchapi/src/thrift_cache.h | 2 +- switchlink/src/switchlink.h | 35 +- switchlink/src/switchlink_address.c | 202 +- switchlink/src/switchlink_db.c | 1426 +- switchlink/src/switchlink_db.h | 315 +- switchlink/src/switchlink_db_int.h | 67 +- switchlink/src/switchlink_link.c | 776 +- switchlink/src/switchlink_link.h | 38 +- switchlink/src/switchlink_main.c | 467 +- switchlink/src/switchlink_mdb.c | 272 +- switchlink/src/switchlink_neigh.c | 394 +- switchlink/src/switchlink_neigh.h | 15 +- switchlink/src/switchlink_netconf.c | 244 +- switchlink/src/switchlink_packet.c | 282 +- switchlink/src/switchlink_packet.h | 6 +- switchlink/src/switchlink_route.c | 839 +- switchlink/src/switchlink_route.h | 12 +- switchlink/src/switchlink_sai.c | 1802 +- switchlink/src/switchlink_sai.h | 124 +- switchsai/Makefile.am | 8 + switchsai/src/sai-param-check.c | 604 +- switchsai/src/sai.c | 499 +- switchsai/src/sai_bmlib.c | 265 +- switchsai/src/saiacl.c | 1428 +- switchsai/src/saibuffer.c | 379 + switchsai/src/saifdb.c | 605 +- switchsai/src/saihash.c | 55 + switchsai/src/saihostintf.c | 1164 +- switchsai/src/saiinternal.h | 175 +- switchsai/src/saiipmc.c | 586 +- switchsai/src/sail2mc.c | 342 +- switchsai/src/sailag.c | 367 +- switchsai/src/saimirror.c | 315 +- switchsai/src/saineighbor.c | 356 +- switchsai/src/sainexthop.c | 272 +- switchsai/src/sainexthopgroup.c | 417 +- switchsai/src/saiobject.c | 42 + switchsai/src/saipolicer.c | 510 +- switchsai/src/saiport.c | 265 +- switchsai/src/saiqosmaps.c | 334 + switchsai/src/saiqueue.c | 147 + switchsai/src/sairoute.c | 346 +- switchsai/src/sairouter.c | 184 +- switchsai/src/sairouterintf.c | 410 +- switchsai/src/saischeduler.c | 186 + switchsai/src/saischedulergroup.c | 216 + switchsai/src/saistp.c | 387 +- switchsai/src/saiswitch.c | 244 +- switchsai/src/saiudf.c | 106 + switchsai/src/saiutils.c | 517 +- switchsai/src/saivlan.c | 720 +- switchsai/src/switch_sai.thrift | 71 +- switchsai/src/switch_sai_rpc_server.cpp | 633 +- switchsai/submodules/.clang-format | 3 + tests/ptf-tests/api-tests/switch.py | 2421 ++- tests/ptf-tests/api-tests/switch_acl.py | 64 +- tests/ptf-tests/api-tests/switch_mcast.py | 97 +- tests/ptf-tests/api-tests/switch_qos.py | 164 + tests/ptf-tests/api-tests/switch_sflow.py | 18 +- tests/ptf-tests/common/pd_utils.py | 131 +- tests/ptf-tests/common/sai_utils.py | 108 +- tests/ptf-tests/common/utils.py | 7 +- tests/ptf-tests/pd-tests/pd_base_tests.py | 75 + tests/ptf-tests/pd-tests/switch.py | 17 +- tests/ptf-tests/sai-tests/switch.py | 412 +- tests/ptf-tests/sai-tests/switch_qos.py | 145 + third-party/.clang-format | 3 + 220 files changed, 48846 insertions(+), 37487 deletions(-) create mode 100644 .clang-format create mode 100644 p4src/.clang-format create mode 100644 p4src/includes/cpu_reason_codes.h create mode 100644 p4src/includes/drop_reason_codes.h rename p4src/includes/{sizes.p4 => p4_table_sizes.h} (90%) create mode 100644 p4src/nat.p4 create mode 100644 p4src/qos.p4 delete mode 100644 switchapi/inc/switchapi/switch_INT.h delete mode 100644 switchapi/inc/switchapi/switch_acl.h delete mode 100644 switchapi/inc/switchapi/switch_capability.h delete mode 100644 switchapi/inc/switchapi/switch_handle.h delete mode 100644 switchapi/inc/switchapi/switch_hostif.h delete mode 100644 switchapi/inc/switchapi/switch_interface.h delete mode 100644 switchapi/inc/switchapi/switch_l3.h delete mode 100644 switchapi/inc/switchapi/switch_mirror.h delete mode 100644 switchapi/inc/switchapi/switch_port.h delete mode 100644 switchapi/inc/switchapi/switch_porting.h delete mode 100644 switchapi/inc/switchapi/switch_protocol.h delete mode 100644 switchapi/inc/switchapi/switch_sflow.h delete mode 100644 switchapi/inc/switchapi/switch_status.h delete mode 100644 switchapi/inc/switchapi/switch_tunnel.h create mode 100644 switchapi/include/switchapi/switch_INT.h create mode 100644 switchapi/include/switchapi/switch_acl.h rename switchapi/{inc => include}/switchapi/switch_base_types.h (56%) create mode 100644 switchapi/include/switchapi/switch_buffer.h create mode 100644 switchapi/include/switchapi/switch_capability.h rename switchapi/{inc => include}/switchapi/switch_config.h (86%) create mode 100644 switchapi/include/switchapi/switch_dox.h create mode 100644 switchapi/include/switchapi/switch_handle.h create mode 100644 switchapi/include/switchapi/switch_hostif.h rename switchapi/{inc => include}/switchapi/switch_id.h (68%) create mode 100644 switchapi/include/switchapi/switch_interface.h rename switchapi/{inc => include}/switchapi/switch_l2.h (57%) create mode 100644 switchapi/include/switchapi/switch_l3.h rename switchapi/{inc => include}/switchapi/switch_lag.h (71%) rename switchapi/{inc => include}/switchapi/switch_log.h (74%) rename switchapi/{inc => include}/switchapi/switch_mcast.h (58%) rename switchapi/{inc => include}/switchapi/switch_meter.h (55%) create mode 100644 switchapi/include/switchapi/switch_mirror.h create mode 100644 switchapi/include/switchapi/switch_nat.h rename switchapi/{inc => include}/switchapi/switch_neighbor.h (51%) rename switchapi/{inc => include}/switchapi/switch_nhop.h (60%) create mode 100644 switchapi/include/switchapi/switch_port.h create mode 100644 switchapi/include/switchapi/switch_porting.h create mode 100644 switchapi/include/switchapi/switch_protocol.h create mode 100644 switchapi/include/switchapi/switch_qos.h create mode 100644 switchapi/include/switchapi/switch_queue.h rename switchapi/{inc => include}/switchapi/switch_rmac.h (76%) create mode 100644 switchapi/include/switchapi/switch_scheduler.h create mode 100644 switchapi/include/switchapi/switch_sflow.h create mode 100644 switchapi/include/switchapi/switch_status.h rename switchapi/{inc => include}/switchapi/switch_stp.h (68%) create mode 100644 switchapi/include/switchapi/switch_tunnel.h rename switchapi/{inc => include}/switchapi/switch_utils.h (83%) rename switchapi/{inc => include}/switchapi/switch_vlan.h (57%) rename switchapi/{inc => include}/switchapi/switch_vrf.h (63%) create mode 100644 switchapi/src/switch_buffer.c create mode 100644 switchapi/src/switch_buffer_int.h create mode 100644 switchapi/src/switch_log.h create mode 100644 switchapi/src/switch_lpm.c create mode 100644 switchapi/src/switch_lpm_int.h create mode 100644 switchapi/src/switch_nat.c create mode 100644 switchapi/src/switch_nat_int.h create mode 100644 switchapi/src/switch_pd_buffer.c create mode 100644 switchapi/src/switch_pd_nat.c create mode 100644 switchapi/src/switch_pd_ppg.c create mode 100644 switchapi/src/switch_pd_qos.c create mode 100644 switchapi/src/switch_pd_queue.c create mode 100644 switchapi/src/switch_pd_types.h create mode 100644 switchapi/src/switch_qos.c create mode 100644 switchapi/src/switch_qos_int.h create mode 100644 switchapi/src/switch_queue.c create mode 100644 switchapi/src/switch_queue_int.h create mode 100644 switchapi/src/switch_scheduler.c create mode 100644 switchapi/src/switch_scheduler_int.h create mode 100644 switchsai/src/saibuffer.c create mode 100644 switchsai/src/saihash.c create mode 100644 switchsai/src/saiobject.c create mode 100644 switchsai/src/saiqosmaps.c create mode 100644 switchsai/src/saiqueue.c create mode 100644 switchsai/src/saischeduler.c create mode 100644 switchsai/src/saischedulergroup.c create mode 100644 switchsai/src/saiudf.c create mode 100644 switchsai/submodules/.clang-format create mode 100644 tests/ptf-tests/api-tests/switch_qos.py create mode 100644 tests/ptf-tests/pd-tests/pd_base_tests.py create mode 100644 tests/ptf-tests/sai-tests/switch_qos.py create mode 100644 third-party/.clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ce92134 --- /dev/null +++ b/.clang-format @@ -0,0 +1,8 @@ +--- +Language: Cpp +BasedOnStyle: Google +BinPackArguments: false +BinPackParameters: false +DerivePointerAlignment: false +PointerAlignment: Right +... diff --git a/README.md b/README.md index cc8a4e6..44eb75d 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,10 @@ 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/p4c-bm) on your system. Note that when running +`./configure` for bmv2, you need to provide the `--with-pdfixed` option, as +switch requires the PD library. 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: diff --git a/p4src/.clang-format b/p4src/.clang-format new file mode 100644 index 0000000..ac2aa81 --- /dev/null +++ b/p4src/.clang-format @@ -0,0 +1,3 @@ +--- +DisableFormat : true +... diff --git a/p4src/acl.p4 b/p4src/acl.p4 index d3bb812..5897d37 100644 --- a/p4src/acl.p4 +++ b/p4src/acl.p4 @@ -16,21 +16,19 @@ limitations under the License. /* * ACL processing : MAC, IPv4, IPv6, RACL/PBR - * Qos processing */ /* - * ACL and QoS metadata + * ACL metadata */ header_type acl_metadata_t { fields { acl_deny : 1; /* ifacl/vacl deny action */ - acl_copy : 1; /* generate copy to cpu */ racl_deny : 1; /* racl deny action */ acl_nexthop : 16; /* next hop from ifacl/vacl */ racl_nexthop : 16; /* next hop from racl */ - acl_nexthop_type : 1; /* ecmp or nexthop */ - racl_nexthop_type : 1; /* ecmp or nexthop */ + acl_nexthop_type : 2; /* ecmp or nexthop */ + racl_nexthop_type : 2; /* ecmp or nexthop */ acl_redirect : 1; /* ifacl/vacl redirect action */ racl_redirect : 1; /* racl redirect action */ if_label : 16; /* if label for acls */ @@ -38,14 +36,6 @@ header_type acl_metadata_t { acl_stats_index : 14; /* acl stats index */ } } -header_type qos_metadata_t { - fields { - outer_dscp : 8; /* outer dscp */ - marked_cos : 3; /* marked vlan cos value */ - marked_dscp : 8; /* marked dscp value */ - marked_exp : 3; /* marked exp value */ - } -} header_type i2e_metadata_t { fields { @@ -55,81 +45,103 @@ header_type i2e_metadata_t { } metadata acl_metadata_t acl_metadata; -metadata qos_metadata_t qos_metadata; metadata i2e_metadata_t i2e_metadata; -#ifndef ACL_DISABLE /*****************************************************************************/ /* ACL Actions */ /*****************************************************************************/ -action acl_deny(acl_stats_index, acl_meter_index, acl_copy, acl_copy_reason) { +action acl_deny(acl_stats_index, acl_meter_index, acl_copy_reason, + nat_mode, ingress_cos, tc, color) { modify_field(acl_metadata.acl_deny, TRUE); modify_field(acl_metadata.acl_stats_index, acl_stats_index); modify_field(meter_metadata.meter_index, acl_meter_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); + modify_field(nat_metadata.ingress_nat_mode, nat_mode); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ + } -action acl_permit(acl_stats_index, acl_meter_index, acl_copy, acl_copy_reason) { +action acl_permit(acl_stats_index, acl_meter_index, acl_copy_reason, + nat_mode, ingress_cos, tc, color) { modify_field(acl_metadata.acl_stats_index, acl_stats_index); modify_field(meter_metadata.meter_index, acl_meter_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); + modify_field(nat_metadata.ingress_nat_mode, nat_mode); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } field_list i2e_mirror_info { i2e_metadata.ingress_tstamp; i2e_metadata.mirror_session_id; -#ifdef __TARGET_BMV2__ - standard_metadata.instance_type; -#endif } field_list e2e_mirror_info { i2e_metadata.ingress_tstamp; i2e_metadata.mirror_session_id; -#ifdef __TARGET_BMV2__ - standard_metadata.instance_type; -#endif } -action acl_mirror(session_id, acl_stats_index, acl_meter_index) { +action acl_mirror(session_id, acl_stats_index, acl_meter_index, nat_mode, + ingress_cos, tc, color) { modify_field(i2e_metadata.mirror_session_id, session_id); - modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); clone_ingress_pkt_to_egress(session_id, i2e_mirror_info); modify_field(acl_metadata.acl_stats_index, acl_stats_index); modify_field(meter_metadata.meter_index, acl_meter_index); + modify_field(nat_metadata.ingress_nat_mode, nat_mode); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } action acl_redirect_nexthop(nexthop_index, acl_stats_index, acl_meter_index, - acl_copy, acl_copy_reason) { + acl_copy_reason, nat_mode, + ingress_cos, tc, color) { 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(acl_metadata.acl_stats_index, acl_stats_index); modify_field(meter_metadata.meter_index, acl_meter_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); + modify_field(nat_metadata.ingress_nat_mode, nat_mode); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } action acl_redirect_ecmp(ecmp_index, acl_stats_index, acl_meter_index, - acl_copy, acl_copy_reason) { + acl_copy_reason, nat_mode, + ingress_cos, tc, color) { modify_field(acl_metadata.acl_redirect, TRUE); modify_field(acl_metadata.acl_nexthop, ecmp_index); modify_field(acl_metadata.acl_nexthop_type, NEXTHOP_TYPE_ECMP); modify_field(acl_metadata.acl_stats_index, acl_stats_index); modify_field(meter_metadata.meter_index, acl_meter_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); + modify_field(nat_metadata.ingress_nat_mode, nat_mode); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } -#endif /* ACL_DISABLE */ /*****************************************************************************/ /* MAC ACL */ /*****************************************************************************/ -#if !defined(ACL_DISABLE) && !defined(L2_DISABLE) +#ifndef L2_DISABLE table mac_acl { reads { acl_metadata.if_label : ternary; @@ -143,26 +155,28 @@ table mac_acl { nop; acl_deny; acl_permit; - acl_mirror; acl_redirect_nexthop; acl_redirect_ecmp; +#ifndef MIRROR_DISABLE + acl_mirror; +#endif /* MIRROR_DISABLE */ } size : INGRESS_MAC_ACL_TABLE_SIZE; } -#endif /* !ACL_DISABLE && !L2_DISABLE */ +#endif /* L2_DISABLE */ control process_mac_acl { -#if !defined(ACL_DISABLE) && !defined(L2_DISABLE) +#ifndef L2_DISABLE if (DO_LOOKUP(ACL)) { apply(mac_acl); } -#endif /* !ACL_DISABLE && !L2_DISABLE */ +#endif /* L2_DISABLE */ } /*****************************************************************************/ /* IPv4 ACL */ /*****************************************************************************/ -#if !defined(ACL_DISABLE) && !defined(IPV4_DISABLE) +#ifndef IPV4_DISABLE table ip_acl { reads { acl_metadata.if_label : ternary; @@ -181,19 +195,21 @@ table ip_acl { nop; acl_deny; acl_permit; - acl_mirror; acl_redirect_nexthop; acl_redirect_ecmp; +#ifndef MIRROR_DISABLE + acl_mirror; +#endif /* MIRROR_DISABLE */ } size : INGRESS_IP_ACL_TABLE_SIZE; } -#endif /* !ACL_DISABLE && !IPV4_DISABLE */ +#endif /* IPV4_DISABLE */ /*****************************************************************************/ /* IPv6 ACL */ /*****************************************************************************/ -#if !defined(ACL_DISABLE) && !defined(IPV6_DISABLE) +#ifndef IPV6_DISABLE table ipv6_acl { reads { acl_metadata.if_label : ternary; @@ -212,20 +228,21 @@ table ipv6_acl { nop; acl_deny; acl_permit; - acl_mirror; acl_redirect_nexthop; acl_redirect_ecmp; +#ifndef MIRROR_DISABLE + acl_mirror; +#endif /* MIRROR_DISABLE */ } size : INGRESS_IPV6_ACL_TABLE_SIZE; } -#endif /* !ACL_DISABLE && !IPV6_DISABLE */ +#endif /* IPV6_DISABLE */ /*****************************************************************************/ /* ACL Control flow */ /*****************************************************************************/ control process_ip_acl { -#ifndef ACL_DISABLE if (DO_LOOKUP(ACL)) { if (l3_metadata.lkp_ip_type == IPTYPE_IPV4) { #ifndef IPV4_DISABLE @@ -239,102 +256,69 @@ control process_ip_acl { } } } -#endif /* ACL_DISABLE */ -} - -/*****************************************************************************/ -/* Qos Processing */ -/*****************************************************************************/ -#if !defined(ACL_DISABLE) && !defined(QOS_DISABLE) -action apply_cos_marking(cos) { - modify_field(qos_metadata.marked_cos, cos); -} - -action apply_dscp_marking(dscp) { - modify_field(qos_metadata.marked_dscp, dscp); -} - -action apply_tc_marking(tc) { - modify_field(qos_metadata.marked_exp, tc); -} - -table qos { - reads { - acl_metadata.if_label : ternary; - - /* ip */ - ipv4_metadata.lkp_ipv4_sa : ternary; - ipv4_metadata.lkp_ipv4_da : ternary; - l3_metadata.lkp_ip_proto : ternary; - l3_metadata.lkp_ip_tc : ternary; - - /* mpls */ - tunnel_metadata.mpls_exp : ternary; - - /* outer ip */ - qos_metadata.outer_dscp : ternary; - } - actions { - nop; - apply_cos_marking; - apply_dscp_marking; - apply_tc_marking; - } - size : INGRESS_QOS_ACL_TABLE_SIZE; -} -#endif /* !ACL_DISABLE && !QOS_DISABLE */ - -control process_qos { -#if !defined(ACL_DISABLE) && !defined(QOS_DISABLE) - apply(qos); -#endif /* !ACL_DISABLE && !QOS_DISABLE */ } - /*****************************************************************************/ /* RACL actions */ /*****************************************************************************/ -#ifndef ACL_DISABLE -action racl_deny(acl_stats_index, acl_copy, acl_copy_reason) { +action racl_deny(acl_stats_index, acl_copy_reason, + ingress_cos, tc, color) { modify_field(acl_metadata.racl_deny, TRUE); modify_field(acl_metadata.acl_stats_index, acl_stats_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } -action racl_permit(acl_stats_index, - acl_copy, acl_copy_reason) { +action racl_permit(acl_stats_index, acl_copy_reason, + ingress_cos, tc, color) { modify_field(acl_metadata.acl_stats_index, acl_stats_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } action racl_redirect_nexthop(nexthop_index, acl_stats_index, - acl_copy, acl_copy_reason) { + acl_copy_reason, + ingress_cos, tc, color) { modify_field(acl_metadata.racl_redirect, TRUE); modify_field(acl_metadata.racl_nexthop, nexthop_index); modify_field(acl_metadata.racl_nexthop_type, NEXTHOP_TYPE_SIMPLE); modify_field(acl_metadata.acl_stats_index, acl_stats_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } action racl_redirect_ecmp(ecmp_index, acl_stats_index, - acl_copy, acl_copy_reason) { + acl_copy_reason, + ingress_cos, tc, color) { modify_field(acl_metadata.racl_redirect, TRUE); modify_field(acl_metadata.racl_nexthop, ecmp_index); modify_field(acl_metadata.racl_nexthop_type, NEXTHOP_TYPE_ECMP); modify_field(acl_metadata.acl_stats_index, acl_stats_index); - modify_field(acl_metadata.acl_copy, acl_copy); modify_field(fabric_metadata.reason_code, acl_copy_reason); +#ifndef QOS_DISABLE + modify_field(intrinsic_metadata.ingress_cos, ingress_cos); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +#endif /* QOS_DISABLE */ } -#endif /* ACL_DISABLE */ /*****************************************************************************/ /* IPv4 RACL */ /*****************************************************************************/ -#if !defined(ACL_DISABLE) && !defined(IPV4_DISABLE) +#ifndef IPV4_DISABLE table ipv4_racl { reads { acl_metadata.bd_label : ternary; @@ -354,19 +338,19 @@ table ipv4_racl { } size : INGRESS_IP_RACL_TABLE_SIZE; } -#endif /* !ACL_DISABLE && !IPV4_DISABLE */ +#endif /* IPV4_DISABLE */ control process_ipv4_racl { -#if !defined(ACL_DISABLE) && !defined(IPV4_DISABLE) +#ifndef IPV4_DISABLE apply(ipv4_racl); -#endif /* !ACL_DISABLE && !IPV4_DISABLE */ +#endif /* IPV4_DISABLE */ } /*****************************************************************************/ /* IPv6 RACL */ /*****************************************************************************/ -#if !defined(ACL_DISABLE) && !defined(IPV6_DISABLE) +#ifndef IPV6_DISABLE table ipv6_racl { reads { acl_metadata.bd_label : ternary; @@ -386,17 +370,18 @@ table ipv6_racl { } size : INGRESS_IPV6_RACL_TABLE_SIZE; } -#endif /* !ACL_DISABLE && !IPV6_DISABLE */ +#endif /* IPV6_DISABLE */ control process_ipv6_racl { -#if !defined(ACL_DISABLE) && !defined(IPV6_DISABLE) +#ifndef IPV6_DISABLE apply(ipv6_racl); -#endif /* !ACL_DISABLE && !IPV6_DISABLE */ +#endif /* IPV6_DISABLE */ } /*****************************************************************************/ /* ACL stats */ /*****************************************************************************/ +#ifndef STATS_DISABLE counter acl_stats { type : packets_and_bytes; instance_count : ACL_STATS_TABLE_SIZE; @@ -413,6 +398,7 @@ table acl_stats { } size : ACL_STATS_TABLE_SIZE; } +#endif /* STATS_DISABLE */ control process_ingress_acl_stats { #ifndef STATS_DISABLE @@ -420,6 +406,18 @@ control process_ingress_acl_stats { #endif /* STATS_DISABLE */ } +/*****************************************************************************/ +/* CoPP */ +/*****************************************************************************/ +#ifndef METER_DISABLE +meter copp { + type: bytes; + static: system_acl; + result: intrinsic_metadata.packet_color; + instance_count: COPP_TABLE_SIZE; +} +#endif /* METER_DISABLE */ + /*****************************************************************************/ /* System ACL */ /*****************************************************************************/ @@ -445,8 +443,16 @@ action negative_mirror(session_id) { drop(); } -action redirect_to_cpu(reason_code) { - copy_to_cpu_with_reason(reason_code); +action redirect_to_cpu_with_reason(reason_code, qid, meter_id, icos) { + copy_to_cpu_with_reason(reason_code, qid, meter_id, icos); + drop(); +#ifdef FABRIC_ENABLE + modify_field(fabric_metadata.dst_device, 0); +#endif /* FABRIC_ENABLE */ +} + +action redirect_to_cpu(qid, meter_id, icos) { + copy_to_cpu(qid, meter_id, icos); drop(); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); @@ -463,13 +469,16 @@ field_list cpu_info { #endif } -action copy_to_cpu_with_reason(reason_code) { - modify_field(fabric_metadata.reason_code, reason_code); +action copy_to_cpu(qid, meter_id, icos) { + modify_field(intrinsic_metadata.qid, qid); + modify_field(intrinsic_metadata.ingress_cos, icos); clone_ingress_pkt_to_egress(CPU_MIRROR_SESSION_ID, cpu_info); + execute_meter(copp, meter_id, intrinsic_metadata.packet_color); } -action copy_to_cpu() { - clone_ingress_pkt_to_egress(CPU_MIRROR_SESSION_ID, cpu_info); +action copy_to_cpu_with_reason(reason_code, qid, meter_id, icos) { + modify_field(fabric_metadata.reason_code, reason_code); + copy_to_cpu(qid, meter_id, icos); } action drop_packet() { @@ -486,24 +495,17 @@ table system_acl { acl_metadata.if_label : ternary; acl_metadata.bd_label : ternary; - /* mac acl */ - l2_metadata.lkp_mac_sa : ternary; - l2_metadata.lkp_mac_da : ternary; - l2_metadata.lkp_mac_type : ternary; - ingress_metadata.ifindex : ternary; /* drop reasons */ + l2_metadata.lkp_mac_type : ternary; l2_metadata.port_vlan_mapping_miss : ternary; security_metadata.ipsg_check_fail : ternary; - security_metadata.storm_control_color : ternary; acl_metadata.acl_deny : ternary; acl_metadata.racl_deny: ternary; l3_metadata.urpf_check_fail : ternary; ingress_metadata.drop_flag : ternary; - /* copy reason */ - acl_metadata.acl_copy : ternary; l3_metadata.l3_copy : ternary; l3_metadata.rmac_hit : ternary; @@ -526,12 +528,15 @@ table system_acl { /* egress information */ ingress_metadata.egress_ifindex : ternary; + fabric_metadata.reason_code : ternary; + } actions { nop; redirect_to_cpu; - copy_to_cpu_with_reason; + redirect_to_cpu_with_reason; copy_to_cpu; + copy_to_cpu_with_reason; drop_packet; drop_packet_with_reason; negative_mirror; @@ -562,7 +567,6 @@ control process_system_acl { /*****************************************************************************/ /* Egress ACL */ /*****************************************************************************/ -#ifndef ACL_DISABLE action egress_mirror(session_id) { modify_field(i2e_metadata.mirror_session_id, session_id); clone_egress_pkt_to_egress(session_id, e2e_mirror_info); @@ -597,12 +601,9 @@ table egress_acl { } size : EGRESS_ACL_TABLE_SIZE; } -#endif /* ACL_DISABLE */ control process_egress_acl { -#ifndef ACL_DISABLE if (egress_metadata.bypass == FALSE) { apply(egress_acl); } -#endif /* ACL_DISABLE */ } diff --git a/p4src/fabric.p4 b/p4src/fabric.p4 index c87cc97..478c5b6 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(ingress_egress_port, + modify_field(standard_metadata.egress_spec, 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(ingress_egress_port, + modify_field(standard_metadata.egress_spec, 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_mcast_grp, + modify_field(intrinsic_metadata.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_mcast_grp, fabric_header.dstPortOrGroup); + modify_field(intrinsic_metadata.mcast_grp, fabric_header.dstPortOrGroup); } #endif /* MULTICAST_DISABLE */ #endif /* FABRIC_ENABLE */ @@ -203,16 +203,16 @@ control process_ingress_fabric { /*****************************************************************************/ #ifdef FABRIC_ENABLE action set_fabric_lag_port(port) { - modify_field(ingress_egress_port, port); + modify_field(standard_metadata.egress_spec, port); } #ifndef MULTICAST_DISABLE action set_fabric_multicast(fabric_mgid) { - modify_field(multicast_metadata.mcast_grp, intrinsic_mcast_grp); + modify_field(multicast_metadata.mcast_grp, intrinsic_metadata.mcast_grp); #ifdef FABRIC_NO_LOCAL_SWITCHING // no local switching, reset fields to send packet on fabric mgid - modify_field(intrinsic_mcast_grp, fabric_mgid); + modify_field(intrinsic_metadata.mcast_grp, fabric_mgid); #endif /* FABRIC_NO_LOCAL_SWITCHING */ } #endif /* MULTICAST_DISABLE */ diff --git a/p4src/hashes.p4 b/p4src/hashes.p4 index 2746ce7..5b1aa5d 100644 --- a/p4src/hashes.p4 +++ b/p4src/hashes.p4 @@ -166,7 +166,9 @@ table compute_other_hashes { control process_hashes { if (((tunnel_metadata.tunnel_terminate == FALSE) and valid(ipv4)) or ((tunnel_metadata.tunnel_terminate == TRUE) and valid(inner_ipv4))) { +#ifndef IPV4_DISABLE apply(compute_ipv4_hashes); +#endif /* IPV4_DISABLE */ } #ifndef IPV6_DISABLE else { @@ -176,7 +178,9 @@ control process_hashes { } #endif /* IPV6_DISABLE */ else { +#ifndef L2_DISABLE apply(compute_non_ip_hashes); +#endif /* L2_DISABLE */ } #ifndef IPV6_DISABLE } diff --git a/p4src/includes/cpu_reason_codes.h b/p4src/includes/cpu_reason_codes.h new file mode 100644 index 0000000..ad33dea --- /dev/null +++ b/p4src/includes/cpu_reason_codes.h @@ -0,0 +1,23 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* + * other reason codes shared between P4 program and APIs + * Must match the definitions in switch_hostif.h file + */ + +#define CPU_REASON_CODE_DEFAULT 0x0 +#define CPU_REASON_CODE_SFLOW 0x4 +#define CPU_REASON_CODE_L3_REDIRECT 0x217 diff --git a/p4src/includes/defines.p4 b/p4src/includes/defines.p4 index 1fb6ba2..7d78174 100644 --- a/p4src/includes/defines.p4 +++ b/p4src/includes/defines.p4 @@ -100,6 +100,8 @@ limitations under the License. #define PORT_TYPE_FABRIC 1 #define PORT_TYPE_CPU 2 +#define DEFAULT_INGRESS_COS 0 + /* BYPASS LOOKUP */ #define BYPASS_L2 0x0001 #define BYPASS_L3 0x0002 @@ -107,6 +109,8 @@ limitations under the License. #define BYPASS_QOS 0x0008 #define BYPASS_METER 0x0010 #define BYPASS_SYSTEM_ACL 0x0020 +#define BYPASS_PKT_VALIDATION 0x0040 +#define BYPASS_SMAC_CHK 0x0080 #define BYPASS_ALL 0xFFFF #define DO_LOOKUP(l) \ diff --git a/p4src/includes/drop_reason_codes.h b/p4src/includes/drop_reason_codes.h new file mode 100644 index 0000000..7180949 --- /dev/null +++ b/p4src/includes/drop_reason_codes.h @@ -0,0 +1,50 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#define DROP_UNKNOWN 0 + +#define DROP_OUTER_SRC_MAC_ZERO 10 +#define DROP_OUTER_SRC_MAC_MULTICAST 11 +#define DROP_OUTER_DST_MAC_ZERO 12 +#define DROP_OUTER_ETHERNET_MISS 13 +#define DROP_SRC_MAC_ZERO 14 +#define DROP_SRC_MAC_MULTICAST 15 +#define DROP_DST_MAC_ZERO 16 + +#define DROP_OUTER_IP_VERSION_INVALID 25 +#define DROP_OUTER_IP_TTL_ZERO 26 +#define DROP_OUTER_IP_SRC_MULTICAST 27 +#define DROP_OUTER_IP_SRC_LOOPBACK 28 +#define DROP_OUTER_IP_MISS 29 +#define DROP_IP_VERSION_INVALID 30 +#define DROP_IP_TTL_ZERO 31 +#define DROP_IP_SRC_MULTICAST 32 +#define DROP_IP_SRC_LOOPBACK 33 + +#define DROP_PORT_VLAN_MAPPING_MISS 40 +#define DROP_STP_STATE_LEARNING 41 +#define DROP_STP_STATE_BLOCKING 42 +#define DROP_SAME_IFINDEX 43 +#define DROP_MULTICAST_SNOOPING_ENABLED 44 + +#define DROP_MTU_CHECK_FAIL 50 +#define DROP_TRAFFIC_MANAGER 51 + +#define DROP_ACL_DENY 60 +#define DROP_RACL_DENY 61 +#define DROP_URPF_CHECK_FAIL 62 +#define DROP_IPSG_MISS 63 +#define DROP_IFINDEX 64 + diff --git a/p4src/includes/headers.p4 b/p4src/includes/headers.p4 index a412acf..a0947d6 100644 --- a/p4src/includes/headers.p4 +++ b/p4src/includes/headers.p4 @@ -191,7 +191,8 @@ header_type erspan_header_t3_t { priority : 6; span_id : 10; timestamp : 32; - sgt_other : 32; + sgt : 16; + ft_d_other: 16; } } @@ -525,6 +526,7 @@ header_type fabric_header_cpu_t { header_type fabric_header_sflow_t { fields { sflow_session_id : 16; + sflow_egress_ifindex : 16; } } diff --git a/p4src/includes/intrinsic.p4 b/p4src/includes/intrinsic.p4 index 601d9c1..708f001 100644 --- a/p4src/includes/intrinsic.p4 +++ b/p4src/includes/intrinsic.p4 @@ -45,9 +45,18 @@ header_type ingress_intrinsic_metadata_t { // enqueue and dequeue time. mcast_hash : 13; // multicast hashing + egress_rid : 16; // Replication ID for multicast + lf_field_list : 32; // Learn filter field list + priority : 3; // set packet priority + + ingress_cos: 3; // ingress cos + + packet_color: 2; // packet color + + qid: 5; // queue id } } metadata ingress_intrinsic_metadata_t intrinsic_metadata; diff --git a/p4src/includes/sizes.p4 b/p4src/includes/p4_table_sizes.h similarity index 90% rename from p4src/includes/sizes.p4 rename to p4src/includes/p4_table_sizes.h index 5804a9a..7879bf3 100644 --- a/p4src/includes/sizes.p4 +++ b/p4src/includes/p4_table_sizes.h @@ -26,8 +26,10 @@ limitations under the License. #define PORT_VLAN_TABLE_SIZE 4096 #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 IPV4_SRC_TUNNEL_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define IPV6_SRC_TUNNEL_TABLE_SIZE MIN_SRAM_TABLE_SIZE +#define TUNNEL_SRC_REWRITE_TABLE_SIZE MIN_SRAM_TABLE_SIZE +#define TUNNEL_DST_REWRITE_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 @@ -45,10 +47,10 @@ limitations under the License. #define INGRESS_MAC_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IP_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IPV6_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE -#define INGRESS_QOS_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IP_RACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IPV6_RACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define IP_NAT_TABLE_SIZE MIN_SRAM_TABLE_SIZE +#define IP_NAT_FLOW_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define EGRESS_NAT_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define IPV4_LPM_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define IPV6_LPM_TABLE_SIZE MIN_TCAM_TABLE_SIZE @@ -100,3 +102,11 @@ limitations under the License. #define SFLOW_INGRESS_TABLE_SIZE 512 #define SFLOW_EGRESS_TABLE_SIZE 512 #define MAX_SFLOW_SESSIONS 16 + +#define INGRESS_QOS_MAP_TABLE_SIZE 512 +#define EGRESS_QOS_MAP_TABLE_SIZE 512 +#define QUEUE_TABLE_SIZE 512 +#define DSCP_TO_TC_AND_COLOR_TABLE_SIZE 64 +#define PCP_TO_TC_AND_COLOR_TABLE_SIZE 64 + +#define COPP_TABLE_SIZE 128 diff --git a/p4src/ipv4.p4 b/p4src/ipv4.p4 index 9095478..b7aa087 100644 --- a/p4src/ipv4.p4 +++ b/p4src/ipv4.p4 @@ -38,7 +38,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_dscp, ipv4.diffserv); modify_field(l3_metadata.lkp_ip_version, ipv4.version); } @@ -51,11 +51,7 @@ table validate_outer_ipv4_packet { reads { ipv4.version : ternary; ipv4.ttl : ternary; -#ifndef __TARGET_BMV2__ ipv4.srcAddr mask 0xFF000000 : ternary; -#else - ipv4.srcAddr : ternary; -#endif } actions { set_valid_outer_ipv4_packet; diff --git a/p4src/ipv6.p4 b/p4src/ipv6.p4 index d6767ea..6898685 100644 --- a/p4src/ipv6.p4 +++ b/p4src/ipv6.p4 @@ -39,7 +39,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_dscp, ipv6.trafficClass); modify_field(l3_metadata.lkp_ip_version, ipv6.version); } @@ -57,11 +57,7 @@ table validate_outer_ipv6_packet { reads { ipv6.version : ternary; ipv6.hopLimit : ternary; -#ifndef __TARGET_BMV2__ ipv6.srcAddr mask 0xFFFF0000000000000000000000000000 : ternary; -#else - ipv6.srcAddr : ternary; -#endif } actions { set_valid_outer_ipv6_packet; diff --git a/p4src/l2.p4 b/p4src/l2.p4 index dad7a52..000c2bc 100644 --- a/p4src/l2.p4 +++ b/p4src/l2.p4 @@ -24,9 +24,10 @@ header_type l2_metadata_t { lkp_mac_da : 48; lkp_pkt_type : 3; lkp_mac_type : 16; + lkp_pcp: 3; l2_nexthop : 16; /* next hop from l2 */ - l2_nexthop_type : 1; /* ecmp or nexthop */ + l2_nexthop_type : 2; /* ecmp or nexthop */ l2_redirect : 1; /* l2 redirect action */ l2_src_miss : 1; /* l2 source miss */ l2_src_move : IFINDEX_BIT_WIDTH; /* l2 source interface mis-match */ @@ -104,7 +105,7 @@ action dmac_hit(ifindex) { } action dmac_multicast_hit(mc_index) { - modify_field(intrinsic_mcast_grp, mc_index); + modify_field(intrinsic_metadata.mcast_grp, mc_index); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, FABRIC_DEVICE_MULTICAST); #endif /* FABRIC_ENABLE */ @@ -158,7 +159,8 @@ table dmac { control process_mac { #ifndef L2_DISABLE - if (ingress_metadata.port_type == PORT_TYPE_NORMAL) { + if (DO_LOOKUP(SMAC_CHK) and + (ingress_metadata.port_type == PORT_TYPE_NORMAL)) { apply(smac); } if (DO_LOOKUP(L2)) { @@ -239,26 +241,14 @@ action set_malformed_packet(drop_reason) { table validate_packet { reads { -#ifndef __TARGET_BMV2__ - l2_metadata.lkp_mac_sa mask 0x010000000000 : ternary; -#else l2_metadata.lkp_mac_sa : ternary; -#endif l2_metadata.lkp_mac_da : ternary; l3_metadata.lkp_ip_type : ternary; l3_metadata.lkp_ip_ttl : ternary; l3_metadata.lkp_ip_version : ternary; -#ifndef __TARGET_BMV2__ ipv4_metadata.lkp_ipv4_sa mask 0xFF000000 : ternary; -#else - ipv4_metadata.lkp_ipv4_sa : ternary; -#endif #ifndef IPV6_DISABLE -#ifndef __TARGET_BMV2__ ipv6_metadata.lkp_ipv6_sa mask 0xFFFF0000000000000000000000000000 : ternary; -#else - ipv6_metadata.lkp_ipv6_sa : ternary; -#endif #endif /* IPV6_DISABLE */ } actions { @@ -274,7 +264,8 @@ table validate_packet { } control process_validate_packet { - if (ingress_metadata.drop_flag == FALSE) { + if (DO_LOOKUP(PKT_VALIDATION) and + (ingress_metadata.drop_flag == FALSE)) { apply(validate_packet); } } @@ -308,8 +299,9 @@ control process_egress_bd_stats { #endif /* STATS_DISABLE */ } -action set_egress_bd_properties(smac_idx) { +action set_egress_bd_properties(smac_idx, nat_mode) { modify_field(egress_metadata.smac_idx, smac_idx); + modify_field(nat_metadata.egress_nat_mode, nat_mode); } table egress_bd_map { diff --git a/p4src/l3.p4 b/p4src/l3.p4 index cadbc0a..807ca3d 100644 --- a/p4src/l3.p4 +++ b/p4src/l3.p4 @@ -27,7 +27,7 @@ header_type l3_metadata_t { lkp_ip_type : 2; lkp_ip_version : 4; lkp_ip_proto : 8; - lkp_ip_tc : 8; + lkp_dscp : 8; lkp_ip_ttl : 8; lkp_l4_sport : 16; lkp_l4_dport : 16; @@ -43,7 +43,7 @@ header_type l3_metadata_t { urpf_bd_group : BD_BIT_WIDTH; /* urpf bd group */ fib_hit : 1; /* fib hit */ fib_nexthop : 16; /* next hop from fib */ - fib_nexthop_type : 1; /* ecmp or nexthop */ + fib_nexthop_type : 2; /* ecmp or nexthop */ same_bd_check : BD_BIT_WIDTH; /* ingress bd xor egress bd */ nexthop_index : 16; /* nexthop/rewrite index */ routed : 1; /* is packet routed? */ @@ -153,21 +153,33 @@ table smac_rewrite { action ipv4_unicast_rewrite() { modify_field(ethernet.dstAddr, egress_metadata.mac_da); add_to_field(ipv4.ttl, -1); +#ifndef QOS_DISABLE + modify_field(ipv4.diffserv, l3_metadata.lkp_dscp); +#endif /* QOS_DISABLE */ } action ipv4_multicast_rewrite() { bit_or(ethernet.dstAddr, ethernet.dstAddr, 0x01005E000000); add_to_field(ipv4.ttl, -1); +#ifndef QOS_DISABLE + modify_field(ipv4.diffserv, l3_metadata.lkp_dscp); +#endif /* QOS_DISABLE */ } action ipv6_unicast_rewrite() { modify_field(ethernet.dstAddr, egress_metadata.mac_da); add_to_field(ipv6.hopLimit, -1); +#ifndef QOS_DISABLE + modify_field(ipv6.trafficClass, l3_metadata.lkp_dscp); +#endif /* QOS_DISABLE */ } action ipv6_multicast_rewrite() { bit_or(ethernet.dstAddr, ethernet.dstAddr, 0x333300000000); add_to_field(ipv6.hopLimit, -1); +#ifndef QOS_DISABLE + modify_field(ipv6.trafficClass, l3_metadata.lkp_dscp); +#endif /* QOS_DISABLE */ } action mpls_rewrite() { @@ -208,10 +220,12 @@ table l3_rewrite { } control process_mac_rewrite { +#if !defined(L3_DISABLE) if (egress_metadata.routed == TRUE) { apply(l3_rewrite); apply(smac_rewrite); } +#endif /* L3_DISABLE */ } diff --git a/p4src/meter.p4 b/p4src/meter.p4 index 52c0442..ca8e400 100644 --- a/p4src/meter.p4 +++ b/p4src/meter.p4 @@ -19,7 +19,7 @@ limitations under the License. */ header_type meter_metadata_t { fields { - meter_color : 2; /* meter color */ + packet_color : 2; /* packet color */ meter_index : 16; /* meter index */ } } @@ -45,7 +45,7 @@ counter meter_stats { table meter_action { reads { - meter_metadata.meter_color : exact; + meter_metadata.packet_color : exact; meter_metadata.meter_index : exact; } @@ -59,7 +59,7 @@ table meter_action { meter meter_index { type : bytes; direct : meter_index; - result : meter_metadata.meter_color; + result : meter_metadata.packet_color; } table meter_index { diff --git a/p4src/mirror.p4 b/p4src/mirror.p4 index eb5421b..2041984 100644 --- a/p4src/mirror.p4 +++ b/p4src/mirror.p4 @@ -40,3 +40,9 @@ table mirror { } size : MIRROR_SESSIONS_TABLE_SIZE; } + +control process_mirroring { +#ifndef MIRROR_DISABLE + apply(mirror); +#endif /* MIRROR_DISABLE */ +} diff --git a/p4src/multicast.p4 b/p4src/multicast.p4 index e23e6a6..2992714 100644 --- a/p4src/multicast.p4 +++ b/p4src/multicast.p4 @@ -84,7 +84,7 @@ control process_outer_multicast_rpf { /*****************************************************************************/ #if !defined(TUNNEL_DISABLE) && !defined(MULTICAST_DISABLE) action outer_multicast_bridge_star_g_hit(mc_index) { - modify_field(intrinsic_mcast_grp, mc_index); + modify_field(intrinsic_metadata.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_mcast_grp, mc_index); + modify_field(intrinsic_metadata.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_mcast_grp, mc_index); + modify_field(intrinsic_metadata.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_mcast_grp, mc_index); + modify_field(intrinsic_metadata.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_mcast_grp, mc_index); + modify_field(intrinsic_metadata.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); @@ -542,7 +542,7 @@ control process_multicast { /* Multicast flooding */ /*****************************************************************************/ action set_bd_flood_mc_index(mc_index) { - modify_field(intrinsic_mcast_grp, mc_index); + modify_field(intrinsic_metadata.mcast_grp, mc_index); } table bd_flood { @@ -592,7 +592,7 @@ action inner_replica_from_rid(bd, tunnel_index, tunnel_type, header_count) { table rid { reads { - egress_egress_rid : exact; + intrinsic_metadata.egress_rid: exact; } actions { nop; @@ -621,7 +621,7 @@ table replica_type { control process_replication { #ifndef MULTICAST_DISABLE - if(egress_egress_rid != 0) { + if(intrinsic_metadata.egress_rid != 0) { /* set info from rid */ apply(rid); diff --git a/p4src/nat.p4 b/p4src/nat.p4 new file mode 100644 index 0000000..26637b8 --- /dev/null +++ b/p4src/nat.p4 @@ -0,0 +1,246 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* + * NAT processing + */ + +header_type nat_metadata_t { + fields { + ingress_nat_mode : 2; /* 0: none, 1: inside, 2: outside */ + egress_nat_mode : 2; /* nat mode of egress_bd */ + nat_nexthop : 16; /* next hop from nat */ + nat_nexthop_type : 2; /* ecmp or nexthop */ + nat_hit : 1; /* fwd and rewrite info from nat */ + nat_rewrite_index : 14; /* NAT rewrite index */ + update_checksum : 1; /* update tcp/udp checksum */ + update_inner_checksum : 1; /* update inner tcp/udp checksum */ + l4_len : 16; /* l4 length */ + } +} + +metadata nat_metadata_t nat_metadata; + +#ifndef NAT_DISABLE +/*****************************************************************************/ +/* Ingress NAT lookup - src, dst, twice */ +/*****************************************************************************/ +/* + * packet has matched source nat binding, provide rewrite index for source + * ip/port rewrite + */ +action set_src_nat_rewrite_index(nat_rewrite_index) { + modify_field(nat_metadata.nat_rewrite_index, nat_rewrite_index); +} + +/* + * packet has matched destination nat binding, provide nexthop index for + * forwarding and rewrite index for destination ip/port rewrite + */ +action set_dst_nat_nexthop_index(nexthop_index, nexthop_type, + nat_rewrite_index) { + modify_field(nat_metadata.nat_nexthop, nexthop_index); + modify_field(nat_metadata.nat_nexthop_type, nexthop_type); + modify_field(nat_metadata.nat_rewrite_index, nat_rewrite_index); + modify_field(nat_metadata.nat_hit, TRUE); +} + +/* + * packet has matched twice nat binding, provide nexthop index for forwarding, + * and rewrite index for source and destination ip/port rewrite + */ +action set_twice_nat_nexthop_index(nexthop_index, nexthop_type, + nat_rewrite_index) { + modify_field(nat_metadata.nat_nexthop, nexthop_index); + modify_field(nat_metadata.nat_nexthop_type, nexthop_type); + modify_field(nat_metadata.nat_rewrite_index, nat_rewrite_index); + modify_field(nat_metadata.nat_hit, TRUE); +} + +table nat_src { + reads { + l3_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_sa : exact; + l3_metadata.lkp_ip_proto : exact; + l3_metadata.lkp_l4_sport : exact; + } + actions { + on_miss; + set_src_nat_rewrite_index; + } + size : IP_NAT_TABLE_SIZE; +} + +table nat_dst { + reads { + l3_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_da : exact; + l3_metadata.lkp_ip_proto : exact; + l3_metadata.lkp_l4_dport : exact; + } + actions { + on_miss; + set_dst_nat_nexthop_index; + } + size : IP_NAT_TABLE_SIZE; +} + +table nat_twice { + reads { + l3_metadata.vrf : exact; + ipv4_metadata.lkp_ipv4_sa : exact; + ipv4_metadata.lkp_ipv4_da : exact; + l3_metadata.lkp_ip_proto : exact; + l3_metadata.lkp_l4_sport : exact; + l3_metadata.lkp_l4_dport : exact; + } + actions { + on_miss; + set_twice_nat_nexthop_index; + } + size : IP_NAT_TABLE_SIZE; +} + +table nat_flow { + reads { + l3_metadata.vrf : ternary; + ipv4_metadata.lkp_ipv4_sa : ternary; + ipv4_metadata.lkp_ipv4_da : ternary; + l3_metadata.lkp_ip_proto : ternary; + l3_metadata.lkp_l4_sport : ternary; + l3_metadata.lkp_l4_dport : ternary; + } + actions { + nop; + set_src_nat_rewrite_index; + set_dst_nat_nexthop_index; + set_twice_nat_nexthop_index; + } + size : IP_NAT_FLOW_TABLE_SIZE; +} +#endif /* NAT_DISABLE */ + +control process_ingress_nat { +#ifndef NAT_DISABLE + apply(nat_twice) { + on_miss { + apply(nat_dst) { + on_miss { + apply(nat_src) { + on_miss { + apply(nat_flow); + } + } + } + } + } + } +#endif /* NAT DISABLE */ +} + + +/*****************************************************************************/ +/* Egress NAT rewrite */ +/*****************************************************************************/ +#ifndef NAT_DISABLE +action nat_update_l4_checksum() { + modify_field(nat_metadata.update_checksum, 1); + add(nat_metadata.l4_len, ipv4.totalLen, -20); +} + +action set_nat_src_rewrite(src_ip) { + modify_field(ipv4.srcAddr, src_ip); + nat_update_l4_checksum(); +} + +action set_nat_dst_rewrite(dst_ip) { + modify_field(ipv4.dstAddr, dst_ip); + nat_update_l4_checksum(); +} + +action set_nat_src_dst_rewrite(src_ip, dst_ip) { + modify_field(ipv4.srcAddr, src_ip); + modify_field(ipv4.dstAddr, dst_ip); + nat_update_l4_checksum(); +} + +action set_nat_src_udp_rewrite(src_ip, src_port) { + modify_field(ipv4.srcAddr, src_ip); + modify_field(udp.srcPort, src_port); + nat_update_l4_checksum(); +} + +action set_nat_dst_udp_rewrite(dst_ip, dst_port) { + modify_field(ipv4.dstAddr, dst_ip); + modify_field(udp.dstPort, dst_port); + nat_update_l4_checksum(); +} + +action set_nat_src_dst_udp_rewrite(src_ip, dst_ip, src_port, dst_port) { + modify_field(ipv4.srcAddr, src_ip); + modify_field(ipv4.dstAddr, dst_ip); + modify_field(udp.srcPort, src_port); + modify_field(udp.dstPort, dst_port); + nat_update_l4_checksum(); +} + +action set_nat_src_tcp_rewrite(src_ip, src_port) { + modify_field(ipv4.srcAddr, src_ip); + modify_field(tcp.srcPort, src_port); + nat_update_l4_checksum(); +} + +action set_nat_dst_tcp_rewrite(dst_ip, dst_port) { + modify_field(ipv4.dstAddr, dst_ip); + modify_field(tcp.dstPort, dst_port); + nat_update_l4_checksum(); +} + +action set_nat_src_dst_tcp_rewrite(src_ip, dst_ip, src_port, dst_port) { + modify_field(ipv4.srcAddr, src_ip); + modify_field(ipv4.dstAddr, dst_ip); + modify_field(tcp.srcPort, src_port); + modify_field(tcp.dstPort, dst_port); + nat_update_l4_checksum(); +} + +table egress_nat { + reads { + nat_metadata.nat_rewrite_index : exact; + } + actions { + nop; + set_nat_src_rewrite; + set_nat_dst_rewrite; + set_nat_src_dst_rewrite; + set_nat_src_udp_rewrite; + set_nat_dst_udp_rewrite; + set_nat_src_dst_udp_rewrite; + set_nat_src_tcp_rewrite; + set_nat_dst_tcp_rewrite; + set_nat_src_dst_tcp_rewrite; + } + size : EGRESS_NAT_TABLE_SIZE; +} +#endif /* NAT_DISABLE */ + +control process_egress_nat { +#ifndef NAT_DISABLE + if ((nat_metadata.ingress_nat_mode != NAT_MODE_NONE) and + (nat_metadata.ingress_nat_mode != nat_metadata.egress_nat_mode)) { + apply(egress_nat); + } +#endif /* NAT_DISABLE */ +} diff --git a/p4src/nexthop.p4 b/p4src/nexthop.p4 index 54dec82..becd415 100644 --- a/p4src/nexthop.p4 +++ b/p4src/nexthop.p4 @@ -23,7 +23,7 @@ limitations under the License. */ header_type nexthop_metadata_t { fields { - nexthop_type : 1; /* final next hop index type */ + nexthop_type : 2; /* final next hop index type */ } } @@ -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_mcast_grp, 0); + modify_field(intrinsic_metadata.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_mcast_grp, 0); + modify_field(intrinsic_metadata.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_mcast_grp, 0); + modify_field(intrinsic_metadata.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_mcast_grp, 0); + modify_field(intrinsic_metadata.mcast_grp, 0); /* set the reason code incase packet is redirected to cpu */ modify_field(fabric_metadata.reason_code, CPU_REASON_CODE_L3_REDIRECT); #ifdef FABRIC_ENABLE @@ -75,10 +75,20 @@ action set_fib_redirect_action() { #endif /* FABRIC_ENABLE */ } +action set_nat_redirect_action() { + modify_field(l3_metadata.nexthop_index, nat_metadata.nat_nexthop); + modify_field(nexthop_metadata.nexthop_type, nat_metadata.nat_nexthop_type); + modify_field(l3_metadata.routed, TRUE); + modify_field(intrinsic_metadata.mcast_grp, 0); +#ifdef FABRIC_ENABLE + modify_field(fabric_metadata.dst_device, 0); +#endif /* FABRIC_ENABLE */ +} + action set_cpu_redirect_action() { modify_field(l3_metadata.routed, FALSE); - modify_field(intrinsic_mcast_grp, 0); - modify_field(ingress_egress_port, CPU_PORT_ID); + modify_field(intrinsic_metadata.mcast_grp, 0); + modify_field(standard_metadata.egress_spec, CPU_PORT_ID); modify_field(ingress_metadata.egress_ifindex, 0); #ifdef FABRIC_ENABLE modify_field(fabric_metadata.dst_device, 0); @@ -90,7 +100,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_mcast_grp, + modify_field(intrinsic_metadata.mcast_grp, multicast_metadata.multicast_route_mc_index); modify_field(l3_metadata.routed, TRUE); modify_field(l3_metadata.same_bd_check, 0xFFFF); @@ -101,7 +111,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_mcast_grp, + modify_field(intrinsic_metadata.mcast_grp, multicast_metadata.multicast_bridge_mc_index); } @@ -124,6 +134,7 @@ table fwd_result { acl_metadata.racl_redirect : ternary; l3_metadata.rmac_hit : ternary; l3_metadata.fib_hit : ternary; + nat_metadata.nat_hit : ternary; l2_metadata.lkp_pkt_type : ternary; l3_metadata.lkp_ip_type : ternary; multicast_metadata.igmp_snooping_enabled : ternary; @@ -138,10 +149,11 @@ table fwd_result { set_l2_redirect_action; set_fib_redirect_action; set_cpu_redirect_action; -#ifndef ACL_DISABLE set_acl_redirect_action; set_racl_redirect_action; -#endif /* ACL_DISABLE */ +#ifndef NAT_DISABLE + set_nat_redirect_action; +#endif /* NAT_DISABLE */ #ifndef MULTICAST_DISABLE set_multicast_route_action; set_multicast_bridge_action; @@ -168,7 +180,7 @@ control process_fwd_results { */ action set_ecmp_nexthop_details_for_post_routed_flood(bd, uuc_mc_index, nhop_index) { - modify_field(intrinsic_mcast_grp, uuc_mc_index); + modify_field(intrinsic_metadata.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); @@ -230,7 +242,7 @@ table ecmp_group { * egress BD */ action set_nexthop_details_for_post_routed_flood(bd, uuc_mc_index) { - modify_field(intrinsic_mcast_grp, uuc_mc_index); + modify_field(intrinsic_metadata.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/port.p4 b/p4src/port.p4 index 333c857..b083ddb 100644 --- a/p4src/port.p4 +++ b/p4src/port.p4 @@ -29,16 +29,19 @@ action set_valid_outer_unicast_packet_untagged() { 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } action set_valid_outer_multicast_packet_untagged() { @@ -49,16 +52,19 @@ action set_valid_outer_multicast_packet_untagged() { 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } action set_valid_outer_broadcast_packet_untagged() { @@ -69,16 +75,19 @@ action set_valid_outer_broadcast_packet_untagged() { 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } 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(l2_metadata.lkp_pcp, vlan_tag_[0].pcp); } action malformed_outer_ethernet_packet(drop_reason) { @@ -153,13 +162,20 @@ table ingress_port_mapping { size : PORTMAP_TABLE_SIZE; } -action set_ingress_port_properties(if_label) { +action set_ingress_port_properties(if_label, qos_group, tc_qos_group, + tc, color, trust_dscp, trust_pcp) { modify_field(acl_metadata.if_label, if_label); + modify_field(qos_metadata.ingress_qos_group, qos_group); + modify_field(qos_metadata.tc_qos_group, tc_qos_group); + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); + modify_field(qos_metadata.trust_dscp, trust_dscp); + modify_field(qos_metadata.trust_pcp, trust_pcp); } table ingress_port_properties { reads { - ingress_input_port : exact; + standard_metadata.ingress_port : exact; } actions { set_ingress_port_properties; @@ -240,6 +256,10 @@ table port_vlan_mapping { control process_port_vlan_mapping { apply(port_vlan_mapping); +#ifdef TUNNEL_DISABLE + apply(adjust_lkp_fields); +#endif + } @@ -300,7 +320,7 @@ action set_lag_remote_port(device, port) { #endif /* FABRIC_ENABLE */ action set_lag_port(port) { - modify_field(ingress_egress_port, port); + modify_field(standard_metadata.egress_spec, port); } action set_lag_miss() { @@ -334,29 +354,29 @@ control process_lag { /*****************************************************************************/ /* Egress port lookup */ /*****************************************************************************/ -action egress_port_type_normal(ifindex) { +action egress_port_type_normal(ifindex, qos_group) { modify_field(egress_metadata.port_type, PORT_TYPE_NORMAL); modify_field(egress_metadata.ifindex, ifindex); + modify_field(qos_metadata.egress_qos_group, qos_group); } 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 { - egress_egress_port : exact; + standard_metadata.egress_port : exact; } + actions { egress_port_type_normal; egress_port_type_fabric; diff --git a/p4src/qos.p4 b/p4src/qos.p4 new file mode 100644 index 0000000..085fca0 --- /dev/null +++ b/p4src/qos.p4 @@ -0,0 +1,163 @@ + +/*****************************************************************************/ +/* Qos Processing */ +/*****************************************************************************/ + +header_type qos_metadata_t { + fields { + ingress_qos_group: 5; + tc_qos_group: 5; + egress_qos_group: 5; + lkp_tc: 8; + trust_dscp: 1; + trust_pcp: 1; + } +} + +metadata qos_metadata_t qos_metadata; + +/*****************************************************************************/ +/* Ingress QOS Map */ +/*****************************************************************************/ +#ifndef QOS_DISABLE +action set_ingress_tc_and_color(tc, color) { + modify_field(qos_metadata.lkp_tc, tc); + modify_field(meter_metadata.packet_color, color); +} + +action set_ingress_tc(tc) { + modify_field(qos_metadata.lkp_tc, tc); +} + +action set_ingress_color(color) { + modify_field(meter_metadata.packet_color, color); +} + +table ingress_qos_map_dscp { + reads { + qos_metadata.ingress_qos_group: ternary; + l3_metadata.lkp_dscp: ternary; + } + + actions { + nop; + set_ingress_tc; + set_ingress_color; + set_ingress_tc_and_color; + } + + size: DSCP_TO_TC_AND_COLOR_TABLE_SIZE; +} + +table ingress_qos_map_pcp { + reads { + qos_metadata.ingress_qos_group: ternary; + l2_metadata.lkp_pcp: ternary; + } + + actions { + nop; + set_ingress_tc; + set_ingress_color; + set_ingress_tc_and_color; + } + + size: PCP_TO_TC_AND_COLOR_TABLE_SIZE; +} + +#endif /* QOS_DISABLE */ + +control process_ingress_qos_map { +#ifndef QOS_DISABLE + if (DO_LOOKUP(QOS)) { + if (qos_metadata.trust_dscp == TRUE) { + apply(ingress_qos_map_dscp); + } else { + if (qos_metadata.trust_pcp == TRUE) { + apply(ingress_qos_map_pcp); + } + } + } +#endif /* QOS_DISABLE */ +} + + +/*****************************************************************************/ +/* Queuing */ +/*****************************************************************************/ + +#ifndef QOS_DISABLE +action set_icos(icos) { + modify_field(intrinsic_metadata.ingress_cos, icos); +} + +action set_queue(qid) { + modify_field(intrinsic_metadata.qid, qid); +} + +action set_icos_and_queue(icos, qid) { + modify_field(intrinsic_metadata.ingress_cos, icos); + modify_field(intrinsic_metadata.qid, qid); +} + +table traffic_class { + reads { + qos_metadata.tc_qos_group: ternary; + qos_metadata.lkp_tc: ternary; + } + + actions { + nop; + set_icos; + set_queue; + set_icos_and_queue; + } + size: QUEUE_TABLE_SIZE; +} +#endif /* QOS_DISABLE */ + +control process_traffic_class{ +#ifndef QOS_DISABLE + apply(traffic_class); +#endif /* QOS_DISABLE */ +} + +/*****************************************************************************/ +/* Egress QOS Map */ +/*****************************************************************************/ +#ifndef QOS_DISABLE +action set_mpls_exp_marking(exp) { + modify_field(l3_metadata.lkp_dscp, exp); +} + +action set_ip_dscp_marking(dscp) { + modify_field(l3_metadata.lkp_dscp, dscp); +} + +action set_vlan_pcp_marking(pcp) { + modify_field(l2_metadata.lkp_pcp, pcp); +} + +table egress_qos_map { + reads { + qos_metadata.egress_qos_group: ternary; + qos_metadata.lkp_tc: ternary; + //meter_metadata.packet_color : ternary; + } + actions { + nop; + set_mpls_exp_marking; + set_ip_dscp_marking; + set_vlan_pcp_marking; + } + size: EGRESS_QOS_MAP_TABLE_SIZE; +} +#endif /* QOS_DISABLE */ + +control process_egress_qos_map { +#ifndef QOS_DISABLE + if (DO_LOOKUP(QOS)) { + apply(egress_qos_map); + } +#endif /* QOS_DISABLE */ +} diff --git a/p4src/security.p4 b/p4src/security.p4 index 48e4f71..1ccd5a6 100644 --- a/p4src/security.p4 +++ b/p4src/security.p4 @@ -23,7 +23,6 @@ limitations under the License. */ header_type security_metadata_t { fields { - storm_control_color : 1; /* 0 : pass, 1 : fail */ ipsg_enabled : 1; /* is ip source guard feature enabled */ ipsg_check_fail : 1; /* ipsg check failed */ } @@ -43,8 +42,8 @@ counter storm_control_stats { table storm_control_stats { reads { - meter_metadata.meter_color: exact; - ingress_input_port: exact; + meter_metadata.packet_color: exact; + standard_metadata.ingress_port : exact; } actions { nop; @@ -57,7 +56,7 @@ table storm_control_stats { meter storm_control_meter { type : bytes; static : storm_control; - result : meter_metadata.meter_color; + result : meter_metadata.packet_color; instance_count : STORM_CONTROL_METER_TABLE_SIZE; } #endif /* METER_DISABLE */ @@ -65,14 +64,14 @@ meter storm_control_meter { action set_storm_control_meter(meter_idx) { #ifndef METER_DISABLE execute_meter(storm_control_meter, meter_idx, - meter_metadata.meter_color); + meter_metadata.packet_color); modify_field(meter_metadata.meter_index, meter_idx); #endif /* METER_DISABLE */ } table storm_control { reads { - ingress_input_port : exact; + standard_metadata.ingress_port : exact; l2_metadata.lkp_pkt_type : ternary; } actions { diff --git a/p4src/sflow.p4 b/p4src/sflow.p4 index 1530371..ae82762 100644 --- a/p4src/sflow.p4 +++ b/p4src/sflow.p4 @@ -24,7 +24,7 @@ metadata sflow_meta_t sflow_metadata; counter sflow_ingress_session_pkt_counter { type : packets; - direct : sflow_ing_take_sample; + direct : sflow_ingress; saturating; } #endif @@ -61,10 +61,10 @@ field_list sflow_cpu_info { cpu_info; sflow_metadata.sflow_session_id; i2e_metadata.mirror_session_id; + ingress_metadata.egress_ifindex; } -action sflow_ing_pkt_to_cpu(sflow_i2e_mirror_id, reason_code) { - modify_field(fabric_metadata.reason_code, reason_code); +action sflow_ing_pkt_to_cpu(sflow_i2e_mirror_id ) { modify_field(i2e_metadata.mirror_session_id, sflow_i2e_mirror_id); clone_ingress_pkt_to_egress(sflow_i2e_mirror_id, sflow_cpu_info); } @@ -79,6 +79,8 @@ table sflow_ing_take_sample { nop; sflow_ing_pkt_to_cpu; } + + size: MAX_SFLOW_SESSIONS; } #endif /*SFLOW_ENABLE */ @@ -90,7 +92,7 @@ control process_ingress_sflow { } /* ----- egress processing ----- */ #ifdef SFLOW_ENABLE -action sflow_pkt_to_cpu() { +action sflow_pkt_to_cpu(reason_code) { /* This action is called from the mirror table in the egress pipeline */ /* Add sflow header to the packet */ /* sflow header sits between cpu header and the rest of the original packet */ @@ -101,5 +103,8 @@ action sflow_pkt_to_cpu() { add_header(fabric_header_sflow); modify_field(fabric_header_sflow.sflow_session_id, sflow_metadata.sflow_session_id); + modify_field(fabric_header_sflow.sflow_egress_ifindex, + ingress_metadata.egress_ifindex); + modify_field(fabric_metadata.reason_code, reason_code); } #endif diff --git a/p4src/switch.p4 b/p4src/switch.p4 index 31f0745..4fcdd72 100644 --- a/p4src/switch.p4 +++ b/p4src/switch.p4 @@ -15,13 +15,13 @@ limitations under the License. */ #include "includes/p4features.h" -#include "includes/drop_reasons.h" +#include "includes/drop_reason_codes.h" +#include "includes/cpu_reason_codes.h" +#include "includes/p4_table_sizes.h" #include "includes/headers.p4" #include "includes/parser.p4" -#include "includes/sizes.p4" #include "includes/defines.p4" #include "includes/intrinsic.p4" -#include "archdeps.p4" /* METADATA */ header_type ingress_metadata_t { @@ -81,6 +81,7 @@ metadata global_config_metadata_t global_config_metadata; #include "ipv6.p4" #include "tunnel.p4" #include "acl.p4" +#include "nat.p4" #include "multicast.p4" #include "nexthop.p4" #include "rewrite.p4" @@ -92,6 +93,7 @@ metadata global_config_metadata_t global_config_metadata; #include "hashes.p4" #include "meter.p4" #include "sflow.p4" +#include "qos.p4" action nop() { } @@ -106,33 +108,30 @@ control ingress { /* process outer packet headers */ process_validate_outer_header(); - /* read and apply system confuration parametes */ + /* read and apply system configuration parametes */ process_global_params(); -#ifdef OPENFLOW_ENABLE - if (ingress_metadata.port_type == PORT_TYPE_CPU) { - apply(packet_out); - } -#endif /* OPENFLOW_ENABLE */ - /* derive bd and its properties */ process_port_vlan_mapping(); /* spanning tree state checks */ process_spanning_tree(); + /* ingress qos map */ + process_ingress_qos_map(); + /* IPSG */ process_ip_sourceguard(); /* INT src,sink determination */ process_int_endpoint(); - /* tunnel termination processing */ - process_tunnel(); - /* ingress sflow determination */ process_ingress_sflow(); + /* tunnel termination processing */ + process_tunnel(); + /* storm control */ process_storm_control(); @@ -154,8 +153,6 @@ control ingress { process_ip_acl(); } - process_qos(); - apply(rmac) { rmac_miss { process_multicast(); @@ -166,14 +163,12 @@ control ingress { (ipv4_metadata.ipv4_unicast_enabled == TRUE)) { /* router ACL/PBR */ process_ipv4_racl(); - process_ipv4_urpf(); process_ipv4_fib(); } 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(); @@ -184,6 +179,9 @@ control ingress { } } } + + /* ingress NAT */ + process_ingress_nat(); #ifndef MPLS_DISABLE } #endif /* MPLS_DISABLE */ @@ -208,6 +206,11 @@ control ingress { /* ecmp/nexthop lookup */ process_nexthop(); +#ifdef OPENFLOW_ENABLE + /* openflow processing for ingress */ + process_ofpat_ingress(); +#endif /* OPENFLOW_ENABLE */ + if (ingress_metadata.egress_ifindex == IFINDEX_FLOOD) { /* resolve multicast index for flooding */ process_multicast_flooding(); @@ -216,11 +219,6 @@ control ingress { process_lag(); } -#ifdef OPENFLOW_ENABLE - /* openflow processing for ingress */ - process_ofpat_ingress(); -#endif /* OPENFLOW_ENABLE */ - /* generate learn notify digest if permitted */ process_mac_learning(); } @@ -228,6 +226,9 @@ control ingress { /* resolve fabric port to destination device */ process_fabric_lag(); + /* set queue id for tm */ + process_traffic_class(); + if (ingress_metadata.port_type != PORT_TYPE_FABRIC) { /* system acls */ process_system_acl(); @@ -235,7 +236,6 @@ control ingress { } control egress { - #ifdef OPENFLOW_ENABLE if (openflow_metadata.ofvalid == TRUE) { process_ofpat_egress(); @@ -267,13 +267,15 @@ control egress { /* perform tunnel decap */ process_tunnel_decap(); - /* apply nexthop_index based packet rewrites */ process_rewrite(); /* egress bd properties */ process_egress_bd(); + /* egress qos map */ + process_egress_qos_map(); + /* rewrite source/destination mac if needed */ process_mac_rewrite(); @@ -283,6 +285,10 @@ control egress { /* INT processing */ process_int_insertion(); + /* egress nat processing */ + process_egress_nat(); + + /* update egress bd stats */ process_egress_bd_stats(); } } diff --git a/p4src/switch_config.p4 b/p4src/switch_config.p4 index e72b1b2..b158e86 100644 --- a/p4src/switch_config.p4 +++ b/p4src/switch_config.p4 @@ -26,9 +26,9 @@ action set_config_parameters(enable_dod) { /* initialization */ modify_field(i2e_metadata.ingress_tstamp, _ingress_global_tstamp_); - modify_field(ingress_metadata.ingress_port, ingress_input_port); + modify_field(ingress_metadata.ingress_port, standard_metadata.ingress_port); modify_field(l2_metadata.same_if_check, ingress_metadata.ifindex); - modify_field(ingress_egress_port, INVALID_PORT_ID); + modify_field(standard_metadata.egress_spec, INVALID_PORT_ID); #ifdef SFLOW_ENABLE /* use 31 bit random number generator and detect overflow into upper half * to decide to take a sample diff --git a/p4src/tunnel.p4 b/p4src/tunnel.p4 index 075dc27..58ef42b 100644 --- a/p4src/tunnel.p4 +++ b/p4src/tunnel.p4 @@ -40,6 +40,7 @@ header_type tunnel_metadata_t { tunnel_if_check : 1; /* tun terminate xor originate */ egress_header_count: 4; /* number of mpls header stack */ inner_ip_proto : 8; /* Inner IP protocol */ + skip_encap_inner : 1; /* skip encap_process_inner */ } } metadata tunnel_metadata_t tunnel_metadata; @@ -106,7 +107,7 @@ table ipv4_src_vtep { on_miss; src_vtep_hit; } - size : SRC_TUNNEL_TABLE_SIZE; + size : IPV4_SRC_TUNNEL_TABLE_SIZE; } #endif /* IPV4_DISABLE */ @@ -145,23 +146,23 @@ table ipv6_src_vtep { #endif /* TUNNEL_DISABLE */ control process_ipv4_vtep { -#if !defined(TUNNEL_DISABLE) && !defined(L3_DISABLE) && !defined(IPV4_DISABLE) +#if !defined(TUNNEL_DISABLE) && !defined(IPV4_DISABLE) apply(ipv4_src_vtep) { src_vtep_hit { apply(ipv4_dest_vtep); } } -#endif /* TUNNEL_DISABLE && L3_DISABLE && IPV4_DISABLE */ +#endif /* TUNNEL_DISABLE && IPV4_DISABLE */ } control process_ipv6_vtep { -#if !defined(TUNNEL_DISABLE) && !defined(L3_DISABLE) && !defined(IPV6_DISABLE) +#if !defined(TUNNEL_DISABLE) && !defined(IPV6_DISABLE) apply(ipv6_src_vtep) { src_vtep_hit { apply(ipv6_dest_vtep); } } -#endif /* TUNNEL_DISABLE && L3_DISABLE && IPV6_DISABLE */ +#endif /* TUNNEL_DISABLE && IPV6_DISABLE */ } @@ -188,7 +189,6 @@ action terminate_tunnel_inner_ethernet_ipv4(bd, vrf, modify_field(tunnel_metadata.tunnel_terminate, TRUE); 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(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); @@ -198,7 +198,9 @@ action terminate_tunnel_inner_ethernet_ipv4(bd, vrf, 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); +#ifdef QOS_DISABLE + modify_field(l3_metadata.lkp_dscp, inner_ipv4.diffserv); +#endif /* QOS_DISABLE */ modify_field(multicast_metadata.igmp_snooping_enabled, igmp_snooping_enabled); @@ -212,7 +214,6 @@ action terminate_tunnel_inner_ipv4(vrf, rmac_group, ipv4_multicast_enabled, mrpf_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); @@ -221,7 +222,9 @@ action terminate_tunnel_inner_ipv4(vrf, rmac_group, modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV4); modify_field(l3_metadata.lkp_ip_version, inner_ipv4.version); - modify_field(l3_metadata.lkp_ip_tc, inner_ipv4.diffserv); +#ifdef QOS_DISABLE + modify_field(l3_metadata.lkp_dscp, inner_ipv4.diffserv); +#endif /* QOS_DISABLE */ modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); modify_field(multicast_metadata.ipv4_multicast_enabled, @@ -238,7 +241,6 @@ action terminate_tunnel_inner_ethernet_ipv6(bd, vrf, modify_field(tunnel_metadata.tunnel_terminate, TRUE); 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(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); @@ -248,7 +250,10 @@ action terminate_tunnel_inner_ethernet_ipv6(bd, vrf, 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); + +#ifdef QOS_DISABLE + modify_field(l3_metadata.lkp_dscp, inner_ipv6.trafficClass); +#endif /* QOS_DISABLE */ modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); modify_field(multicast_metadata.ipv6_multicast_enabled, @@ -261,7 +266,6 @@ action terminate_tunnel_inner_ipv6(vrf, rmac_group, ipv6_multicast_enabled, mrpf_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); @@ -270,7 +274,10 @@ action terminate_tunnel_inner_ipv6(vrf, rmac_group, modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); modify_field(l3_metadata.lkp_ip_type, IPTYPE_IPV6); modify_field(l3_metadata.lkp_ip_version, inner_ipv6.version); - modify_field(l3_metadata.lkp_ip_tc, inner_ipv6.trafficClass); + +#ifdef QOS_DISABLE + modify_field(l3_metadata.lkp_dscp, inner_ipv6.trafficClass); +#endif /* QOS_DISABLE */ modify_field(multicast_metadata.bd_mrpf_group, mrpf_group); modify_field(multicast_metadata.ipv6_multicast_enabled, @@ -305,7 +312,7 @@ table tunnel { } #endif /* TUNNEL_DISABLE */ -action ipv4_tunnel_lookup_miss() { +action ipv4_lkp() { 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); @@ -314,10 +321,11 @@ action ipv4_tunnel_lookup_miss() { 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); + + modify_field(intrinsic_metadata.mcast_grp, 0); } -action ipv6_tunnel_lookup_miss() { +action ipv6_lkp() { 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); @@ -326,25 +334,27 @@ action ipv6_tunnel_lookup_miss() { 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); + + modify_field(intrinsic_metadata.mcast_grp, 0); } -action non_ip_tunnel_lookup_miss() { +action non_ip_lkp() { modify_field(l2_metadata.lkp_mac_sa, ethernet.srcAddr); modify_field(l2_metadata.lkp_mac_da, ethernet.dstAddr); - modify_field(intrinsic_mcast_grp, 0); + + modify_field(intrinsic_metadata.mcast_grp, 0); } -table tunnel_miss { +table adjust_lkp_fields { reads { ipv4 : valid; ipv6 : valid; } actions { - non_ip_tunnel_lookup_miss; - ipv4_tunnel_lookup_miss; + non_ip_lkp; + ipv4_lkp; #ifndef IPV6_DISABLE - ipv6_tunnel_lookup_miss; + ipv6_lkp; #endif /* IPV6_DISABLE */ } } @@ -355,10 +365,10 @@ table tunnel_lookup_miss { ipv6 : valid; } actions { - non_ip_tunnel_lookup_miss; - ipv4_tunnel_lookup_miss; + non_ip_lkp; + ipv4_lkp; #ifndef IPV6_DISABLE - ipv6_tunnel_lookup_miss; + ipv6_lkp; #endif /* IPV6_DISABLE */ } } @@ -411,7 +421,7 @@ control process_tunnel { } } } else { - apply(tunnel_miss); + apply(adjust_lkp_fields); } #endif /* TUNNEL_DISABLE */ } @@ -494,7 +504,9 @@ action terminate_ipv4_over_mpls(vrf, tunnel_type) { 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); +#ifdef QOS_DISABLE + modify_field(l3_metadata.lkp_dscp, inner_ipv4.diffserv); +#endif /* QOS_DISABLE */ } #endif /* IPV4_DISABLE */ @@ -509,7 +521,9 @@ action terminate_ipv6_over_mpls(vrf, tunnel_type) { 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); +#ifdef QOS_DISABLE + modify_field(l3_metadata.lkp_dscp, inner_ipv6.trafficClass); +#endif /* QOS_DISABLE */ } #endif /* IPV6_DISABLE */ @@ -905,10 +919,10 @@ control process_tunnel_decap { } +#ifndef TUNNEL_DISABLE /*****************************************************************************/ /* Egress tunnel VNI lookup */ /*****************************************************************************/ -#ifndef TUNNEL_DISABLE action set_egress_tunnel_vni(vnid) { modify_field(tunnel_metadata.vnid, vnid); } @@ -1042,24 +1056,6 @@ action f_insert_vxlan_header() { modify_field(vxlan.reserved2, 0); } -action f_insert_ipv4_header(proto) { - add_header(ipv4); - modify_field(ipv4.protocol, proto); - modify_field(ipv4.ttl, 64); - modify_field(ipv4.version, 0x4); - modify_field(ipv4.ihl, 0x5); - modify_field(ipv4.identification, 0); -} - -action f_insert_ipv6_header(proto) { - add_header(ipv6); - modify_field(ipv6.version, 0x6); - modify_field(ipv6.nextHdr, proto); - modify_field(ipv6.hopLimit, 64); - modify_field(ipv6.trafficClass, 0); - modify_field(ipv6.flowLabel, 0); -} - action ipv4_vxlan_rewrite() { f_insert_vxlan_header(); f_insert_ipv4_header(IP_PROTOCOLS_UDP); @@ -1123,12 +1119,7 @@ action f_insert_nvgre_header() { modify_field(gre.S, 0); modify_field(gre.s, 0); modify_field(nvgre.tni, tunnel_metadata.vnid); -#ifndef __TARGET_BMV2__ modify_field(nvgre.flow_id, hash_metadata.entropy_hash, 0xFF); -#else - modify_field(nvgre.flow_id, hash_metadata.entropy_hash & 0xFF); -#endif - } action ipv4_nvgre_rewrite() { @@ -1178,37 +1169,6 @@ action ipv6_ip_rewrite() { modify_field(ethernet.etherType, ETHERTYPE_IPV6); } -action f_insert_erspan_t3_header() { - copy_header(inner_ethernet, ethernet); - add_header(gre); - add_header(erspan_t3_header); - modify_field(gre.C, 0); - modify_field(gre.R, 0); - modify_field(gre.K, 0); - modify_field(gre.S, 0); - modify_field(gre.s, 0); - modify_field(gre.recurse, 0); - modify_field(gre.flags, 0); - modify_field(gre.ver, 0); - modify_field(gre.proto, GRE_PROTOCOLS_ERSPAN_T3); - modify_field(erspan_t3_header.timestamp, i2e_metadata.ingress_tstamp); - modify_field(erspan_t3_header.span_id, i2e_metadata.mirror_session_id); - modify_field(erspan_t3_header.version, 2); - modify_field(erspan_t3_header.sgt_other, 0); -} - -action ipv4_erspan_t3_rewrite() { - f_insert_erspan_t3_header(); - f_insert_ipv4_header(IP_PROTOCOLS_GRE); - add(ipv4.totalLen, egress_metadata.payload_length, 50); -} - -action ipv6_erspan_t3_rewrite() { - f_insert_erspan_t3_header(); - f_insert_ipv6_header(IP_PROTOCOLS_GRE); - add(ipv6.payloadLen, egress_metadata.payload_length, 26); -} - #ifndef MPLS_DISABLE action mpls_ethernet_push1_rewrite() { copy_header(inner_ethernet, ethernet); @@ -1243,6 +1203,88 @@ action mpls_ip_push3_rewrite() { modify_field(ethernet.etherType, ETHERTYPE_MPLS); } #endif /* MPLS_DISABLE */ +#endif /* TUNNEL_DISABLE */ + +#if !defined(TUNNEL_DISABLE) || !defined(MIRROR_DISABLE) +action f_insert_ipv4_header(proto) { + add_header(ipv4); + modify_field(ipv4.protocol, proto); + modify_field(ipv4.ttl, 64); + modify_field(ipv4.version, 0x4); + modify_field(ipv4.ihl, 0x5); + modify_field(ipv4.identification, 0); +} + +action f_insert_ipv6_header(proto) { + add_header(ipv6); + modify_field(ipv6.version, 0x6); + modify_field(ipv6.nextHdr, proto); + modify_field(ipv6.hopLimit, 64); + modify_field(ipv6.trafficClass, 0); + modify_field(ipv6.flowLabel, 0); +} +#endif /* !TUNNEL_DISABLE || !MIRROR_DISABLE*/ + +#ifndef MIRROR_DISABLE +action f_insert_erspan_common_header() { + copy_header(inner_ethernet, ethernet); + add_header(gre); + add_header(erspan_t3_header); + modify_field(gre.C, 0); + modify_field(gre.R, 0); + modify_field(gre.K, 0); + modify_field(gre.S, 0); + modify_field(gre.s, 0); + modify_field(gre.recurse, 0); + modify_field(gre.flags, 0); + modify_field(gre.ver, 0); + modify_field(gre.proto, GRE_PROTOCOLS_ERSPAN_T3); + modify_field(erspan_t3_header.timestamp, i2e_metadata.ingress_tstamp); + modify_field(erspan_t3_header.span_id, i2e_metadata.mirror_session_id); + modify_field(erspan_t3_header.version, 2); + modify_field(erspan_t3_header.sgt, 0); +} + +action f_insert_erspan_t3_header() { + f_insert_erspan_common_header(); +} + +action ipv4_erspan_t3_rewrite() { + f_insert_erspan_t3_header(); + f_insert_ipv4_header(IP_PROTOCOLS_GRE); + add(ipv4.totalLen, egress_metadata.payload_length, 50); +} + +action ipv6_erspan_t3_rewrite() { + f_insert_erspan_t3_header(); + f_insert_ipv6_header(IP_PROTOCOLS_GRE); + add(ipv6.payloadLen, egress_metadata.payload_length, 26); +} + +#ifdef NEGATIVE_MIRRORING_ENABLE +action f_insert_erspan_negative_mirroring_header() { + f_insert_erspan_common_header(); + add_header(erspan_platform_subheader); + modify_field(erspan_t3_header.ft_d_other, 1); + modify_field_with_hash_based_offset(erspan_platform_subheader.neg_mirror, 0, + calc_neg_mirror, 0x100000000); + modify_field(erspan_platform_subheader.switch_id, + global_config_metadata.switch_id); +} + +action ipv4_erspan_nm_rewrite() { + f_insert_erspan_negative_mirroring_header(); + f_insert_ipv4_header(IP_PROTOCOLS_GRE); + add(ipv4.totalLen, egress_metadata.payload_length, 58); +} + +action ipv6_erspan_nm_rewrite() { + f_insert_erspan_negative_mirroring_header(); + f_insert_ipv6_header(IP_PROTOCOLS_GRE); + add(ipv6.payloadLen, egress_metadata.payload_length, 34); +} +#endif /* NEGATIVE_MIRRORING_ENABLE */ +#endif /* MIRROR_DISABLE */ table tunnel_encap_process_outer { reads { @@ -1252,24 +1294,24 @@ table tunnel_encap_process_outer { } actions { nop; + fabric_rewrite; +#ifndef TUNNEL_DISABLE ipv4_vxlan_rewrite; ipv4_genv_rewrite; #ifndef NVGRE_DISABLE ipv4_nvgre_rewrite; -#endif +#endif /* NVGRE_DISABLE */ ipv4_gre_rewrite; ipv4_ip_rewrite; - ipv4_erspan_t3_rewrite; #ifndef TUNNEL_OVER_IPV6_DISABLE ipv6_gre_rewrite; ipv6_ip_rewrite; #ifndef NVGRE_DISABLE ipv6_nvgre_rewrite; -#endif +#endif /* NVGRE_DISABLE */ ipv6_vxlan_rewrite; ipv6_genv_rewrite; - ipv6_erspan_t3_rewrite; -#endif +#endif /* TUNNEL_OVER_IPV6_DISABLE */ #ifndef MPLS_DISABLE mpls_ethernet_push1_rewrite; mpls_ip_push1_rewrite; @@ -1278,7 +1320,11 @@ table tunnel_encap_process_outer { mpls_ethernet_push3_rewrite; mpls_ip_push3_rewrite; #endif /* MPLS_DISABLE */ - fabric_rewrite; +#endif /* TUNNEL_DISABLE */ +#ifndef MIRROR_DISABLE + ipv4_erspan_t3_rewrite; + ipv6_erspan_t3_rewrite; +#endif /* MIRROR_DISABLE */ } size : TUNNEL_HEADER_TABLE_SIZE; } @@ -1345,13 +1391,15 @@ table tunnel_rewrite { } actions { nop; + cpu_rx_rewrite; +#if !defined(TUNNEL_DISABLE) || !defined(MIRROR_DISABLE) set_tunnel_rewrite_details; +#endif /* !TUNNEL_DISABLE || !MIRROR_DISABLE*/ #ifndef MPLS_DISABLE set_mpls_rewrite_push1; set_mpls_rewrite_push2; set_mpls_rewrite_push3; #endif /* MPLS_DISABLE */ - cpu_rx_rewrite; #ifdef FABRIC_ENABLE fabric_unicast_rewrite; #ifndef MULTICAST_DISABLE @@ -1363,6 +1411,7 @@ table tunnel_rewrite { } +#if !defined(TUNNEL_DISABLE) || !defined(MIRROR_DISABLE) /*****************************************************************************/ /* Tunnel MTU check */ /*****************************************************************************/ @@ -1410,7 +1459,7 @@ table tunnel_src_rewrite { rewrite_tunnel_ipv6_src; #endif /* IPV6_DISABLE */ } - size : DEST_TUNNEL_TABLE_SIZE; + size : TUNNEL_SRC_REWRITE_TABLE_SIZE; } @@ -1438,7 +1487,7 @@ table tunnel_dst_rewrite { rewrite_tunnel_ipv6_dst; #endif /* IPV6_DISABLE */ } - size : SRC_TUNNEL_TABLE_SIZE; + size : TUNNEL_DST_REWRITE_TABLE_SIZE; } action rewrite_tunnel_smac(smac) { @@ -1478,7 +1527,7 @@ table tunnel_dmac_rewrite { } size : TUNNEL_DMAC_REWRITE_TABLE_SIZE; } -#endif /* TUNNEL_DISABLE */ +#endif /* !TUNNEL_DISABLE || !MIRROR_DISABLE*/ /*****************************************************************************/ diff --git a/switchapi/Makefile.am b/switchapi/Makefile.am index 75089d4..22a40cb 100644 --- a/switchapi/Makefile.am +++ b/switchapi/Makefile.am @@ -9,7 +9,7 @@ TARGET_CFLAGS += $(P4C_LIBPDFIXED_CFLAGS) TARGET_CFLAGS += -I $(srcdir)/../p4src/bmv2_p4_pd endif -libswitchapi_la_CFLAGS = -I$(srcdir)/inc +libswitchapi_la_CFLAGS = -I$(srcdir)/include libswitchapi_la_CFLAGS += -I$(srcdir)/src/gen-cpp libswitchapi_la_CFLAGS += -I$(srcdir)/third-party/tommyds/include libswitchapi_la_CFLAGS += -I$(srcdir)/../p4src/includes @@ -38,6 +38,8 @@ src/switch_acl.c \ src/switch_acl_int.h \ src/switch_api_rpc_server.cpp \ src/switch_api.thrift \ +src/switch_buffer.c \ +src/switch_buffer_int.h \ src/switch_capability.c \ src/switch_capability_int.h \ src/switch_config.c \ @@ -58,11 +60,15 @@ src/switch_l3_int.h \ src/switch_lag.c \ src/switch_lag_int.h \ src/switch_log.c \ -src/switch_log.h \ +src/switch_log_int.h \ +src/switch_lpm.c \ +src/switch_lpm_int.h \ src/switch_mcast.c \ src/switch_mcast_int.h \ src/switch_mirror.c \ src/switch_mirror_int.h \ +src/switch_nat.c \ +src/switch_nat_int.h \ src/switch_neighbor.c \ src/switch_neighbor_int.h \ src/switch_nhop.c \ @@ -71,9 +77,19 @@ src/switch_packet.c \ src/switch_packet_int.h \ src/switch_pd.c \ src/switch_pd.h \ +src/switch_pd_buffer.c \ src/switch_pd_mcast.c \ +src/switch_pd_nat.c \ +src/switch_pd_ppg.c \ +src/switch_pd_qos.c \ +src/switch_pd_queue.c \ +src/switch_pd_types.h \ src/switch_port.c \ src/switch_port_int.h \ +src/switch_qos.x \ +src/switch_qos_int.h \ +src/switch_queue.c \ +src/switch_queue_int.h \ src/switch_rmac.c \ src/switch_rmac_int.h \ src/switch_stp.c \ @@ -87,36 +103,40 @@ src/switch_vrf.c \ src/switch_meter.c \ src/switch_meter_int.h \ src/switch_vrf_int.h \ +src/switch_scheduler.c \ +src/switch_scheduler_int.h \ src/switch_sflow_int.h \ src/switch_sflow.c \ src/thrift_cache.h \ -inc/switchapi/switch_acl.h \ -inc/switchapi/switch_base_types.h \ -inc/switchapi/switch_capability.h \ -inc/switchapi/switchapi/switch_config.h \ -inc/switchapi/switch_handle.h \ -inc/switchapi/switchapi/switch_hostif.h \ -inc/switchapi/switch_id.h \ -inc/switchapi/switch_interface.h \ -inc/switchapi/switch_l2.h \ -inc/switchapi/switch_l3.h \ -inc/switchapi/switch_lag.h \ -inc/switchapi/switch_mcast.h \ -inc/switchapi/switchapi/switch_meter.h \ -inc/switchapi/switch_neighbor.h \ -inc/switchapi/switch_nhop.h \ -inc/switchapi/switch_port.h \ -inc/switchapi/switch_porting.h \ -inc/switchapi/switch_protocol.h \ -inc/switchapi/switch_rmac.h \ -inc/switchapi/switch_status.h \ -inc/switchapi/switch_stp.h \ -inc/switchapi/switch_tunnel.h \ -inc/switchapi/switch_utils.h \ -inc/switchapi/switch_vlan.h \ -inc/switchapi/switch_INT.h \ -inc/switchapi/switch_vrf.h \ -inc/switchapi/switch_sflow.h +include/switchapi/switch_acl.h \ +include/switchapi/switch_base_types.h \ +include/switchapi/switch_capability.h \ +include/switchapi/switchapi/switch_config.h \ +include/switchapi/switch_handle.h \ +include/switchapi/switchapi/switch_hostif.h \ +include/switchapi/switch_id.h \ +include/switchapi/switch_interface.h \ +include/switchapi/switch_l2.h \ +include/switchapi/switch_l3.h \ +include/switchapi/switch_lag.h \ +include/switchapi/switch_mcast.h \ +include/switchapi/switchapi/switch_meter.h \ +include/switchapi/switch_neighbor.h \ +include/switchapi/switch_nhop.h \ +include/switchapi/switch_port.h \ +include/switchapi/switch_porting.h \ +include/switchapi/switch_protocol.h \ +include/switchapi/switch_qos.h \ +include/switchapi/switch_queue.h \ +include/switchapi/switch_rmac.h \ +include/switchapi/switch_status.h \ +include/switchapi/switch_stp.h \ +include/switchapi/switch_tunnel.h \ +include/switchapi/switch_utils.h \ +include/switchapi/switch_vlan.h \ +include/switchapi/switch_INT.h \ +include/switchapi/switch_vrf.h \ +include/switchapi/switch_sflow.h #libswitchapi_a_SOURCES = $(libswitchapi_la_SOURCES) libswitchapi_la_LIBADD = third-party/tommyds/libtommyds.la diff --git a/switchapi/README.md b/switchapi/README.md index e5c8500..fff1023 100644 --- a/switchapi/README.md +++ b/switchapi/README.md @@ -37,13 +37,16 @@ Supported Features 12. Mirroring: Ingress and egress mirroring with ERSPAN 13. Counters/Statistics 14. Ingress Policers +15. Lookup bypass in Cpu Tx path +16. Netfilter Rx/Tx support +17. QoS (Quality of Service) - Buffers, Queues +18. Nat +19. CoPP (Control Plance Policing) Upcoming Features ----------------- -1. NAT -2. QoS -3. VPLS +1. VPLS Documentation ------------- diff --git a/switchapi/inc/switchapi/switch_INT.h b/switchapi/inc/switchapi/switch_INT.h deleted file mode 100644 index 99e2050..0000000 --- a/switchapi/inc/switchapi/switch_INT.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2015-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _SWITCH_INT_H_ -#define _SWITCH_INT_H_ -#include "switch_base_types.h" -#include "switch_handle.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define INT_INS_MASK_VALID_BITS 0xFF00 - -switch_status_t -switch_int_transit_enable(switch_device_t device, int32_t switch_id, int32_t enable); - -switch_status_t -switch_int_src_enable(switch_device_t device, int32_t switch_id, - switch_ip_addr_t *src, - switch_ip_addr_t *dst, - uint8_t max_hop, uint16_t ins_mask - ); -switch_status_t -switch_int_src_disable(switch_device_t device, - switch_ip_addr_t *src, - switch_ip_addr_t *dst - ); -switch_status_t -switch_int_sink_enable(switch_device_t device, - switch_ip_addr_t *dst, - int32_t mirror_id - ); -switch_status_t -switch_int_sink_disable(switch_device_t device, - switch_ip_addr_t *dst - ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif // _SWITCH_INT_H_ diff --git a/switchapi/inc/switchapi/switch_acl.h b/switchapi/inc/switchapi/switch_acl.h deleted file mode 100644 index 5dc79db..0000000 --- a/switchapi/inc/switchapi/switch_acl.h +++ /dev/null @@ -1,624 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_acl_h_ -#define _switch_acl_h_ - -#include "switch_id.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup ACL ACL API - * API functions define and manipulate Access lists - * @{ - */ // begin of ACL API - -/** ACL Types */ -typedef enum switch_acl_type_ { - SWITCH_ACL_TYPE_IP, /**< IPv4 ACL */ - SWITCH_ACL_TYPE_MAC, /**< MAC ACL */ - SWITCH_ACL_TYPE_IPV6, /**< IPv6 ACL */ - SWITCH_ACL_TYPE_MIRROR, /**< Mirror ACL */ - SWITCH_ACL_TYPE_QOS, /**< QoS ACL */ - SWITCH_ACL_TYPE_SYSTEM, /**< Ingress System ACL */ - SWITCH_ACL_TYPE_EGRESS_SYSTEM, /**< Egress System ACL */ - SWITCH_ACL_TYPE_IP_RACL, /**< IPv4 Route ACL */ - SWITCH_ACL_TYPE_IPV6_RACL, /**< IPv6 Route ACL */ - SWITCH_ACL_TYPE_MAX -} switch_acl_type_t; - -/** Acl IP field enum */ -typedef enum switch_acl_ip_field_ { - SWITCH_ACL_IP_FIELD_IPV4_SRC, /**< IPv4 Source address */ - SWITCH_ACL_IP_FIELD_IPV4_DEST, /**< IPv4 Dest address */ - SWITCH_ACL_IP_FIELD_IP_PROTO, /**< IP Protocol */ - SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT, /**< L4 source port UDP/TCP */ - SWITCH_ACL_IP_FIELD_L4_DEST_PORT, /**< L4 dest port UDP/TCP */ - SWITCH_ACL_IP_FIELD_ICMP_TYPE, /**< ICMP type */ - SWITCH_ACL_IP_FIELD_ICMP_CODE, /**< ICMP code */ - SWITCH_ACL_IP_FIELD_TCP_FLAGS, /**< TCP flags */ - SWITCH_ACL_IP_FIELD_TTL, /**< TTL */ - SWITCH_ACL_IP_FIELD_DSCP, /**< DSCP */ - SWITCH_ACL_IP_FIELD_IP_FLAGS, /**< IP flags */ - SWITCH_ACL_IP_FIELD_TOS, /**< TOS */ - SWITCH_ACL_IP_FIELD_IP_FRAGMENT, /**< IP FRAG */ - - SWITCH_ACL_IP_FIELD_MAX -} switch_acl_ip_field_t; - -/** Acl IPv6 field enum */ -typedef enum switch_acl_ipv6_field_ { - SWITCH_ACL_IPV6_FIELD_IPV6_SRC, /**< IPv6 Source address */ - SWITCH_ACL_IPV6_FIELD_IPV6_DEST, /**< IPv6 Destination address */ - SWITCH_ACL_IPV6_FIELD_IP_PROTO, /**< IP protocol */ - SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT, /**< L4 source port (UDP/TCP) */ - SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT, /**< L4 Dest port (UDP/TCP) */ - SWITCH_ACL_IPV6_FIELD_ICMP_TYPE, /**< ICMP type */ - SWITCH_ACL_IPV6_FIELD_ICMP_CODE, /**< ICMP code */ - SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, /**< TCP flags */ - SWITCH_ACL_IPV6_FIELD_TTL, /**< TTL */ - SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, /**< Flow Label */ - SWITCH_ACL_IPV6_FIELD_TOS, /**< TOS */ - - SWITCH_ACL_IPV6_FIELD_MAX -} switch_acl_ipv6_field_t; - -/** Acl IP field list */ -typedef union switch_acl_ip_value_ { - unsigned int ipv4_source; /**< v4 source IP */ - unsigned int ipv4_dest; /**< v4 destination IP */ - unsigned char ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< souce port */ - unsigned short l4_dest_port; /**< destination port */ - unsigned char icmp_type; /**< icmp type */ - unsigned char icmp_code; /**< icmp code */ - unsigned char tcp_flags; /**< tcp flags */ - unsigned char ttl; /**< time to live */ - unsigned char dscp; /**< DSCP */ - unsigned char ip_flags; /**< IP flags */ - unsigned char tos; /**< TOS */ - unsigned char ip_frag; /**< IP FRAG */ -} switch_acl_ip_value; - -/** Acl IPv6 field list */ -typedef union switch_acl_ipv6_value_ { - uint128_t ipv6_source; /**< v6 souce IP */ - uint128_t ipv6_dest; /**< v6 destination IP */ - unsigned char ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< source port */ - unsigned short l4_dest_port; /**< destination port */ - unsigned char icmp_type; /**< icmp type */ - unsigned char icmp_code; /**< icmp code */ - unsigned char tcp_flags; /**< tcp flags */ - unsigned char ttl; /**< time to live */ - uint32_t flow_label; /**< flow label */ -} switch_acl_ipv6_value; - -/** Acl IP mask */ -typedef union switch_acl_ip_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint32_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< ip mask union */ -} switch_acl_ip_mask; - -/** Acl IPV6 mask */ -typedef union switch_acl_ipv6_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint128_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< ipv6 mask union */ -} switch_acl_ipv6_mask; - -/** Acl IP key value pair */ -typedef struct switch_acl_ip_key_value_pair_ { - switch_acl_ip_field_t field; /**< acl ip field type */ - switch_acl_ip_value value; /**< acl ip field value */ - switch_acl_ip_mask mask; /**< acl ip field mask */ -} switch_acl_ip_key_value_pair_t; - -/** Acl IPv6 key value pair */ -typedef struct { - switch_acl_ipv6_field_t field; /**< acl ip field type */ - switch_acl_ipv6_value value; /**< acl ip field value */ - switch_acl_ipv6_mask mask; /**< acl ip field mask */ -} switch_acl_ipv6_key_value_pair_t; - -/** Acl IP action */ -typedef enum switch_acl_action_ { - SWITCH_ACL_ACTION_NOP, /**< Do nothing action */ - SWITCH_ACL_ACTION_DROP, /**< Drop the packet */ - SWITCH_ACL_ACTION_PERMIT, /**< Permit */ - SWITCH_ACL_ACTION_LOG, /**< Log packet by sending to CPU */ - SWITCH_ACL_ACTION_REDIRECT, /**< Redirect packet to new destination */ - SWITCH_ACL_ACTION_REDIRECT_TO_CPU, /**< Redirect packet to CPU */ - SWITCH_ACL_ACTION_COPY_TO_CPU, /**< Send Copy of packet to CPU */ - SWITCH_ACL_ACTION_NEGATIVE_MIRROR, /**< Negative mirror to defined target */ - SWITCH_ACL_ACTION_SET_NATMODE, /**< Set NAT mode */ - SWITCH_ACL_ACTION_SET_MIRROR, /**< Set mirror session */ - SWITCH_ACL_QOS_ACTION_COS, /**< Set Class of Service */ - SWITCH_ACL_QOS_ACTION_DSCP, /**< Set the DSCP */ - SWITCH_ACL_QOS_ACTION_TC, /**< Set the traffic class */ - SWITCH_ACL_ACTION_FLOOD_TO_VLAN, /**< Flood to all members of BD */ - - SWITCH_ACL_ACTION_MAX -} switch_acl_action_t; - -/** Acl Mac field enum */ -typedef enum switch_acl_mac_field_ { - SWITCH_ACL_MAC_FIELD_ETH_TYPE, /**< Ether type */ - SWITCH_ACL_MAC_FIELD_SOURCE_MAC, /**< Source MAC address */ - SWITCH_ACL_MAC_FIELD_DEST_MAC, /**< Destination MAC address */ - SWITCH_ACL_MAC_FIELD_VLAN_PRI, /**< VLAN priority */ - SWITCH_ACL_MAC_FIELD_VLAN_CFI, /**< VLAN CFI */ - - SWITCH_ACL_MAC_FIELD_MAX -} switch_acl_mac_field_t; - -/** Acl mac field list */ -typedef union switch_acl_mac_value_ { - unsigned short eth_type; /**< ethernet type */ - uint8_t source_mac[6]; /**< source mac */ - uint8_t dest_mac[6]; /**< destionation mac */ - uint8_t vlan_pri; /**< VLAN priority */ - uint8_t vlan_cfi; /**< drop eligible */ -} switch_acl_mac_value; - -/** Acl mac mask */ -typedef union switch_acl_mac_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint8_t mac_mask[6]; /**< MAC addr mask */ - uint16_t mask16; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< mac mask union */ -} switch_acl_mac_mask; - -/** Acl mac key value pair */ -typedef struct switch_acl_mac_key_value_pair_ { - switch_acl_mac_field_t field; /**< acl mac field type */ - switch_acl_mac_value value; /**< acl mac field value */ - switch_acl_mac_mask mask; /**< acl mac field mask */ -} switch_acl_mac_key_value_pair_t; - -/** ACL ip racl field enum */ -typedef enum switch_acl_ip_racl_field_ { - SWITCH_ACL_IP_RACL_FIELD_IPV4_SRC, /**< IPv4 Source address */ - SWITCH_ACL_IP_RACL_FIELD_IPV4_DEST, /**< IPv4 Dest address */ - SWITCH_ACL_IP_RACL_FIELD_IP_PROTO, /**< IP protocol (TCP/UDP) */ - SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT, /**< L4 source port */ - SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT, /**< L4 dest port */ - - SWITCH_ACL_IP_RACL_FIELD_MAX -} switch_acl_ip_racl_field_t; - -/** ACL ipv6 racl field enum */ -typedef enum switch_acl_ipv6_racl_field_ { - SWITCH_ACL_IPV6_RACL_FIELD_IPV6_SRC, /**< IPv6 source address */ - SWITCH_ACL_IPV6_RACL_FIELD_IPV6_DEST, /**< IPv6 dest address */ - SWITCH_ACL_IPV6_RACL_FIELD_IP_PROTO, /**< IPv6 protocol */ - SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT, /**< L4 source port */ - SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT, /**< L4 dest port */ - - SWITCH_ACL_IPV6_RACL_FIELD_MAX -} switch_acl_ipv6_racl_field_t; - -/** Acl ip racl field list */ -typedef union switch_acl_ip_racl_value_ { - unsigned int ipv4_source; /**< v4 source IP */ - unsigned int ipv4_dest; /**< v4 destination IP */ - unsigned short ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< source port */ - unsigned short l4_dest_port; /**< destination port */ -} switch_acl_ip_racl_value; - -/** Acl ipv6 racl field list */ -typedef union switch_acl_ipv6_racl_value_ { - uint128_t ipv6_source; /**< v6 source IP */ - uint128_t ipv6_dest; /**< v6 destination IP */ - unsigned short ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< source port */ - unsigned short l4_dest_port; /**< destination port */ -} switch_acl_ipv6_racl_value; - -/** Acl ip racl mask */ -typedef union switch_acl_ip_racl_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint32_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< ip racl mask union */ -} switch_acl_ip_racl_mask; - -/** Acl ipv6 racl mask */ -typedef union switch_acl_ipv6_racl_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint128_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< ipv6 racl mask union */ -} switch_acl_ipv6_racl_mask; - -/** Acl ip racl key value pair */ -typedef struct switch_acl_ip_racl_key_value_pair_ { - switch_acl_ip_racl_field_t field; /**< acl ip racl field type */ - switch_acl_ip_racl_value value; /**< acl ip racl field value */ - switch_acl_ip_racl_mask mask; /**< acl ip racl field mask */ -} switch_acl_ip_racl_key_value_pair_t; - -/** Acl ipv6 racl key value pair */ -typedef struct switch_acl_ipv6_racl_key_value_pair_ { - switch_acl_ipv6_racl_field_t field; /**< acl ip racl field type */ - switch_acl_ipv6_racl_value value; /**< acl ip racl field value */ - switch_acl_ipv6_racl_mask mask; /**< acl ip racl field mask */ -} switch_acl_ipv6_racl_key_value_pair_t; - -/** Acl Qos field enum */ -typedef enum switch_acl_qos_field_ { - SWITCH_ACL_QOS_FIELD_IPV4_SRC, /**< IPv4 Source address */ - SWITCH_ACL_QOS_FIELD_IPV4_DEST, /**< IPv4 Dest address */ - SWITCH_ACL_QOS_FIELD_IP_PROTO, /**< IP protocol */ - SWITCH_ACL_QOS_FIELD_TC, /**< IP traffic class */ - SWITCH_ACL_QOS_FIELD_EXP, /**< EXP value */ - SWITCH_ACL_QOS_FIELD_DSCP, /**< DSCP value */ - - SWITCH_ACL_QOS_FIELD_MAX -} switch_acl_qos_field_t; - -/** Acl qos field list */ -typedef union switch_acl_qos_value_ { - unsigned int ipv4_source; /**< v4 source IP */ - unsigned int ipv4_dest; /**< v4 destination IP */ - unsigned short ip_proto; /**< protocol */ - unsigned char tc; /**< traffic control */ - unsigned char exp; /**< experimental */ - unsigned char dscp; /**< dscp */ -} switch_acl_qos_value; - -/** Acl qod mask */ -typedef union switch_acl_qos_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint32_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< qos mask union */ -} switch_acl_qos_mask; - -/** Acl qos key value pair */ -typedef struct switch_acl_qos_key_value_pair_ { - switch_acl_qos_field_t field; /**< acl qos field type */ - switch_acl_qos_value value; /**< acl qos field value */ - switch_acl_qos_mask mask; /**< acl qos field mask */ -} switch_acl_qos_key_value_pair_t; - -/** Acl mirror field enum */ -typedef enum switch_acl_mirror_field_ { - SWITCH_ACL_MIRROR_FIELD_IPV4_SRC, /**< IPv4 source address */ - SWITCH_ACL_MIRROR_FIELD_IPV4_DEST, /**< IPv4 dest address */ - SWITCH_ACL_MIRROR_FIELD_IP_PROTO, /**< IP protocol */ - SWITCH_ACL_MIRROR_FIELD_ETH_TYPE, /**< Ether type */ - SWITCH_ACL_MIRROR_FIELD_SOURCE_MAC, /**< Source MAC address */ - SWITCH_ACL_MIRROR_FIELD_DEST_MAC, /**< Dest MAC address */ - - SWITCH_ACL_MIRROR_FIELD_MAX -} switch_acl_mirror_field_t; - -/** Acl mirror field list */ -typedef union switch_acl_mirror_value_ { - unsigned int ipv4_source; /**< v4 source IP */ - unsigned int ipv4_dest; /**< v4 destination IP */ - unsigned short ip_proto; /**< protocol */ - unsigned short eth_type; /**< ethernet type */ - uint64_t source_mac; /**< source mac */ - uint64_t dest_mac; /**< destination mac */ -} switch_acl_mirror_value; - -/** Acl mirror mask */ -typedef union switch_acl_mirror_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint32_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< mirror mask union */ -} switch_acl_mirror_mask; - -/** Acl mirror key value pair */ -typedef struct switch_acl_mirror_key_value_pair_ { - switch_acl_mirror_field_t field; /**< acl mirror field type */ - switch_acl_mirror_value value; /**< acl mirror field value */ - switch_acl_mirror_mask mask; /**< acl mirror field mask */ -} switch_acl_mirror_key_value_pair_t; - -/** Acl system field enum */ -typedef enum switch_acl_system_field_ { - SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE, /**< Ether type */ - SWITCH_ACL_SYSTEM_FIELD_SOURCE_MAC, /**< Source MAC address */ - SWITCH_ACL_SYSTEM_FIELD_DEST_MAC, /**< Dest MAC address */ - SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS, /**< Port/vlan miss*/ - SWITCH_ACL_SYSTEM_FIELD_IPSG_CHECK, /**< IP sourceguard check */ - SWITCH_ACL_SYSTEM_FIELD_ACL_DENY, /**< ACL deny */ - SWITCH_ACL_SYSTEM_FIELD_ACL_COPY, /**< ACL copy */ - SWITCH_ACL_SYSTEM_FIELD_RACL_DENY, /**< Route ACL deny check */ - SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK, /**< URPF check */ - SWITCH_ACL_SYSTEM_FIELD_DROP, /**< Dropped packet */ - SWITCH_ACL_SYSTEM_FIELD_L3_COPY, /**< L3 copy */ - SWITCH_ACL_SYSTEM_FIELD_ROUTED, /**< Routed packet check */ - SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL, /**< Link local address (IPv6) */ - SWITCH_ACL_SYSTEM_FIELD_BD_CHECK, /**< Bridge domain check */ - SWITCH_ACL_SYSTEM_FIELD_TTL, /**< TTL */ - SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX, /**< Egress ifindex */ - SWITCH_ACL_SYSTEM_FIELD_STP_STATE, /**< STP state */ - SWITCH_ACL_SYSTEM_FIELD_CONTROL_FRAME, /**< Control frame */ - SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED, /**< IPv4 enabled on BD */ - SWITCH_ACL_SYSTEM_FIELD_IPV6_ENABLED, /**< IPv6 enabled on BD */ - SWITCH_ACL_SYSTEM_FIELD_RMAC_HIT, /**< Rmac hit */ - SWITCH_ACL_SYSTEM_FIELD_IF_CHECK, /**< Same intf check */ - SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK, /**< Tunnel intf check */ - - SWITCH_ACL_SYSTEM_FIELD_MAX -} switch_acl_system_field_t; - -/** Maximum Acl fields */ -#define SWITCH_ACL_FIELD_MAX SWITCH_ACL_SYSTEM_FIELD_MAX - -/** Acl system field list */ -typedef union switch_acl_system_value_ { - unsigned short eth_type; /**< ethernet type */ - switch_mac_addr_t source_mac; /**< source mac */ - switch_mac_addr_t dest_mac; /**< destination mac */ - unsigned ipsg_check :1, /**< ip sourceguard check */ - acl_deny:1, /**< acl deny */ - acl_copy:1, /**< acl copy */ - racl_deny:1, /**< racl deny */ - urpf_check_fail:1, /**< urpf check fail */ - port_vlan_mapping_miss:1, /**< port vlan mapping miss */ - drop_flag:1, /**< drop flag */ - l3_copy:1, /**< l3 copy */ - routed:1, /**< routed */ - src_is_link_local:1, /**< link local source ip */ - tunnel_if_check:1, /**< tunnel if check */ - control_frame:1, /**< control frame */ - ipv4_enabled:1, /**< IPv4 enabled on BD */ - ipv6_enabled:1, /**< IPv6 enabled on BD */ - rmac_hit:1; /**< rmac hit */ - unsigned short if_check:16; /**< same if check */ - unsigned short bd_check:16; /**< same bd check */ - unsigned char ttl; /**< time to live */ - unsigned short out_ifindex; /**< egress ifindex */ - unsigned char stp_state; /**< spanning tree port state */ -} switch_acl_system_value; - -/** Acl system mask */ -typedef union switch_acl_system_mask_ { - unsigned type:1; /**< acl mask type */ - union { - uint64_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< system acl mask union */ -} switch_acl_system_mask; - -/** Acl system key value pair */ -typedef struct switch_acl_system_key_value_pair_ { - switch_acl_system_field_t field; /**< acl system field type */ - switch_acl_system_value value; /**< acl system field value */ - switch_acl_system_mask mask; /**< acl system field mask */ -} switch_acl_system_key_value_pair_t; - -/** Acl action parameters */ -typedef union switch_acl_action_params_ { - struct { - switch_handle_t handle; /**< port/nexthop handle */ - } redirect; /**< port redirect struct */ - struct { - uint16_t reason_code; /**< cpu reason code */ - } cpu_redirect; /**< cpu redirect struct */ - struct { - uint8_t reason_code; /**< drop reason code */ - } drop; /**< drop action struct */ -} switch_acl_action_params_t; - -/** Acl optional action parameters */ -typedef struct switch_acl_opt_action_params_ { - bool copy_to_cpu; /**< generate a cpu copy */ - switch_handle_t mirror_handle; /**< mirror session handle */ - unsigned int switch_id; /**< mirror switch id */ - switch_handle_t meter_handle; /**< meter handle */ - switch_handle_t counter_handle; /**< counter handle */ -} switch_acl_opt_action_params_t; - -/** Egress ACL field enum */ -typedef enum switch_acl_egr_field_ { - SWITCH_ACL_EGR_DEST_PORT, - SWITCH_ACL_EGR_DEFLECT, - SWITCH_ACL_EGR_L3_MTU_CHECK, - SWITCH_ACL_EGR_FIELD_MAX -} switch_acl_egr_field_t; - -/** Egress ACL match value */ -typedef union switch_acl_egr_value_ { - 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 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; /**< mask union */ -} switch_acl_egr_mask_t; - -/** Egress acl key value pair */ -typedef struct switch_acl_egr_key_value_pair_ { - switch_acl_egr_field_t field; /**< acl ip field type */ - switch_acl_egr_value_t value; /**< acl ip field value */ - switch_acl_egr_mask_t mask; /**< acl ip field mask */ -} switch_acl_egr_key_value_pair_t; - -/** Egress acl port action */ -typedef enum switch_acl_egr_action_ { - SWITCH_ACL_EGR_ACTION_NOP, /**< Do nothing action */ - SWITCH_ACL_EGR_ACTION_SET_MIRROR, /**< Set mirror session */ - SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU, /**< redirect to cpu */ - SWITCH_ACL_EGR_ACTION_SET_MIRROR_META, /**< Set mirror session and switch_id */ -} switch_acl_egr_action_t; - -typedef switch_acl_action_t switch_acl_ip_action_t; /**< acl action */ -typedef switch_acl_action_t switch_acl_ipv6_action_t; /**< IPv6 acl action */ -typedef switch_acl_action_t switch_acl_mac_action_t; /**< mac acl action */ -typedef switch_acl_action_t switch_acl_system_action_t;/**< system acl action */ - -/** Acl info struct */ -typedef struct switch_acl_info_ { - switch_acl_type_t type; /**< acl type */ - void *rules; /**< set of rules */ - tommy_list interface_list; /**< list of interface handles */ -} switch_acl_info_t; - -/** - ACL Key list create - @param device device - @param type - acl type -*/ -switch_handle_t switch_api_acl_list_create(switch_device_t device, switch_acl_type_t type); - -/** - ACL Key list update - @param device device - @param acl_handle handle of created ACL - @param type - acl type -*/ -switch_handle_t switch_api_acl_list_update(switch_device_t device, - switch_handle_t acl_handle, - switch_acl_type_t type); - -/** - Delete the ACL key list - @param device device - @param acl_handle handle of created ACL -*/ -switch_status_t switch_api_acl_list_delete(switch_device_t device, switch_handle_t acl_handle); - -/** - Create ACL Rules - @param device device - @param acl_handle - Acl handle - @param priority - priority of Acl - @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 - 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, - unsigned int priority, unsigned int key_value_count, - void *acl_kvp, switch_acl_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - switch_handle_t *ace_handle); - -/** - Delete ACL Rules - @param device device - @param acl_handle - Acl handle - @param ace_handle - handle obtained from create_rule -*/ -switch_status_t switch_api_acl_rule_delete(switch_device_t device, switch_handle_t acl_handle, switch_handle_t ace_handle); - -/** - Renumber ACL Rules - @param device device - @param acl_handle - Acl handle - @param increment_priority - priority to reorder the acl rule -*/ -switch_status_t switch_api_acl_renumber(switch_device_t device, switch_handle_t acl_handle, int increment_priority); - -/** - Apply ACLs on interfaces, VLANs, etc. - @param device device - @param acl_handle handle created with list_create - @param interface_handle - Interface handle -*/ -switch_status_t switch_api_acl_reference(switch_device_t device, switch_handle_t acl_handle, switch_handle_t interface_handle); - -/** - Apply ACLs on interfaces, VLANs, etc. - @param device device - @param acl_handle handle created with list_create - @param interface_handle - Interface handle -*/ -switch_status_t switch_api_acl_remove(switch_device_t device, switch_handle_t acl_handle, switch_handle_t interface_handle); - -/** - Get ACL type, given the ACL handle - @param acl_handle handle created with list_create -*/ -switch_acl_info_t *switch_acl_get(switch_handle_t acl_handle); - -/** - Get drop statistics - @param device device - @param num_counters number of counters - @param counters pointer to counter array -*/ -switch_status_t switch_api_drop_stats_get(switch_device_t device, - int *num_counters, - uint64_t **counters); - -/** - create acl counter handle - @param device device -*/ -switch_handle_t -switch_api_acl_counter_create( - switch_device_t device); - -/** - delete acl counter handle - @param device device - @param counter_handle acl counter handle -*/ -switch_status_t -switch_api_acl_counter_delete( - switch_device_t device, - switch_handle_t counter_handle); - -/** - get acl statistics - @param device device - @param counter_handle acl counter handle - @param counter counter value -*/ -switch_status_t -switch_api_acl_stats_get( - switch_device_t device, - switch_handle_t counter_handle, - switch_counter_t *counter); - -/** @} */ // end of ACL API - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_capability.h b/switchapi/inc/switchapi/switch_capability.h deleted file mode 100644 index 714fbcb..0000000 --- a/switchapi/inc/switchapi/switch_capability.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_capability_h -#define _switch_capability_h - -#include "switch_base_types.h" -#include "switch_handle.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** @defgroup SWITCH Switch API - * @{ - */ // begin of SWITCH API - -// Switch - -#define SWITCH_API_DEFAULT_VLAN 1 /**< system default vlan */ -#define SWITCH_API_DEFAULT_VRF 1 /**< system default vrf */ -#define SWITCH_API_MAX_PORTS 288 /**< system default ports */ - -/** switch operational status */ -typedef enum switch_oper_status_ { - SWITCH_OPER_STATUS_UNKNOWN, - SWITCH_OPER_STATUS_UP, - SWITCH_OPER_STATUS_DOWN, - SWITCH_OPER_STATUS_FAILED -} switch_oper_status_t; - -/** switch statistics */ -typedef enum switch_stat_counter_ { - SWITCH_STAT_GLOBAL_LOW_DROP_PKTS, - SWITCH_STAT_GLOBAL_HIGH_DROP_PKTS, - SWITCH_STAT_GLOBAL_PRIVILEGE_DROP_PKTS, - SWITCH_STAT_DROP_COUNT_TX, - SWITCH_STAT_DROP_COUNT_RX -} switch_stat_counter_t; - -/** switch hash fields */ -typedef enum switch_ecmp_hash_fields_ { - SWITCH_HASH_SRC_IP = (1 << 0), - SWITCH_HASH_DST_IP = (1 << 1), - SWITCH_HASH_L4_SRC_PORT = (1 << 2), - SWITCH_HASH_L4_DST_PORT = (1 << 3), -} switch_ecmp_hash_fields_t; - -/** switch attributes */ -typedef enum switch_capability_attr_ { - SWITCH_ATTR_PORT_NUMBER, - SWITCH_ATTR_PORT_LIST, - SWITCH_ATTR_MAX_VRF, - SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED, - SWITCH_ATTR_OPER_STATUS, - SWITCH_ATTR_HW_SEQUENCE_ID, - SWITCH_ATTR_ADMIN_STATE, - SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE, - SWITCH_ATTR_MCAST_CPU_FLOOD_ENABLE, - SWITCH_ATTR_DEFAULT_VLAN_ID, - SWITCH_ATTR_MAX_LEARNED_ADDRESSES, - SWITCH_ATTR_FDB_UNICAST_MISS_ACTION, - SWITCH_ATTR_FDB_MULTICAST_MISS_ACTION, - SWITCH_ATTR_FDB_BROADCAST_MISS_ACTION, - SWITCH_ATTR_ECMP_HASH_TYPE, - SWITCH_ATTR_ECMP_HASH_FIELDS, - - SWITCH_ATTR_CUSTOM_RANGE_BASE = 0x10000000, - SWITCH_ATTR_DEFAULT_VRF_ID -} switch_capability_attr_t; - -/** switch capability info */ -typedef struct switch_api_capability_ { - switch_vlan_t default_vlan; /**< default vlan */ - switch_vrf_id_t default_vrf; /**< default vrf */ - switch_mac_addr_t switch_mac; /**< default switch mac */ - uint16_t max_ports; /**< max ports in the switch */ - uint16_t max_lags; /**< max lag supported */ - uint16_t max_port_per_lag; /**< max ports per lag */ - uint16_t max_vrf; /**< max vrf supported */ - uint16_t max_stp_groups; /**< max spanning tree group */ - uint16_t max_tunnels; /**< max tunnels */ - uint16_t max_span_sessions; /**< max span sessions */ - switch_handle_t port_list[SWITCH_API_MAX_PORTS]; /**< list of ports */ -} switch_api_capability_t; - -/** - Sets switch capability attributes - @param device device - @param api_capability switch capability attributes - */ -switch_status_t switch_api_capability_set(switch_device_t device, switch_api_capability_t *api_capability); - -/** - Returns all switch capability attributes - @param device device - @param api_capability switch capability attributes - */ -switch_status_t switch_api_capability_get(switch_device_t device, switch_api_capability_t *api_capability); - -/** @} */ // end of switch API - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_handle.h b/switchapi/inc/switchapi/switch_handle.h deleted file mode 100644 index e554f75..0000000 --- a/switchapi/inc/switchapi/switch_handle.h +++ /dev/null @@ -1,227 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_handle_h_ -#define _switch_handle_h_ - -#include "switch_id.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef enum { - SWITCH_HANDLE_TYPE_NONE, - SWITCH_HANDLE_TYPE_PORT, - SWITCH_HANDLE_TYPE_LAG, - SWITCH_HANDLE_TYPE_INTERFACE, - SWITCH_HANDLE_TYPE_VRF, - SWITCH_HANDLE_TYPE_BD, - SWITCH_HANDLE_TYPE_TUNNEL, - SWITCH_HANDLE_TYPE_NHOP, - SWITCH_HANDLE_TYPE_ARP, - SWITCH_HANDLE_TYPE_MY_MAC, - SWITCH_HANDLE_TYPE_LABEL, - SWITCH_HANDLE_TYPE_STP, - SWITCH_HANDLE_TYPE_MGID, - SWITCH_HANDLE_TYPE_ACL, - SWITCH_HANDLE_TYPE_MCAST_ECMP, - SWITCH_HANDLE_TYPE_URPF, - SWITCH_HANDLE_TYPE_HOSTIF_GROUP, - SWITCH_HANDLE_TYPE_HOSTIF, - SWITCH_HANDLE_TYPE_ACE, - SWITCH_HANDLE_TYPE_MIRROR, - SWITCH_HANDLE_TYPE_METER, - SWITCH_HANDLE_TYPE_SFLOW, - SWITCH_HANDLE_TYPE_SFLOW_ACE, - SWITCH_HANDLE_TYPE_LAG_MEMBER, - SWITCH_HANDLE_TYPE_ACL_COUNTER, - - SWITCH_HANDLE_TYPE_MAX=32 -} switch_handle_type_t; - -/** - Generic handle to encode different types of objects - handle impicitly encodes the device, type and type specific - */ - typedef unsigned long switch_handle_t; - - /** Handle related information */ -typedef struct { - switch_handle_type_t type; /**< type of handle */ - switch_api_id_allocator *allocator; /**< allocator associated with handle */ - unsigned int num_in_use; /**< number of handle in use */ - unsigned int initial_size; /**< current size of allocator */ - unsigned int num_handles; /**< number of handles to allocate */ - bool grow_on_demand; /**< allocate new handles as needed */ - bool zero_based; /**< 0 is a valid id */ -} switch_handle_info_t; - -// Protoypes -int switch_handle_type_init(switch_handle_type_t type, unsigned int size); -int switch_handle_type_allocator_init(switch_handle_type_t type, - unsigned int num_handles, - bool grow_on_demand, bool zero_based); -void switch_handle_type_free(switch_handle_type_t type); -switch_handle_t switch_handle_allocate(switch_handle_type_t type); -switch_handle_t switch_handle_set_and_allocate(switch_handle_t type, - unsigned int id); -void switch_handle_free(switch_handle_t handle); -switch_handle_type_t switch_handle_get_type(switch_handle_t handle); - -#define SWITCH_HANDLE_VALID(handle, type) \ - ((handle >> HANDLE_TYPE_SHIFT) == type) - -#define SWITCH_PORT_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_PORT) - -#define SWITCH_INTERFACE_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_INTERFACE) - -#define SWITCH_LAG_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_LAG) - -#define SWITCH_VRF_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_VRF) - -#define SWITCH_BD_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_BD) - -#define SWITCH_TUNNEL_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_TUNNEL) - -#define SWITCH_NHOP_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_NHOP) - -#define SWITCH_NEIGHBOR_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_ARP) - -#define SWITCH_RMAC_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_MY_MAC) - -#define SWITCH_STP_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_STP) - -#define SWITCH_MGID_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_MGID) - -#define SWITCH_ACL_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_ACL) - -#define SWITCH_ACE_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_ACE) - -#define SWITCH_HOSTIF_GROUP_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_HOSTIF_GROUP) - -#define SWITCH_HOSTIF_HANDLE_VALID(handle) \ - SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_HOSTIF) - -// Easy use macros -#define SWITCH_API_INVALID_HANDLE 0xFFFFFFFF -#define SWITCH_HW_INVALID_HANDLE 0xFFFFFFFF - -#define _switch_handle_create(_type, _info, _judy, _init, _handle) \ - _handle = switch_handle_allocate(_type); \ - if(_handle) { \ - _info *_i_info = (_info *)switch_malloc(sizeof(_info), 1); \ - if(_i_info) { \ - char *_ap=NULL; \ - memset(_i_info, 0, sizeof(_info)); \ - JLI(_ap, _judy, (unsigned int)_handle); \ - if(_ap) { \ - *(unsigned long *)_ap = (unsigned long)_i_info; \ - } else { \ - switch_free(_i_info); \ - switch_handle_free(_handle); \ - _handle = 0; \ - } \ - } else { \ - switch_handle_free(_handle); \ - _handle = 0; \ - } \ - } \ - -#define _switch_handle_set_and_create( \ - _type, _info, _judy, _init, _id, _handle) \ - _handle = switch_handle_set_and_allocate(_type, _id); \ - if(_handle) { \ - _info *_i_info = (_info *)switch_malloc(sizeof(_info), 1); \ - if(_i_info) { \ - char *_ap=NULL; \ - memset(_i_info, 0, sizeof(_info)); \ - JLI(_ap, _judy, (unsigned int)_handle); \ - if(_ap) { \ - *(unsigned long *)_ap = (unsigned long)_i_info; \ - } else { \ - switch_free(_i_info); \ - switch_handle_free(_handle); \ - _handle = 0; \ - } \ - } else { \ - switch_handle_free(_handle); \ - _handle = 0; \ - } \ - } \ - -#define _switch_handle_delete(_info, _judy, _handle) \ - _info *_handle_info; \ - int _ret = 0; \ - void *_dp=NULL; \ - JLG(_dp, _judy, (unsigned int)_handle); \ - if((_handle_info = (_info *) (*(unsigned long *)_dp))) { \ - JLD(_ret, _judy, (unsigned int)_handle); \ - switch_free(_handle_info); \ - } \ - switch_handle_free(_handle); \ - -#define _switch_handle_get(_info, _judy, _handle, _handle_info) \ - void *_gp=NULL; \ - JLG(_gp, _judy, (unsigned int)_handle); \ - if (_gp) \ - _handle_info = (_info *) (*(unsigned long *)_gp); \ - -#define switch_handle_get_first(_judy, _handle) \ - int ret = 0; \ - J1F(ret, _judy, _handle); \ - if (!ret) { \ - _handle = 0; \ - } - -#define switch_handle_get_next(_judy, old_handle, new_handle) \ - int ret = 0; \ - new_handle = 0; \ - J1N(ret, _judy, old_handle); \ - if (ret) { \ - new_handle = old_handle; \ - } - -#define SWITCH_HANDLE_IS_LAG(handle) \ - switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_LAG - -#define SWITCH_HANDLE_IS_VRF(handle) \ - switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_VRF - -#define SWITCH_HANDLE_IS_BD(handle) \ - switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_BD - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_hostif.h b/switchapi/inc/switchapi/switch_hostif.h deleted file mode 100644 index 3fd1550..0000000 --- a/switchapi/inc/switchapi/switch_hostif.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -#ifndef _switch_hostif_h_ -#define _switch_hostif_h_ - -#include "switch_base_types.h" -#include "switch_handle.h" -#include "switch_acl.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup HostInterface Host Interface API - * API functions define and manipulate host interfaces - * @{ - */ // begin of Host Interface API - -/** switch hostif reason code */ -typedef enum switch_hostif_reason_code_ { - /* - * Reason code groups must start on power of 2 boundary since - * rx_net_filters are setup to use masks - */ - /* generic reason codes 0x0-0x0FF */ - SWITCH_HOSTIF_REASON_CODE_NONE = 0x0, - SWITCH_HOSTIF_REASON_CODE_CUSTOM = 0x1, - SWITCH_HOSTIF_REASON_CODE_DROP = 0x2, - SWITCH_HOSTIF_REASON_CODE_NULL_DROP = 0x3, - SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE = 0x4, /* must match the value in headers.p4 */ - - /* L2 reason codes 0x100 - 0x1FF */ - SWITCH_HOSTIF_REASON_CODE_L2_START = 0x100, - SWITCH_HOSTIF_REASON_CODE_STP = SWITCH_HOSTIF_REASON_CODE_L2_START, - SWITCH_HOSTIF_REASON_CODE_LACP, /* 0x101 */ - SWITCH_HOSTIF_REASON_CODE_EAPOL, /* 0x102 */ - SWITCH_HOSTIF_REASON_CODE_LLDP, /* 0x103 */ - SWITCH_HOSTIF_REASON_CODE_PVRST, /* 0x104 */ - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_QUERY, /* 0x105 */ - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_LEAVE, /* 0x106 */ - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V1_REPORT, /* 0x107 */ - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT, /* 0x108 */ - SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V3_REPORT, /* 0x109 */ - - /* L3 reason codes 0x200-0x2FF */ - SWITCH_HOSTIF_REASON_CODE_L3_START = 0x200, - SWITCH_HOSTIF_REASON_CODE_SAMPLEPACKET = SWITCH_HOSTIF_REASON_CODE_L3_START, - SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST, /* 0x201 */ - SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE, /* 0x202 */ - SWITCH_HOSTIF_REASON_CODE_DHCP, /* 0x203 */ - SWITCH_HOSTIF_REASON_CODE_OSPF, /* 0x204 */ - SWITCH_HOSTIF_REASON_CODE_PIM, /* 0x205 */ - SWITCH_HOSTIF_REASON_CODE_VRRP, /* 0x206 */ - SWITCH_HOSTIF_REASON_CODE_BGP, /* 0x207 */ - SWITCH_HOSTIF_REASON_CODE_DHCPV6, /* 0x208 */ - SWITCH_HOSTIF_REASON_CODE_OSPFV6, /* 0x209 */ - SWITCH_HOSTIF_REASON_CODE_VRRPV6, /* 0x20a */ - SWITCH_HOSTIF_REASON_CODE_BGPV6, /* 0x20b */ - SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY, /* 0x20c */ - SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_V2, /* 0x20d */ - SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_REPORT, /* 0x20e */ - SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_DONE, /* 0x20f */ - SWITCH_HOSTIF_REASON_CODE_MLD_V2_REPORT, /* 0x210 */ - SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR, /* 0x211 */ - SWITCH_HOSTIF_REASON_CODE_TTL_ERROR, /* 0x212 */ - SWITCH_HOSTIF_REASON_CODE_GLEAN, /* 0x213 */ - SWITCH_HOSTIF_REASON_CODE_MYIP, /* 0x214 */ - SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT, /* 0x215 */ - SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL, /* 0x216 */ - SWITCH_HOSTIF_REASON_CODE_L3_REDIRECT, /* 0x217 */ - - SWITCH_HOSTIF_REASON_CODE_MAX, -} switch_hostif_reason_code_t; - -/** switch channel */ -typedef enum switch_hostif_channel_ { - SWITCH_HOSTIF_CHANNEL_CB, - SWITCH_HOSTIF_CHANNEL_FD, - SWITCH_HOSTIF_CHANNEL_NETDEV, -} switch_hostif_channel_t; - -/** switch hostif group */ -typedef struct switch_hostif_group_ { - uint32_t egress_queue; /**< egress queue number */ - uint32_t priority; /**< priority */ -} switch_hostif_group_t; - -/** switch hostif reason code info */ -typedef struct switch_api_hostif_rcode_info_ { - switch_hostif_reason_code_t reason_code; /**< reason code */ - switch_acl_action_t action; /**< packet action */ - uint32_t priority; /**< priority */ - switch_hostif_channel_t channel; /**< hostif channel */ - switch_handle_t hostif_group_id; /**< hostif group id */ -} switch_api_hostif_rcode_info_t; - -/** hostif tx/rx packet info */ -typedef struct switch_hostif_packet_ { - switch_hostif_reason_code_t reason_code; /**< reason code */ - bool is_lag; /**< handle is lag or port. used in rx */ - switch_handle_t handle; /**< port or lag. used in tx/rx */ - bool tx_bypass; /**< tx type flag to skip pipeline */ - void *pkt; /**< packet buffer rx/tx */ - uint32_t pkt_size; /**< packet buffer size */ -} switch_hostif_packet_t; - -/** Host interface name size */ -#define SWITCH_HOSTIF_NAME_SIZE 16 - -/** host interface */ -typedef struct switch_hostif_ { - char intf_name[SWITCH_HOSTIF_NAME_SIZE]; /**< interface name */ -} switch_hostif_t; - -/** CPU Rx Callback */ -typedef void(*switch_hostif_rx_callback_fn)(switch_hostif_packet_t *hostif_packet); - -/** -Register for callback on reception of packets qualified by reason -@param device device to register callback -@param cb_fn callback function pointer -*/ -switch_status_t switch_api_hostif_register_rx_callback(switch_device_t device, switch_hostif_rx_callback_fn cb_fn); - -/** -Deregister for callback on reception of packets qualified by reason -@param device device to register callback -@param cb_fn callback function pointer -*/ -switch_status_t switch_api_hostif_deregister_rx_callback(switch_device_t device, switch_hostif_rx_callback_fn cb_fn); - -/** -Allocate packe memory to transmit -@param device device -@param hostif_packet packet info -*/ -switch_status_t switch_api_hostif_tx_packet(switch_device_t device, switch_hostif_packet_t *hostif_packet); - -/** - Create a hostif profile to be shared across multiple reason codes - @param device device - @param hostif_group hostif group info - */ -switch_handle_t switch_api_hostif_group_create(switch_device_t device, switch_hostif_group_t *hostif_group); - -/** - Delete a hostif profile that is shared across multiple reason codes - @param device device - @param hostif_group_id hostif group id - */ -switch_status_t switch_api_hostif_group_delete(switch_device_t device, switch_handle_t hostif_group_id); - -/** - Add a hostif reason code to trap/forward the packet to cpu - @param device device - @param rcode_api_info reason code info - */ -switch_status_t switch_api_hostif_reason_code_create(switch_device_t device, - switch_api_hostif_rcode_info_t *rcode_api_info); - -/** - Update a hostif reason code to trap/forward the packet to cpu - @param device device - @param rcode_api_info reason code info - */ -switch_status_t switch_api_hostif_reason_code_update(switch_device_t device, - switch_api_hostif_rcode_info_t *rcode_api_info); - -/** - Remove a reason code to trap/forward the packet to cpu - @param device device - @param reason_code reason code - */ -switch_status_t switch_api_hostif_reason_code_delete(switch_device_t device, - switch_hostif_reason_code_t reason_code); - -/** - Create host interface - @param device device - @param hostif host interface - */ -switch_handle_t -switch_api_hostif_create(switch_device_t device, switch_hostif_t *hostif); - -/** - Delete host interface - @param device device - @param hostif_handle hostif handle - */ -switch_status_t -switch_api_hostif_delete(switch_device_t device, switch_handle_t hostif_handle); - -/** - Return nexthop based on reason code - @param rcode Reason code - */ -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 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 */ - 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 reason_code_mask; /**< reason code mask */ - 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 */ - switch_tx_bypass_flags_t bypass_flags; /**< bypass flags */ - 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 -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_interface.h b/switchapi/inc/switchapi/switch_interface.h deleted file mode 100644 index be4a167..0000000 --- a/switchapi/inc/switchapi/switch_interface.h +++ /dev/null @@ -1,302 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_interface_h_ -#define _switch_interface_h_ - -#include "switch_base_types.h" -#include "switch_handle.h" -#include "switch_vlan.h" -#include "switch_l3.h" -#include "switch_tunnel.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup Interface Interface configuration API - * API functions listed to configure the interfaces - Interface API - Interfaces are the basic element for provisioning services on the device. - Interfaces can be any of physical, link aggregation group, or tunnels. - * @{ - */ // begin of interface - -/** Interface Types */ -typedef enum switch_interface_type_ { - SWITCH_API_INTERFACE_NONE, /**< none */ - SWITCH_API_INTERFACE_LOOPBACK, /**< loopback interface */ - SWITCH_API_INTERFACE_L2_VLAN_ACCESS, /**< L2 interface on VLAN */ - SWITCH_API_INTERFACE_L2_VLAN_TRUNK, /**< L2 interface on VLAN */ - SWITCH_API_INTERFACE_L3, /**< L3 interface on port */ - SWITCH_API_INTERFACE_L3_VLAN, /**< L3 interface on VLAN */ - SWITCH_API_INTERFACE_L3_PORT_VLAN, /**< Sub-Intf - L3 interface on VLAN on a port */ - SWITCH_API_INTERFACE_LAG, /**< Interface on lag */ - SWITCH_API_INTERFACE_TUNNEL, /**< L3 Tunnel interface */ - SWITCH_API_INTERFACE_L2_PORT_VLAN, /** L2 sub interface */ - - SWITCH_API_INTERFACE_MAX -} switch_interface_type_t; - -/** Restrict VLAN behavior on a particular port (RoCE like) */ -typedef struct switch_port_vlan_ { - switch_handle_t port_lag_handle; /**< Port or lag */ - switch_vlan_t vlan_id; /**< VLAN id on port */ -} switch_port_vlan_t; - -/** Interface attributes */ -typedef enum switch_intf_attr_ { - SWITCH_INTF_ATTR_V4_UNICAST, /**< IPv4 Unicast */ - SWITCH_INTF_ATTR_V6_UNICAST, /**< IPv6 Unicast */ - SWITCH_INTF_ATTR_V4_URPF_MODE, /**< IPv4 Urpf mode */ - SWITCH_INTF_ATTR_V6_URPF_MODE, /**< IPv6 Urpf mode */ - - SWITCH_INTF_ATTR_CUSTOM_RANGE_BASE = 0x10000000, /**< Custom Attribute base */ - SWITCH_INTF_ATTR_NATIVE_VLAN, /**< Native Vlan */ -} switch_intf_attr_t; - -/** Interface information */ -typedef struct switch_api_interface_info_ { - switch_interface_type_t type; /**< type of interface */ - union { - switch_handle_t port_lag_handle; /**< Port or LAG handle */ - switch_vlan_t vlan_id; /**< Vlan Inteface */ - switch_port_vlan_t port_vlan; /**< L3 sub Interface */ - switch_tunnel_info_t tunnel_info; /**< Tunnel handle */ - } u; /**< Base information */ - - struct { - uint8_t core_intf:1; /**< interface flags */ - uint8_t flood_enabled:1; /**< Add to flood list (only for tunnels) */ - } flags; /**< interface flags struct */ - // L2 - switch_handle_t native_vlan; /**< native vlan id */ - // L3 - bool ipv4_unicast_enabled; /**< IPv4 unicast enabled */ - bool ipv6_unicast_enabled; /**< IPv6 unicast enabled */ - bool ipv4_multicast_enabled; /**< IPv4 multicast enabled */ - bool ipv6_multicast_enabled; /**< IPV6 multicast menabled */ - switch_urpf_mode_t ipv4_urpf_mode; /**< IPv4 urpf mode */ - switch_urpf_mode_t ipv6_urpf_mode; /**< IPv6 urpf mode */ - unsigned char nat_mode; /**< nat mode */ - switch_handle_t vrf_handle; /**< vrf handle */ - bool mac_valid; /**< mac address valid */ - switch_mac_addr_t mac; /**< Mac address associated with interface */ - switch_handle_t rmac_handle; /**< rmac group id */ -} switch_api_interface_info_t; - -/** - Interface create - @param device - device on which interface is created - @param intf_info - interface information specific to type - */ -switch_handle_t switch_api_interface_create(switch_device_t device, - switch_api_interface_info_t *intf_info); - -/** - Interface delete - @param device - device on which interface is created - @param interface_handle handle returned by interface creation - */ -switch_status_t switch_api_interface_delete(switch_device_t device, - switch_handle_t interface_handle); - -/** - Set interface attributes - @param intf_handle - Handle that uniquely identifies interface - @param attr_type - Attribute of an interface - @param value - Value that has to be set for an attribute -*/ -switch_status_t switch_api_interface_attribute_set(switch_handle_t intf_handle, - switch_intf_attr_t attr_type, - uint64_t value); -/** - Get interface attributes - @param intf_handle - Handle that uniquely identifies interface - @param attr_type - Attribute of an interface - @param value - Value that has to be obtained for an attribute -*/ -switch_status_t switch_api_interface_attribute_get(switch_handle_t intf_handle, - switch_intf_attr_t attr_type, - uint64_t *value); - -/** - Set IPv4 enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Enable/Disable V4 routing on interface -*/ -switch_status_t switch_api_interface_ipv4_unicast_enabled_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get IPv4 enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Get V4 routing on interface -*/ -switch_status_t switch_api_interface_ipv4_unicast_enabled_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set IPv6 enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Enable/Disable V4 routing on interface -*/ -switch_status_t switch_api_interface_ipv6_unicast_enabled_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get IPv6 enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Get V4 routing on interface -*/ -switch_status_t switch_api_interface_ipv6_unicast_enabled_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set IPv4 multicast enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Enable/Disable V4 multicast routing on interface -*/ -switch_status_t switch_api_interface_ipv4_multicast_enabled_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get IPv4 multicast enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Get V4 multicast routing on interface -*/ -switch_status_t switch_api_interface_ipv4_multicast_enabled_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set IPv6 multicast enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Enable/Disable V4 multicast routing on interface -*/ -switch_status_t switch_api_interface_ipv6_multicast_enabled_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get IPv6 multicast enable interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Get V4 multicast routing on interface -*/ -switch_status_t switch_api_interface_ipv6_multicast_enabled_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set IPv4 unicast rpf mode interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Unicast RPF mode -*/ -switch_status_t switch_api_interface_ipv4_urpf_mode_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get IPv4 unicast rpf mode interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Unicast RPF mode -*/ -switch_status_t switch_api_interface_ipv4_urpf_mode_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set IPv6 unicast rpf mode interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Unicast RPF mode -*/ -switch_status_t switch_api_interface_ipv6_urpf_mode_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get IPv6 unicast rpf mode interface attribute - @param intf_handle - Handle that uniquely identifies interface - @param value - Unicast RPF mode -*/ -switch_status_t switch_api_interface_ipv6_urpf_mode_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set native vlan on interface - @param intf_handle - Handle that uniquely identifies interface - @param value - Value of native vlan -*/ -switch_status_t switch_api_interface_native_vlan_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get native vlan on interface - @param intf_handle - Handle that uniquely identifies interface - @param value - Value of native vlan -*/ -switch_status_t switch_api_interface_native_vlan_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Iterator function prototype for l3 interfaces - @param intf_info Interface Info - */ -typedef switch_status_t (*switch_l3_interfaces_iterator_fn)(switch_api_interface_info_t intf_info); - -/** - Get all l3 interfaces - @param iterator_fn Iterator function to be called for every l3 interface - */ -switch_status_t switch_api_interface_l3_ifs_get(switch_l3_interfaces_iterator_fn iterator_fn); - -/** - Given an interface handle, get the associated port handle - @param intf_handle - Handle that uniquely identifies interface - @param port_handle - Port handle associated with the interface - */ -switch_status_t -switch_api_interface_get_port_handle(switch_handle_t intf_handle, - switch_handle_t *port_handle); - -/** - Given an L3 interface handle, get the associated vlan handle - @param intf_handle - Handle that uniquely identifies interface - @param vlan_handle - Vlan handle associated with the interface - */ -switch_status_t -switch_api_interface_get_vlan_handle(switch_handle_t intf_handle, - switch_handle_t *vlan_handle); - -/** - Given an interface handle, get its type - @param intf_handle - Handle that uniquely identifies interface - @param type - Interface type - */ -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 - */ -switch_status_t switch_api_interface_print_all(void); - -/** @} */ // end of interface - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_l3.h b/switchapi/inc/switchapi/switch_l3.h deleted file mode 100644 index 5399e77..0000000 --- a/switchapi/inc/switchapi/switch_l3.h +++ /dev/null @@ -1,157 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_l3_h_ -#define _switch_l3_h_ - -#include "switch_base_types.h" -#include "switch_handle.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup L3 L3 API - * API functions create IP interfaces and route - * @{ - */ // begin of L3 API -//L3 - -//RPF check -/** Mode for RPF check - loose or strict mode */ -typedef enum { - SWITCH_API_RPF_CHECK_DEFAULT, - SWITCH_API_RPF_CHECK_LOOSE, - SWITCH_API_RPF_CHECK_STRICT -} switch_urpf_mode_t; - -/** - Configure IP address on L3 interface - @param device device - @param interface_handle interface handle returned from interface_create() - @param vrf virtual domain identifier - @param ip_addr IP address to be configured(v4 or v6) -*/ -switch_status_t switch_api_l3_interface_address_add(switch_device_t device, - switch_handle_t interface_handle, - switch_handle_t vrf, - switch_ip_addr_t *ip_addr); -/** - Delete a configured IP address on interface - @param device device - @param interface_handle interface handle returned from interface_create() - @param vrf virtual domain identifier - @param ip_addr IP address to be deleted -*/ -switch_status_t switch_api_l3_interface_address_delete(switch_device_t device, - switch_handle_t interface_handle, - switch_handle_t vrf, - switch_ip_addr_t *ip_addr); -/** - Host address reachability entry - inserted into a Hash table to match a - /32 IPv4 ot /128 IPv6 address, When there are multiple paths to reach - the same destiantion ECMP tables is used implicitly - @param device device - @param vrf virtual domain identifier - @param ip_addr IP address - @param nhop_handle Nexthop Handle -*/ -switch_status_t switch_api_l3_route_add(switch_device_t device, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, switch_handle_t nhop_handle); -/** - Host address entry delete - @param device device - @param vrf virtual domain identifier - @param ip_addr IP address - @param nhop_handle Nexthop Handle -*/ -switch_status_t switch_api_l3_route_delete(switch_device_t device, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, switch_handle_t nhop_handle); - -/** - Set native vlan on interface - @param intf_handle - Handle that uniquely identifies interface - @param value - Value of v4 urpf mode -*/ -switch_status_t switch_api_interface_ipv4_urpf_mode_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get native vlan on interface - @param intf_handle - Handle that uniquely identifies interface - @param value - Value of v4 urpf mode -*/ -switch_status_t switch_api_interface_ipv4_urpf_mode_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Set native vlan on interface - @param intf_handle - Handle that uniquely identifies interface - @param value - Value of v6 urpf mode -*/ -switch_status_t switch_api_interface_ipv6_urpf_mode_set(switch_handle_t intf_handle, uint64_t value); - -/** - Get native vlan on interface - @param intf_handle - Handle that uniquely identifies interface - @param value - Value of v6 urpf mode -*/ -switch_status_t switch_api_interface_ipv6_urpf_mode_get(switch_handle_t intf_handle, uint64_t *value); - -/** - Iterator function prototype for L3 routes - @param vrf_handle Vrf handle - @param ip_addr IP Address - @param nhop_handle Nexthop handle - */ -typedef switch_status_t (*switch_l3_table_iterator_fn)(switch_handle_t vrf_handle, switch_ip_addr_t ip_addr, switch_handle_t nhop_handle); - -/** - Get all L3 routes - @param iterator_fn - Iterator function to be called -*/ -switch_status_t switch_api_l3_route_entries_get(switch_l3_table_iterator_fn iterator_fn); - -/** - Get all L3 routes in a vrf - @param vrf_handle Vrf handle - @param iterator_fn - Iterator function to be called - */ -switch_status_t switch_api_l3_route_entries_get_by_vrf(switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn); - -/** - Get all L3 V4 routes in a vrf - @param vrf_handle Vrf handle - @param iterator_fn - Iterator function to be called - */ -switch_status_t switch_api_l3_v4_route_entries_get_by_vrf(switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn); - -/** - Get all L3 V6 routes in a vrf - @param vrf_handle Vrf handle - @param iterator_fn - Iterator function to be called - */ -switch_status_t switch_api_l3_v6_route_entries_get_by_vrf(switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn); - -/** - Dump L3 routing table - */ -switch_status_t switch_api_l3_routes_print_all(void); -/** @} */ // end of L3 API - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_mirror.h b/switchapi/inc/switchapi/switch_mirror.h deleted file mode 100644 index 22e51d8..0000000 --- a/switchapi/inc/switchapi/switch_mirror.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_mirror_h -#define _switch_mirror_h - -#include "switch_base_types.h" -#include "switch_handle.h" -#include "switch_tunnel.h" -//#include "model_flags.h" -#ifdef BMV2 -#include "pd/pd_mirroring.h" -#else -#include "p4_sim/mirroring.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** -* @defgroup Mirror Mirroring API -* API functions define and manipulate Access lists -* @{ -*/ -// begin of MIRROR API - -/** Mirror ID */ -typedef unsigned int switch_mirror_id_t; - -/** 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, /**< 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; /**< 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 - */ -#define SWITCH_CPU_MIRROR_SESSION_ID 250 - -/** - * ID for negative mirror session - */ -#define SWITCH_NEGATIVE_MIRROR_SESSION_ID 1015 - -/** - Create a mirror sesion - @param device device on which to create mirror session - @param api_mirror_info parameters of mirror session -*/ - -switch_handle_t switch_api_mirror_session_create(switch_device_t device, - switch_api_mirror_info_t *api_mirror_info); - -/** - Update a mirror sesion - @param device device on which to create mirror session - @param mirror_handle mirror handle - @param api_mirror_info parameters of mirror session -*/ -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 - @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); - -/** - 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 Mirror API - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_port.h b/switchapi/inc/switchapi/switch_port.h deleted file mode 100644 index 7f75a02..0000000 --- a/switchapi/inc/switchapi/switch_port.h +++ /dev/null @@ -1,317 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_port_h_ -#define _switch_port_h_ - -#include "switch_base_types.h" -#include "switch_handle.h" -#include "switch_vlan.h" -#include "switch_meter.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup Port Port configuration API - * API functions listed to configure the ports. Mostly - * related to MAC programming - The basic configuration on the port dictates the MAC programming. - The modes can be set to one of 1x100G, 2x50G, 4x25G, 2x40G or 4x10G. - The ports can be configured with an administrative mode and default behavior can be set. - The tables that get modified in response to the port APIs are mostly the early stage tables. - The port can have a default, which generally allows tagging of untagged packets to this default - domain for forwarding the packets through the device. - * @{ - */ // begin of Port - -/** Port information */ -typedef struct switch_api_port_info_ { - uint16_t port_number; /**< FP port number */ - bool phy_detected; /**< whether phy is present */ - unsigned int ifg; /**<. inter frame gap in cycles */ - unsigned int l3mtu; /**< L3 MTU */ - unsigned int l2mtu; /**< Max frame size */ - bool learn_enable; /**< enable learning on port */ - bool bpdu_enable; /**< allow bpdu even when port is in block state */ - unsigned int egress_rate; /**< Max rate on egress */ - bool tunnel_term; /**< Permit tunnel termination */ - bool ipv4_term; /**< Permit IPv4 termination */ - bool ipv6_term; /**< Permit IPv6 termination */ - bool igmp_snoop; /**< Enable IGMP snopping */ - uint8_t urpf_mode; /**< None/Loose/Strict */ -} switch_api_port_info_t; - -/** port speed */ -typedef enum { - SWITCH_API_PORT_SPEED_NONE, /**< Port Speed Not set */ - SWITCH_API_PORT_SPEED_1G, /**< port speed 1G */ - SWITCH_API_PORT_SPEED_10G, /**< port speed 10G */ - SWITCH_API_PORT_SPEED_25G, /**< port speed 25G */ - SWITCH_API_PORT_SPEED_40G, /**< port speed 40G */ - SWITCH_API_PORT_SPEED_50G, /**< port speed 50G */ - SWITCH_API_PORT_SPEED_100G /**< port speed 100G */ -} switch_port_speed_t; - -/** - * Probe for existing ports - configuration based on current status - * or default (when called immediately after init with default - * config - @param device device to use - @param max_count maximum number of ports to return - @param count actual count returned - @param port_info array of port_info structures per port - */ -switch_status_t switch_api_port_probe(switch_device_t device, unsigned int max_count, - unsigned int *count, switch_api_port_info_t *port_info); - -/** - Port Enable Set- Enabled the port on a device - @param device device to use - @param port port on device to set - @param enable TRUE => port is enabled FALSE => Port is disabled -*/ -switch_status_t switch_api_port_enable_set(switch_device_t device, switch_port_t port, - bool enable); - -/** - Port Enable Get - Get the Port Enabled state - @param device device to use - @param port port on device to get information - @param enable TRUE => port is enabled FALSE => Port is disabled -*/ -switch_status_t switch_api_port_enable_get(switch_device_t device, switch_port_t port, - bool *enable); - -/** - Port Speed Set - @param device device to use - @param port port on device to set - @param speed desired speed of port -*/ -switch_status_t switch_api_port_speed_set(switch_device_t device, switch_port_t port, - switch_port_speed_t speed); - -/** -Port Speed Get -@param device device to use -@param port port on device to get -@param speed actual speed of port -*/ -switch_status_t switch_api_port_speed_get(switch_device_t device, switch_port_t port, - switch_port_speed_t *speed); - -/** - Port Autonegotiation Set - @param device device to use - @param port port on device to set - @param enable Enable Autonegotiation if TRUE else disable -*/ -switch_status_t switch_api_port_autoneg_set(switch_device_t device, switch_port_t port, - bool enable); -/** -Port Autonegotiation get -@param device device to use -@param port port on device to get -@param enable returns TRUE if Autonegotiation is set else FALSE -*/ -switch_status_t switch_api_port_autoneg_get(switch_device_t device, switch_port_t port, - bool *enable); - -/** Port Pause message information */ -typedef struct switch_port_pause_info_ { - bool rx; /**< rx ignore PAUSE FALSE => disable PAUSE */ - bool tx; /**< tx send PAUSE frames when needed */ - switch_mac_addr_t mac; /**< MAC addr to use when sending pause frames */ - bool symmetric; /**< Symmetric or Asymmetric mode */ - unsigned int quanta; /**< time in ms after which to stop sending pause */ -} switch_port_pause_info_t; - -/** - Port PAUSE control set - @param device device to use - @param port port on device to set - @param pause_info Pause informaion for the port -*/ -switch_status_t switch_api_port_pause_set(switch_device_t device, switch_port_t port, - switch_port_pause_info_t *pause_info); - -/** - Port PAUSE control get - @param device device to use - @param port port on device to get - @param pause_info Pause informaion for the port -*/ -switch_status_t switch_api_port_pause_get(switch_device_t device, switch_port_t port, - switch_port_pause_info_t *pause_info); - -/** Priority Flow Control configuration */ -typedef struct switch_pfc_config_ { - uint32_t flags; /**< flags to control */ - bool lossless; /**< lossless mode */ - uint32_t fc_on_threshold; /**< Threshold in bytes to turn on FC */ - uint32_t fc_off_threshold; /**< Threshold in bytes to turn on FC */ - uint32_t drop_threshold; /**< Discard threshold */ -} switch_pfc_config_t; - -/** - Set the threshholds and mode or PFC on a port - @param device device - @param port port on device to configure - @param queue on the port to configure - @param pfc PFC configuration parameters -*/ -switch_status_t switch_api_port_pfc_config_set(switch_device_t device, switch_port_t port, - uint8_t queue, switch_pfc_config_t *pfc); - -/** - Port operational state - @param device device to use - @param port port on device to get - @param up port state -*/ -switch_status_t switch_api_port_state_get(switch_device_t device, switch_port_t port, bool *up); - -/** - Port operational state declaration interval - @param device device to use - @param port port on device to get - @param interval microseconds to debounce -*/ -switch_status_t switch_api_port_debounce_set(switch_device_t device, switch_port_t port, - unsigned int interval); - -/** - Port set MAC in loopback - @param device device to use - @param port port on device to set - @param enable loopback enabled if TRUE else FALSE -*/ -switch_status_t switch_api_port_mac_loopback_set(switch_device_t device, switch_port_t port, - bool enable); - -/** - Port get MAC loopback config - @param device device to use - @param port port on device to get - @param enable TRUE if loopback is enabled else FALSE -*/ -switch_status_t switch_api_port_mac_loopback_get(switch_device_t device, switch_port_t port, - bool *enable); - -/** - Port L2 MTU settings - @param device device to use - @param port port on device to set - @param l2mtu Max frame size on port -*/ -switch_status_t switch_api_port_mtu_set(switch_device_t device, switch_port_t port, - unsigned int l2mtu); - -/** - Port L3 MTU settings - @param device device to use - @param port port on device to set - @param l3mtu IP MTU on port -*/ -switch_status_t switch_api_port_l3_mtu_set(switch_device_t device, switch_port_t port, - unsigned int l3mtu); - -/** - Port MTU settings get - @param device device to use - @param port port on device to get - @param l2mtu maximum frame size (rx and tx) - @param l3mtu IP MTU on port -*/ -switch_status_t switch_api_port_l3_mtu_get(switch_device_t device, switch_port_t port, - unsigned int *l2mtu, unsigned int *l3mtu); - -/** - Port egress rate set - @param device device to use - @param port port on device to set - @param rate rate in kbps -*/ -switch_status_t switch_api_port_egress_rate_set(switch_device_t device, switch_port_t port, - unsigned int rate); - -/** - Set Port configuration - @param device device to use - @param api_port_info port information inclduing port number - (portnumber specified in port_info->port_number) -*/ -switch_status_t switch_api_port_set(switch_device_t device, switch_api_port_info_t *api_port_info); - -/** - Get Port configuration - @param device device to use - @param api_port_info port information inclduing port number - (portnumber specified in port_info->port_number) -*/ -switch_status_t switch_api_port_get(switch_device_t device, switch_api_port_info_t *api_port_info); - -/** - Set meter handle for port - @param device device to use - @param port port on device - @param pkt_type packet type - @param meter_handle meter handle - */ -switch_status_t switch_api_port_storm_control_set(switch_device_t device, - switch_port_t port, - switch_packet_type_t pkt_type, - switch_handle_t meter_handle); - -/** - Get meter handle for port - @param device device to use - @param port port on device - @param pkt_type packet type - @param meter_handle meter handle - */ -switch_status_t switch_api_port_storm_control_get(switch_device_t device, - switch_port_t port, - switch_packet_type_t pkt_type, - switch_handle_t *meter_handle); -/** - Meter stats - @param device device - @param meter_handle meter handle - @param count number of counters - @param counter_ids meter counter ids - @param counters counter values - */ -switch_status_t -switch_api_storm_control_stats_get(switch_device_t device, - switch_handle_t meter_handle, - uint8_t count, - switch_meter_stats_t *counter_ids, - switch_counter_t *counters); - -/** - Dump port table - */ -switch_status_t switch_api_port_print_all(void); - -/** @} */ // end of Port - -#ifdef __cplusplus -} -#endif - -#endif /* defined(_switch_port_h_) */ diff --git a/switchapi/inc/switchapi/switch_porting.h b/switchapi/inc/switchapi/switch_porting.h deleted file mode 100644 index 4f71c48..0000000 --- a/switchapi/inc/switchapi/switch_porting.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/**************************************************************************//** - * - * @file - * @brief Switch Porting Macros. - * - * @addtogroup switch-porting - * @{ - * - *****************************************************************************/ -#ifndef __SWITCH_PORTING_H__ -#define __SWITCH_PORTING_H__ - - -/* */ -#if SWITCH_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1 -#include -#include -#include -#include -#include -#endif - -#ifndef SWITCH_MALLOC - #if defined(GLOBAL_MALLOC) - #define SWITCH_MALLOC GLOBAL_MALLOC - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_MALLOC malloc - #else - #error The macro SWITCH_MALLOC is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_FREE - #if defined(GLOBAL_FREE) - #define SWITCH_FREE GLOBAL_FREE - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_FREE free - #else - #error The macro SWITCH_FREE is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_MEMSET - #if defined(GLOBAL_MEMSET) - #define SWITCH_MEMSET GLOBAL_MEMSET - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_MEMSET memset - #else - #error The macro SWITCH_MEMSET is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_MEMCPY - #if defined(GLOBAL_MEMCPY) - #define SWITCH_MEMCPY GLOBAL_MEMCPY - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_MEMCPY memcpy - #else - #error The macro SWITCH_MEMCPY is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_STRNCPY - #if defined(GLOBAL_STRNCPY) - #define SWITCH_STRNCPY GLOBAL_STRNCPY - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_STRNCPY strncpy - #else - #error The macro SWITCH_STRNCPY is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_VSNPRINTF - #if defined(GLOBAL_VSNPRINTF) - #define SWITCH_VSNPRINTF GLOBAL_VSNPRINTF - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_VSNPRINTF vsnprintf - #else - #error The macro SWITCH_VSNPRINTF is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_SNPRINTF - #if defined(GLOBAL_SNPRINTF) - #define SWITCH_SNPRINTF GLOBAL_SNPRINTF - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_SNPRINTF snprintf - #else - #error The macro SWITCH_SNPRINTF is required but cannot be defined. - #endif -#endif - -#ifndef SWITCH_STRLEN - #if defined(GLOBAL_STRLEN) - #define SWITCH_STRLEN GLOBAL_STRLEN - #elif SWITCH_CONFIG_PORTING_STDLIB == 1 - #define SWITCH_STRLEN strlen - #else - #error The macro SWITCH_STRLEN is required but cannot be defined. - #endif -#endif - -/* */ - - -#endif /* __SWITCH_PORTING_H__ */ -/* @} */ diff --git a/switchapi/inc/switchapi/switch_protocol.h b/switchapi/inc/switchapi/switch_protocol.h deleted file mode 100644 index aa1d44b..0000000 --- a/switchapi/inc/switchapi/switch_protocol.h +++ /dev/null @@ -1,215 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_protocol_h -#define _switch_protocol_h - -#include "switch_handle.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup Protocol Protocol types and info - * Protocol types and info - * @{ - */ // begin of Protocol API - -/** Encap type */ -typedef enum switch_encap_type_ { - SWITCH_API_ENCAP_TYPE_NONE=0, /**< Not a tunnel */ - SWITCH_API_ENCAP_TYPE_VLAN=1, /**< VLAN encapsulation */ - SWITCH_API_ENCAP_TYPE_QINQ=2, /**< Double Tag encap */ - SWITCH_API_ENCAP_TYPE_VXLAN=3, /**< VxLAN encapsulation */ - 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_IPIP=8, /**< IP in IP encapsulation */ -} switch_encap_type_t; - -/** UDP fields that are relevant */ -typedef struct switch_udp_ { - uint16_t src_port; /**< Source port number */ - uint16_t dst_port; /**< Destination port number */ -} switch_udp_t; - -/** TCP fields that are relevant */ -typedef struct switch_tcp_ { - uint16_t src_port; /**< Source port number */ - uint16_t dst_port; /**< Destination port number */ -} switch_tcp_t; - -/** QinQ encapsulation format */ -typedef struct { - switch_vlan_t outer; /**< outer tag */ - switch_vlan_t inner; /**< Inner tag */ -} switch_qinq_t; - -/** VxLAN identifier */ -typedef struct { - unsigned int vnid:24; /**< Unique value for a tenant */ - unsigned int rsvd:8; /**< unused - should be 0 */ -} switch_vxlan_id_t; - -/** NvGRE identifier */ -typedef struct { - unsigned int tnid:24; /**< Unique value for a tenant */ - unsigned int rsvd:8; /**< unused - should be 0 */ -} switch_nvgre_id_t; - -/** Geneve identifier */ -typedef struct { - unsigned int version:2, /**< version - set to 0 */ - option_length:6, /**< option length */ - oam:1, /**< OAM Pkt */ - critical:1, /**< Critical */ - rsvd:6, /**< reserved data should be 0 */ - prototype:16; /**< ether type */ - unsigned int vni:24, /**< Tenant ID */ - rsvd2:8; /**< reserved should be 0 */ -} switch_geneve_id_t; - -/** Gre identifier */ -typedef struct { - unsigned short csum_present: 1, /**< Checksum present? */ - routing_present:1, /**< Routing info present? */ - key_present: 1, /**< Key present? */ - sequence_present: 1, /**< Sequence present? */ - strict_route: 1, /**< strict route? */ - recursion_control: 1, /**< recursion control */ - flags: 5, /**< flags */ - version: 3; /**< version */ - unsigned short protocol; /**< ether type */ - unsigned short checksum; /**< checksum of packet (opt) */ - unsigned short offset; /**< offset in packet */ - unsigned int key; /**< GRE key */ - unsigned int sequence; /**< sequence number */ - unsigned int routing; /**< Routing information */ -} switch_gre_t; - -/** IP Header information relevant */ -typedef struct switch_ip_encap_ { - switch_handle_t vrf_handle; /**< VRF instance */ - switch_ip_addr_t src_ip; /**< Source IP address of tunnel */ - switch_ip_addr_t dst_ip; /**< Destination IP of tunnel */ - unsigned short mtu; /**< IP MTU supported */ - unsigned char ttl; /**< Time to live */ - unsigned char proto; /**< UDP/TCP/GRE */ - union { - switch_udp_t udp; /**< UDP header */ - switch_tcp_t tcp; /**< TCP header */ - switch_gre_t gre; /**< IP GRE header */ - } u; /**< union */ -} switch_ip_encap_t; - -/** Maximum mpls labels supported */ -#define SWITCH_MPLS_LABEL_MAX 5 - -/** Mpls header */ -typedef struct switch_mpls_ { - unsigned int label:20; /**< mpls label */ - unsigned int exp:3; /**< experimental */ - unsigned int bos:1; /**< bottom of stack */ - unsigned int ttl:8; /**< time to live */ -} switch_mpls_t; - -/** Mpls tunnel type */ -typedef enum switch_mpls_type_ { - SWITCH_API_MPLS_TYPE_EOMPLS, - SWITCH_API_MPLS_TYPE_IPV4_MPLS, - SWITCH_API_MPLS_TYPE_IPV6_MPLS, - SWITCH_API_MPLS_TYPE_VPLS, - SWITCH_API_MPLS_TYPE_PW -} switch_mpls_type_t; - -/** Mpls mode */ -typedef enum switch_mpls_mode_ { - SWITCH_API_MPLS_INITIATE, - SWITCH_API_MPLS_TRANSIT, - SWITCH_API_MPLS_TERMINATE -} switch_mpls_mode_t; - -/** Mpls action */ -typedef enum switch_mpls_action_ { - SWITCH_API_MPLS_ACTION_POP, - SWITCH_API_MPLS_ACTION_PUSH, - SWITCH_API_MPLS_ACTION_SWAP, - SWITCH_API_MPLS_ACTION_SWAP_PUSH -} switch_mpls_action_t; - -/** Mpls swap identifier */ -typedef struct switch_mpls_swap_ { - switch_mpls_t old_tag; /**< old mpls header */ - switch_mpls_t new_tag; /**< new mpls header */ -} switch_mpls_swap_t; - -/** Mpls pop identifier */ -typedef struct switch_mpls_pop_ { - switch_mpls_t tag[SWITCH_MPLS_LABEL_MAX]; /**< mpls header stack to pop */ - uint8_t count; /**< number of label stack to pop */ -} switch_mpls_pop_t; - -/** Mpls push identifier */ -typedef struct switch_mpls_push_ { - switch_mpls_t tag[SWITCH_MPLS_LABEL_MAX]; /**< mpls header stack to push */ - uint8_t count; /**< number of label stack to push */ -} switch_mpls_push_t; - -/** Mpls swap identifier */ -typedef struct switch_mpls_swap_push_ { - switch_mpls_t old_tag; /**< old mpls header */ - switch_mpls_t new_tag[SWITCH_MPLS_LABEL_MAX]; /**< new mpls header stack to push */ - uint8_t count; /**< number of label stack to push */ -} switch_mpls_swap_push_t; - -/** Mpls encap identifer */ -typedef struct switch_mpls_encap_ { - switch_mpls_type_t mpls_type; /**< mpls tunnel type */ - switch_mpls_action_t mpls_action; /**< mpls action - push/pop/swap */ - switch_mpls_mode_t mpls_mode; /**< mpls mode */ - union { - switch_mpls_swap_t swap_info; /**< mpls swap info */ - switch_mpls_push_t push_info; /**< mpls push info */ - switch_mpls_pop_t pop_info; /**< mpls pop info */ - switch_mpls_swap_push_t swap_push_info; /**< mpls swap push info */ - } u; /**< union */ - switch_handle_t bd_handle; /**< bridge domain handle */ - switch_handle_t vrf_handle; /**< vrf handle */ - switch_handle_t nhop_handle; /**< nexthop handle */ - switch_handle_t egress_if; /**< egress interface handle */ -} switch_mpls_encap_t; - -/** Tunnel encap identifier */ -typedef struct switch_encap_info_ { - switch_encap_type_t encap_type; /**< Encap type */ - union { - switch_vlan_t vlan_id; /**< VLAN Id*/ - switch_vxlan_id_t vxlan_info; /**< VxLAN domain info */ - switch_geneve_id_t geneve_info; /**< Geneve domain info */ - switch_nvgre_id_t nvgre_info; /**< NVGRE domain info */ - switch_qinq_t qinq_info; /**< Qinq info */ - uint32_t tunnel_vni; /**< Tunnel Vni - Used only in LN Basic mode */ - } u; /**< union */ -} switch_encap_info_t; - -/** @} */ // end of Protocol - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/switchapi/inc/switchapi/switch_sflow.h b/switchapi/inc/switchapi/switch_sflow.h deleted file mode 100644 index ad59a06..0000000 --- a/switchapi/inc/switchapi/switch_sflow.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2015-present Barefoot Networks, Inc. - */ - -#ifndef _switch_sflow_h -#define _switch_sflow_h - -#include "switch_base_types.h" -#include "switch_handle.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define SWITCH_MAX_SFLOW_SESSIONS 16 // MAX_SFLOW_SESSIONS from sizes.h -#define SWITCH_MAX_SFLOW_ACES 512 // SFLOW_INGRESS_TABLE_SIZE from sizes.h - -typedef enum switch_sflow_match_field_ { - SWITCH_SFLOW_MATCH_PORT = 0, - SWITCH_SFLOW_MATCH_VLAN, - SWITCH_SFLOW_MATCH_SIP, - SWITCH_SFLOW_MATCH_DIP, - SWITCH_SFLOW_MATCH_FIELD_MAX, -} switch_sflow_match_field_t; - -/* sflow match values */ -typedef union switch_sflow_match_value_ { - switch_handle_t port; - uint32_t vlan; - uint32_t sip; - uint32_t dip; -} switch_sflow_match_value_t; - -/* sflow match mask - same as masks used for acl */ -typedef union switch_sflow_match_mask_ { - unsigned type:1; /**< mask type */ - union { - uint64_t mask; /**< mask value */ - unsigned int start, end; /**< mask range */ - } u; /**< ip mask union */ -} switch_sflow_match_mask_t; - -/** Egress acl key value pair */ -typedef struct switch_sflow_match_key_value_pair_ { - switch_sflow_match_field_t field; - switch_sflow_match_value_t value; - switch_sflow_match_mask_t mask; -} switch_sflow_match_key_value_pair_t; - -typedef enum { - SFLOW_COLLECTOR_TYPE_CPU = 0, - SFLOW_COLLECTOR_TYPE_REMOTE -} switch_sflow_collector_type_e; - -typedef enum { - SWITCH_SFLOW_SAMPLE_PKT = 0, -} switch_sflow_sample_mode_e; - -typedef struct switch_api_sflow_session_info_ { - uint32_t session_id; - uint32_t timeout_usec; // 0 => 100us (default) - uint32_t sample_rate; // 0 => every 10k pkts (default) - uint32_t extract_len; // 0 => 80 (default) - switch_handle_t egress_port_hdl; - switch_sflow_collector_type_e collector_type; - switch_sflow_sample_mode_e sample_mode; -} switch_api_sflow_session_info_t; - -switch_handle_t -switch_api_sflow_session_create (switch_device_t device, - switch_api_sflow_session_info_t *api_sflow_info); -switch_status_t -switch_api_sflow_session_delete (switch_device_t device, - switch_handle_t sflow_hdl, - bool all_cleanup); - -switch_status_t -switch_api_sflow_session_attach (switch_device_t device, - switch_handle_t sflow_hdl, - switch_direction_t direction, - unsigned int priority, - unsigned int sample_rate, /* != 0 can override sampling rate of the session */ - unsigned int key_value_count, - switch_sflow_match_key_value_pair_t *kvp, - switch_handle_t *entry_hdl); - -switch_status_t -switch_api_sflow_session_detach (switch_device_t device, - switch_handle_t sflow_hdl, - switch_handle_t entry_hdl - ); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _switch_sflow_h */ diff --git a/switchapi/inc/switchapi/switch_status.h b/switchapi/inc/switchapi/switch_status.h deleted file mode 100644 index dd649e0..0000000 --- a/switchapi/inc/switchapi/switch_status.h +++ /dev/null @@ -1,186 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_status_h -#define _switch_status_h - -#include "switch_base_types.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * Status success - */ -#define SWITCH_STATUS_SUCCESS 0x00000000L - -/* - * General failure - */ -#define SWITCH_STATUS_FAILURE 0x00000001L - -/* - * The request is not supported - */ -#define SWITCH_STATUS_NOT_SUPPORTED 0x00000002L - -/* - * Not enough memory to complete the operation - */ -#define SWITCH_STATUS_NO_MEMORY 0x00000003L - -/* - * Insufficient system resources exist to complete the operation - */ -#define SWITCH_STATUS_INSUFFICIENT_RESOURCES 0x00000004L - -/* - * An invalid parameter was passed to a function - */ -#define SWITCH_STATUS_INVALID_PARAMETER 0x00000005L - -/* - * An item already exists - */ -#define SWITCH_STATUS_ITEM_ALREADY_EXISTS 0x00000006L - -/* - * An item was not found - */ -#define SWITCH_STATUS_ITEM_NOT_FOUND 0x00000007L - -/* - * The data was too large to fit into the specified buffer. - */ -#define SWITCH_STATUS_BUFFER_OVERFLOW 0x00000008L - -/* - * Invalid port number - */ -#define SWITCH_STATUS_INVALID_PORT_NUMBER 0x00000009L - -/* - * Invalid port member - */ -#define SWITCH_STATUS_INVALID_PORT_MEMBER 0x0000000AL - -/* - * Invalid VLAN id - */ -#define SWITCH_STATUS_INVALID_VLAN_ID 0x0000000BL - -/* - * Object is uninitialized - */ -#define SWITCH_STATUS_UNINITIALIZED 0x0000000CL - -/* - * Table is full - */ -#define SWITCH_STATUS_TABLE_FULL 0x0000000DL - -/* - * Attribute is invalid - */ -#define SWITCH_STATUS_INVALID_ATTRIBUTE 0x0000000EL - -/* - * Invalid interface id - */ -#define SWITCH_STATUS_INVALID_INTERFACE 0x0000000FL - -/* - * Port is in use - */ -#define SWITCH_STATUS_PORT_IN_USE 0x00000010L - -/* - * Invalid switch ID - */ -#define SWITCH_STATUS_INVALID_SWITCH_ID 0x00000011L - -/* - * Function is not implemented - */ -#define SWITCH_STATUS_NOT_IMPLEMENTED 0x00000012L - -/* - * Address not found - */ -#define SWITCH_STATUS_ADDR_NOT_FOUND 0x00000013L - -/* - * Invalid virtual router ID - */ -#define SWITCH_STATUS_INVALID_VRID 0x00000014L - -/* - * Invalid attribute value - */ -#define SWITCH_STATUS_INVALID_ATTR_VALUE 0x00000015L - -/* - * Invalid Tunnel type - */ -#define SWITCH_STATUS_INVALID_TUNNEL_TYPE 0x000000016L - -/* - * Invalid Next Hop - */ -#define SWITCH_STATUS_INVALID_NHOP 0x000000017L - -/* - * Invalid Handle - */ -#define SWITCH_STATUS_INVALID_HANDLE 0x000000018L - -/* -* RESOURCE is in use -*/ -#define SWITCH_STATUS_RESOURCE_IN_USE 0x00000019L - -/* - * Invalid LN type - */ -#define SWITCH_STATUS_INVALID_LN_TYPE 0x00000001AL - -/* - * Invalid encap type - */ -#define SWITCH_STATUS_INVALID_ENCAP_TYPE 0x00000001BL - -/* - * Unsupported type - */ -#define SWITCH_STATUS_UNSUPPORTED_TYPE 0x00000001CL - -/* - * pd failure - */ -#define SWITCH_STATUS_PD_FAILURE 0x00000001DL - -/* - * invalid device id - */ -#define SWITCH_STATUS_INVALID_DEVICE 0x00000001EL - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/switchapi/inc/switchapi/switch_tunnel.h b/switchapi/inc/switchapi/switch_tunnel.h deleted file mode 100644 index b3799d6..0000000 --- a/switchapi/inc/switchapi/switch_tunnel.h +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef _switch_tunnel_h_ -#define _switch_tunnel_h_ - -#include "switch_handle.h" -#include "switch_vlan.h" -#include "switch_protocol.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @defgroup Tunnel Tunnel API - * API functions create tunnel interfaces - * @{ - */ // begin of Tunnel API - -/** Tunnel encap mode */ -typedef enum switch_encap_mode_ { - SWITCH_API_TUNNEL_ENCAP_MODE_IP, - SWITCH_API_TUNNEL_ENCAP_MODE_MPLS -} switch_encap_mode_t; - -/** Tunnel information */ -typedef struct switch_tunnel_info_ { - switch_encap_info_t encap_info; /**< Encap Info */ - switch_encap_mode_t encap_mode; /**< Encap mode - ip/mpls */ - union { - switch_ip_encap_t ip_encap; /**< IP encapsulation */ - switch_mpls_encap_t mpls_encap; /**< Mpls Encapsulation */ - } u; /**< tunnel encap union */ - switch_handle_t out_if; /**< Underlying interface */ - struct { - bool core_intf:1; /**< core interface */ - bool flood_enabled:1; /**< flooding enabled */ - } flags; /**< tunnel flags */ -} switch_tunnel_info_t; - -/** Tunnel Egress type */ -typedef enum switch_tunnel_type_egress_ { - SWITCH_EGRESS_TUNNEL_TYPE_NONE = 0, - SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN = 1, - SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN = 2, - SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE = 3, - SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE = 4, - SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE = 5, - SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE = 6, - SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3 = 7, - SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3 = 8, - SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GRE = 9, - SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GRE = 10, - SWITCH_EGRESS_TUNNEL_TYPE_MPLS_L2VPN = 13, - SWITCH_EGRESS_TUNNEL_TYPE_MPLS_L3VPN = 14, - 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 */ -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_IPIP = 3, - SWITCH_INGRESS_TUNNEL_TYPE_GENEVE = 4, - SWITCH_INGRESS_TUNNEL_TYPE_NVGRE = 5, - SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_1 = 6, - SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_2 = 7, - SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_3 = 8, - SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_1 = 9, - SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_2 = 10, - SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_3 = 11, - SWITCH_INGRESS_TUNNEL_TYPE_VXLAN_GPE = 12, -} switch_tunnel_type_ingress_t; - -/** Mpls ipv4 explicit null label */ -#define SWITCH_MPLS_IPV4_EXPLICIT_NULL 0 - -/** 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 - L2 or L3 service on the tunnel - @param device device - @param direction allow for ingress or egress only interfaces - @param tunnel_info tunnel encapsulation information -*/ -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 - deleted - @param device device - @param tunnel_handle handle of tunnel returned on tunnel creation -*/ -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 - @param network_handle Logical network handle - @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 interface_handle); - -/** - Delete member from logical network - @param device device - @param network_handle Logical network handle - @param interface_handle Handle of access port ot Tunnel interface -*/ -switch_status_t switch_api_logical_network_member_remove(switch_device_t device, - switch_handle_t network_handle, - switch_handle_t interface_handle); - -/** - Mpls Transit Create - @param device device - @param mpls_encap mpls info -*/ -switch_status_t switch_api_mpls_tunnel_transit_create(switch_device_t device, switch_mpls_encap_t *mpls_encap); - -/** - Mpls Transit Create - @param device device - @param mpls_encap mpls info -*/ -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 - -#endif /* defined(_switch_tunnel_h_) */ diff --git a/switchapi/include/switchapi/switch_INT.h b/switchapi/include/switchapi/switch_INT.h new file mode 100644 index 0000000..465189d --- /dev/null +++ b/switchapi/include/switchapi/switch_INT.h @@ -0,0 +1,50 @@ +/* +Copyright 2015-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _SWITCH_INT_H_ +#define _SWITCH_INT_H_ +#include "switch_base_types.h" +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define INT_INS_MASK_VALID_BITS 0xFF00 + +switch_status_t switch_int_transit_enable(switch_device_t device, + int32_t switch_id, + int32_t enable); + +switch_status_t switch_int_src_enable(switch_device_t device, + int32_t switch_id, + switch_ip_addr_t *src, + switch_ip_addr_t *dst, + uint8_t max_hop, + uint16_t ins_mask); +switch_status_t switch_int_src_disable(switch_device_t device, + switch_ip_addr_t *src, + switch_ip_addr_t *dst); +switch_status_t switch_int_sink_enable(switch_device_t device, + switch_ip_addr_t *dst, + int32_t mirror_id); +switch_status_t switch_int_sink_disable(switch_device_t device, + switch_ip_addr_t *dst); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif // _SWITCH_INT_H_ diff --git a/switchapi/include/switchapi/switch_acl.h b/switchapi/include/switchapi/switch_acl.h new file mode 100644 index 0000000..8b2d682 --- /dev/null +++ b/switchapi/include/switchapi/switch_acl.h @@ -0,0 +1,606 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_acl_h_ +#define _switch_acl_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_id.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup ACL ACL API + * API functions define and manipulate Access lists + * @{ + */ // begin of ACL API + +/** ACL Types */ +typedef enum switch_acl_type_ { + SWITCH_ACL_TYPE_IP, /**< IPv4 ACL */ + SWITCH_ACL_TYPE_MAC, /**< MAC ACL */ + SWITCH_ACL_TYPE_IPV6, /**< IPv6 ACL */ + SWITCH_ACL_TYPE_MIRROR, /**< Mirror ACL */ + SWITCH_ACL_TYPE_QOS, /**< QoS ACL */ + SWITCH_ACL_TYPE_SYSTEM, /**< Ingress System ACL */ + SWITCH_ACL_TYPE_EGRESS_SYSTEM, /**< Egress System ACL */ + SWITCH_ACL_TYPE_IP_RACL, /**< IPv4 Route ACL */ + SWITCH_ACL_TYPE_IPV6_RACL, /**< IPv6 Route ACL */ + SWITCH_ACL_TYPE_MAX +} switch_acl_type_t; + +/** Acl IP field enum */ +typedef enum switch_acl_ip_field_ { + SWITCH_ACL_IP_FIELD_IPV4_SRC, /**< IPv4 Source address */ + SWITCH_ACL_IP_FIELD_IPV4_DEST, /**< IPv4 Dest address */ + SWITCH_ACL_IP_FIELD_IP_PROTO, /**< IP Protocol */ + SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT, /**< L4 source port UDP/TCP */ + SWITCH_ACL_IP_FIELD_L4_DEST_PORT, /**< L4 dest port UDP/TCP */ + SWITCH_ACL_IP_FIELD_ICMP_TYPE, /**< ICMP type */ + SWITCH_ACL_IP_FIELD_ICMP_CODE, /**< ICMP code */ + SWITCH_ACL_IP_FIELD_TCP_FLAGS, /**< TCP flags */ + SWITCH_ACL_IP_FIELD_TTL, /**< TTL */ + SWITCH_ACL_IP_FIELD_IP_FLAGS, /**< IP flags */ + SWITCH_ACL_IP_FIELD_IP_FRAGMENT, /**< IP FRAG */ + + SWITCH_ACL_IP_FIELD_MAX +} switch_acl_ip_field_t; + +/** Acl IPv6 field enum */ +typedef enum switch_acl_ipv6_field_ { + SWITCH_ACL_IPV6_FIELD_IPV6_SRC, /**< IPv6 Source address */ + SWITCH_ACL_IPV6_FIELD_IPV6_DEST, /**< IPv6 Destination address */ + SWITCH_ACL_IPV6_FIELD_IP_PROTO, /**< IP protocol */ + SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT, /**< L4 source port (UDP/TCP) */ + SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT, /**< L4 Dest port (UDP/TCP) */ + SWITCH_ACL_IPV6_FIELD_ICMP_TYPE, /**< ICMP type */ + SWITCH_ACL_IPV6_FIELD_ICMP_CODE, /**< ICMP code */ + SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, /**< TCP flags */ + SWITCH_ACL_IPV6_FIELD_TTL, /**< TTL */ + SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, /**< Flow Label */ + + SWITCH_ACL_IPV6_FIELD_MAX +} switch_acl_ipv6_field_t; + +/** Acl IP field list */ +typedef union switch_acl_ip_value_ { + unsigned int ipv4_source; /**< v4 source IP */ + unsigned int ipv4_dest; /**< v4 destination IP */ + unsigned char ip_proto; /**< protocol */ + unsigned short l4_source_port; /**< souce port */ + unsigned short l4_dest_port; /**< destination port */ + unsigned char icmp_type; /**< icmp type */ + unsigned char icmp_code; /**< icmp code */ + unsigned char tcp_flags; /**< tcp flags */ + unsigned char ttl; /**< time to live */ + unsigned char dscp; /**< DSCP */ + unsigned char ip_flags; /**< IP flags */ + unsigned char tos; /**< TOS */ + unsigned char ip_frag; /**< IP FRAG */ +} switch_acl_ip_value; + +/** Acl IPv6 field list */ +typedef union switch_acl_ipv6_value_ { + uint128_t ipv6_source; /**< v6 souce IP */ + uint128_t ipv6_dest; /**< v6 destination IP */ + unsigned char ip_proto; /**< protocol */ + unsigned short l4_source_port; /**< source port */ + unsigned short l4_dest_port; /**< destination port */ + unsigned char icmp_type; /**< icmp type */ + unsigned char icmp_code; /**< icmp code */ + unsigned char tcp_flags; /**< tcp flags */ + unsigned char ttl; /**< time to live */ + uint32_t flow_label; /**< flow label */ +} switch_acl_ipv6_value; + +/** Acl IP mask */ +typedef union switch_acl_ip_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint32_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< ip mask union */ +} switch_acl_ip_mask; + +/** Acl IPV6 mask */ +typedef union switch_acl_ipv6_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint128_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< ipv6 mask union */ +} switch_acl_ipv6_mask; + +/** Acl IP key value pair */ +typedef struct switch_acl_ip_key_value_pair_ { + switch_acl_ip_field_t field; /**< acl ip field type */ + switch_acl_ip_value value; /**< acl ip field value */ + switch_acl_ip_mask mask; /**< acl ip field mask */ +} switch_acl_ip_key_value_pair_t; + +/** Acl IPv6 key value pair */ +typedef struct { + switch_acl_ipv6_field_t field; /**< acl ip field type */ + switch_acl_ipv6_value value; /**< acl ip field value */ + switch_acl_ipv6_mask mask; /**< acl ip field mask */ +} switch_acl_ipv6_key_value_pair_t; + +/** Acl IP action */ +typedef enum switch_acl_action_ { + SWITCH_ACL_ACTION_NOP, /**< Do nothing action */ + SWITCH_ACL_ACTION_DROP, /**< Drop the packet */ + SWITCH_ACL_ACTION_PERMIT, /**< Permit */ + SWITCH_ACL_ACTION_LOG, /**< Log packet by sending to CPU */ + SWITCH_ACL_ACTION_REDIRECT, /**< Redirect packet to new destination */ + SWITCH_ACL_ACTION_REDIRECT_TO_CPU, /**< Redirect packet to CPU */ + SWITCH_ACL_ACTION_COPY_TO_CPU, /**< Send Copy of packet to CPU */ + SWITCH_ACL_ACTION_NEGATIVE_MIRROR, /**< Negative mirror to defined target */ + SWITCH_ACL_ACTION_SET_NATMODE, /**< Set NAT mode */ + SWITCH_ACL_ACTION_SET_MIRROR, /**< Set mirror session */ + SWITCH_ACL_ACTION_FLOOD_TO_VLAN, /**< Flood to all members of BD */ + + SWITCH_ACL_ACTION_MAX +} switch_acl_action_t; + +/** Acl Mac field enum */ +typedef enum switch_acl_mac_field_ { + SWITCH_ACL_MAC_FIELD_ETH_TYPE, /**< Ether type */ + SWITCH_ACL_MAC_FIELD_SOURCE_MAC, /**< Source MAC address */ + SWITCH_ACL_MAC_FIELD_DEST_MAC, /**< Destination MAC address */ + SWITCH_ACL_MAC_FIELD_VLAN_PRI, /**< VLAN priority */ + SWITCH_ACL_MAC_FIELD_VLAN_CFI, /**< VLAN CFI */ + + SWITCH_ACL_MAC_FIELD_MAX +} switch_acl_mac_field_t; + +/** Acl mac field list */ +typedef union switch_acl_mac_value_ { + unsigned short eth_type; /**< ethernet type */ + switch_mac_addr_t source_mac; /**< source mac */ + switch_mac_addr_t dest_mac; /**< destionation mac */ + uint8_t vlan_pri; /**< VLAN priority */ + uint8_t vlan_cfi; /**< drop eligible */ +} switch_acl_mac_value; + +/** Acl mac mask */ +typedef union switch_acl_mac_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint64_t mask; + uint16_t mask16; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< mac mask union */ +} switch_acl_mac_mask; + +/** Acl mac key value pair */ +typedef struct switch_acl_mac_key_value_pair_ { + switch_acl_mac_field_t field; /**< acl mac field type */ + switch_acl_mac_value value; /**< acl mac field value */ + switch_acl_mac_mask mask; /**< acl mac field mask */ +} switch_acl_mac_key_value_pair_t; + +/** ACL ip racl field enum */ +typedef enum switch_acl_ip_racl_field_ { + SWITCH_ACL_IP_RACL_FIELD_IPV4_SRC, /**< IPv4 Source address */ + SWITCH_ACL_IP_RACL_FIELD_IPV4_DEST, /**< IPv4 Dest address */ + SWITCH_ACL_IP_RACL_FIELD_IP_PROTO, /**< IP protocol (TCP/UDP) */ + SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT, /**< L4 source port */ + SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT, /**< L4 dest port */ + + SWITCH_ACL_IP_RACL_FIELD_MAX +} switch_acl_ip_racl_field_t; + +/** ACL ipv6 racl field enum */ +typedef enum switch_acl_ipv6_racl_field_ { + SWITCH_ACL_IPV6_RACL_FIELD_IPV6_SRC, /**< IPv6 source address */ + SWITCH_ACL_IPV6_RACL_FIELD_IPV6_DEST, /**< IPv6 dest address */ + SWITCH_ACL_IPV6_RACL_FIELD_IP_PROTO, /**< IPv6 protocol */ + SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT, /**< L4 source port */ + SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT, /**< L4 dest port */ + + SWITCH_ACL_IPV6_RACL_FIELD_MAX +} switch_acl_ipv6_racl_field_t; + +/** Acl ip racl field list */ +typedef union switch_acl_ip_racl_value_ { + unsigned int ipv4_source; /**< v4 source IP */ + unsigned int ipv4_dest; /**< v4 destination IP */ + unsigned short ip_proto; /**< protocol */ + unsigned short l4_source_port; /**< source port */ + unsigned short l4_dest_port; /**< destination port */ +} switch_acl_ip_racl_value; + +/** Acl ipv6 racl field list */ +typedef union switch_acl_ipv6_racl_value_ { + uint128_t ipv6_source; /**< v6 source IP */ + uint128_t ipv6_dest; /**< v6 destination IP */ + unsigned short ip_proto; /**< protocol */ + unsigned short l4_source_port; /**< source port */ + unsigned short l4_dest_port; /**< destination port */ +} switch_acl_ipv6_racl_value; + +/** Acl ip racl mask */ +typedef union switch_acl_ip_racl_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint32_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< ip racl mask union */ +} switch_acl_ip_racl_mask; + +/** Acl ipv6 racl mask */ +typedef union switch_acl_ipv6_racl_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint128_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< ipv6 racl mask union */ +} switch_acl_ipv6_racl_mask; + +/** Acl ip racl key value pair */ +typedef struct switch_acl_ip_racl_key_value_pair_ { + switch_acl_ip_racl_field_t field; /**< acl ip racl field type */ + switch_acl_ip_racl_value value; /**< acl ip racl field value */ + switch_acl_ip_racl_mask mask; /**< acl ip racl field mask */ +} switch_acl_ip_racl_key_value_pair_t; + +/** Acl ipv6 racl key value pair */ +typedef struct switch_acl_ipv6_racl_key_value_pair_ { + switch_acl_ipv6_racl_field_t field; /**< acl ip racl field type */ + switch_acl_ipv6_racl_value value; /**< acl ip racl field value */ + switch_acl_ipv6_racl_mask mask; /**< acl ip racl field mask */ +} switch_acl_ipv6_racl_key_value_pair_t; + +/** Acl mirror field enum */ +typedef enum switch_acl_mirror_field_ { + SWITCH_ACL_MIRROR_FIELD_IPV4_SRC, /**< IPv4 source address */ + SWITCH_ACL_MIRROR_FIELD_IPV4_DEST, /**< IPv4 dest address */ + SWITCH_ACL_MIRROR_FIELD_IP_PROTO, /**< IP protocol */ + SWITCH_ACL_MIRROR_FIELD_ETH_TYPE, /**< Ether type */ + SWITCH_ACL_MIRROR_FIELD_SOURCE_MAC, /**< Source MAC address */ + SWITCH_ACL_MIRROR_FIELD_DEST_MAC, /**< Dest MAC address */ + + SWITCH_ACL_MIRROR_FIELD_MAX +} switch_acl_mirror_field_t; + +/** Acl mirror field list */ +typedef union switch_acl_mirror_value_ { + unsigned int ipv4_source; /**< v4 source IP */ + unsigned int ipv4_dest; /**< v4 destination IP */ + unsigned short ip_proto; /**< protocol */ + unsigned short eth_type; /**< ethernet type */ + uint64_t source_mac; /**< source mac */ + uint64_t dest_mac; /**< destination mac */ +} switch_acl_mirror_value; + +/** Acl mirror mask */ +typedef union switch_acl_mirror_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint32_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< mirror mask union */ +} switch_acl_mirror_mask; + +/** Acl mirror key value pair */ +typedef struct switch_acl_mirror_key_value_pair_ { + switch_acl_mirror_field_t field; /**< acl mirror field type */ + switch_acl_mirror_value value; /**< acl mirror field value */ + switch_acl_mirror_mask mask; /**< acl mirror field mask */ +} switch_acl_mirror_key_value_pair_t; + +/** Acl system field enum */ +typedef enum switch_acl_system_field_ { + SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE, /**< Ether type */ + SWITCH_ACL_SYSTEM_FIELD_SOURCE_MAC, /**< Source MAC address */ + SWITCH_ACL_SYSTEM_FIELD_DEST_MAC, /**< Dest MAC address */ + SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS, /**< Port/vlan miss*/ + SWITCH_ACL_SYSTEM_FIELD_IPSG_CHECK, /**< IP sourceguard check */ + SWITCH_ACL_SYSTEM_FIELD_ACL_DENY, /**< ACL deny */ + SWITCH_ACL_SYSTEM_FIELD_RACL_DENY, /**< Route ACL deny check */ + SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK, /**< URPF check */ + SWITCH_ACL_SYSTEM_FIELD_DROP, /**< Dropped packet */ + SWITCH_ACL_SYSTEM_FIELD_L3_COPY, /**< L3 copy */ + SWITCH_ACL_SYSTEM_FIELD_ROUTED, /**< Routed packet check */ + SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL, /**< Link local address (IPv6) */ + SWITCH_ACL_SYSTEM_FIELD_BD_CHECK, /**< Bridge domain check */ + SWITCH_ACL_SYSTEM_FIELD_TTL, /**< TTL */ + SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX, /**< Egress ifindex */ + SWITCH_ACL_SYSTEM_FIELD_STP_STATE, /**< STP state */ + SWITCH_ACL_SYSTEM_FIELD_CONTROL_FRAME, /**< Control frame */ + SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED, /**< IPv4 enabled on BD */ + SWITCH_ACL_SYSTEM_FIELD_IPV6_ENABLED, /**< IPv6 enabled on BD */ + SWITCH_ACL_SYSTEM_FIELD_RMAC_HIT, /**< Rmac hit */ + SWITCH_ACL_SYSTEM_FIELD_IF_CHECK, /**< Same intf check */ + SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK, /**< Tunnel intf check */ + SWITCH_ACL_SYSTEM_FIELD_REASON_CODE, /**< hostif reason code */ + + SWITCH_ACL_SYSTEM_FIELD_MAX +} switch_acl_system_field_t; + +/** Maximum Acl fields */ +#define SWITCH_ACL_FIELD_MAX SWITCH_ACL_SYSTEM_FIELD_MAX + +/** Acl system field list */ +typedef union switch_acl_system_value_ { + unsigned short eth_type; /**< ethernet type */ + switch_mac_addr_t source_mac; /**< source mac */ + switch_mac_addr_t dest_mac; /**< destination mac */ + unsigned ipsg_check : 1, /**< ip sourceguard check */ + acl_deny : 1, /**< acl deny */ + acl_copy : 1, /**< acl copy */ + racl_deny : 1, /**< racl deny */ + urpf_check_fail : 1, /**< urpf check fail */ + port_vlan_mapping_miss : 1, /**< port vlan mapping miss */ + drop_flag : 1, /**< drop flag */ + l3_copy : 1, /**< l3 copy */ + routed : 1, /**< routed */ + src_is_link_local : 1, /**< link local source ip */ + tunnel_if_check : 1, /**< tunnel if check */ + control_frame : 1, /**< control frame */ + ipv4_enabled : 1, /**< IPv4 enabled on BD */ + ipv6_enabled : 1, /**< IPv6 enabled on BD */ + rmac_hit : 1; /**< rmac hit */ + unsigned short if_check : 16; /**< same if check */ + unsigned short bd_check : 16; /**< same bd check */ + unsigned char ttl; /**< time to live */ + unsigned short out_ifindex; /**< egress ifindex */ + unsigned char stp_state; /**< spanning tree port state */ + uint16_t reason_code; /**< hostif reason code */ +} switch_acl_system_value; + +/** Acl system mask */ +typedef union switch_acl_system_mask_ { + unsigned type : 1; /**< acl mask type */ + union { + uint64_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< system acl mask union */ +} switch_acl_system_mask; + +/** Acl system key value pair */ +typedef struct switch_acl_system_key_value_pair_ { + switch_acl_system_field_t field; /**< acl system field type */ + switch_acl_system_value value; /**< acl system field value */ + switch_acl_system_mask mask; /**< acl system field mask */ +} switch_acl_system_key_value_pair_t; + +/** Acl action parameters */ +typedef union switch_acl_action_params_ { + struct { + switch_handle_t handle; /**< port/nexthop handle */ + } redirect; /**< port redirect struct */ + struct { + uint16_t reason_code; /**< cpu reason code */ + } cpu_redirect; /**< cpu redirect struct */ + struct { + uint8_t reason_code; /**< drop reason code */ + uint8_t platform_id; /**< platform id */ + } drop; /**< drop struct */ +} switch_acl_action_params_t; + +/** Acl optional action parameters */ +typedef struct switch_acl_opt_action_params_ { + bool copy_to_cpu; /**< generate a cpu copy */ + switch_handle_t mirror_handle; /**< mirror session handle */ + unsigned int switch_id; /**< mirror switch id */ + switch_handle_t meter_handle; /**< meter handle */ + switch_handle_t counter_handle; /**< counter handle */ + uint8_t nat_mode; /**< nat mode */ + uint16_t tc; /**< traffic class */ + switch_color_t color; /**< packet color */ + uint8_t ingress_cos; /**< ingress cos */ + switch_qid_t queue_id; /**< queue id */ +} switch_acl_opt_action_params_t; + +/** Egress ACL field enum */ +typedef enum switch_acl_egr_field_ { + SWITCH_ACL_EGR_DEST_PORT, + SWITCH_ACL_EGR_DEFLECT, + SWITCH_ACL_EGR_L3_MTU_CHECK, + SWITCH_ACL_EGR_FIELD_MAX +} switch_acl_egr_field_t; + +/** Egress ACL match value */ +typedef union switch_acl_egr_value_ { + 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 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; /**< mask union */ +} switch_acl_egr_mask_t; + +/** Egress acl key value pair */ +typedef struct switch_acl_egr_key_value_pair_ { + switch_acl_egr_field_t field; /**< acl ip field type */ + switch_acl_egr_value_t value; /**< acl ip field value */ + switch_acl_egr_mask_t mask; /**< acl ip field mask */ +} switch_acl_egr_key_value_pair_t; + +/** Egress acl port action */ +typedef enum switch_acl_egr_action_ { + SWITCH_ACL_EGR_ACTION_NOP, /**< Do nothing action */ + SWITCH_ACL_EGR_ACTION_SET_MIRROR, /**< Set mirror session */ + SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU, /**< redirect to cpu */ + SWITCH_ACL_EGR_MIRROR_DROP, /**< negative mirror */ +} switch_acl_egr_action_t; + +typedef switch_acl_action_t switch_acl_ip_action_t; /**< acl action */ +typedef switch_acl_action_t switch_acl_ipv6_action_t; /**< IPv6 acl action */ +typedef switch_acl_action_t switch_acl_mac_action_t; /**< mac acl action */ +typedef switch_acl_action_t + switch_acl_system_action_t; /**< system acl action */ + +/** Acl info struct */ +typedef struct switch_acl_info_ { + switch_acl_type_t type; /**< acl type */ + void *rules; /**< set of rules */ + tommy_list interface_list; /**< list of interface handles */ +} switch_acl_info_t; + +/** + ACL Key list create + @param device device + @param type - acl type +*/ +switch_handle_t switch_api_acl_list_create(switch_device_t device, + switch_acl_type_t type); + +/** + ACL Key list update + @param device device + @param acl_handle handle of created ACL + @param type - acl type +*/ +switch_handle_t switch_api_acl_list_update(switch_device_t device, + switch_handle_t acl_handle, + switch_acl_type_t type); + +/** + Delete the ACL key list + @param device device + @param acl_handle handle of created ACL +*/ +switch_status_t switch_api_acl_list_delete(switch_device_t device, + switch_handle_t acl_handle); + +/** + Create ACL Rules + @param device device + @param acl_handle - Acl handle + @param priority - priority of Acl + @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 - 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, + unsigned int priority, + unsigned int key_value_count, + void *acl_kvp, + switch_acl_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + switch_handle_t *ace_handle); + +/** + Delete ACL Rules + @param device device + @param acl_handle - Acl handle + @param ace_handle - handle obtained from create_rule +*/ +switch_status_t switch_api_acl_rule_delete(switch_device_t device, + switch_handle_t acl_handle, + switch_handle_t ace_handle); + +/** + Renumber ACL Rules + @param device device + @param acl_handle - Acl handle + @param increment_priority - priority to reorder the acl rule +*/ +switch_status_t switch_api_acl_renumber(switch_device_t device, + switch_handle_t acl_handle, + int increment_priority); + +/** + Apply ACLs on interfaces, VLANs, etc. + @param device device + @param acl_handle handle created with list_create + @param interface_handle - Interface handle +*/ +switch_status_t switch_api_acl_reference(switch_device_t device, + switch_handle_t acl_handle, + switch_handle_t interface_handle); + +/** + Apply ACLs on interfaces, VLANs, etc. + @param device device + @param acl_handle handle created with list_create + @param interface_handle - Interface handle +*/ +switch_status_t switch_api_acl_remove(switch_device_t device, + switch_handle_t acl_handle, + switch_handle_t interface_handle); + +/** + Get ACL type, given the ACL handle + @param acl_handle handle created with list_create +*/ +switch_acl_info_t *switch_acl_get(switch_handle_t acl_handle); + +/** + Get drop statistics + @param device device + @param num_counters number of counters + @param counters pointer to counter array +*/ +switch_status_t switch_api_drop_stats_get(switch_device_t device, + int *num_counters, + uint64_t **counters); + +/** + create acl counter handle + @param device device +*/ +switch_handle_t switch_api_acl_counter_create(switch_device_t device); + +/** + delete acl counter handle + @param device device + @param counter_handle acl counter handle +*/ +switch_status_t switch_api_acl_counter_delete(switch_device_t device, + switch_handle_t counter_handle); + +/** + get acl statistics + @param device device + @param counter_handle acl counter handle + @param counter counter value +*/ +switch_status_t switch_api_acl_stats_get(switch_device_t device, + switch_handle_t counter_handle, + switch_counter_t *counter); + +/** + get acl type + @param device device + @param acl_handle acl handle +*/ +switch_acl_type_t switch_acl_type_get(switch_device_t device, + switch_handle_t acl_handle); + +/** @} */ // end of ACL API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_base_types.h b/switchapi/include/switchapi/switch_base_types.h similarity index 56% rename from switchapi/inc/switchapi/switch_base_types.h rename to switchapi/include/switchapi/switch_base_types.h index 5a739b0..bc4b45b 100644 --- a/switchapi/inc/switchapi/switch_base_types.h +++ b/switchapi/include/switchapi/switch_base_types.h @@ -21,15 +21,10 @@ limitations under the License. #include #include "p4features.h" -#include "drop_reasons.h" -#include "p4features.h" -#ifdef BMV2 -#include "pd/pd.h" -#include "pd/pd_pre.h" -#else -#include "p4_sim/pd.h" -#include "p4_sim/pd_pre.h" -#endif +#include "drop_reason_codes.h" +#include "p4_table_sizes.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -45,14 +40,14 @@ extern "C" { #define ETH_LEN 6 -#define switch_malloc(x, c) malloc(x * c) +#define switch_malloc(x, c) malloc(x *c) #define switch_free(x) free(x) #define switch_realloc(x, sz) realloc(x, sz) #define HANDLE_TYPE_SHIFT 27 #define handle_to_id(x) (x & 0x3FFFFFF) -#define id_to_handle(t,x) (t << HANDLE_TYPE_SHIFT | x) +#define id_to_handle(t, x) (t << HANDLE_TYPE_SHIFT | (x)) typedef int switch_status_t; typedef uint16_t switch_vlan_t; @@ -65,28 +60,31 @@ typedef unsigned long switch_port_t; typedef unsigned char switch_device_t; typedef uint8_t switch_cos_t; typedef unsigned int switch_vrf_id_t; +typedef uint16_t switch_tc_t; +typedef uint16_t switch_qid_t; +typedef uint16_t switch_qos_group_t; typedef uint16_t switch_rid_t; /** Direction - ingress, egress or both */ typedef enum { - SWITCH_API_DIRECTION_BOTH, /**< Ingress and Egress directions */ - SWITCH_API_DIRECTION_INGRESS, /**< Ingress Only */ - SWITCH_API_DIRECTION_EGRESS /**< Egress Only */ + SWITCH_API_DIRECTION_BOTH, /**< Ingress and Egress directions */ + SWITCH_API_DIRECTION_INGRESS, /**< Ingress Only */ + SWITCH_API_DIRECTION_EGRESS /**< Egress Only */ } switch_direction_t; /** 128 bit field */ typedef struct uint128_t { - union { - uint8_t addr8[16]; /** 16x8bit */ - uint16_t addr16[8]; /** 8x16bit */ - uint32_t addr32[4]; /** 4x32bit */ - } u; /**< union */ -} uint128_t; /**< 128-bit value */ + union { + 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 { - uint8_t mac_addr[ETH_LEN]; /**< 6 bytes of mac address */ + uint8_t mac_addr[ETH_LEN]; /**< 6 bytes of mac address */ } switch_mac_addr_t; /* init */ @@ -95,44 +93,52 @@ int start_switch_api_packet_driver(void); /** IP address type v4 or v6 */ typedef enum { - SWITCH_API_IP_ADDR_V4, /**< IPv4 address type */ - SWITCH_API_IP_ADDR_V6 /**< IPv6 address type */ + SWITCH_API_IP_ADDR_V4, /**< IPv4 address type */ + SWITCH_API_IP_ADDR_V6 /**< IPv6 address type */ } switch_ip_addr_type_t; /** IP address - v4 and v6 with type */ typedef struct switch_ip_addr_ { - switch_ip_addr_type_t type; /**< IPv4 or IPv6 */ - union { - unsigned int v4addr; /**< IPv4 address */ - uint8_t v6addr[16]; /**< IPv6 address */ - } ip; /**< detail based on type */ - unsigned int prefix_len; /**< prefix length on interface */ + switch_ip_addr_type_t type; /**< IPv4 or IPv6 */ + union { + unsigned int v4addr; /**< IPv4 address */ + uint8_t v6addr[16]; /**< IPv6 address */ + } ip; /**< detail based on type */ + unsigned int prefix_len; /**< prefix length on interface */ } switch_ip_addr_t; #define SWITCH_IFINDEX_PORT_WIDTH 9 /** Ifindex type */ typedef enum switch_ifindex_type_ { - SWITCH_IFINDEX_TYPE_VLAN_INTERFACE = 1, - SWITCH_IFINDEX_TYPE_LAG = 2, - SWITCH_IFINDEX_TYPE_TUNNEL = 3, - SWITCH_IFINDEX_TYPE_CPU = 4, - SWITCH_IFINDEX_TYPE_MAX = 128 + SWITCH_IFINDEX_TYPE_VLAN_INTERFACE = 1, + SWITCH_IFINDEX_TYPE_LAG = 2, + SWITCH_IFINDEX_TYPE_TUNNEL = 3, + SWITCH_IFINDEX_TYPE_CPU = 4, + SWITCH_IFINDEX_TYPE_MAX = 128 } switch_ifinedx_type_t; /** counter info */ typedef struct switch_counter_ { - uint64_t num_packets; /**< number of packets */ - uint64_t num_bytes; /**< number of bytes */ + uint64_t num_packets; /**< number of packets */ + uint64_t num_bytes; /**< number of bytes */ } switch_counter_t; typedef enum switch_packet_type_ { - SWITCH_PACKET_TYPE_UNICAST = 1, - SWITCH_PACKET_TYPE_MULTICAST = 2, - SWITCH_PACKET_TYPE_BROADCAST = 4, - SWITCH_PACKET_TYPE_MAX = SWITCH_PACKET_TYPE_BROADCAST + SWITCH_PACKET_TYPE_UNICAST = 1, + SWITCH_PACKET_TYPE_MULTICAST = 2, + SWITCH_PACKET_TYPE_BROADCAST = 4, + SWITCH_PACKET_TYPE_MAX = SWITCH_PACKET_TYPE_BROADCAST } switch_packet_type_t; +/* packet color */ +typedef enum switch_color_ { + SWITCH_COLOR_GREEN, + SWITCH_COLOR_YELLOW, + SWITCH_COLOR_RED, + SWITCH_COLOR_MAX +} switch_color_t; + #ifdef __cplusplus } #endif diff --git a/switchapi/include/switchapi/switch_buffer.h b/switchapi/include/switchapi/switch_buffer.h new file mode 100644 index 0000000..6beeb8d --- /dev/null +++ b/switchapi/include/switchapi/switch_buffer.h @@ -0,0 +1,171 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_buffer_h_ +#define _switch_buffer_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_meter.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup Buffer Buffer API + * API functions to create buffers + * @{ + */ // begin of Buffer API + +// Buffer +/** Buffer information */ + +/** Buffer threshold mode */ +typedef enum switch_buffer_threshold_mode_ { + SWITCH_BUFFER_THRESHOLD_MODE_STATIC = 1, + SWITCH_BUFFER_THRESHOLD_MODE_DYNAMIC = 2 +} switch_buffer_threshold_mode_t; + +/** Buffer profile struct */ +typedef struct switch_api_buffer_profile_ { + switch_buffer_threshold_mode_t threshold_mode; /**< buffer threshold mode */ + switch_handle_t pool_handle; /**< buffer pool handle */ + uint32_t buffer_size; /**< buffer size */ + uint32_t threshold; /**< threshold limit */ + uint32_t xoff_threshold; /**< xoff threshold */ + uint32_t xon_threshold; /**< xon threashold */ +} switch_api_buffer_profile_t; + +/** + Create a buffer pool + @param device device + @param direction direction (ingress or egress) + @param pool_size size of the buffer pool +*/ +switch_handle_t switch_api_buffer_pool_create(switch_device_t device, + switch_direction_t direction, + uint32_t pool_size); + +/** + Delete a buffer pool + @param device device + @param pool_handle pool handle +*/ +switch_status_t switch_api_buffer_pool_delete(switch_device_t device, + switch_handle_t pool_handle); + +/** + Create switch buffer profile + @param device device + @param buffer_info buffer profile info +*/ +switch_handle_t switch_api_buffer_profile_create( + switch_device_t device, switch_api_buffer_profile_t *buffer_info); + +/** + Delete switch buffer profile + @param device device + @param buffer_profile_handle buffer profile handle +*/ +switch_status_t switch_api_buffer_profile_delete( + switch_device_t device, switch_handle_t buffer_profile_handle); + +/** + Set buffer profile for a priority group + @param device device + @param pg_handle priority group handle + @param buffer_profile_handle buffer profile handle +*/ +switch_status_t switch_api_priority_group_buffer_profile_set( + switch_device_t device, + switch_handle_t pg_handle, + switch_handle_t buffer_profile_handle); + +/** + Set skid buffer size + @param device device + @param buffer_size buffer size +*/ +switch_status_t switch_api_buffer_skid_limit_set(switch_device_t device, + uint32_t buffer_size); + +/** + Set skid buffer size + @param device device + @param num_bytes number of bytes +*/ +switch_status_t switch_api_buffer_skid_hysteresis_set(switch_device_t device, + uint32_t num_bytes); + +/** + set buffer pool pfc limit for a icos + @param device device + @param pool_handle pool handle + @param icos ingress cos + @param num_bytes number of bytes +*/ +switch_status_t switch_api_buffer_pool_pfc_limit(switch_device_t device, + switch_handle_t pool_handle, + uint8_t icos, + uint32_t num_bytes); + +/** + Set buffer profile for a queue + @param device device + @param queue_handle queue handle + @param buffer_profile_handle buffer profile handle +*/ +switch_status_t switch_api_queue_buffer_profile_set( + switch_device_t device, + switch_handle_t queue_handle, + switch_handle_t buffer_profile_handle); + +/** + enable color based drop on a pool + @param device device + @param pool_handle pool handle + @param enable enable/disable +*/ +switch_status_t switch_api_buffer_pool_color_drop_enable( + switch_device_t device, switch_handle_t pool_handle, bool enable); + +/** + buffer pool color limit set + @param device device + @param pool_handle pool handle + @param color packet color + @param num_bytes number of bytes +*/ +switch_status_t switch_api_buffer_pool_color_limit_set( + switch_device_t device, + switch_handle_t pool_handle, + switch_color_t color, + uint32_t num_bytes); + +/** + pool color hystersis set + @param device device + @param color packet color + @param num_bytes number of bytes +*/ +switch_status_t switch_api_buffer_pool_color_hysteresis_set( + switch_device_t device, switch_color_t color, uint32_t num_bytes); + +/** @} */ // end of Buffer API +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/include/switchapi/switch_capability.h b/switchapi/include/switchapi/switch_capability.h new file mode 100644 index 0000000..fbe0594 --- /dev/null +++ b/switchapi/include/switchapi/switch_capability.h @@ -0,0 +1,127 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_capability_h +#define _switch_capability_h + +#include "switch_base_types.h" +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup SWITCH Switch API + * @{ + */ // begin of SWITCH API + +// Switch + +#define SWITCH_API_DEFAULT_VLAN 1 /**< system default vlan */ +#define SWITCH_API_DEFAULT_VRF 1 /**< system default vrf */ +#define SWITCH_API_MAX_PORTS 288 /**< system default ports */ + +/** switch operational status */ +typedef enum switch_oper_status_ { + SWITCH_OPER_STATUS_UNKNOWN, + SWITCH_OPER_STATUS_UP, + SWITCH_OPER_STATUS_DOWN, + SWITCH_OPER_STATUS_FAILED +} switch_oper_status_t; + +/** switch statistics */ +typedef enum switch_stat_counter_ { + SWITCH_STAT_GLOBAL_LOW_DROP_PKTS, + SWITCH_STAT_GLOBAL_HIGH_DROP_PKTS, + SWITCH_STAT_GLOBAL_PRIVILEGE_DROP_PKTS, + SWITCH_STAT_DROP_COUNT_TX, + SWITCH_STAT_DROP_COUNT_RX +} switch_stat_counter_t; + +/** switch hash fields */ +typedef enum switch_ecmp_hash_fields_ { + SWITCH_HASH_SRC_IP = (1 << 0), + SWITCH_HASH_DST_IP = (1 << 1), + SWITCH_HASH_L4_SRC_PORT = (1 << 2), + SWITCH_HASH_L4_DST_PORT = (1 << 3), +} switch_ecmp_hash_fields_t; + +/** switch attributes */ +typedef enum switch_capability_attr_ { + SWITCH_ATTR_PORT_NUMBER, + SWITCH_ATTR_PORT_LIST, + SWITCH_ATTR_MAX_VRF, + SWITCH_ATTR_ON_LINK_ROUTE_SUPPORTED, + SWITCH_ATTR_OPER_STATUS, + SWITCH_ATTR_HW_SEQUENCE_ID, + SWITCH_ATTR_ADMIN_STATE, + SWITCH_ATTR_BCAST_CPU_FLOOD_ENABLE, + SWITCH_ATTR_MCAST_CPU_FLOOD_ENABLE, + SWITCH_ATTR_DEFAULT_VLAN_ID, + SWITCH_ATTR_MAX_LEARNED_ADDRESSES, + SWITCH_ATTR_FDB_UNICAST_MISS_ACTION, + SWITCH_ATTR_FDB_MULTICAST_MISS_ACTION, + SWITCH_ATTR_FDB_BROADCAST_MISS_ACTION, + SWITCH_ATTR_ECMP_HASH_TYPE, + SWITCH_ATTR_ECMP_HASH_FIELDS, + + SWITCH_ATTR_CUSTOM_RANGE_BASE = 0x10000000, + SWITCH_ATTR_DEFAULT_VRF_ID +} switch_capability_attr_t; + +/** switch capability info */ +typedef struct switch_api_capability_ { + switch_vlan_t default_vlan; /**< default vlan */ + switch_vrf_id_t default_vrf; /**< default vrf */ + switch_mac_addr_t switch_mac; /**< default switch mac */ + uint16_t max_ports; /**< max ports in the switch */ + uint16_t max_lags; /**< max lag supported */ + uint16_t max_port_per_lag; /**< max ports per lag */ + uint16_t max_vrf; /**< max vrf supported */ + uint16_t max_stp_groups; /**< max spanning tree group */ + uint16_t max_tunnels; /**< max tunnels */ + uint16_t max_span_sessions; /**< max span sessions */ + switch_handle_t port_list[SWITCH_API_MAX_PORTS]; /**< list of ports */ +} switch_api_capability_t; + +/** + Sets switch capability attributes + @param device device + @param api_capability switch capability attributes + */ +switch_status_t switch_api_capability_set( + switch_device_t device, switch_api_capability_t *api_capability); + +/** + Returns all switch capability attributes + @param device device + @param api_capability switch capability attributes + */ +switch_status_t switch_api_capability_get( + switch_device_t device, switch_api_capability_t *api_capability); + +/** + Returns switch default VRF handle + */ +switch_handle_t switch_api_default_vrf_internal(); + +/** @} */ // end of switch API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_config.h b/switchapi/include/switchapi/switch_config.h similarity index 86% rename from switchapi/inc/switchapi/switch_config.h rename to switchapi/include/switchapi/switch_config.h index 65716aa..0481dea 100644 --- a/switchapi/inc/switchapi/switch_config.h +++ b/switchapi/include/switchapi/switch_config.h @@ -24,8 +24,8 @@ limitations under the License. extern "C" { #endif /* __cplusplus */ -switch_status_t -switch_api_set_deflect_on_drop (switch_device_t device, bool dod); +switch_status_t switch_api_set_deflect_on_drop(switch_device_t device, + bool dod); #ifdef __cplusplus } diff --git a/switchapi/include/switchapi/switch_dox.h b/switchapi/include/switchapi/switch_dox.h new file mode 100644 index 0000000..2cc70ff --- /dev/null +++ b/switchapi/include/switchapi/switch_dox.h @@ -0,0 +1,41 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/**************************************************************************/ /** + * + * switch Doxygen Header + * + *****************************************************************************/ +#ifndef __SWITCH_DOX_H__ +#define __SWITCH_DOX_H__ + +/** + * @defgroup switch switch - switch Description + * + +The documentation overview for this module should go here. + + * + * @{ + * + * @defgroup switch-switch Public Interface + * @defgroup switch-config Compile Time Configuration + * @defgroup switch-porting Porting Macros + * + * @} + * + */ + +#endif /* __SWITCH_DOX_H__ */ diff --git a/switchapi/include/switchapi/switch_handle.h b/switchapi/include/switchapi/switch_handle.h new file mode 100644 index 0000000..4eeb3df --- /dev/null +++ b/switchapi/include/switchapi/switch_handle.h @@ -0,0 +1,234 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_handle_h_ +#define _switch_handle_h_ + +#include "switch_id.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum { + SWITCH_HANDLE_TYPE_NONE, + SWITCH_HANDLE_TYPE_PORT, + SWITCH_HANDLE_TYPE_LAG, + SWITCH_HANDLE_TYPE_INTERFACE, + SWITCH_HANDLE_TYPE_VRF, + SWITCH_HANDLE_TYPE_BD, + SWITCH_HANDLE_TYPE_TUNNEL, + SWITCH_HANDLE_TYPE_NHOP, + SWITCH_HANDLE_TYPE_ARP, + SWITCH_HANDLE_TYPE_MY_MAC, + SWITCH_HANDLE_TYPE_LABEL, + SWITCH_HANDLE_TYPE_STP, + SWITCH_HANDLE_TYPE_MGID, + SWITCH_HANDLE_TYPE_ACL, + SWITCH_HANDLE_TYPE_MCAST_ECMP, + SWITCH_HANDLE_TYPE_URPF, + SWITCH_HANDLE_TYPE_HOSTIF_GROUP, + SWITCH_HANDLE_TYPE_HOSTIF, + SWITCH_HANDLE_TYPE_ACE, + SWITCH_HANDLE_TYPE_MIRROR, + SWITCH_HANDLE_TYPE_METER, + SWITCH_HANDLE_TYPE_SFLOW, + SWITCH_HANDLE_TYPE_SFLOW_ACE, + SWITCH_HANDLE_TYPE_LAG_MEMBER, + SWITCH_HANDLE_TYPE_ACL_COUNTER, + SWITCH_HANDLE_TYPE_QOS_MAP, + SWITCH_HANDLE_TYPE_PRIORITY_GROUP, + SWITCH_HANDLE_TYPE_QUEUE, + SWITCH_HANDLE_TYPE_BUFFER_POOL, + SWITCH_HANDLE_TYPE_BUFFER_PROFILE, + SWITCH_HANDLE_TYPE_VLAN_MEMBER, + SWITCH_HANDLE_TYPE_SCHEDULER, + + SWITCH_HANDLE_TYPE_MAX = 32 +} switch_handle_type_t; + +/** + Generic handle to encode different types of objects + handle impicitly encodes the device, type and type specific + */ +typedef unsigned long switch_handle_t; + +/** Handle related information */ +typedef struct { + switch_handle_type_t type; /**< type of handle */ + switch_api_id_allocator *allocator; /**< allocator associated with handle */ + unsigned int num_in_use; /**< number of handle in use */ + unsigned int initial_size; /**< current size of allocator */ + unsigned int num_handles; /**< number of handles to allocate */ + bool grow_on_demand; /**< allocate new handles as needed */ + bool zero_based; /**< 0 is a valid id */ +} switch_handle_info_t; + +// Protoypes +int switch_handle_type_init(switch_handle_type_t type, unsigned int size); +int switch_handle_type_allocator_init(switch_handle_type_t type, + unsigned int num_handles, + bool grow_on_demand, + bool zero_based); +void switch_handle_type_free(switch_handle_type_t type); +switch_handle_t switch_handle_allocate(switch_handle_type_t type); +switch_handle_t switch_handle_set_and_allocate(switch_handle_t type, + unsigned int id); +void switch_handle_free(switch_handle_t handle); +switch_handle_type_t switch_handle_get_type(switch_handle_t handle); + +#define SWITCH_HANDLE_VALID(handle, type) \ + ((handle >> HANDLE_TYPE_SHIFT) == type) + +#define SWITCH_PORT_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_PORT) + +#define SWITCH_INTERFACE_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_INTERFACE) + +#define SWITCH_LAG_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_LAG) + +#define SWITCH_VRF_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_VRF) + +#define SWITCH_BD_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_BD) + +#define SWITCH_TUNNEL_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_TUNNEL) + +#define SWITCH_NHOP_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_NHOP) + +#define SWITCH_NEIGHBOR_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_ARP) + +#define SWITCH_RMAC_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_MY_MAC) + +#define SWITCH_STP_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_STP) + +#define SWITCH_MGID_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_MGID) + +#define SWITCH_ACL_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_ACL) + +#define SWITCH_ACE_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_ACE) + +#define SWITCH_HOSTIF_GROUP_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_HOSTIF_GROUP) + +#define SWITCH_HOSTIF_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_HOSTIF) + +// Easy use macros +#define SWITCH_API_INVALID_HANDLE 0xFFFFFFFF +#define SWITCH_HW_INVALID_HANDLE 0xFFFFFFFF + +#define _switch_handle_create(_type, _info, _judy, _init, _handle) \ + _handle = switch_handle_allocate(_type); \ + if (_handle) { \ + _info *_i_info = (_info *)switch_malloc(sizeof(_info), 1); \ + if (_i_info) { \ + char *_ap = NULL; \ + memset(_i_info, 0, sizeof(_info)); \ + JLI(_ap, _judy, (unsigned int)_handle); \ + if (_ap) { \ + *(unsigned long *)_ap = (unsigned long)_i_info; \ + } else { \ + switch_free(_i_info); \ + switch_handle_free(_handle); \ + _handle = 0; \ + } \ + } else { \ + switch_handle_free(_handle); \ + _handle = 0; \ + } \ + } + +#define _switch_handle_set_and_create( \ + _type, _info, _judy, _init, _id, _handle) \ + _handle = switch_handle_set_and_allocate(_type, _id); \ + if (_handle) { \ + _info *_i_info = (_info *)switch_malloc(sizeof(_info), 1); \ + if (_i_info) { \ + char *_ap = NULL; \ + memset(_i_info, 0, sizeof(_info)); \ + JLI(_ap, _judy, (unsigned int)_handle); \ + if (_ap) { \ + *(unsigned long *)_ap = (unsigned long)_i_info; \ + } else { \ + switch_free(_i_info); \ + switch_handle_free(_handle); \ + _handle = 0; \ + } \ + } else { \ + switch_handle_free(_handle); \ + _handle = 0; \ + } \ + } + +#define _switch_handle_delete(_info, _judy, _handle) \ + _info *_handle_info; \ + int _ret = 0; \ + void *_dp = NULL; \ + JLG(_dp, _judy, (unsigned int)_handle); \ + if ((_handle_info = (_info *)(*(unsigned long *)_dp))) { \ + JLD(_ret, _judy, (unsigned int)_handle); \ + switch_free(_handle_info); \ + } \ + switch_handle_free(_handle); + +#define _switch_handle_get(_info, _judy, _handle, _handle_info) \ + void *_gp = NULL; \ + JLG(_gp, _judy, (unsigned int)_handle); \ + if (_gp) _handle_info = (_info *)(*(unsigned long *)_gp); + +#define switch_handle_get_first(_judy, _handle) \ + int ret = 0; \ + J1F(ret, _judy, _handle); \ + if (!ret) { \ + _handle = 0; \ + } + +#define switch_handle_get_next(_judy, old_handle, new_handle) \ + int ret = 0; \ + new_handle = 0; \ + J1N(ret, _judy, old_handle); \ + if (ret) { \ + new_handle = old_handle; \ + } + +#define SWITCH_HANDLE_IS_LAG(handle) \ + switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_LAG + +#define SWITCH_HANDLE_IS_VRF(handle) \ + switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_VRF + +#define SWITCH_HANDLE_IS_BD(handle) \ + switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_BD + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/include/switchapi/switch_hostif.h b/switchapi/include/switchapi/switch_hostif.h new file mode 100644 index 0000000..b647640 --- /dev/null +++ b/switchapi/include/switchapi/switch_hostif.h @@ -0,0 +1,343 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_hostif_h_ +#define _switch_hostif_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_acl.h" +#include "switch_meter.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup HostInterface Host Interface API + * API functions define and manipulate host interfaces + * @{ + */ // begin of Host Interface API + +/** switch hostif reason code */ +typedef enum switch_hostif_reason_code_ { + /* + * Reason code groups must start on power of 2 boundary since + * rx_net_filters are setup to use masks + */ + /* generic reason codes 0x0-0x0FF */ + SWITCH_HOSTIF_REASON_CODE_NONE = 0x0, + SWITCH_HOSTIF_REASON_CODE_CUSTOM = 0x1, + SWITCH_HOSTIF_REASON_CODE_DROP = 0x2, + SWITCH_HOSTIF_REASON_CODE_NULL_DROP = 0x3, + SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE = 0x4, + + /* L2 reason codes 0x100 - 0x1FF */ + SWITCH_HOSTIF_REASON_CODE_L2_START = 0x100, + SWITCH_HOSTIF_REASON_CODE_STP = SWITCH_HOSTIF_REASON_CODE_L2_START, + SWITCH_HOSTIF_REASON_CODE_LACP, /* 0x101 */ + SWITCH_HOSTIF_REASON_CODE_EAPOL, /* 0x102 */ + SWITCH_HOSTIF_REASON_CODE_LLDP, /* 0x103 */ + SWITCH_HOSTIF_REASON_CODE_PVRST, /* 0x104 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_QUERY, /* 0x105 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_LEAVE, /* 0x106 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V1_REPORT, /* 0x107 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT, /* 0x108 */ + SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V3_REPORT, /* 0x109 */ + + /* L3 reason codes 0x200-0x2FF */ + SWITCH_HOSTIF_REASON_CODE_L3_START = 0x200, + SWITCH_HOSTIF_REASON_CODE_SAMPLEPACKET = SWITCH_HOSTIF_REASON_CODE_L3_START, + SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST, /* 0x201 */ + SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE, /* 0x202 */ + SWITCH_HOSTIF_REASON_CODE_DHCP, /* 0x203 */ + SWITCH_HOSTIF_REASON_CODE_OSPF, /* 0x204 */ + SWITCH_HOSTIF_REASON_CODE_PIM, /* 0x205 */ + SWITCH_HOSTIF_REASON_CODE_VRRP, /* 0x206 */ + SWITCH_HOSTIF_REASON_CODE_BGP, /* 0x207 */ + SWITCH_HOSTIF_REASON_CODE_DHCPV6, /* 0x208 */ + SWITCH_HOSTIF_REASON_CODE_OSPFV6, /* 0x209 */ + SWITCH_HOSTIF_REASON_CODE_VRRPV6, /* 0x20a */ + SWITCH_HOSTIF_REASON_CODE_BGPV6, /* 0x20b */ + SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY, /* 0x20c */ + SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_V2, /* 0x20d */ + SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_REPORT, /* 0x20e */ + SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_DONE, /* 0x20f */ + SWITCH_HOSTIF_REASON_CODE_MLD_V2_REPORT, /* 0x210 */ + SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR, /* 0x211 */ + SWITCH_HOSTIF_REASON_CODE_TTL_ERROR, /* 0x212 */ + SWITCH_HOSTIF_REASON_CODE_GLEAN, /* 0x213 */ + SWITCH_HOSTIF_REASON_CODE_MYIP, /* 0x214 */ + SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT, /* 0x215 */ + SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL, /* 0x216 */ + SWITCH_HOSTIF_REASON_CODE_L3_REDIRECT, /* 0x217 */ + SWITCH_HOSTIF_REASON_CODE_BROADCAST, /* 0x218 */ + + SWITCH_HOSTIF_REASON_CODE_MAX, +} switch_hostif_reason_code_t; + +/** switch channel */ +typedef enum switch_hostif_channel_ { + SWITCH_HOSTIF_CHANNEL_CB, + SWITCH_HOSTIF_CHANNEL_FD, + SWITCH_HOSTIF_CHANNEL_NETDEV, +} switch_hostif_channel_t; + +/** switch hostif group */ +typedef struct switch_hostif_group_ { + switch_qid_t queue_id; /**< egress queue number */ + uint32_t priority; /**< priority */ + switch_handle_t policer_handle; /**< policer id */ +} switch_hostif_group_t; + +/** switch hostif reason code info */ +typedef struct switch_api_hostif_rcode_info_ { + switch_hostif_reason_code_t reason_code; /**< reason code */ + switch_acl_action_t action; /**< packet action */ + uint32_t priority; /**< priority */ + switch_hostif_channel_t channel; /**< hostif channel */ + switch_handle_t hostif_group_id; /**< hostif group id */ +} switch_api_hostif_rcode_info_t; + +/** hostif tx/rx packet info */ +typedef struct switch_hostif_packet_ { + switch_hostif_reason_code_t reason_code; /**< reason code */ + 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; + uint16_t sflow_session_id; + bool tx_bypass; /**< tx type flag to skip pipeline */ + void *pkt; /**< packet buffer rx/tx */ + uint32_t pkt_size; /**< packet buffer size */ +} switch_hostif_packet_t; + +/** Host interface name size */ +#define SWITCH_HOSTIF_NAME_SIZE 16 + +/** host interface */ +typedef struct switch_hostif_ { + char intf_name[SWITCH_HOSTIF_NAME_SIZE]; /**< interface name */ +} switch_hostif_t; + +/** CPU Rx Callback */ +typedef void (*switch_hostif_rx_callback_fn)( + switch_hostif_packet_t *hostif_packet); + +/** +Register for callback on reception of packets qualified by reason +@param device device to register callback +@param cb_fn callback function pointer +*/ +switch_status_t switch_api_hostif_register_rx_callback( + switch_device_t device, switch_hostif_rx_callback_fn cb_fn); + +/** +Deregister for callback on reception of packets qualified by reason +@param device device to register callback +@param cb_fn callback function pointer +*/ +switch_status_t switch_api_hostif_deregister_rx_callback( + switch_device_t device, switch_hostif_rx_callback_fn cb_fn); + +/** +Allocate packe memory to transmit +@param device device +@param hostif_packet packet info +*/ +switch_status_t switch_api_hostif_tx_packet( + switch_device_t device, switch_hostif_packet_t *hostif_packet); + +/** + Create a hostif profile to be shared across multiple reason codes + @param device device + @param hostif_group hostif group info + */ +switch_handle_t switch_api_hostif_group_create( + switch_device_t device, switch_hostif_group_t *hostif_group); + +/** + Delete a hostif profile that is shared across multiple reason codes + @param device device + @param hostif_group_id hostif group id + */ +switch_status_t switch_api_hostif_group_delete(switch_device_t device, + switch_handle_t hostif_group_id); + +/** + Add a hostif reason code to trap/forward the packet to cpu + @param device device + @param rcode_api_info reason code info + */ +switch_status_t switch_api_hostif_reason_code_create( + switch_device_t device, switch_api_hostif_rcode_info_t *rcode_api_info); + +/** + Update a hostif reason code to trap/forward the packet to cpu + @param device device + @param rcode_api_info reason code info + */ +switch_status_t switch_api_hostif_reason_code_update( + switch_device_t device, switch_api_hostif_rcode_info_t *rcode_api_info); + +/** + Remove a reason code to trap/forward the packet to cpu + @param device device + @param reason_code reason code + */ +switch_status_t switch_api_hostif_reason_code_delete( + switch_device_t device, switch_hostif_reason_code_t reason_code); + +/** + Create host interface + @param device device + @param hostif host interface + */ +switch_handle_t switch_api_hostif_create(switch_device_t device, + switch_hostif_t *hostif); + +/** + Delete host interface + @param device device + @param hostif_handle hostif handle + */ +switch_status_t switch_api_hostif_delete(switch_device_t device, + switch_handle_t hostif_handle); + +/** + Return nexthop based on reason code + @param rcode Reason code + */ +switch_handle_t switch_api_cpu_nhop_get(switch_hostif_reason_code_t rcode); + +/** Packet vlan action */ +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; + +/** Tx bypass flags */ +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; + +/** Rx key for net filter */ +typedef struct switch_packet_rx_key_ { + bool port_valid; /**< port handle valid */ + switch_handle_t port_handle; /**< port handle */ + bool port_lag_valid; /**< port lag handle valid */ + switch_handle_t port_lag_handle; /**< port lag handle */ + bool handle_valid; /**< bd or interface handle valid */ + switch_handle_t handle; /**< bd or interface handle */ + bool reason_code_valid; /**< reascon code valid */ + switch_hostif_reason_code_t reason_code; /**< reason code */ + uint32_t reason_code_mask; /**< reason code mask */ + uint32_t priority; /**< net filter priority */ +} switch_packet_rx_key_t; + +/** Rx net filter action */ +typedef struct switch_packet_rx_action_ { + switch_handle_t hostif_handle; /**< hostif handle */ + switch_vlan_t vlan_id; /**< vlan id */ + switch_packet_vlan_action_t vlan_action; /**< vlan packet action */ +} switch_packet_rx_action_t; + +/** Tx key for net filter */ +typedef struct switch_packet_tx_key_ { + bool handle_valid; /**< hostif handle valid */ + switch_handle_t hostif_handle; /**< hostif handle */ + bool vlan_valid; /**< vlan valid */ + switch_vlan_t vlan_id; /**< vlan id */ + uint32_t priority; /**< net filter priority */ +} switch_packet_tx_key_t; + +/** Tx net filter ation */ +typedef struct switch_packet_tx_action_ { + switch_handle_t handle; /**< bd or interface handle */ + switch_tx_bypass_flags_t bypass_flags; /**< bypass flags */ + switch_handle_t port_handle; /**< egress port */ +} switch_packet_tx_action_t; + +/** + Create tx net filter + @param device device + @param tx_key tx net filter key + @param tx_action tx net filter action + */ +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); + +/** + Delete tx net filter + @param device device + @param tx_key tx net filter key + */ +switch_status_t switch_api_packet_net_filter_tx_delete( + switch_device_t device, switch_packet_tx_key_t *tx_key); + +/** + Create rx net filter + @param device device + @param rx_key rx net filter key + @param rx_action rx net filter action + */ +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); + +/** + Delete rx net filter + @param device device + @param rx_key rx net filter key + */ +switch_status_t switch_api_packet_net_filter_rx_delete( + switch_device_t device, switch_packet_rx_key_t *rx_key); + +/** + create a meter for control plane policing + @param device device + @param api_meter_info meter struct + @param meter_handle return meter handle + */ +switch_status_t switch_api_hostif_meter_create( + switch_device_t device, + switch_api_meter_t *api_meter_info, + switch_handle_t *meter_handle); + +/** + delete meter for control plane policing + @param device device + @param meter_handle meter handle +*/ +switch_status_t switch_api_hostif_meter_delete(switch_device_t device, + switch_handle_t meter_handle); + +/** @} */ // end of Host Interface API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_id.h b/switchapi/include/switchapi/switch_id.h similarity index 68% rename from switchapi/inc/switchapi/switch_id.h rename to switchapi/include/switchapi/switch_id.h index 0683548..d3677a6 100644 --- a/switchapi/inc/switchapi/switch_id.h +++ b/switchapi/include/switchapi/switch_id.h @@ -22,60 +22,66 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + /** ID allocator */ typedef struct switch_api_id_allocator_ { - uint32_t n_words; /**< number fo 32 bit words in allocator */ - uint32_t *data; /**< bitmap of allocator */ - bool zero_based; /**< allocate index from zero if set */ + uint32_t n_words; /**< number fo 32 bit words in allocator */ + uint32_t *data; /**< bitmap of allocator */ + bool zero_based; /**< allocate index from zero if set */ } switch_api_id_allocator; - + /** Create a new allocator @param initial_size init size in words (32-bit) for allocator @param zero_based allocate index from 0 if set to true */ -switch_api_id_allocator *switch_api_id_allocator_new(unsigned int initial_size, bool zero_based); - +switch_api_id_allocator *switch_api_id_allocator_new(unsigned int initial_size, + bool zero_based); + /** Delete the allocator @param allocator allocator allocated with create */ void switch_api_id_allocator_destroy(switch_api_id_allocator *allocator); - + /** Allocate one id from the allocator @param allocator allocator created with create */ -unsigned int switch_api_id_allocator_allocate (switch_api_id_allocator *allocator); +unsigned int switch_api_id_allocator_allocate( + switch_api_id_allocator *allocator); /** Allocate count consecutive ids from the allocator @param allocator allocator created with create @param count number of consecutive ids to allocate */ -unsigned int switch_api_id_allocator_allocate_contiguous (switch_api_id_allocator *allocator, uint8_t count); - +unsigned int switch_api_id_allocator_allocate_contiguous( + switch_api_id_allocator *allocator, uint8_t count); + /** Free up id in allocator @param allocator allocator created with create @param id id to free in allocator */ -void switch_api_id_allocator_release (switch_api_id_allocator *allocator, unsigned int id); - +void switch_api_id_allocator_release(switch_api_id_allocator *allocator, + unsigned int id); + /** Set a bit in allocator @param allocator - bitmap allocator reference @param id - bit to be set in allocator */ -void switch_api_id_allocator_set (switch_api_id_allocator *allocator, unsigned int id); +void switch_api_id_allocator_set(switch_api_id_allocator *allocator, + unsigned int id); /** Check if a bit is set in allocator @param allocator - bitmap allocator reference @param id - bit to be checked in allocator */ -int switch_api_id_allocator_is_set (switch_api_id_allocator *allocator, unsigned int id); +int switch_api_id_allocator_is_set(switch_api_id_allocator *allocator, + unsigned int id); #ifdef __cplusplus } diff --git a/switchapi/include/switchapi/switch_interface.h b/switchapi/include/switchapi/switch_interface.h new file mode 100644 index 0000000..6185d60 --- /dev/null +++ b/switchapi/include/switchapi/switch_interface.h @@ -0,0 +1,383 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_interface_h_ +#define _switch_interface_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_vlan.h" +#include "switch_l3.h" +#include "switch_tunnel.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup Interface Interface configuration API + * API functions listed to configure the interfaces + Interface API + Interfaces are the basic element for provisioning services on the device. + Interfaces can be any of physical, link aggregation group, or tunnels. + * @{ + */ // begin of interface + +/** Interface Types */ +typedef enum switch_interface_type_ { + SWITCH_API_INTERFACE_NONE, /**< none */ + SWITCH_API_INTERFACE_LOOPBACK, /**< loopback interface */ + SWITCH_API_INTERFACE_L2_VLAN_ACCESS, /**< L2 interface on VLAN */ + SWITCH_API_INTERFACE_L2_VLAN_TRUNK, /**< L2 interface on VLAN */ + SWITCH_API_INTERFACE_L3, /**< L3 interface on port */ + SWITCH_API_INTERFACE_L3_VLAN, /**< L3 interface on VLAN */ + SWITCH_API_INTERFACE_L3_PORT_VLAN, /**< Sub-Intf - L3 interface on VLAN on a + port */ + SWITCH_API_INTERFACE_LAG, /**< Interface on lag */ + SWITCH_API_INTERFACE_TUNNEL, /**< L3 Tunnel interface */ + SWITCH_API_INTERFACE_L2_PORT_VLAN, /** L2 sub interface */ + + SWITCH_API_INTERFACE_MAX +} switch_interface_type_t; + +/** Restrict VLAN behavior on a particular port (RoCE like) */ +typedef struct switch_port_vlan_ { + switch_handle_t port_lag_handle; /**< Port or lag */ + switch_vlan_t vlan_id; /**< VLAN id on port */ +} switch_port_vlan_t; + +/** Interface attributes */ +typedef enum switch_intf_attr_ { + SWITCH_INTF_ATTR_VRF, /**< Vrf interface */ + SWITCH_INTF_ATTR_TYPE, /**< interface attribute */ + SWITCH_INTF_ATTR_PORT_ID, /**< port id */ + SWITCH_INTF_ATTR_VLAN_ID, /**< vlan id */ + + SWITCH_INTF_ATTR_RMAC_ADDR, /**< rmac address */ + SWITCH_INTF_ATTR_V4_UNICAST, /**< IPv4 Unicast */ + SWITCH_INTF_ATTR_V6_UNICAST, /**< IPv6 Unicast */ + SWITCH_INTF_ATTR_V4_URPF_MODE, /**< IPv4 Urpf mode */ + SWITCH_INTF_ATTR_V6_URPF_MODE, /**< IPv6 Urpf mode */ + + SWITCH_INTF_ATTR_CUSTOM_RANGE_BASE = 0x10000000, /**< Custom Attribute base */ + SWITCH_INTF_ATTR_NATIVE_VLAN, /**< Native Vlan */ +} switch_intf_attr_t; + +/** Interface information */ +typedef struct switch_api_interface_info_ { + switch_interface_type_t type; /**< type of interface */ + union { + switch_handle_t port_lag_handle; /**< Port or LAG handle */ + switch_vlan_t vlan_id; /**< Vlan Inteface */ + switch_port_vlan_t port_vlan; /**< L3 sub Interface */ + switch_tunnel_info_t tunnel_info; /**< Tunnel handle */ + } u; /**< Base information */ + + struct { + uint8_t core_intf : 1; /**< interface flags */ + uint8_t flood_enabled : 1; /**< Add to flood list (only for tunnels) */ + } flags; /**< interface flags struct */ + // L2 + switch_handle_t native_vlan; /**< native vlan id */ + // L3 + bool ipv4_unicast_enabled; /**< IPv4 unicast enabled */ + bool ipv6_unicast_enabled; /**< IPv6 unicast enabled */ + bool ipv4_multicast_enabled; /**< IPv4 multicast enabled */ + bool ipv6_multicast_enabled; /**< IPV6 multicast menabled */ + switch_urpf_mode_t ipv4_urpf_mode; /**< IPv4 urpf mode */ + switch_urpf_mode_t ipv6_urpf_mode; /**< IPv6 urpf mode */ + unsigned char nat_mode; /**< nat mode */ + switch_handle_t vrf_handle; /**< vrf handle */ + bool mac_valid; /**< mac address valid */ + switch_mac_addr_t mac; /**< Mac address associated with interface */ + switch_handle_t rmac_handle; /**< rmac group id */ +} switch_api_interface_info_t; + +/** + Interface create + @param device - device on which interface is created + @param intf_info - interface information specific to type + */ +switch_handle_t switch_api_interface_create( + switch_device_t device, switch_api_interface_info_t *intf_info); + +/** + Interface delete + @param device - device on which interface is created + @param interface_handle handle returned by interface creation + */ +switch_status_t switch_api_interface_delete(switch_device_t device, + switch_handle_t interface_handle); + +/** + Set interface attributes + @param intf_handle - Handle that uniquely identifies interface + @param attr_type - Attribute of an interface + @param value - Value that has to be set for an attribute +*/ +switch_status_t switch_api_interface_attribute_set(switch_handle_t intf_handle, + switch_intf_attr_t attr_type, + uint64_t value); +/** + Get interface attributes + @param intf_handle - Handle that uniquely identifies interface + @param attr_type - Attribute of an interface + @param value - Value that has to be obtained for an attribute +*/ +switch_status_t switch_api_interface_attribute_get(switch_handle_t intf_handle, + switch_intf_attr_t attr_type, + uint64_t *value); + +/** + Get the interface's port id + @param intf_handle - Handle that uniquely identifies interface + @param value - Address of vrf destination + */ +switch_status_t switch_api_interface_vrf_get(switch_handle_t intf_handle, + uint64_t *value); + +/** + Get the interface's port id + @param intf_handle - Handle that uniquely identifies interface + @param value - Address of port id destination + */ +switch_status_t switch_api_interface_port_id_get(switch_handle_t intf_handle, + uint64_t *value); + +/** + Get the interface's vlan id + @param intf_handle - Handle that uniquely identifies interface + @param value - Address of vlan id destination + */ +switch_status_t switch_api_interface_vlan_id_get(switch_handle_t intf_handle, + uint64_t *value); + +/** + Get the interface's mac address + @param intf_handle - Handle that uniquely identifies interface + @param value - Address of destination mac container + */ +switch_status_t switch_api_interface_rmac_addr_get(switch_handle_t intf_handle, + uint64_t *value); + +/** + Set IPv4 enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Enable/Disable V4 routing on interface +*/ +switch_status_t switch_api_interface_ipv4_unicast_enabled_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get IPv4 enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Get V4 routing on interface +*/ +switch_status_t switch_api_interface_ipv4_unicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set IPv6 enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Enable/Disable V4 routing on interface +*/ +switch_status_t switch_api_interface_ipv6_unicast_enabled_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get IPv6 enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Get V4 routing on interface +*/ +switch_status_t switch_api_interface_ipv6_unicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set IPv4 multicast enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Enable/Disable V4 multicast routing on interface +*/ +switch_status_t switch_api_interface_ipv4_multicast_enabled_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get IPv4 multicast enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Get V4 multicast routing on interface +*/ +switch_status_t switch_api_interface_ipv4_multicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set IPv6 multicast enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Enable/Disable V4 multicast routing on interface +*/ +switch_status_t switch_api_interface_ipv6_multicast_enabled_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get IPv6 multicast enable interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Get V4 multicast routing on interface +*/ +switch_status_t switch_api_interface_ipv6_multicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set IPv4 unicast rpf mode interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Unicast RPF mode +*/ +switch_status_t switch_api_interface_ipv4_urpf_mode_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get IPv4 unicast rpf mode interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Unicast RPF mode +*/ +switch_status_t switch_api_interface_ipv4_urpf_mode_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set IPv6 unicast rpf mode interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Unicast RPF mode +*/ +switch_status_t switch_api_interface_ipv6_urpf_mode_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get IPv6 unicast rpf mode interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - Unicast RPF mode +*/ +switch_status_t switch_api_interface_ipv6_urpf_mode_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set NAT mode interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - NAT mode +*/ +switch_status_t switch_api_interface_nat_mode_set(switch_handle_t intf_handle, + uint8_t value); + +/** + Get NAT mode interface attribute + @param intf_handle - Handle that uniquely identifies interface + @param value - NAT mode +*/ +switch_status_t switch_api_interface_nat_mode_get(switch_handle_t intf_handle, + uint8_t *value); + +/** + Set native vlan on interface + @param intf_handle - Handle that uniquely identifies interface + @param value - Value of native vlan +*/ +switch_status_t switch_api_interface_native_vlan_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get native vlan on interface + @param intf_handle - Handle that uniquely identifies interface + @param value - Value of native vlan +*/ +switch_status_t switch_api_interface_native_vlan_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Iterator function prototype for l3 interfaces + @param intf_info Interface Info + */ +typedef switch_status_t (*switch_l3_interfaces_iterator_fn)( + switch_api_interface_info_t intf_info); + +/** + Get all l3 interfaces + @param iterator_fn Iterator function to be called for every l3 interface + */ +switch_status_t switch_api_interface_l3_ifs_get( + switch_l3_interfaces_iterator_fn iterator_fn); + +/** + Given an interface handle, get the associated port handle + @param intf_handle - Handle that uniquely identifies interface + @param port_handle - Port handle associated with the interface + */ +switch_status_t switch_api_interface_get_port_handle( + switch_handle_t intf_handle, switch_handle_t *port_handle); + +/** + Given an L3 interface handle, get the associated vlan handle + @param intf_handle - Handle that uniquely identifies interface + @param vlan_handle - Vlan handle associated with the interface + */ +switch_status_t switch_api_interface_get_vlan_handle( + switch_handle_t intf_handle, switch_handle_t *vlan_handle); + +/** + Given an interface handle, get its type + @param intf_handle - Handle that uniquely identifies interface + @param type - Interface type + */ +switch_status_t switch_api_interface_get_type(switch_handle_t intf_handle, + switch_interface_type_t *type); + +/** + enable bd stats on interface + @param device device + @param intf_handle - Handle that uniquely identifies interface + */ +switch_status_t switch_api_l3_interface_bd_stats_enable( + switch_device_t device, switch_handle_t intf_handle); + +/** + disable bd stats on interface + @param device device + @param intf_handle - Handle that uniquely identifies interface + */ +switch_status_t switch_api_l3_interface_bd_stats_disable( + switch_device_t device, switch_handle_t intf_handle); + +/** + get stats on l3 interface + @param device device + @param intf_handle - Handle that uniquely identifies interface + @param count number of counters + @param counter_ids counter ids + @param counters counter return value + */ +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 + */ +switch_status_t switch_api_interface_print_all(void); + +/** @} */ // end of interface + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_l2.h b/switchapi/include/switchapi/switch_l2.h similarity index 57% rename from switchapi/inc/switchapi/switch_l2.h rename to switchapi/include/switchapi/switch_l2.h index 19ba8f6..e04fc93 100644 --- a/switchapi/inc/switchapi/switch_l2.h +++ b/switchapi/include/switchapi/switch_l2.h @@ -26,69 +26,73 @@ limitations under the License. #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* __cplusplus */ /** @defgroup Switching L2 Switching API * API functions listed to configure Mac Address tables * @{ The basic switching APIs are controlled by the manipulation of the MAC tables – source and destination. Addresses learnt from packets on a port and/or VLAN are used to switch packets destined that address within the VLAN. - */ // begin of L2 - // L2 + */ // begin of L2 + // L2 /** Mac entry type */ typedef enum switch_mac_entry_type_ { - SWITCH_MAC_ENTRY_UNSPECIFIED, - SWITCH_MAC_ENTRY_DYNAMIC, - SWITCH_MAC_ENTRY_STATIC + SWITCH_MAC_ENTRY_UNSPECIFIED, + SWITCH_MAC_ENTRY_DYNAMIC, + SWITCH_MAC_ENTRY_STATIC } switch_mac_entry_type_t; /** Mac event */ typedef enum switch_mac_event_ { - SWITCH_MAC_EVENT_UNSPECIFIED, - SWITCH_MAC_EVENT_LEARNED, - SWITCH_MAC_EVENT_AGED, - SWITCH_MAC_EVENT_FLUSHED + SWITCH_MAC_EVENT_UNSPECIFIED, + SWITCH_MAC_EVENT_LEARNED, + SWITCH_MAC_EVENT_AGED, + SWITCH_MAC_EVENT_FLUSHED } switch_mac_event_t; /** Mac attributes */ typedef enum switch_mac_attr_ { - SWITCH_MAC_ATTR_AGING_TIME, - SWITCH_MAC_ATTR_TABLE_SIZE, + SWITCH_MAC_ATTR_AGING_TIME, + SWITCH_MAC_ATTR_TABLE_SIZE, - SWITCH_MAC_ATTR_CUSTOM_RANGE_BASE = 0x10000000 + SWITCH_MAC_ATTR_CUSTOM_RANGE_BASE = 0x10000000 } switch_mac_attr_t; /** Mac action */ typedef enum switch_mac_action_ { - SWITCH_MAC_ACTION_DROP, - SWITCH_MAC_ACTION_FORWARD + SWITCH_MAC_ACTION_DROP, + SWITCH_MAC_ACTION_FORWARD } switch_mac_action_t; /** Mac entry */ typedef struct switch_api_mac_entry_ { - switch_handle_t vlan_handle; /**< vlan handle */ - switch_mac_addr_t mac; /**< mac address */ - switch_handle_t handle; /**< Interface or nexthop handle */ - switch_mac_entry_type_t entry_type; /**< entry type */ - switch_mac_action_t mac_action; /**< mac action */ + switch_handle_t vlan_handle; /**< vlan handle */ + switch_mac_addr_t mac; /**< mac address */ + switch_handle_t handle; /**< Interface or nexthop handle */ + switch_mac_entry_type_t entry_type; /**< entry type */ + switch_mac_action_t mac_action; /**< mac action */ } switch_api_mac_entry_t; /** learn notification callback function pointer @param mac_entries - set of mac entries */ -typedef void (*switch_mac_learn_entry_notify_cb)(switch_api_mac_entry_t *mac_entry); +typedef void (*switch_mac_learn_entry_notify_cb)( + switch_api_mac_entry_t *mac_entry); /** learn notification callback function pointer @param mac_entries - set of mac entries */ -typedef void (*switch_mac_aging_entry_notify_cb)(switch_api_mac_entry_t *mac_entry); +typedef void (*switch_mac_aging_entry_notify_cb)( + switch_api_mac_entry_t *mac_entry); /** Learn and aging call back functions */ typedef struct switch_mac_cb_fn_ { - switch_mac_learn_entry_notify_cb mac_learn_notify_cb; /**< mac learn notification callback */ - switch_mac_aging_entry_notify_cb mac_aging_notify_cb; /**< mac aging notification callback */ + switch_mac_learn_entry_notify_cb + mac_learn_notify_cb; /**< mac learn notification callback */ + switch_mac_aging_entry_notify_cb + mac_aging_notify_cb; /**< mac aging notification callback */ } switch_mac_cb_fn_t; /** @@ -96,8 +100,8 @@ typedef struct switch_mac_cb_fn_ { @param device - device @param mac_entry - contains the vlan and mac that has to be programmed */ -switch_status_t switch_api_mac_table_entry_add(switch_device_t device, - switch_api_mac_entry_t *mac_entry); +switch_status_t switch_api_mac_table_entry_add( + switch_device_t device, switch_api_mac_entry_t *mac_entry); /** Add a set of Destination MAC table entries. @@ -106,45 +110,50 @@ switch_status_t switch_api_mac_table_entry_add(switch_device_t device, @param mac_entries - list of entries contains the vlan and mac that has to be programmed */ -switch_status_t switch_api_mac_table_entries_add(switch_device_t device, uint16_t mac_entry_count, - switch_api_mac_entry_t *mac_entries); +switch_status_t switch_api_mac_table_entries_add( + switch_device_t device, + uint16_t mac_entry_count, + switch_api_mac_entry_t *mac_entries); /** Update Destination MAC entry @param device - device @param mac_entry - contains the vlan and mac that has to be programmed */ -switch_status_t switch_api_mac_table_entry_update(switch_device_t device, - switch_api_mac_entry_t *mac_entry); +switch_status_t switch_api_mac_table_entry_update( + switch_device_t device, switch_api_mac_entry_t *mac_entry); /** - Update a set of Destination MAC table entries. + Update a set of Destination MAC table entries. @param device - device @param mac_entry_count - Number of mac entries to be updated @param mac_entries - list of entries contains the vlan and mac that has to be programmed */ -switch_status_t switch_api_mac_table_entries_update(switch_device_t device, uint16_t mac_entry_count, - switch_api_mac_entry_t *mac_entries); +switch_status_t switch_api_mac_table_entries_update( + switch_device_t device, + uint16_t mac_entry_count, + switch_api_mac_entry_t *mac_entries); /** Delete a Destination MAC entry. @param device - device @param mac_entry - contains the vlan and mac that has to be deleted */ -switch_status_t switch_api_mac_table_entry_delete(switch_device_t device, - switch_api_mac_entry_t *mac_entry); +switch_status_t switch_api_mac_table_entry_delete( + switch_device_t device, switch_api_mac_entry_t *mac_entry); /** - Delete a set of destination mac table entries. + Delete a set of destination mac table entries. @param device - device @param mac_entries - list of entries contains the vlan and mac that has to be deleted @param mac_entry_count - Number of mac entries to be deleted */ -switch_status_t switch_api_mac_table_entries_delete(switch_device_t device, - uint16_t mac_entry_count, - switch_api_mac_entry_t *mac_entries); +switch_status_t switch_api_mac_table_entries_delete( + switch_device_t device, + uint16_t mac_entry_count, + switch_api_mac_entry_t *mac_entries); /** Delete all Destination MAC entries from FDB. @param device - device @@ -156,16 +165,16 @@ switch_status_t switch_api_mac_table_entries_delete_all(switch_device_t device); @param device - device @param interface_handle outgoing interface handle */ -switch_status_t switch_api_mac_table_entries_delete_by_interface(switch_device_t device, - switch_handle_t interface_handle); +switch_status_t switch_api_mac_table_entries_delete_by_interface( + switch_device_t device, switch_handle_t interface_handle); /** Delete all MACs on a selected VLAN @param device - device @param vlan_handle idenifes the VLAN (domain) */ -switch_status_t switch_api_mac_table_entries_delete_by_vlan(switch_device_t device, - switch_handle_t vlan_handle); +switch_status_t switch_api_mac_table_entries_delete_by_vlan( + switch_device_t device, switch_handle_t vlan_handle); /** Delete all MACs on a selected VLAN + Interface @@ -173,35 +182,40 @@ switch_status_t switch_api_mac_table_entries_delete_by_vlan(switch_device_t devi @param handle idenfies the interface/port/lag @param vlan_handle idenifes the VLAN (domain) */ -switch_status_t switch_api_mac_table_entries_delete_by_interface_vlan(switch_device_t device, - switch_handle_t handle, - switch_handle_t vlan_handle); +switch_status_t switch_api_mac_table_entries_delete_by_interface_vlan( + switch_device_t device, + switch_handle_t handle, + switch_handle_t vlan_handle); /** Register a calback function for mac learning @param cb_fn - function to be called when a mac is learnt */ -switch_status_t switch_api_mac_register_learning_callback(switch_mac_learn_entry_notify_cb cb_fn); +switch_status_t switch_api_mac_register_learning_callback( + switch_mac_learn_entry_notify_cb cb_fn); /** Register a calback function for mac aging @param cb_fn - function to be called when a mac is aged */ -switch_status_t switch_api_mac_register_aging_callback(switch_mac_aging_entry_notify_cb cb_fn); +switch_status_t switch_api_mac_register_aging_callback( + switch_mac_aging_entry_notify_cb cb_fn); /** Set global attribute for mac table @param mac_attr- Attribute type @param value - value of the attribute */ -switch_status_t switch_api_mac_table_attribute_set(switch_mac_attr_t mac_attr, uint64_t value); +switch_status_t switch_api_mac_table_attribute_set(switch_mac_attr_t mac_attr, + uint64_t value); /** Get global attribute of mac table @param mac_attr - Attribute type @param value - value of the attribute */ -switch_status_t switch_api_mac_table_attribute_get(switch_mac_attr_t mac_attr, uint64_t *value); +switch_status_t switch_api_mac_table_attribute_get(switch_mac_attr_t mac_attr, + uint64_t *value); /** Set mac aging time of mac table @@ -219,29 +233,31 @@ switch_status_t switch_api_mac_table_aging_time_get(uint64_t *value); Register a iterator function to walk through all the mac entries @param mac_entry - Mac entry */ -typedef switch_status_t (*switch_mac_table_iterator_fn)(switch_api_mac_entry_t *mac_entry); +typedef switch_status_t (*switch_mac_table_iterator_fn)( + switch_api_mac_entry_t *mac_entry); /** Calls the iterator function for every mac entry @param iterator_fn - Iterator function */ -switch_status_t switch_api_mac_table_entries_get(switch_mac_table_iterator_fn iterator_fn); +switch_status_t switch_api_mac_table_entries_get( + switch_mac_table_iterator_fn iterator_fn); /** Calls the iterator function for every mac entry on vlan @param vlan_handle - Handle of vlan @param iterator_fn - Iterator function */ -switch_status_t switch_api_mac_table_entries_get_by_vlan(switch_handle_t vlan_handle, - switch_mac_table_iterator_fn iterator_fn); +switch_status_t switch_api_mac_table_entries_get_by_vlan( + switch_handle_t vlan_handle, switch_mac_table_iterator_fn iterator_fn); /** Calls the iterator function for every mac entry on interface @param intf_handle - Interface handle @param iterator_fn - Iterator function */ -switch_status_t switch_api_mac_table_entries_get_by_interface(switch_handle_t intf_handle, - switch_mac_table_iterator_fn iterator_fn); +switch_status_t switch_api_mac_table_entries_get_by_interface( + switch_handle_t intf_handle, switch_mac_table_iterator_fn iterator_fn); /** Calls the iterator function for every mac entry on interface and vlan @@ -249,23 +265,26 @@ switch_status_t switch_api_mac_table_entries_get_by_interface(switch_handle_t in @param vlan_handle - idenifes the VLAN (domain) @param iterator_fn - Iterator function */ -switch_status_t switch_api_mac_table_entries_get_by_interface_vlan(switch_handle_t intf_handle, - switch_handle_t vlan_handle, switch_mac_table_iterator_fn iterator_fn); +switch_status_t switch_api_mac_table_entries_get_by_interface_vlan( + switch_handle_t intf_handle, + switch_handle_t vlan_handle, + switch_mac_table_iterator_fn iterator_fn); /** Set the learning buffer timeout value @param device device @param timeout - Timeout in milliseconds */ -switch_status_t switch_api_mac_table_set_learning_timeout(switch_device_t device, uint32_t timeout); +switch_status_t switch_api_mac_table_set_learning_timeout( + switch_device_t device, uint32_t timeout); /** Dump mac table */ switch_status_t switch_api_mac_table_print_all(); -/** @} */ // end of L2 - +/** @} */ // end of L2 + #ifdef __cplusplus } #endif diff --git a/switchapi/include/switchapi/switch_l3.h b/switchapi/include/switchapi/switch_l3.h new file mode 100644 index 0000000..a78a2b1 --- /dev/null +++ b/switchapi/include/switchapi/switch_l3.h @@ -0,0 +1,210 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_l3_h_ +#define _switch_l3_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup L3 L3 API + * API functions create IP interfaces and route + * @{ + */ // begin of L3 API +// L3 + +// RPF check +/** Mode for RPF check - loose or strict mode */ +typedef enum { + SWITCH_API_RPF_CHECK_DEFAULT, + SWITCH_API_RPF_CHECK_LOOSE, + SWITCH_API_RPF_CHECK_STRICT +} switch_urpf_mode_t; + +/** + Configure IP address on L3 interface + @param device device + @param interface_handle interface handle returned from interface_create() + @param vrf virtual domain identifier + @param ip_addr IP address to be configured(v4 or v6) +*/ +switch_status_t switch_api_l3_interface_address_add( + switch_device_t device, + switch_handle_t interface_handle, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr); +/** + Delete a configured IP address on interface + @param device device + @param interface_handle interface handle returned from interface_create() + @param vrf virtual domain identifier + @param ip_addr IP address to be deleted +*/ +switch_status_t switch_api_l3_interface_address_delete( + switch_device_t device, + switch_handle_t interface_handle, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr); +/** + Get the handle of the interface that route lookup returns for a host addr + If the nexthop is ECMP group, return INVALID_HANDLE + @param device device + @param vrf virtual domain identifier + @param ip_addr IP address (host or prefix) + @param intf_handle pointer to return Interface handle +*/ +switch_status_t switch_api_l3_route_nhop_intf_get(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t *intf_handle); + +/** + Prefix/Host address reachability entry - inserted into a host table to match a + /32 IPv4 ot /128 IPv6 address, When there are multiple paths to reach + the same destiantion ECMP tables is used implicitly + @param device device + @param vrf virtual domain identifier + @param ip_addr IP address + @param nhop_handle Nexthop Handle +*/ +switch_status_t switch_api_l3_route_add(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t nhop_handle); +/** + Prefix/Host address entry delete + @param device device + @param vrf virtual domain identifier + @param ip_addr IP address + @param nhop_handle Nexthop Handle +*/ +switch_status_t switch_api_l3_route_delete(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t nhop_handle); +/** + Lookup FIB table (host or LPM) for a given host address + Return nexthop handle (single path or ECMP group) + Return INVALID_HANDLE if lookup fails + @param device device + @param vrf virtual domain identifier + @param ip_addr IP address + @param nhop_handle pointer to return Nexthop Handle +*/ +switch_status_t switch_api_l3_route_lookup(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t *nhop_handle); + +/** + Set native vlan on interface + @param intf_handle - Handle that uniquely identifies interface + @param value - Value of v4 urpf mode +*/ +switch_status_t switch_api_interface_ipv4_urpf_mode_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get native vlan on interface + @param intf_handle - Handle that uniquely identifies interface + @param value - Value of v4 urpf mode +*/ +switch_status_t switch_api_interface_ipv4_urpf_mode_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Set native vlan on interface + @param intf_handle - Handle that uniquely identifies interface + @param value - Value of v6 urpf mode +*/ +switch_status_t switch_api_interface_ipv6_urpf_mode_set( + switch_handle_t intf_handle, uint64_t value); + +/** + Get native vlan on interface + @param intf_handle - Handle that uniquely identifies interface + @param value - Value of v6 urpf mode +*/ +switch_status_t switch_api_interface_ipv6_urpf_mode_get( + switch_handle_t intf_handle, uint64_t *value); + +/** + Iterator function prototype for L3 routes + @param vrf_handle Vrf handle + @param ip_addr IP Address + @param nhop_handle Nexthop handle + */ +typedef switch_status_t (*switch_l3_table_iterator_fn)( + switch_handle_t vrf_handle, + switch_ip_addr_t ip_addr, + switch_handle_t nhop_handle); + +/** + Get all L3 routes + @param iterator_fn - Iterator function to be called +*/ +switch_status_t switch_api_l3_route_entries_get( + switch_l3_table_iterator_fn iterator_fn); + +/** + Get all L3 routes in a vrf + @param vrf_handle Vrf handle + @param iterator_fn - Iterator function to be called + */ +switch_status_t switch_api_l3_route_entries_get_by_vrf( + switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn); + +/** + Get all L3 V4 routes in a vrf + @param vrf_handle Vrf handle + @param iterator_fn - Iterator function to be called + */ +switch_status_t switch_api_l3_v4_route_entries_get_by_vrf( + switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn); + +/** + Get all L3 V6 routes in a vrf + @param vrf_handle Vrf handle + @param iterator_fn - Iterator function to be called + */ +switch_status_t switch_api_l3_v6_route_entries_get_by_vrf( + switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn); + +/** + Dump L3 routing table + */ +switch_status_t switch_api_l3_routes_print_all(void); + +/** + create mtu entry + @param device device + @param mtu_index mtu index + @param mtu mtu value + */ +switch_status_t switch_api_mtu_create_entry(switch_device_t device, + uint16_t mtu_index, + uint32_t mtu); +/** @} */ // end of L3 API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_lag.h b/switchapi/include/switchapi/switch_lag.h similarity index 71% rename from switchapi/inc/switchapi/switch_lag.h rename to switchapi/include/switchapi/switch_lag.h index db4869c..a1a9cd2 100644 --- a/switchapi/inc/switchapi/switch_lag.h +++ b/switchapi/include/switchapi/switch_lag.h @@ -23,8 +23,7 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - - + /** @defgroup LAG LAG configuration API * API functions listed to configure the Link Aggregation groups. * Create LAG, Add/Del ports to LAG and set admin states @@ -35,19 +34,17 @@ extern "C" { scheme selectable globally. Typically the L2 fields (DMAC, SMAC, EtherType) are used for this. The choice of this is configurable by the APIs. * @{ - */ // begin of LAG - + */ // begin of LAG /**< 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_API_LAG_SIMPLE, /**< simple hash */ + SWITCH_API_LAG_RESILIENT /**< weighted/resilient hash */ } switch_lag_type_t; - // Simple LAG API /** Link Aggregation Group creation @@ -60,27 +57,32 @@ switch_handle_t switch_api_lag_create(switch_device_t device); @param device device to use @param lag_handle handle of group returned on creation */ -switch_status_t switch_api_lag_delete(switch_device_t device, switch_handle_t lag_handle); +switch_status_t switch_api_lag_delete(switch_device_t device, + switch_handle_t lag_handle); /** Link Aggregation Group member port add @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_status_t switch_api_lag_member_add(switch_device_t device, switch_handle_t lag_handle, - switch_direction_t side, switch_port_t port); +switch_status_t switch_api_lag_member_add(switch_device_t device, + switch_handle_t lag_handle, + switch_direction_t direction, + switch_port_t port); /** Link Aggregation Group member port delete @param device device to use @param lag_handle handle of group returned on creation - @param side control rx and tx members independently or both + @param direction control rx and tx members independently or both @param port port in the same device on which lag_handle was created */ -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); +switch_status_t switch_api_lag_member_delete(switch_device_t device, + switch_handle_t lag_handle, + switch_direction_t direction, + switch_port_t port); /** Link Aggregation Group member add by handle @@ -89,22 +91,18 @@ switch_status_t switch_api_lag_member_delete(switch_device_t device, switch_hand @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 -switch_api_lag_member_create( - switch_device_t device, - switch_handle_t lag_handle, - switch_direction_t direction, - switch_port_t port); +switch_handle_t switch_api_lag_member_create(switch_device_t device, + switch_handle_t lag_handle, + switch_direction_t direction, + switch_port_t port); /** Link Aggregation Group member deletion by handle @param device device to use @param lag_member_handle handle of member returned on creation */ -switch_status_t -switch_api_lag_member_remove( - switch_device_t device, - switch_handle_t lag_member_handle); +switch_status_t switch_api_lag_member_remove(switch_device_t device, + switch_handle_t lag_member_handle); /** Link Aggregation group member count @@ -118,7 +116,9 @@ unsigned int switch_lag_get_count(switch_handle_t lag_handle); @param intf_handle List of member interfaces @param member_count Number of lag members */ -typedef switch_status_t (*switch_lag_iterator_fn)(uint8_t lag_id, switch_handle_t *intf_handle, uint8_t member_count); +typedef switch_status_t (*switch_lag_iterator_fn)(uint8_t lag_id, + switch_handle_t *intf_handle, + uint8_t member_count); /** Calls the iterator function for every lag @@ -130,9 +130,9 @@ switch_status_t switch_api_lag_get(switch_lag_iterator_fn iterator_fn); Dump lag table */ switch_status_t switch_api_lag_print_all(); - -/** @} */ // end of LAG - + +/** @} */ // end of LAG + #ifdef __cplusplus } #endif diff --git a/switchapi/inc/switchapi/switch_log.h b/switchapi/include/switchapi/switch_log.h similarity index 74% rename from switchapi/inc/switchapi/switch_log.h rename to switchapi/include/switchapi/switch_log.h index da04a63..2bef0e7 100644 --- a/switchapi/inc/switchapi/switch_log.h +++ b/switchapi/include/switchapi/switch_log.h @@ -17,18 +17,18 @@ limitations under the License. #define _SWITCH_LOG_H_ #include "p4features.h" -#include +#include "switch_status.h" typedef enum switch_api_log_levels_ { - SWITCH_API_LOG_NONE = 0, - SWITCH_API_LOG_ERROR, - SWITCH_API_LOG_WARN, - SWITCH_API_LOG_INFO, - SWITCH_API_LOG_VERBOSE, - SWITCH_API_LOG_TRACE, + SWITCH_API_LOG_NONE = 0, + SWITCH_API_LOG_ERROR, + SWITCH_API_LOG_WARN, + SWITCH_API_LOG_INFO, + SWITCH_API_LOG_VERBOSE, + SWITCH_API_LOG_TRACE, } switch_api_log_level_t; -typedef int (switch_api_log_fn_t)(switch_api_log_level_t level, char *fmt, ...); +typedef int(switch_api_log_fn_t)(switch_api_log_level_t level, char *fmt, ...); void switch_api_log_function_set(switch_api_log_fn_t *log_fn); #endif /* _SWITCH_LOG_H_ */ diff --git a/switchapi/inc/switchapi/switch_mcast.h b/switchapi/include/switchapi/switch_mcast.h similarity index 58% rename from switchapi/inc/switchapi/switch_mcast.h rename to switchapi/include/switchapi/switch_mcast.h index 351a90b..04c7cad 100644 --- a/switchapi/inc/switchapi/switch_mcast.h +++ b/switchapi/include/switchapi/switch_mcast.h @@ -27,14 +27,14 @@ extern "C" { The multicast API's are controlled based on the multicast protocols that propagates the route entries to MFIB. A multicast tree handle is programmed against each route in mfib. The tree is derived in the queuing block and the packet is replicated based on the members. - */ // begin of MCAST - // MCAST + */ // begin of MCAST + // MCAST /** Multicast mode */ typedef enum switch_mcast_mode_ { - SWITCH_API_MCAST_IPMC_NONE, - SWITCH_API_MCAST_IPMC_PIM_SM, - SWITCH_API_MCAST_IPMC_PIM_BIDIR + SWITCH_API_MCAST_IPMC_NONE, + SWITCH_API_MCAST_IPMC_PIM_SM, + SWITCH_API_MCAST_IPMC_PIM_BIDIR } switch_mcast_mode_t; /* MCAST API's */ @@ -49,7 +49,8 @@ switch_handle_t switch_api_multicast_tree_create(switch_device_t device); @param device - device that programs the tree @param mgid_handle - Handle that uniquely identifies multicast tree */ -switch_status_t switch_api_multicast_tree_delete(switch_device_t device, switch_handle_t mgid_handle); +switch_status_t switch_api_multicast_tree_delete(switch_device_t device, + switch_handle_t mgid_handle); /** Add a list of members to multicast tree @@ -59,9 +60,9 @@ switch_status_t switch_api_multicast_tree_delete(switch_device_t device, switch_ @param mbrs - List of interfaces to be added to multicast tree */ switch_status_t switch_api_multicast_member_add(switch_device_t device, - switch_handle_t mgid_handle, - uint16_t mbr_count, - switch_vlan_interface_t *mbrs); + switch_handle_t mgid_handle, + uint16_t mbr_count, + switch_vlan_interface_t *mbrs); /** Delete a list of members to multicast tree @@ -70,10 +71,11 @@ switch_status_t switch_api_multicast_member_add(switch_device_t device, @param mbr_count - Count of members @param mbrs - List of interfaces to be deleted from multicast tree */ -switch_status_t switch_api_multicast_member_delete(switch_device_t device, - switch_handle_t mgid_handle, - uint16_t mbr_count, - switch_vlan_interface_t *mbrs); +switch_status_t switch_api_multicast_member_delete( + switch_device_t device, + switch_handle_t mgid_handle, + uint16_t mbr_count, + switch_vlan_interface_t *mbrs); /** Get the list of members of a multicast tree @@ -83,15 +85,15 @@ switch_status_t switch_api_multicast_member_delete(switch_device_t device, @param mbrs - List of interfaces part of the multicast tree */ switch_status_t switch_api_multicast_member_get(switch_device_t device, - switch_handle_t mgid_handle, - uint16_t *mbr_count, - switch_vlan_interface_t **mbrs); + switch_handle_t mgid_handle, + uint16_t *mbr_count, + switch_vlan_interface_t **mbrs); /** 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 vlan_vrf_handle - VLAN/VRF handle + @param vlan_vrf_handle - 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 @@ -99,13 +101,13 @@ switch_status_t switch_api_multicast_member_get(switch_device_t device, @param rpf_vlan_count - Count of RPF vlan's */ switch_status_t switch_api_multicast_mroute_add(switch_device_t device, - switch_handle_t mgid_handle, - switch_handle_t vlan_vrf_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip, - switch_mcast_mode_t mc_mode, - switch_handle_t *rpf_vlan_list, - uint16_t rpf_vlan_count); + switch_handle_t mgid_handle, + switch_handle_t vlan_vrf_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip, + switch_mcast_mode_t mc_mode, + switch_handle_t *rpf_vlan_list, + uint16_t rpf_vlan_count); /** Delete a (S,G) or (*, G) entry from MFIB. @@ -114,10 +116,11 @@ switch_status_t switch_api_multicast_mroute_add(switch_device_t device, @param src_ip - Source IP address @param grp_ip - Group IP address */ -switch_status_t switch_api_multicast_mroute_delete(switch_device_t device, - switch_handle_t vrf_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip); +switch_status_t switch_api_multicast_mroute_delete( + switch_device_t device, + switch_handle_t vrf_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip); /** For a (S,G) or (*, G) get the multicast tree @@ -127,11 +130,12 @@ switch_status_t switch_api_multicast_mroute_delete(switch_device_t device, @param grp_ip - Group IP address @param mgid_handle - Handle of multicast tree */ -switch_status_t switch_api_multicast_mroute_tree_get(switch_device_t device, - switch_handle_t vrf_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip, - switch_handle_t *mgid_handle); +switch_status_t switch_api_multicast_mroute_tree_get( + switch_device_t device, + switch_handle_t vrf_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip, + switch_handle_t *mgid_handle); /** Add an L2 (S,G) or (*, G) route entry to MFIB. @@ -141,11 +145,12 @@ switch_status_t switch_api_multicast_mroute_tree_get(switch_device_t device, @param src_ip - Source IP address @param grp_ip - Group IP address */ -switch_status_t switch_api_multicast_l2route_add(switch_device_t device, - switch_handle_t mgid_handle, - switch_handle_t vlan_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip); +switch_status_t switch_api_multicast_l2route_add( + switch_device_t device, + switch_handle_t mgid_handle, + switch_handle_t vlan_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip); /** Delete an L2 (S,G) or (*, G) route entry to MFIB. @@ -154,10 +159,11 @@ switch_status_t switch_api_multicast_l2route_add(switch_device_t device, @param src_ip - Source IP address @param grp_ip - Group IP address */ -switch_status_t switch_api_multicast_l2route_delete(switch_device_t device, - switch_handle_t vlan_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip); +switch_status_t switch_api_multicast_l2route_delete( + switch_device_t device, + switch_handle_t vlan_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip); /** For an L2 (S,G) or (*, G) get the multicast tree @@ -167,13 +173,14 @@ switch_status_t switch_api_multicast_l2route_delete(switch_device_t device, @param grp_ip - Group IP address @param mgid_handle - Handle of multicast tree */ -switch_status_t switch_api_multicast_l2route_tree_get(switch_device_t device, - switch_handle_t vlan_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip, - switch_handle_t *mgid_handle); - -/** @} */ // end of mcast API +switch_status_t switch_api_multicast_l2route_tree_get( + switch_device_t device, + switch_handle_t vlan_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip, + switch_handle_t *mgid_handle); + +/** @} */ // end of mcast API #ifdef __cplusplus } diff --git a/switchapi/inc/switchapi/switch_meter.h b/switchapi/include/switchapi/switch_meter.h similarity index 55% rename from switchapi/inc/switchapi/switch_meter.h rename to switchapi/include/switchapi/switch_meter.h index 45605a4..a3259bc 100644 --- a/switchapi/inc/switchapi/switch_meter.h +++ b/switchapi/include/switchapi/switch_meter.h @@ -26,48 +26,43 @@ limitations under the License. #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ -/** @defgroup Meters Meters Switching API +#endif /* __cplusplus */ +/** @defgroup Meters API * API functions listed to configure meters * @{ - */ // begin of meters - // meters + */ // begin of meters + // meters /** Meter mode */ typedef enum switch_meter_mode_ { - SWITCH_METER_MODE_NONE, /**< none */ - SWITCH_METER_MODE_TWO_RATE_THREE_COLOR, /**< two rate, three color */ - SWITCH_METER_MODE_STORM_CONTROL /**< storm control */ + SWITCH_METER_MODE_NONE, /**< none */ + SWITCH_METER_MODE_TWO_RATE_THREE_COLOR, /**< two rate, three color */ + SWITCH_METER_MODE_STORM_CONTROL /**< storm control */ } switch_meter_mode_t; /** Meter color mode */ typedef enum switch_meter_color_source_ { - SWITCH_METER_COLOR_SOURCE_NONE, /**< none */ - SWITCH_METER_COLOR_SOURCE_BLIND, /**< color blind */ - SWITCH_METER_COLOR_SOURCE_AWARE /**< color source */ + SWITCH_METER_COLOR_SOURCE_NONE, /**< none */ + SWITCH_METER_COLOR_SOURCE_BLIND, /**< color blind */ + SWITCH_METER_COLOR_SOURCE_AWARE /**< color source */ } switch_meter_color_source_t; /** Meter type */ typedef enum switch_meter_type_ { - SWITCH_METER_TYPE_NONE = 0, - SWITCH_METER_TYPE_PACKETS = 1, - SWITCH_METER_TYPE_BYTES = 2, + SWITCH_METER_TYPE_NONE = 0, + SWITCH_METER_TYPE_PACKETS = 1, + SWITCH_METER_TYPE_BYTES = 2, } switch_meter_type_t; -/** Meter color */ -typedef enum switch_meter_color_ { - SWITCH_METER_COLOR_GREEN, - SWITCH_METER_COLOR_YELLOW, - SWITCH_METER_COLOR_RED, - SWITCH_METER_COLOR_MAX -} switch_meter_color_t; +/** shaper type */ +typedef switch_meter_type_t switch_shaper_type_t; -/** Meter stats */ +/** Meter stat id */ typedef enum switch_meter_stats_ { - SWITCH_METER_STATS_GREEEN, - SWITCH_METER_STATS_YELLOW, - SWITCH_METER_STATS_RED, - SWITCH_METER_STATS_MAX + SWITCH_METER_STATS_GREEEN, + SWITCH_METER_STATS_YELLOW, + SWITCH_METER_STATS_RED, + SWITCH_METER_STATS_MAX } switch_meter_stats_t; /** committed burst size */ @@ -83,15 +78,15 @@ typedef uint64_t switch_cir_t; typedef uint64_t switch_pir_t; /** Meter attributes */ -typedef struct switch_api_meter_{ - switch_meter_mode_t meter_mode; /**< meter mode */ - switch_meter_color_source_t color_source; /**< color source */ - switch_meter_type_t meter_type; /**< meter type */ - switch_cbs_t cbs; /**< committed burst size */ - switch_pbs_t pbs; /**< peak burst size */ - switch_cir_t cir; /**< committed information rate */ - switch_pir_t pir; /**< peak information rate */ - switch_acl_action_t action[SWITCH_METER_COLOR_MAX]; /**< packet action */ +typedef struct switch_api_meter_ { + switch_meter_mode_t meter_mode; /**< meter mode */ + switch_meter_color_source_t color_source; /**< color source */ + switch_meter_type_t meter_type; /**< meter type */ + switch_cbs_t cbs; /**< committed burst size */ + switch_pbs_t pbs; /**< peak burst size */ + switch_cir_t cir; /**< committed information rate */ + switch_pir_t pir; /**< peak information rate */ + switch_acl_action_t action[SWITCH_COLOR_MAX]; /**< packet action */ } switch_api_meter_t; /** @@ -128,14 +123,13 @@ switch_status_t switch_api_meter_delete(switch_device_t device, @param counter_ids meter counter ids @param counters counter values */ -switch_status_t -switch_api_meter_stats_get(switch_device_t device, - switch_handle_t meter_handle, - uint8_t count, - switch_meter_stats_t *counter_ids, - switch_counter_t *counters); - -/** @} */ // end of meter +switch_status_t switch_api_meter_stats_get(switch_device_t device, + switch_handle_t meter_handle, + uint8_t count, + switch_meter_stats_t *counter_ids, + switch_counter_t *counters); + +/** @} */ // end of meter #ifdef __cplusplus } diff --git a/switchapi/include/switchapi/switch_mirror.h b/switchapi/include/switchapi/switch_mirror.h new file mode 100644 index 0000000..d8708b4 --- /dev/null +++ b/switchapi/include/switchapi/switch_mirror.h @@ -0,0 +1,142 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_mirror_h +#define _switch_mirror_h + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_tunnel.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** +* @defgroup Mirror Mirroring API +* API functions to manage mirror sessions +* @{ +*/ +// begin of MIRROR API + +/** Mirror ID */ +typedef unsigned int switch_mirror_id_t; + +/** 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_t; + +/** Mirror Session Info */ +typedef struct switch_api_mirror_info_ { + 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 +*/ +#define SWITCH_CPU_MIRROR_SESSION_ID 250 + +/** + * ID for negative mirror session + */ +#define SWITCH_NEGATIVE_MIRROR_SESSION_ID 1015 + +/** + Create a mirror sesion + @param device device on which to create mirror session + @param api_mirror_info parameters of mirror session +*/ + +switch_handle_t switch_api_mirror_session_create( + switch_device_t device, switch_api_mirror_info_t *api_mirror_info); + +/** + Update a mirror sesion + @param device device on which to create mirror session + @param mirror_handle mirror handle + @param api_mirror_info parameters of mirror session +*/ +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 + @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); + +/** + 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 Mirror API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/include/switchapi/switch_nat.h b/switchapi/include/switchapi/switch_nat.h new file mode 100644 index 0000000..37243f2 --- /dev/null +++ b/switchapi/include/switchapi/switch_nat.h @@ -0,0 +1,101 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// +// switch_nat.h +// switch_api +// +// Created on 7/28/14. +// Copyright (c) 2014 bn. All rights reserved. +// + +#ifndef _switch_nat_h +#define _switch_nat_h + +#include "switch_base_types.h" +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup NAT NAT API + * API function to add and delete nat rewrites + * @{ + */ // begin of NAT API + +// NAT +/** Nat mode */ +typedef enum switch_nat_mode_ { + SWITCH_NAT_MODE_NONE, /**< Nat mode none */ + SWITCH_NAT_MODE_INNER, /**< Nat mode Inner */ + SWITCH_NAT_MODE_OUTER /**< Nat mode outer */ +} switch_nat_mode_t; + +/** Nat rewrite type */ +typedef enum switch_nat_rw_type_ { + SWITCH_NAT_RW_TYPE_SRC, /**< Src IP */ + SWITCH_NAT_RW_TYPE_DST, /**< Dst IP */ + SWITCH_NAT_RW_TYPE_SRC_DST, /**< Src and Dst IP */ + SWITCH_NAT_RW_TYPE_SRC_UDP, /**< Src IP and Udp Port */ + SWITCH_NAT_RW_TYPE_DST_UDP, /**< Dst IP and Udp Port */ + SWITCH_NAT_RW_TYPE_SRC_DST_UDP, /**< Src IP, Dst IP and Udp Port */ + SWITCH_NAT_RW_TYPE_SRC_TCP, /**< Src IP and Tcp Port */ + SWITCH_NAT_RW_TYPE_DST_TCP, /**< Dst IP and Tcp Port */ + SWITCH_NAT_RW_TYPE_SRC_DST_TCP /**< Src Ip, Dst IP and Tcp Port */ +} switch_nat_rw_type_t; + +/** Nat info */ +typedef struct switch_api_nat_info_ { + switch_nat_rw_type_t nat_rw_type; /**< Nat rewrite type */ + switch_ip_addr_t src_ip; /**< Source IP */ + switch_ip_addr_t rw_src_ip; /**< Source IP rewrite */ + switch_ip_addr_t dst_ip; /**< Destination IP */ + switch_ip_addr_t rw_dst_ip; /**< Destination IP rewrite */ + uint16_t src_port; /**< Source Port */ + uint16_t rw_src_port; /**< Source Port rewrite */ + uint16_t dst_port; /**< Destination Port */ + uint16_t rw_dst_port; /**< Destination Port rewrite */ + uint16_t protocol; /**< Protocol */ + + switch_handle_t vrf_handle; /**< Vrf ID */ + switch_handle_t nhop_handle; /**< Nexthop handle */ +} switch_api_nat_info_t; + +/** + Add an entry to NAT table based on the rewrite type + @param device - device + @param api_nat_info - NAT info that contains the rewrite information like + source ip/dest ip, source port/dest port. +*/ +switch_status_t switch_api_nat_add(switch_device_t device, + switch_api_nat_info_t *api_nat_info); + +/** + Delete an entry to NAT table based on the rewrite type + @param device - device + @param api_nat_info - NAT info that contains the rewrite information like + source ip/dest ip, source port/dest port. +*/ +switch_status_t switch_api_nat_delete(switch_device_t device, + switch_api_nat_info_t *api_nat_info); + +/** @} */ // end of NAT API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_neighbor.h b/switchapi/include/switchapi/switch_neighbor.h similarity index 51% rename from switchapi/inc/switchapi/switch_neighbor.h rename to switchapi/include/switchapi/switch_neighbor.h index a4255f8..85a5449 100644 --- a/switchapi/inc/switchapi/switch_neighbor.h +++ b/switchapi/include/switchapi/switch_neighbor.h @@ -26,46 +26,45 @@ limitations under the License. extern "C" { #endif /* __cplusplus */ - /** @defgroup ARP ARP/Neighbor API * API functions to add IP-Mac associations * @{ - */ // begin of ARP API + */ // begin of ARP API // ARP /** ARP information */ /** Neighbor type */ typedef enum switch_neighbor_type_ { - SWITCH_API_NEIGHBOR_NONE = 0, - SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN = 1, - SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN = 2, - SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN = 3, - SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN = 4, - SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN = 5, - SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN = 6, - SWITCH_API_NEIGHBOR_IPV4_TUNNEL = 7, - SWITCH_API_NEIGHBOR_IPV6_TUNNEL = 8, + SWITCH_API_NEIGHBOR_NONE = 0, + SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN = 1, + SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN = 2, + SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN = 3, + SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN = 4, + SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN = 5, + SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN = 6, + SWITCH_API_NEIGHBOR_IPV4_TUNNEL = 7, + SWITCH_API_NEIGHBOR_IPV6_TUNNEL = 8, } switch_neighbor_type_t; /** Neighbor rewrite type */ typedef enum switch_neighbor_rw_type_ { - SWITCH_API_NEIGHBOR_RW_TYPE_L2 = 0, - SWITCH_API_NEIGHBOR_RW_TYPE_L3 = 1, + SWITCH_API_NEIGHBOR_RW_TYPE_L2 = 0, + SWITCH_API_NEIGHBOR_RW_TYPE_L3 = 1, } switch_neighbor_rw_type_t; /** Neighbor identifier */ typedef struct switch_api_neighbor_ { - switch_neighbor_type_t neigh_type; /**< neighbor type */ - switch_neighbor_rw_type_t rw_type; /**< rewrite type */ - switch_handle_t vrf_handle; /**< vrf instance */ - switch_ip_addr_t ip_addr; /**< IP address */ - switch_handle_t nhop_handle; /**< Next hop handle for neighbor */ - switch_handle_t interface; /**< interface on which address is */ - switch_vlan_t vlan; /**< Override VLAN */ - switch_mac_addr_t mac_addr; /**< MAC of destination */ - uint32_t mpls_label; /**< Mpls label for swap and swap-push */ - uint8_t header_count; /**< Header count for swap-push and push */ + switch_neighbor_type_t neigh_type; /**< neighbor type */ + switch_neighbor_rw_type_t rw_type; /**< rewrite type */ + switch_handle_t vrf_handle; /**< vrf instance */ + switch_ip_addr_t ip_addr; /**< IP address */ + switch_handle_t nhop_handle; /**< Next hop handle for neighbor */ + switch_handle_t interface; /**< interface on which address is */ + switch_vlan_t vlan; /**< Override VLAN */ + switch_mac_addr_t mac_addr; /**< MAC of destination */ + uint32_t mpls_label; /**< Mpls label for swap and swap-push */ + uint8_t header_count; /**< Header count for swap-push and push */ } switch_api_neighbor_t; /** @@ -73,7 +72,8 @@ ARP entry add @param device device @param neighbor - ARP information used to set egress table */ -switch_handle_t switch_api_neighbor_entry_add(switch_device_t device, switch_api_neighbor_t *neighbor); +switch_handle_t switch_api_neighbor_entry_add(switch_device_t device, + switch_api_neighbor_t *neighbor); /** ARP entry update @@ -81,23 +81,26 @@ ARP entry update @param neighbor_handle - Neighbor handle @param neighbor - ARP information used to set egress table */ -switch_status_t switch_api_neighbor_entry_update(switch_device_t device, switch_handle_t neighbor_handle, - switch_api_neighbor_t *neighbor); +switch_status_t switch_api_neighbor_entry_update( + switch_device_t device, + switch_handle_t neighbor_handle, + switch_api_neighbor_t *neighbor); /** ARP entry delete @param device device @param neighbor_handle - handle of the arp entry */ -switch_status_t switch_api_neighbor_entry_remove(switch_device_t device, switch_handle_t neighbor_handle); +switch_status_t switch_api_neighbor_entry_remove( + switch_device_t device, switch_handle_t neighbor_handle); /** Dump neighbor table */ switch_status_t switch_api_neighbor_print_all(void); - -/** @} */ // end of ARP API - + +/** @} */ // end of ARP API + #ifdef __cplusplus } #endif diff --git a/switchapi/inc/switchapi/switch_nhop.h b/switchapi/include/switchapi/switch_nhop.h similarity index 60% rename from switchapi/inc/switchapi/switch_nhop.h rename to switchapi/include/switchapi/switch_nhop.h index fdb7dbd..b5252c3 100644 --- a/switchapi/inc/switchapi/switch_nhop.h +++ b/switchapi/include/switchapi/switch_nhop.h @@ -26,16 +26,16 @@ extern "C" { /** Nexthop type */ typedef enum switch_nhop_index_type_ { - SWITCH_NHOP_INDEX_TYPE_NONE, - SWITCH_NHOP_INDEX_TYPE_ONE_PATH, - SWITCH_NHOP_INDEX_TYPE_ECMP + SWITCH_NHOP_INDEX_TYPE_NONE, + SWITCH_NHOP_INDEX_TYPE_ONE_PATH, + SWITCH_NHOP_INDEX_TYPE_ECMP } switch_nhop_index_type_t; /** Nexthop Key */ typedef struct switch_nhop_key_ { - switch_handle_t intf_handle; /**< interface handle */ - switch_ip_addr_t ip_addr; /**< ip address */ - bool ip_addr_valid; /**< ip address valid */ + switch_handle_t intf_handle; /**< interface handle */ + switch_ip_addr_t ip_addr; /**< ip address */ + bool ip_addr_valid; /**< ip address valid */ } switch_nhop_key_t; /** @@ -43,14 +43,36 @@ typedef struct switch_nhop_key_ { @param device - device to program the nexthop @param nhop_key- Interface to be associated with the nexthop and nexthop ip */ -switch_handle_t switch_api_nhop_create(switch_device_t device, switch_nhop_key_t *nhop_key); +switch_handle_t switch_api_nhop_create(switch_device_t device, + switch_nhop_key_t *nhop_key); + +/** + Update a Nexthop + @param device - device to program the nexthop + @param handle - handle of the next hop to update + @param nhop_key - nhop key with new info +*/ +switch_status_t switch_api_nhop_set(switch_device_t device, + switch_handle_t handle, + switch_nhop_key_t *nhop_key); + +/** + Get attributes of a Nexthop + @param device - device to program the nexthop + @param handle - handle of the next hop to get + @param [out]nhop_key - pointer to the attribute obj +*/ +switch_status_t switch_api_nhop_get(switch_device_t device, + switch_handle_t handle, + switch_nhop_key_t **nhop_key); /** Delete a Nexthop @param device device on which to create nhop group @param nhop_handle - Handle that identifies nexthop uniquely */ -switch_status_t switch_api_nhop_delete(switch_device_t device, switch_handle_t nhop_handle); +switch_status_t switch_api_nhop_delete(switch_device_t device, + switch_handle_t nhop_handle); /** Create a ECMP Group @@ -62,7 +84,8 @@ switch_handle_t switch_api_ecmp_create(switch_device_t device); Delete a ECMP Group @param ecmp_handle - Handle that identifies ECMP group uniquely */ -switch_status_t switch_api_ecmp_delete(switch_device_t device, switch_handle_t ecmp_handle); +switch_status_t switch_api_ecmp_delete(switch_device_t device, + switch_handle_t ecmp_handle); /** Add nexthop member to ecmp group @@ -71,8 +94,10 @@ switch_status_t switch_api_ecmp_delete(switch_device_t device, switch_handle_t e @param nhop_count - number of nexthops @param nhop_handle_list - List of nexthops to be added to the ECMP Group */ -switch_status_t switch_api_ecmp_member_add(switch_device_t device, switch_handle_t ecmp_handle, - uint16_t nhop_count, switch_handle_t *nhop_handle_list); +switch_status_t switch_api_ecmp_member_add(switch_device_t device, + switch_handle_t ecmp_handle, + uint16_t nhop_count, + switch_handle_t *nhop_handle_list); /** Delete nexthop member from ecmp group @@ -81,16 +106,21 @@ switch_status_t switch_api_ecmp_member_add(switch_device_t device, switch_handle @param nhop_count - number of nexthops @param nhop_handle_list - List of nexthops to be added to the ECMP Group */ -switch_status_t switch_api_ecmp_member_delete(switch_device_t device, switch_handle_t ecmp_handle, - uint16_t nhop_count, switch_handle_t *nhop_handle_list); +switch_status_t switch_api_ecmp_member_delete( + switch_device_t device, + switch_handle_t ecmp_handle, + uint16_t nhop_count, + switch_handle_t *nhop_handle_list); /* Create ECMP Group along with the members. @param member_count - Number of nexthops @param nhop_handle - List of nexthops to be added to ECMP group */ -switch_handle_t switch_api_ecmp_create_with_members(switch_device_t device, uint32_t member_count, - switch_handle_t *nhop_handle); +switch_handle_t switch_api_ecmp_create_with_members( + switch_device_t device, + uint32_t member_count, + switch_handle_t *nhop_handle); /* Return nexthop handle from (intf_handle, ip address) diff --git a/switchapi/include/switchapi/switch_port.h b/switchapi/include/switchapi/switch_port.h new file mode 100644 index 0000000..2d1c776 --- /dev/null +++ b/switchapi/include/switchapi/switch_port.h @@ -0,0 +1,509 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_port_h_ +#define _switch_port_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_vlan.h" +#include "switch_meter.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup Port Port configuration API + * API functions listed to configure the ports. Mostly + * related to MAC programming + The basic configuration on the port dictates the MAC programming. + The modes can be set to one of 1x100G, 2x50G, 4x25G, 2x40G or 4x10G. + The ports can be configured with an administrative mode and default behavior can be set. + The tables that get modified in response to the port APIs are mostly the early stage tables. + The port can have a default, which generally allows tagging of untagged packets to this default + domain for forwarding the packets through the device. + * @{ + */ // begin of Port + +/** Maximum number of port priority groups */ +#define SWITCH_MAX_PPG 32 + +/** Port information */ +typedef struct switch_api_port_info_ { + uint16_t port_number; /**< FP port number */ + bool phy_detected; /**< whether phy is present */ + unsigned int ifg; /**<. inter frame gap in cycles */ + unsigned int l3mtu; /**< L3 MTU */ + unsigned int l2mtu; /**< Max frame size */ + bool learn_enable; /**< enable learning on port */ + bool bpdu_enable; /**< allow bpdu even when port is in block state */ + unsigned int egress_rate; /**< Max rate on egress */ + bool tunnel_term; /**< Permit tunnel termination */ + bool ipv4_term; /**< Permit IPv4 termination */ + bool ipv6_term; /**< Permit IPv6 termination */ + bool igmp_snoop; /**< Enable IGMP snopping */ + uint8_t urpf_mode; /**< None/Loose/Strict */ +} switch_api_port_info_t; + +/** port speed */ +typedef enum { + SWITCH_API_PORT_SPEED_NONE, /**< Port Speed Not set */ + SWITCH_API_PORT_SPEED_1G, /**< port speed 1G */ + SWITCH_API_PORT_SPEED_10G, /**< port speed 10G */ + SWITCH_API_PORT_SPEED_25G, /**< port speed 25G */ + SWITCH_API_PORT_SPEED_40G, /**< port speed 40G */ + SWITCH_API_PORT_SPEED_50G, /**< port speed 50G */ + SWITCH_API_PORT_SPEED_100G /**< port speed 100G */ +} switch_port_speed_t; + +/** port flowcontrol type */ +typedef enum switch_flowcontrol_type_ { + SWITCH_FLOWCONTROL_TYPE_NONE = 0, + SWITCH_FLOWCONTROL_TYPE_PFC = 1, + SWITCH_FLOWCONTROL_TYPE_PAUSE = 2 +} switch_flowcontrol_type_t; + +/** + * Probe for existing ports - configuration based on current status + * or default (when called immediately after init with default + * config + @param device device to use + @param max_count maximum number of ports to return + @param count actual count returned + @param port_info array of port_info structures per port + */ +switch_status_t switch_api_port_probe(switch_device_t device, + unsigned int max_count, + unsigned int *count, + switch_api_port_info_t *port_info); + +/** + Port Enable Set- Enabled the port on a device + @param device device to use + @param port port on device to set + @param enable TRUE => port is enabled FALSE => Port is disabled +*/ +switch_status_t switch_api_port_enable_set(switch_device_t device, + switch_port_t port, + bool enable); + +/** + Port Enable Get - Get the Port Enabled state + @param device device to use + @param port port on device to get information + @param enable TRUE => port is enabled FALSE => Port is disabled +*/ +switch_status_t switch_api_port_enable_get(switch_device_t device, + switch_port_t port, + bool *enable); + +/** + Port Speed Set + @param device device to use + @param port port on device to set + @param speed desired speed of port +*/ +switch_status_t switch_api_port_speed_set(switch_device_t device, + switch_port_t port, + switch_port_speed_t speed); + +/** +Port Speed Get +@param device device to use +@param port port on device to get +@param speed actual speed of port +*/ +switch_status_t switch_api_port_speed_get(switch_device_t device, + switch_port_t port, + switch_port_speed_t *speed); + +/** + Port Autonegotiation Set + @param device device to use + @param port port on device to set + @param enable Enable Autonegotiation if TRUE else disable +*/ +switch_status_t switch_api_port_autoneg_set(switch_device_t device, + switch_port_t port, + bool enable); +/** +Port Autonegotiation get +@param device device to use +@param port port on device to get +@param enable returns TRUE if Autonegotiation is set else FALSE +*/ +switch_status_t switch_api_port_autoneg_get(switch_device_t device, + switch_port_t port, + bool *enable); + +/** Port Pause message information */ +typedef struct switch_port_pause_info_ { + bool rx; /**< rx ignore PAUSE FALSE => disable PAUSE */ + bool tx; /**< tx send PAUSE frames when needed */ + switch_mac_addr_t mac; /**< MAC addr to use when sending pause frames */ + bool symmetric; /**< Symmetric or Asymmetric mode */ + unsigned int quanta; /**< time in ms after which to stop sending pause */ +} switch_port_pause_info_t; + +/** + Port operational state + @param device device to use + @param port port on device to get + @param up port state +*/ +switch_status_t switch_api_port_state_get(switch_device_t device, + switch_port_t port, + bool *up); + +/** + Port operational state declaration interval + @param device device to use + @param port port on device to get + @param interval microseconds to debounce +*/ +switch_status_t switch_api_port_debounce_set(switch_device_t device, + switch_port_t port, + unsigned int interval); + +/** + Port set MAC in loopback + @param device device to use + @param port port on device to set + @param enable loopback enabled if TRUE else FALSE +*/ +switch_status_t switch_api_port_mac_loopback_set(switch_device_t device, + switch_port_t port, + bool enable); + +/** + Port get MAC loopback config + @param device device to use + @param port port on device to get + @param enable TRUE if loopback is enabled else FALSE +*/ +switch_status_t switch_api_port_mac_loopback_get(switch_device_t device, + switch_port_t port, + bool *enable); + +/** + Port L2 MTU settings + @param device device to use + @param port port on device to set + @param l2mtu Max frame size on port +*/ +switch_status_t switch_api_port_mtu_set(switch_device_t device, + switch_port_t port, + unsigned int l2mtu); + +/** + Port L3 MTU settings + @param device device to use + @param port port on device to set + @param l3mtu IP MTU on port +*/ +switch_status_t switch_api_port_l3_mtu_set(switch_device_t device, + switch_port_t port, + unsigned int l3mtu); + +/** + Port MTU settings get + @param device device to use + @param port port on device to get + @param l2mtu maximum frame size (rx and tx) + @param l3mtu IP MTU on port +*/ +switch_status_t switch_api_port_l3_mtu_get(switch_device_t device, + switch_port_t port, + unsigned int *l2mtu, + unsigned int *l3mtu); + +/** + Port egress rate set + @param device device to use + @param port port on device to set + @param rate rate in kbps +*/ +switch_status_t switch_api_port_egress_rate_set(switch_device_t device, + switch_port_t port, + unsigned int rate); + +/** + Set Port configuration + @param device device to use + @param api_port_info port information inclduing port number + (portnumber specified in port_info->port_number) +*/ +switch_status_t switch_api_port_set(switch_device_t device, + switch_api_port_info_t *api_port_info); + +/** + Get Port configuration + @param device device to use + @param api_port_info port information inclduing port number + (portnumber specified in port_info->port_number) +*/ +switch_status_t switch_api_port_get(switch_device_t device, + switch_api_port_info_t *api_port_info); + +/** + Set meter handle for port + @param device device to use + @param port port on device + @param pkt_type packet type + @param meter_handle meter handle + */ +switch_status_t switch_api_port_storm_control_set(switch_device_t device, + switch_port_t port, + switch_packet_type_t pkt_type, + switch_handle_t meter_handle); + +/** + Get meter handle for port + @param device device to use + @param port port on device + @param pkt_type packet type + @param meter_handle meter handle + */ +switch_status_t switch_api_port_storm_control_get( + switch_device_t device, + switch_port_t port, + switch_packet_type_t pkt_type, + switch_handle_t *meter_handle); +/** + Meter stats + @param device device + @param meter_handle meter handle + @param count number of counters + @param counter_ids meter counter ids + @param counters counter values + */ +switch_status_t switch_api_storm_control_stats_get( + switch_device_t device, + switch_handle_t meter_handle, + uint8_t count, + switch_meter_stats_t *counter_ids, + switch_counter_t *counters); + +/** + Get port priority groups + @param device device + @param port_handle port handle + @param num_ppgs number of ppgs + @param ppg_handles list of ppg handles +*/ +switch_status_t switch_api_ppg_get(switch_device_t device, + switch_handle_t port_handle, + uint8_t *num_ppgs, + switch_handle_t *ppg_handles); + +/** + port drop limit set + @param device device + @param port_handle port handle + @param num_bytes number of bytes +*/ +switch_status_t switch_api_port_drop_limit_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes); + +/** + port drop hysteresis set + @param device device + @param port_handle port handle + @param num_bytes number of bytes +*/ +switch_status_t switch_api_port_drop_hysteresis_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes); + +/** + Set port to cos mapping in ingress + @param device device + @param port_handle port handle + @param ppg_handle priority group handle + @param cos_bitmap cos bitmap +*/ +switch_status_t switch_api_port_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t ppg_handle, + uint8_t cos_bitmap); + +/** + Set port cos and pfc cos mapping + @param device device + @param port_handle port handle + @param cos_to_icos cos to ingress cos bitmap +*/ +switch_status_t switch_api_port_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + uint8_t *cos_to_icos); + +/** + Enable port shaping + @param device device + @param port_handle port handle + @param shaper_type shaper type in bytes or packets + @param burst_size burst size + @param rate rate +*/ +switch_status_t switch_api_port_shaping_enable(switch_device_t device, + switch_handle_t port_handle, + switch_shaper_type_t shaper_type, + uint32_t burst_size, + uint32_t rate); + +/** + Disable port shaping + @param device device + @param port_handle port handle +*/ +switch_status_t switch_api_port_shaping_disable(switch_device_t device, + switch_handle_t port_handle); + +/** + enable dscp trust on port + @param device device + @param port_handle port handle + @param trust_dscp dscp trust +*/ +switch_status_t switch_api_port_trust_dscp_set(switch_device_t device, + switch_handle_t port_handle, + bool trust_dscp); + +/** + enable pcp trust on port + @param device device + @param port_handle port handle + @param trust_pcp pcp trust +*/ +switch_status_t switch_api_port_trust_pcp_set(switch_device_t device, + switch_handle_t port_handle, + bool trust_pcp); + +/** + enable lossless mode in port priority group + @param device device + @param ppg_handle ppg handle + @param enable enable +*/ +switch_status_t switch_api_ppg_lossless_enable(switch_device_t device, + switch_handle_t ppg_handle, + bool enable); + +/** + set guaranteed limit on ppg + @param device device + @param ppg_handle ppg handle + @param num_bytes number of bytes +*/ +switch_status_t switch_api_ppg_guaranteed_limit_set(switch_device_t device, + switch_handle_t ppg_handle, + uint32_t num_bytes); + +/** + set skid lmit on ppg + @param device device + @param ppg_handle ppg handle + @param num_bytes number of bytes +*/ +switch_status_t switch_api_ppg_skid_limit_set(switch_device_t device, + switch_handle_t ppg_handle, + uint32_t num_bytes); + +/** + set hystersis lmit on ppg + @param device device + @param ppg_handle ppg handle + @param num_bytes number of bytes +*/ +switch_status_t switch_api_ppg_skid_hysteresis_set(switch_device_t device, + switch_handle_t ppg_handle, + uint32_t num_bytes); + +/** + set ingress qos group on port + @param device device + @param port_handle port handle + @param qos_group qos group +*/ +switch_status_t switch_api_port_qos_group_ingress_set( + switch_device_t device, + switch_handle_t port_handle, + switch_handle_t qos_group); + +/** + set tc qos group on port + @param device device + @param port_handle port handle + @param qos_group qos group +*/ +switch_status_t switch_api_port_qos_group_tc_set(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t qos_group); + +/** + set egress qos group on port + @param device device + @param port_handle port handle + @param qos_group qos group +*/ +switch_status_t switch_api_port_qos_group_egress_set( + switch_device_t device, + switch_handle_t port_handle, + switch_handle_t qos_group); + +/** + set default tc on port + @param device device + @param port_handle port handle + @param tc traffic class +*/ +switch_status_t switch_api_port_tc_default_set(switch_device_t device, + switch_handle_t port_handle, + uint16_t tc); + +/** + set default color on port + @param device device + @param port_handle port handle + @param color packet color +*/ +switch_status_t switch_api_port_color_default_set(switch_device_t device, + switch_handle_t port_handle, + switch_color_t color); + +/** + set port flowcontrol mode + @param device device + @param port_handle port handle + @param flow_control flow control type +*/ +switch_status_t switch_api_port_flowcontrol_mode_set( + switch_device_t device, + switch_handle_t port_handle, + switch_flowcontrol_type_t flow_control); +/** + Dump port table + */ +switch_status_t switch_api_port_print_all(void); + +/** @} */ // end of Port + +#ifdef __cplusplus +} +#endif + +#endif /* defined(_switch_port_h_) */ diff --git a/switchapi/include/switchapi/switch_porting.h b/switchapi/include/switchapi/switch_porting.h new file mode 100644 index 0000000..0af0a95 --- /dev/null +++ b/switchapi/include/switchapi/switch_porting.h @@ -0,0 +1,121 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/**************************************************************************/ /** + * + * @file + * @brief Switch Porting Macros. + * + * @addtogroup switch-porting + * @{ + * + *****************************************************************************/ +#ifndef __SWITCH_PORTING_H__ +#define __SWITCH_PORTING_H__ + +/* */ +#if SWITCH_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1 +#include +#include +#include +#include +#include +#endif + +#ifndef SWITCH_MALLOC +#if defined(GLOBAL_MALLOC) +#define SWITCH_MALLOC GLOBAL_MALLOC +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_MALLOC malloc +#else +#error The macro SWITCH_MALLOC is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_FREE +#if defined(GLOBAL_FREE) +#define SWITCH_FREE GLOBAL_FREE +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_FREE free +#else +#error The macro SWITCH_FREE is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_MEMSET +#if defined(GLOBAL_MEMSET) +#define SWITCH_MEMSET GLOBAL_MEMSET +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_MEMSET memset +#else +#error The macro SWITCH_MEMSET is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_MEMCPY +#if defined(GLOBAL_MEMCPY) +#define SWITCH_MEMCPY GLOBAL_MEMCPY +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_MEMCPY memcpy +#else +#error The macro SWITCH_MEMCPY is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_STRNCPY +#if defined(GLOBAL_STRNCPY) +#define SWITCH_STRNCPY GLOBAL_STRNCPY +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_STRNCPY strncpy +#else +#error The macro SWITCH_STRNCPY is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_VSNPRINTF +#if defined(GLOBAL_VSNPRINTF) +#define SWITCH_VSNPRINTF GLOBAL_VSNPRINTF +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_VSNPRINTF vsnprintf +#else +#error The macro SWITCH_VSNPRINTF is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_SNPRINTF +#if defined(GLOBAL_SNPRINTF) +#define SWITCH_SNPRINTF GLOBAL_SNPRINTF +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_SNPRINTF snprintf +#else +#error The macro SWITCH_SNPRINTF is required but cannot be defined. +#endif +#endif + +#ifndef SWITCH_STRLEN +#if defined(GLOBAL_STRLEN) +#define SWITCH_STRLEN GLOBAL_STRLEN +#elif SWITCH_CONFIG_PORTING_STDLIB == 1 +#define SWITCH_STRLEN strlen +#else +#error The macro SWITCH_STRLEN is required but cannot be defined. +#endif +#endif + +/* */ + +#endif /* __SWITCH_PORTING_H__ */ +/* @} */ diff --git a/switchapi/include/switchapi/switch_protocol.h b/switchapi/include/switchapi/switch_protocol.h new file mode 100644 index 0000000..5ebae08 --- /dev/null +++ b/switchapi/include/switchapi/switch_protocol.h @@ -0,0 +1,216 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_protocol_h +#define _switch_protocol_h + +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup Protocol Protocol types and info + * Protocol types and info + * @{ + */ // begin of Protocol API + +/** Encap type */ +typedef enum switch_encap_type_ { + SWITCH_API_ENCAP_TYPE_NONE = 0, /**< Not a tunnel */ + SWITCH_API_ENCAP_TYPE_VLAN = 1, /**< VLAN encapsulation */ + SWITCH_API_ENCAP_TYPE_QINQ = 2, /**< Double Tag encap */ + SWITCH_API_ENCAP_TYPE_VXLAN = 3, /**< VxLAN encapsulation */ + 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_IPIP = 8, /**< IP in IP encapsulation */ +} switch_encap_type_t; + +/** UDP fields that are relevant */ +typedef struct switch_udp_ { + uint16_t src_port; /**< Source port number */ + uint16_t dst_port; /**< Destination port number */ +} switch_udp_t; + +/** TCP fields that are relevant */ +typedef struct switch_tcp_ { + uint16_t src_port; /**< Source port number */ + uint16_t dst_port; /**< Destination port number */ +} switch_tcp_t; + +/** QinQ encapsulation format */ +typedef struct { + switch_vlan_t outer; /**< outer tag */ + switch_vlan_t inner; /**< Inner tag */ +} switch_qinq_t; + +/** VxLAN identifier */ +typedef struct { + unsigned int vnid : 24; /**< Unique value for a tenant */ + unsigned int rsvd : 8; /**< unused - should be 0 */ +} switch_vxlan_id_t; + +/** NvGRE identifier */ +typedef struct { + unsigned int tnid : 24; /**< Unique value for a tenant */ + unsigned int rsvd : 8; /**< unused - should be 0 */ +} switch_nvgre_id_t; + +/** Geneve identifier */ +typedef struct { + unsigned int version : 2, /**< version - set to 0 */ + option_length : 6, /**< option length */ + oam : 1, /**< OAM Pkt */ + critical : 1, /**< Critical */ + rsvd : 6, /**< reserved data should be 0 */ + prototype : 16; /**< ether type */ + unsigned int vni : 24, /**< Tenant ID */ + rsvd2 : 8; /**< reserved should be 0 */ +} switch_geneve_id_t; + +/** Gre identifier */ +typedef struct { + unsigned short csum_present : 1, /**< Checksum present? */ + routing_present : 1, /**< Routing info present? */ + key_present : 1, /**< Key present? */ + sequence_present : 1, /**< Sequence present? */ + strict_route : 1, /**< strict route? */ + recursion_control : 1, /**< recursion control */ + flags : 5, /**< flags */ + version : 3; /**< version */ + unsigned short protocol; /**< ether type */ + unsigned short checksum; /**< checksum of packet (opt) */ + unsigned short offset; /**< offset in packet */ + unsigned int key; /**< GRE key */ + unsigned int sequence; /**< sequence number */ + unsigned int routing; /**< Routing information */ +} switch_gre_t; + +/** IP Header information relevant */ +typedef struct switch_ip_encap_ { + switch_handle_t vrf_handle; /**< VRF instance */ + switch_ip_addr_t src_ip; /**< Source IP address of tunnel */ + switch_ip_addr_t dst_ip; /**< Destination IP of tunnel */ + unsigned short mtu; /**< IP MTU supported */ + unsigned char ttl; /**< Time to live */ + unsigned char proto; /**< UDP/TCP/GRE */ + union { + switch_udp_t udp; /**< UDP header */ + switch_tcp_t tcp; /**< TCP header */ + switch_gre_t gre; /**< IP GRE header */ + } u; /**< union */ +} switch_ip_encap_t; + +/** Maximum mpls labels supported */ +#define SWITCH_MPLS_LABEL_MAX 5 + +/** Mpls header */ +typedef struct switch_mpls_ { + unsigned int label : 20; /**< mpls label */ + unsigned int exp : 3; /**< experimental */ + unsigned int bos : 1; /**< bottom of stack */ + unsigned int ttl : 8; /**< time to live */ +} switch_mpls_t; + +/** Mpls tunnel type */ +typedef enum switch_mpls_type_ { + SWITCH_API_MPLS_TYPE_EOMPLS, + SWITCH_API_MPLS_TYPE_IPV4_MPLS, + SWITCH_API_MPLS_TYPE_IPV6_MPLS, + SWITCH_API_MPLS_TYPE_VPLS, + SWITCH_API_MPLS_TYPE_PW +} switch_mpls_type_t; + +/** Mpls mode */ +typedef enum switch_mpls_mode_ { + SWITCH_API_MPLS_INITIATE, + SWITCH_API_MPLS_TRANSIT, + SWITCH_API_MPLS_TERMINATE +} switch_mpls_mode_t; + +/** Mpls action */ +typedef enum switch_mpls_action_ { + SWITCH_API_MPLS_ACTION_POP, + SWITCH_API_MPLS_ACTION_PUSH, + SWITCH_API_MPLS_ACTION_SWAP, + SWITCH_API_MPLS_ACTION_SWAP_PUSH +} switch_mpls_action_t; + +/** Mpls swap identifier */ +typedef struct switch_mpls_swap_ { + switch_mpls_t old_tag; /**< old mpls header */ + switch_mpls_t new_tag; /**< new mpls header */ +} switch_mpls_swap_t; + +/** Mpls pop identifier */ +typedef struct switch_mpls_pop_ { + switch_mpls_t tag[SWITCH_MPLS_LABEL_MAX]; /**< mpls header stack to pop */ + uint8_t count; /**< number of label stack to pop */ +} switch_mpls_pop_t; + +/** Mpls push identifier */ +typedef struct switch_mpls_push_ { + switch_mpls_t tag[SWITCH_MPLS_LABEL_MAX]; /**< mpls header stack to push */ + uint8_t count; /**< number of label stack to push */ +} switch_mpls_push_t; + +/** Mpls swap identifier */ +typedef struct switch_mpls_swap_push_ { + switch_mpls_t old_tag; /**< old mpls header */ + switch_mpls_t + new_tag[SWITCH_MPLS_LABEL_MAX]; /**< new mpls header stack to push */ + uint8_t count; /**< number of label stack to push */ +} switch_mpls_swap_push_t; + +/** Mpls encap identifer */ +typedef struct switch_mpls_encap_ { + switch_mpls_type_t mpls_type; /**< mpls tunnel type */ + switch_mpls_action_t mpls_action; /**< mpls action - push/pop/swap */ + switch_mpls_mode_t mpls_mode; /**< mpls mode */ + union { + switch_mpls_swap_t swap_info; /**< mpls swap info */ + switch_mpls_push_t push_info; /**< mpls push info */ + switch_mpls_pop_t pop_info; /**< mpls pop info */ + switch_mpls_swap_push_t swap_push_info; /**< mpls swap push info */ + } u; /**< union */ + switch_handle_t bd_handle; /**< bridge domain handle */ + switch_handle_t vrf_handle; /**< vrf handle */ + switch_handle_t nhop_handle; /**< nexthop handle */ + switch_handle_t egress_if; /**< egress interface handle */ +} switch_mpls_encap_t; + +/** Tunnel encap identifier */ +typedef struct switch_encap_info_ { + switch_encap_type_t encap_type; /**< Encap type */ + union { + switch_vlan_t vlan_id; /**< VLAN Id*/ + switch_vxlan_id_t vxlan_info; /**< VxLAN domain info */ + switch_geneve_id_t geneve_info; /**< Geneve domain info */ + switch_nvgre_id_t nvgre_info; /**< NVGRE domain info */ + switch_qinq_t qinq_info; /**< Qinq info */ + uint32_t tunnel_vni; /**< Tunnel Vni - Used only in LN Basic mode */ + } u; /**< union */ +} switch_encap_info_t; + +/** @} */ // end of Protocol + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/include/switchapi/switch_qos.h b/switchapi/include/switchapi/switch_qos.h new file mode 100644 index 0000000..7117d65 --- /dev/null +++ b/switchapi/include/switchapi/switch_qos.h @@ -0,0 +1,130 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_qos_h_ +#define _switch_qos_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_meter.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup QOS QOS API + * API functions to create buffers and qos maps + * @{ + */ // begin of QOS API + +// QOS +/** QOS information */ + +/** qos map ingress type */ +typedef enum switch_qos_map_ingress_ { + SWITCH_QOS_MAP_INGRESS_NONE = 0, + SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC = 1, + SWITCH_QOS_MAP_INGRESS_PCP_TO_TC = 2, + SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR = 3, + SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR = 4, + SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC_AND_COLOR = 5, + SWITCH_QOS_MAP_INGRESS_PCP_TO_TC_AND_COLOR = 6, + SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS = 7, + SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE = 8, + SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS_AND_QUEUE = 9 +} switch_qos_map_ingress_t; + +/** qos map egress type */ +typedef enum switch_qos_map_egress_ { + SWITCH_QOS_MAP_EGRESS_NONE = 0, + SWITCH_QOS_MAP_EGRESS_TC_TO_DSCP = 1, + SWITCH_QOS_MAP_EGRESS_TC_TO_PCP = 2, + SWITCH_QOS_MAP_EGRESS_COLOR_TO_DSCP = 3, + SWITCH_QOS_MAP_EGRESS_COLOR_TO_PCP = 4, + SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_DSCP = 5, + SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_PCP = 6 +} switch_qos_map_egress_t; + +/** switch qos map struct */ +typedef struct switch_qos_map_ { + uint8_t dscp; /**< dscp */ + uint8_t pcp; /**< pcp */ + uint16_t tc; /**< traffic class */ + switch_color_t color; /**< packet color */ + uint8_t icos; /**< ingress cos */ + uint8_t qid; /**< queue id */ +} switch_qos_map_t; + +/** + Create ingress qos map + @param device device + @param map_type qos map type + @param num_entries number of qos map entries + @param qos_map QOS map +*/ +switch_handle_t switch_api_qos_map_ingress_create( + switch_device_t device, + switch_qos_map_ingress_t map_type, + uint8_t num_entries, + switch_qos_map_t *qos_map); + +/** + Delete ingress qos map + @param device device + @param qos_map_handle Qos map handle +*/ +switch_status_t switch_api_qos_map_ingress_delete( + switch_device_t device, switch_handle_t qos_map_handle); + +/** + Create egress qos map + @param device device + @param map_type qos map type + @param num_entries number of qos map entries + @param qos_map QOS map +*/ +switch_handle_t switch_api_qos_map_egress_create( + switch_device_t device, + switch_qos_map_egress_t map_type, + uint8_t num_entries, + switch_qos_map_t *qos_map); + +/** + Delete ingress qos map + @param device device + @param qos_map_handle Qos map handle +*/ +switch_status_t switch_api_qos_map_egress_delete( + switch_device_t device, switch_handle_t qos_map_handle); + +/** + Update qos map + @param device device + @param num_entries number of qos map entries + @param qos_map_handle Qos map handle + @param qos_map QOS map +*/ +switch_status_t switch_api_qos_map_update(switch_device_t device, + switch_handle_t qos_map_handle, + uint8_t num_entries, + switch_qos_map_t *qos_map); + +/** @} */ // end of QOS API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/include/switchapi/switch_queue.h b/switchapi/include/switchapi/switch_queue.h new file mode 100644 index 0000000..5cb95ba --- /dev/null +++ b/switchapi/include/switchapi/switch_queue.h @@ -0,0 +1,131 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_queue_h_ +#define _switch_queue_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup QUEUE QUEUE API + * API functions to allocate queues + * @{ + */ // begin of QUEUE API + +// QUEUE +/** QUEUE information */ + +/** max number of queues */ +#define SWITCH_MAX_QUEUE 32 + +/** + Allocate egress queue for port + NOTE: Maps to bf_tm_set_port_q_mapping + @param device device + @param port_handle port handle + @param num_queues number of queues + @param queue_handles list of queue handles +*/ +switch_status_t switch_api_queue_allocate(switch_device_t device, + switch_handle_t port_handle, + uint32_t *num_queues, + switch_handle_t *queue_handles); + +/** + Deallocate egress queue for port + @param device device + @param num_queues number of queues + @param queue_handle list of queue handles +*/ +switch_status_t switch_api_queue_deallocate(switch_device_t device, + uint32_t num_queues, + switch_handle_t *queue_handle); + +/** + Get port queues + @param device device + @param port_handle port handle + @param num_queues number of queues + @param queue_handles list of queue handles +*/ +switch_status_t switch_api_queues_get(switch_device_t device, + switch_handle_t port_handle, + uint32_t *num_queues, + switch_handle_t *queue_handles); + +/** + enable color on queue + @param device device + @param port_handle port handle + @param queue_handle queue_handle + @param enable enable +*/ +switch_status_t switch_api_queue_color_drop_enable(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + bool enable); + +/** + set color limit on queue + @param device device + @param port_handle port handle + @param queue_handle queue handle + @param color packet color + @param limit color limit +*/ +switch_status_t switch_api_queue_color_limit_set(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + switch_color_t color, + uint32_t limit); + +/** + set queue color hysteresis + @param device device + @param port_handle port handle + @param queue_handle queue handle + @param color packet color + @param limit color limit +*/ +switch_status_t switch_api_queue_color_hysteresis_set( + switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + switch_color_t color, + uint32_t limit); + +/** + set queue pfc cos mapping + @param device device + @param port_handle port handle + @param queue_handle queue handle + @param cos cos bitmap +*/ +switch_status_t switch_api_queue_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + uint8_t cos); + +/** @} */ // end of QUEUE API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_rmac.h b/switchapi/include/switchapi/switch_rmac.h similarity index 76% rename from switchapi/inc/switchapi/switch_rmac.h rename to switchapi/include/switchapi/switch_rmac.h index dd612aa..0504409 100644 --- a/switchapi/inc/switchapi/switch_rmac.h +++ b/switchapi/include/switchapi/switch_rmac.h @@ -26,7 +26,7 @@ extern "C" { /** @defgroup RMAC Router MAC API * API functions define and manipulate router mac groups * @{ - */ // begin of Router MAC API + */ // begin of Router MAC API /** Create a router mac group @@ -42,7 +42,8 @@ switch_handle_t switch_api_router_mac_group_create(switch_device_t device); @param device Device to be programmed @param rmac_handle - Rmac group to be deleted. */ -switch_status_t switch_api_router_mac_group_delete(switch_device_t device, switch_handle_t rmac_handle); +switch_status_t switch_api_router_mac_group_delete(switch_device_t device, + switch_handle_t rmac_handle); /** Add a mac to router mac group @@ -50,7 +51,9 @@ switch_status_t switch_api_router_mac_group_delete(switch_device_t device, switc @param rmac_handle - ID of the RMAC group @param mac - Router mac address to be added to the group */ -switch_status_t switch_api_router_mac_add(switch_device_t device, switch_handle_t rmac_handle, switch_mac_addr_t *mac); +switch_status_t switch_api_router_mac_add(switch_device_t device, + switch_handle_t rmac_handle, + switch_mac_addr_t *mac); /** Delete a mac from router mac group @@ -58,28 +61,32 @@ switch_status_t switch_api_router_mac_add(switch_device_t device, switch_handle_ @param rmac_handle - ID of the RMAC group @param mac - Router mac address to be removed from the group */ -switch_status_t switch_api_router_mac_delete(switch_device_t device, switch_handle_t rmac_handle, switch_mac_addr_t *mac); +switch_status_t switch_api_router_mac_delete(switch_device_t device, + switch_handle_t rmac_handle, + switch_mac_addr_t *mac); /** Set router mac handle for L3 Interface @param intf_handle - Interface handle @param value - Value of router mac handle */ -switch_status_t switch_api_interface_router_mac_handle_set(switch_handle_t intf_handle, uint64_t value); +switch_status_t switch_api_interface_router_mac_handle_set( + switch_handle_t intf_handle, uint64_t value); /** Set router mac handle for L3 Interface @param intf_handle - Interface handle @param value - Value of router mac handle */ -switch_status_t switch_api_interface_router_mac_handle_get(switch_handle_t intf_handle, uint64_t *value); +switch_status_t switch_api_interface_router_mac_handle_get( + switch_handle_t intf_handle, uint64_t *value); /** Dump router mac group table */ switch_status_t switch_api_router_mac_group_print_all(void); -/** @} */ // end of Router MAC API +/** @} */ // end of Router MAC API #ifdef __cplusplus } #endif diff --git a/switchapi/include/switchapi/switch_scheduler.h b/switchapi/include/switchapi/switch_scheduler.h new file mode 100644 index 0000000..fe15938 --- /dev/null +++ b/switchapi/include/switchapi/switch_scheduler.h @@ -0,0 +1,159 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_scheduler_h_ +#define _switch_scheduler_h_ + +#include "switch_base_types.h" +#include "switch_handle.h" +#include "switch_meter.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup Scheduler Scheduler API + * API functions to create Scheduler + * @{ + */ // begin of Scheduler API + +// Scheduler +/** Scheduler information */ + +/** scheduler type */ +typedef enum switch_scheduler_type_ { + SWITCH_SCHEDULER_MODE_STRICT = 1, + SWITCH_SCHEDULER_MODE_DWRR = 2, + SWITCH_SCHEDULER_MODE_STRICT_AND_DWRR = 3 +} switch_scheduler_type_t; + +/** scheduler struct */ +typedef struct switch_scheduler_info_ { + switch_scheduler_type_t scheduler_type; /**< scheduler type */ + switch_shaper_type_t shaper_type; /**< shaper type */ + switch_handle_t queue_handle; /**< queue handle */ + uint32_t priority; /**< priority */ + uint32_t rem_bw_priority; /**< remaining bandwidth priority */ + uint16_t weight; /**< weight */ + uint32_t min_burst_size; /**< minimum burst size */ + uint32_t min_rate; /**< minimum rate */ + uint32_t max_burst_size; /**< maximum burst size */ + uint32_t max_rate; /**< maximum rate */ +} switch_scheduler_info_t; + +/** + Create a scheduler + @param device device + @param scheduler_info scheduler info +*/ +switch_handle_t switch_api_scheduler_create( + switch_device_t device, switch_scheduler_info_t *scheduler_info); + +/** + Update a scheduler + @param device device + @param scheduler_handle scheduler handle + @param scheduler_info scheduler info +*/ +switch_status_t switch_api_scheduler_update( + switch_device_t device, + switch_handle_t scheduler_handle, + switch_scheduler_info_t *scheduler_info); + +/** + Delete a scheduler + @param device device + @param scheduler_handle scheduler handle +*/ +switch_status_t switch_api_scheduler_delete(switch_device_t device, + switch_handle_t scheduler_handle); + +/** + enable scheduling in queue + @param device device + @param scheduler_handle scheduler handle + @param enable enable +*/ +switch_status_t switch_api_queue_scheduling_enable( + switch_device_t device, switch_handle_t scheduler_handle, bool enable); + +/** + set the priority of queue scheduler + @param device device + @param scheduler_handle scheduler handle + @param priority priority +*/ +switch_status_t switch_api_queue_scheduling_strict_priority_set( + switch_device_t device, + switch_handle_t scheduler_handle, + uint32_t priority); + +/** + set the priority of queue scheduler + @param device device + @param scheduler_handle scheduler handle + @param priority priority +*/ +switch_status_t switch_api_queue_scheduling_remaining_bw_priority_set( + switch_device_t device, + switch_handle_t scheduler_handle, + uint32_t priority); + +/** + set the weight of queue scheduler + @param device device + @param scheduler_handle scheduler handle + @param weight weight +*/ +switch_status_t switch_api_queue_scheduling_dwrr_weight_set( + switch_device_t device, switch_handle_t scheduler_handle, uint16_t weight); + +/** + configure queue scheduler + @param device device + @param scheduler_handle scheduler handle + @param pps packet per second + @param burst_size burst size + @param rate rate +*/ +switch_status_t switch_api_queue_scheduling_guaranteed_shaping_set( + switch_device_t device, + switch_handle_t scheduler_handle, + bool pps, + uint32_t burst_size, + uint32_t rate); + +/** + configure queue remaining bandwidth scheduler + @param device device + @param scheduler_handle scheduler handle + @param pps packet per second + @param burst_size burst size + @param rate rate +*/ +switch_status_t switch_api_queue_scheduling_dwrr_shaping_set( + switch_device_t device, + switch_handle_t scheduler_handle, + bool pps, + uint32_t burst_size, + uint32_t rate); + +/** @} */ // end of Scheduler API + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/include/switchapi/switch_sflow.h b/switchapi/include/switchapi/switch_sflow.h new file mode 100644 index 0000000..890feec --- /dev/null +++ b/switchapi/include/switchapi/switch_sflow.h @@ -0,0 +1,141 @@ +/* + * Copyright 2015-present Barefoot Networks, Inc. + */ + +#ifndef _switch_sflow_h +#define _switch_sflow_h + +#include "switch_base_types.h" +#include "switch_handle.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** Maximum sflow session */ +#define SWITCH_MAX_SFLOW_SESSIONS \ + 16 // MAX_SFLOW_SESSIONS from p4_table_sizes.h + +/** Maximum sflow access control entries */ +#define SWITCH_MAX_SFLOW_ACES 512 // MAX_SFLOW_SESSIONS from p4_table_sizes.h + +/** sflow match fields */ +typedef enum switch_sflow_match_field_ { + SWITCH_SFLOW_MATCH_PORT = 0, + SWITCH_SFLOW_MATCH_VLAN, + SWITCH_SFLOW_MATCH_SIP, + SWITCH_SFLOW_MATCH_DIP, + SWITCH_SFLOW_MATCH_FIELD_MAX, +} switch_sflow_match_field_t; + +/** sflow match values */ +typedef union switch_sflow_match_value_ { + switch_handle_t port; /**< port handle */ + uint32_t vlan; /**< vlan id */ + uint32_t sip; /**< source ip */ + uint32_t dip; /**< destination ip */ +} switch_sflow_match_value_t; + +/** sflow match mask - same as masks used for acl */ +typedef union switch_sflow_match_mask_ { + unsigned type : 1; /**< mask type */ + union { + uint64_t mask; /**< mask value */ + unsigned int start, end; /**< mask range */ + } u; /**< ip mask union */ +} switch_sflow_match_mask_t; + +/** Egress acl key value pair */ +typedef struct switch_sflow_match_key_value_pair_ { + switch_sflow_match_field_t field; /**< sflow match fields */ + switch_sflow_match_value_t value; /**< sflow match values */ + switch_sflow_match_mask_t mask; /**< sflow match masks */ +} switch_sflow_match_key_value_pair_t; + +/** Sflow collector type */ +typedef enum { + SFLOW_COLLECTOR_TYPE_CPU = 0, + SFLOW_COLLECTOR_TYPE_REMOTE +} switch_sflow_collector_type_e; + +/** Sflow sampling mode */ +typedef enum { + SWITCH_SFLOW_SAMPLE_PKT = 0, +} switch_sflow_sample_mode_e; + +/** sflow session struct */ +typedef struct switch_api_sflow_session_info_ { + uint32_t session_id; /**< session id */ + uint32_t timeout_usec; /**< timeout 0 => 100us (default) */ + uint32_t sample_rate; /**< sampling rate 0 => every 10k pkts (default) */ + uint32_t extract_len; /**< extract length 0 => 80 (default) */ + switch_handle_t egress_port_hdl; /**< egress port handle */ + switch_sflow_collector_type_e collector_type; /**< sflow collector type */ + switch_sflow_sample_mode_e sample_mode; /**< sampling mode */ +} switch_api_sflow_session_info_t; + +/** + sflow session create + @param device device + @param api_sflow_info sflow information +*/ +switch_handle_t switch_api_sflow_session_create( + switch_device_t device, switch_api_sflow_session_info_t *api_sflow_info); + +/** + sflow session delete + @param device device + @param sflow_hdl sflow handle + @param all_cleanup all cleanup +*/ +switch_status_t switch_api_sflow_session_delete(switch_device_t device, + switch_handle_t sflow_hdl, + bool all_cleanup); + +/** + sflow session attach + @param device device + @param sflow_hdl sflow handle + @param direction direction + @param priority priority + @param sample_rate sampling rate + @param key_value_count key value count + @param kvp key value pair + @param entry_hdl ace entry handle +*/ +switch_status_t switch_api_sflow_session_attach( + switch_device_t device, + switch_handle_t sflow_hdl, + switch_direction_t direction, + unsigned int priority, + unsigned int sample_rate, + unsigned int key_value_count, + switch_sflow_match_key_value_pair_t *kvp, + switch_handle_t *entry_hdl); + +/** + sflow session detach + @param device device + @param sflow_hdl sflow handle + @param entry_hdl ace entry handle +*/ +switch_status_t switch_api_sflow_session_detach(switch_device_t device, + switch_handle_t sflow_hdl, + switch_handle_t entry_hdl); + +switch_status_t switch_api_sflow_session_sample_count_get( + switch_device_t device, + switch_handle_t sflow_hdl, + switch_handle_t entry_hdl, + switch_counter_t *sample_pool); + +switch_status_t switch_api_sflow_session_sample_count_reset( + switch_device_t device, + switch_handle_t sflow_hdl, + switch_handle_t entry_hdl); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _switch_sflow_h */ diff --git a/switchapi/include/switchapi/switch_status.h b/switchapi/include/switchapi/switch_status.h new file mode 100644 index 0000000..fcc0b5c --- /dev/null +++ b/switchapi/include/switchapi/switch_status.h @@ -0,0 +1,185 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_status_h +#define _switch_status_h + +#include "switch_base_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Status success + */ +#define SWITCH_STATUS_SUCCESS 0x00000000L + +/* + * General failure + */ +#define SWITCH_STATUS_FAILURE 0x00000001L + +/* + * The request is not supported + */ +#define SWITCH_STATUS_NOT_SUPPORTED 0x00000002L + +/* + * Not enough memory to complete the operation + */ +#define SWITCH_STATUS_NO_MEMORY 0x00000003L + +/* + * Insufficient system resources exist to complete the operation + */ +#define SWITCH_STATUS_INSUFFICIENT_RESOURCES 0x00000004L + +/* + * An invalid parameter was passed to a function + */ +#define SWITCH_STATUS_INVALID_PARAMETER 0x00000005L + +/* + * An item already exists + */ +#define SWITCH_STATUS_ITEM_ALREADY_EXISTS 0x00000006L + +/* + * An item was not found + */ +#define SWITCH_STATUS_ITEM_NOT_FOUND 0x00000007L + +/* + * The data was too large to fit into the specified buffer. + */ +#define SWITCH_STATUS_BUFFER_OVERFLOW 0x00000008L + +/* + * Invalid port number + */ +#define SWITCH_STATUS_INVALID_PORT_NUMBER 0x00000009L + +/* + * Invalid port member + */ +#define SWITCH_STATUS_INVALID_PORT_MEMBER 0x0000000AL + +/* + * Invalid VLAN id + */ +#define SWITCH_STATUS_INVALID_VLAN_ID 0x0000000BL + +/* + * Object is uninitialized + */ +#define SWITCH_STATUS_UNINITIALIZED 0x0000000CL + +/* + * Table is full + */ +#define SWITCH_STATUS_TABLE_FULL 0x0000000DL + +/* + * Attribute is invalid + */ +#define SWITCH_STATUS_INVALID_ATTRIBUTE 0x0000000EL + +/* + * Invalid interface id + */ +#define SWITCH_STATUS_INVALID_INTERFACE 0x0000000FL + +/* + * Port is in use + */ +#define SWITCH_STATUS_PORT_IN_USE 0x00000010L + +/* + * Invalid switch ID + */ +#define SWITCH_STATUS_INVALID_SWITCH_ID 0x00000011L + +/* + * Function is not implemented + */ +#define SWITCH_STATUS_NOT_IMPLEMENTED 0x00000012L + +/* + * Address not found + */ +#define SWITCH_STATUS_ADDR_NOT_FOUND 0x00000013L + +/* + * Invalid virtual router ID + */ +#define SWITCH_STATUS_INVALID_VRID 0x00000014L + +/* + * Invalid attribute value + */ +#define SWITCH_STATUS_INVALID_ATTR_VALUE 0x00000015L + +/* + * Invalid Tunnel type + */ +#define SWITCH_STATUS_INVALID_TUNNEL_TYPE 0x000000016L + +/* + * Invalid Next Hop + */ +#define SWITCH_STATUS_INVALID_NHOP 0x000000017L + +/* + * Invalid Handle + */ +#define SWITCH_STATUS_INVALID_HANDLE 0x000000018L + +/* +* RESOURCE is in use +*/ +#define SWITCH_STATUS_RESOURCE_IN_USE 0x00000019L + +/* + * Invalid LN type + */ +#define SWITCH_STATUS_INVALID_LN_TYPE 0x00000001AL + +/* + * Invalid encap type + */ +#define SWITCH_STATUS_INVALID_ENCAP_TYPE 0x00000001BL + +/* + * Unsupported type + */ +#define SWITCH_STATUS_UNSUPPORTED_TYPE 0x00000001CL + +/* + * pd failure + */ +#define SWITCH_STATUS_PD_FAILURE 0x00000001DL + +/* + * invalid device id + */ +#define SWITCH_STATUS_INVALID_DEVICE 0x00000001EL + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/inc/switchapi/switch_stp.h b/switchapi/include/switchapi/switch_stp.h similarity index 68% rename from switchapi/inc/switchapi/switch_stp.h rename to switchapi/include/switchapi/switch_stp.h index 5016690..270f0b6 100644 --- a/switchapi/inc/switchapi/switch_stp.h +++ b/switchapi/include/switchapi/switch_stp.h @@ -40,19 +40,19 @@ extern "C" { /** Spanning Tree Group State */ typedef enum { - SWITCH_PORT_STP_STATE_NONE, - SWITCH_PORT_STP_STATE_DISABLED, - SWITCH_PORT_STP_STATE_LEARNING, - SWITCH_PORT_STP_STATE_FORWARDING, - SWITCH_PORT_STP_STATE_BLOCKING, + SWITCH_PORT_STP_STATE_NONE, + SWITCH_PORT_STP_STATE_DISABLED, + SWITCH_PORT_STP_STATE_LEARNING, + SWITCH_PORT_STP_STATE_FORWARDING, + SWITCH_PORT_STP_STATE_BLOCKING, } switch_stp_state_t; /** Spanning tree mode */ typedef enum switch_stp_mode_ { - SWITCH_PORT_STP_MODE_DISABLED, - SWITCH_PORT_STP_MODE_STP, - SWITCH_PORT_STP_MODE_RSTP, - SWITCH_PORT_STP_MODE_MSTP + SWITCH_PORT_STP_MODE_DISABLED, + SWITCH_PORT_STP_MODE_STP, + SWITCH_PORT_STP_MODE_RSTP, + SWITCH_PORT_STP_MODE_MSTP } switch_stp_mode_t; /** @@ -60,14 +60,16 @@ typedef enum switch_stp_mode_ { @param device device @param stp_mode spanning tree mode */ -switch_handle_t switch_api_stp_group_create(switch_device_t device, switch_stp_mode_t stp_mode); +switch_handle_t switch_api_stp_group_create(switch_device_t device, + switch_stp_mode_t stp_mode); /** Delete a spanning tree group @param device device @param stg_handle handle of the spanning tree group */ -switch_status_t switch_api_stp_group_delete(switch_device_t device, switch_handle_t stg_handle); +switch_status_t switch_api_stp_group_delete(switch_device_t device, + switch_handle_t stg_handle); /** Add VLAN to the stp @@ -77,9 +79,9 @@ switch_status_t switch_api_stp_group_delete(switch_device_t device, switch_handl @param vlan_handle list of vlan handles */ switch_status_t switch_api_stp_group_vlans_add(switch_device_t device, - switch_handle_t stg_handle, - uint16_t vlan_count, - switch_handle_t *vlan_handle); + switch_handle_t stg_handle, + uint16_t vlan_count, + switch_handle_t *vlan_handle); /** Remove VLAN from the stp @@ -89,9 +91,9 @@ switch_status_t switch_api_stp_group_vlans_add(switch_device_t device, @param vlan_handle list of vlan handles */ switch_status_t switch_api_stp_group_vlans_remove(switch_device_t device, - switch_handle_t stg_handle, - uint16_t vlan_count, - switch_handle_t *vlan_handle); + switch_handle_t stg_handle, + uint16_t vlan_count, + switch_handle_t *vlan_handle); /** Set the port belonging to a stp in one of discard, learn or forward @@ -100,8 +102,10 @@ switch_status_t switch_api_stp_group_vlans_remove(switch_device_t device, @param intf_handle - spanning tree interface @param state stp state */ -switch_status_t switch_api_stp_port_state_set(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t intf_handle, switch_stp_state_t state); +switch_status_t switch_api_stp_port_state_set(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t intf_handle, + switch_stp_state_t state); /** Get the state of the port belonging to a stp @@ -110,8 +114,10 @@ switch_status_t switch_api_stp_port_state_set(switch_device_t device, switch_han @param intf_handle - spanning tree interface @param state stp state */ -switch_status_t switch_api_stp_port_state_get(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t intf_handle, switch_stp_state_t *state); +switch_status_t switch_api_stp_port_state_get(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t intf_handle, + switch_stp_state_t *state); /** Set the port belonging to a stp in one of discard, learn or forward @@ -119,8 +125,9 @@ switch_status_t switch_api_stp_port_state_get(switch_device_t device, switch_han @param stg_handle handle of the Spanning tree group @param intf_handle - spanning tree interface */ -switch_status_t switch_api_stp_port_state_clear(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t intf_handle); +switch_status_t switch_api_stp_port_state_clear(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t intf_handle); /** Dump spanning tree group table diff --git a/switchapi/include/switchapi/switch_tunnel.h b/switchapi/include/switchapi/switch_tunnel.h new file mode 100644 index 0000000..4878784 --- /dev/null +++ b/switchapi/include/switchapi/switch_tunnel.h @@ -0,0 +1,166 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_tunnel_h_ +#define _switch_tunnel_h_ + +#include "switch_handle.h" +#include "switch_vlan.h" +#include "switch_nat.h" +#include "switch_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup Tunnel Tunnel API + * API functions create tunnel interfaces + * @{ + */ // begin of Tunnel API + +/** Tunnel encap mode */ +typedef enum switch_encap_mode_ { + SWITCH_API_TUNNEL_ENCAP_MODE_IP, + SWITCH_API_TUNNEL_ENCAP_MODE_MPLS +} switch_encap_mode_t; + +/** Tunnel information */ +typedef struct switch_tunnel_info_ { + switch_encap_info_t encap_info; /**< Encap Info */ + switch_encap_mode_t encap_mode; /**< Encap mode - ip/mpls */ + union { + switch_ip_encap_t ip_encap; /**< IP encapsulation */ + switch_mpls_encap_t mpls_encap; /**< Mpls Encapsulation */ + } u; /**< tunnel encap union */ + switch_handle_t out_if; /**< Underlying interface */ + struct { + bool core_intf : 1; /**< core interface */ + bool flood_enabled : 1; /**< flooding enabled */ + } flags; /**< tunnel flags */ +} switch_tunnel_info_t; + +/** Tunnel Egress type */ +typedef enum switch_tunnel_type_egress_ { + SWITCH_EGRESS_TUNNEL_TYPE_NONE = 0, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN = 1, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN = 2, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE = 3, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE = 4, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE = 5, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE = 6, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3 = 7, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3 = 8, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GRE = 9, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GRE = 10, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_IP = 11, + SWITCH_EGRESS_TUNNEL_TYPE_IPV6_IP = 12, + SWITCH_EGRESS_TUNNEL_TYPE_MPLS_L2VPN = 13, + SWITCH_EGRESS_TUNNEL_TYPE_MPLS_L3VPN = 14, + SWITCH_EGRESS_TUNNEL_TYPE_FABRIC = 15, + SWITCH_EGRESS_TUNNEL_TYPE_CPU = 16, + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN_GPE = 17, +} switch_tunnel_type_egress_t; + +/** Tunnel Ingress type */ +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_IPIP = 3, + SWITCH_INGRESS_TUNNEL_TYPE_GENEVE = 4, + SWITCH_INGRESS_TUNNEL_TYPE_NVGRE = 5, + SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_1 = 6, + SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_2 = 7, + SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_3 = 8, + SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_1 = 9, + SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_2 = 10, + SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_3 = 11, + SWITCH_INGRESS_TUNNEL_TYPE_VXLAN_GPE = 12, +} switch_tunnel_type_ingress_t; + +/** Mpls ipv4 explicit null label */ +#define SWITCH_MPLS_IPV4_EXPLICIT_NULL 0 + +/** 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 + L2 or L3 service on the tunnel + @param device device + @param direction allow for ingress or egress only interfaces + @param tunnel_info tunnel encapsulation information +*/ +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 + deleted + @param device device + @param tunnel_handle handle of tunnel returned on tunnel creation +*/ +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 + @param network_handle Logical network handle + @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 interface_handle); + +/** + Delete member from logical network + @param device device + @param network_handle Logical network handle + @param interface_handle Handle of access port ot Tunnel interface +*/ +switch_status_t switch_api_logical_network_member_remove( + switch_device_t device, + switch_handle_t network_handle, + switch_handle_t interface_handle); + +/** + Mpls Transit Create + @param device device + @param mpls_encap mpls info +*/ +switch_status_t switch_api_mpls_tunnel_transit_create( + switch_device_t device, switch_mpls_encap_t *mpls_encap); + +/** + Mpls Transit Create + @param device device + @param mpls_encap mpls info +*/ +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 + +#endif /* defined(_switch_tunnel_h_) */ diff --git a/switchapi/inc/switchapi/switch_utils.h b/switchapi/include/switchapi/switch_utils.h similarity index 83% rename from switchapi/inc/switchapi/switch_utils.h rename to switchapi/include/switchapi/switch_utils.h index 2d6ad5e..dd4215a 100644 --- a/switchapi/inc/switchapi/switch_utils.h +++ b/switchapi/include/switchapi/switch_utils.h @@ -23,12 +23,12 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - -uint32_t MurmurHash2 (const void * key, size_t len, uint32_t seed); + +uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed); /* API to get version of the library */ -const char * switch_get_version(void); -const char * switch_get_internal_version(void); +const char *switch_get_version(void); +const char *switch_get_internal_version(void); #ifdef __cplusplus } diff --git a/switchapi/inc/switchapi/switch_vlan.h b/switchapi/include/switchapi/switch_vlan.h similarity index 57% rename from switchapi/inc/switchapi/switch_vlan.h rename to switchapi/include/switchapi/switch_vlan.h index 22d9be9..afd1092 100644 --- a/switchapi/inc/switchapi/switch_vlan.h +++ b/switchapi/include/switchapi/switch_vlan.h @@ -30,114 +30,110 @@ extern "C" { /** Logical Network Type */ typedef enum { - SWITCH_LOGICAL_NETWORK_TYPE_NONE, /**< Unitialized domain type */ - SWITCH_LOGICAL_NETWORK_TYPE_VLAN, /**< VLAN domain */ - SWITCH_LOGICAL_NETWORK_TYPE_GRE, /**< GRE Network */ - SWITCH_LOGICAL_NETWORK_TYPE_L3, /**< L3 Network */ - SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, /**< Encap from logical network */ - SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED /**< Encap from interface */ + SWITCH_LOGICAL_NETWORK_TYPE_NONE, /**< Unitialized domain type */ + SWITCH_LOGICAL_NETWORK_TYPE_VLAN, /**< VLAN domain */ + SWITCH_LOGICAL_NETWORK_TYPE_GRE, /**< GRE Network */ + SWITCH_LOGICAL_NETWORK_TYPE_L3, /**< L3 Network */ + SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, /**< Encap from logical network */ + SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED /**< Encap from interface */ } switch_logical_network_type_t; typedef enum { - SWITCH_VLAN_FLOOD_NONE = 0x0, - SWITCH_VLAN_FLOOD_UUC = 0x1, - SWITCH_VLAN_FLOOD_UMC = 0x2, - SWITCH_VLAN_FLOOD_BCAST = 0x4 + SWITCH_VLAN_FLOOD_NONE = 0x0, + SWITCH_VLAN_FLOOD_UUC = 0x1, + SWITCH_VLAN_FLOOD_UMC = 0x2, + SWITCH_VLAN_FLOOD_BCAST = 0x4 } switch_vlan_flood_type_t; -typedef enum switch_vlan_tagging_mode_ -{ - SWITCH_VLAN_PORT_UNTAGGED, - SWITCH_VLAN_PORT_TAGGED, - SWITCH_VLAN_PORT_PRIORITY_TAGGED +typedef enum switch_vlan_tagging_mode_ { + SWITCH_VLAN_PORT_UNTAGGED, + SWITCH_VLAN_PORT_TAGGED, + SWITCH_VLAN_PORT_PRIORITY_TAGGED } switch_vlan_tagging_mode_t; -typedef enum switch_vlan_attr_ -{ - /* Maximum number of learned MAC addresses [uint32_t] */ - SWITCH_VLAN_ATTR_MAX_LEARNED_ADDRESSES, - - /* Custom range base value */ - SWITCH_VLAN_ATTR_CUSTOM_RANGE_BASE = 0x10000000, - SWITCH_VLAN_ATTR_FLOOD_TYPE, - SWITCH_VLAN_ATTR_VRF_ID, - SWITCH_VLAN_ATTR_AGE_INTERVAL, - SWITCH_VLAN_ATTR_IGMP_SNOOPING, - SWITCH_VLAN_ATTR_MLD_SNOOPING, - SWITCH_VLAN_ATTR_MAC_LEARNING +typedef enum switch_vlan_attr_ { + /* Maximum number of learned MAC addresses [uint32_t] */ + SWITCH_VLAN_ATTR_MAX_LEARNED_ADDRESSES, + + /* Custom range base value */ + SWITCH_VLAN_ATTR_CUSTOM_RANGE_BASE = 0x10000000, + SWITCH_VLAN_ATTR_FLOOD_TYPE, + SWITCH_VLAN_ATTR_VRF_ID, + SWITCH_VLAN_ATTR_AGE_INTERVAL, + SWITCH_VLAN_ATTR_IGMP_SNOOPING, + SWITCH_VLAN_ATTR_MLD_SNOOPING, + SWITCH_VLAN_ATTR_MAC_LEARNING } switch_vlan_attr_t; -typedef enum switch_ln_attr_ -{ - /* Maximum number of learned MAC addresses [uint32_t] */ - SWITCH_LN_ATTR_MAX_LEARNED_ADDRESSES, - - /* Custom range base value */ - SWITCH_LN_ATTR_CUSTOM_RANGE_BASE = 0x10000000, - SWITCH_LN_ATTR_FLOOD_TYPE, - SWITCH_LN_ATTR_VRF_ID, - SWITCH_LN_ATTR_NETWORK_TYPE, - SWITCH_LN_ATTR_AGE_INTERVAL, - SWITCH_LN_ATTR_IPV4_UNICAST, - SWITCH_LN_ATTR_IPV6_UNICAST, - SWITCH_LN_ATTR_IGMP_SNOOPING, - SWITCH_LN_ATTR_MLD_SNOOPING, - SWITCH_LN_ATTR_IPV4_MCAST_MODE, - SWITCH_LN_ATTR_IPV6_MCAST_MODE, - SWITCH_LN_ATTR_MAC_LEARNING +typedef enum switch_ln_attr_ { + /* Maximum number of learned MAC addresses [uint32_t] */ + SWITCH_LN_ATTR_MAX_LEARNED_ADDRESSES, + + /* Custom range base value */ + SWITCH_LN_ATTR_CUSTOM_RANGE_BASE = 0x10000000, + SWITCH_LN_ATTR_FLOOD_TYPE, + SWITCH_LN_ATTR_VRF_ID, + SWITCH_LN_ATTR_NETWORK_TYPE, + SWITCH_LN_ATTR_AGE_INTERVAL, + SWITCH_LN_ATTR_IPV4_UNICAST, + SWITCH_LN_ATTR_IPV6_UNICAST, + SWITCH_LN_ATTR_IGMP_SNOOPING, + SWITCH_LN_ATTR_MLD_SNOOPING, + SWITCH_LN_ATTR_IPV4_MCAST_MODE, + SWITCH_LN_ATTR_IPV6_MCAST_MODE, + SWITCH_LN_ATTR_MAC_LEARNING } switch_ln_attr_t; -typedef enum _switch_bd_stats_t -{ - 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, +typedef enum _switch_bd_stats_t { + 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_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; /**< vlan handle */ - switch_handle_t intf_handle; /**< interface handle */ + switch_handle_t vlan_handle; /**< vlan handle */ + switch_handle_t intf_handle; /**< interface handle */ } switch_vlan_interface_t; /** Logical Network information */ typedef struct switch_logical_network_ { - switch_logical_network_type_t type; /**< Type of logical network */ - switch_handle_t vrf_handle; /**< VRF of domain */ - switch_handle_t rmac_handle; /**< RMAC Group */ - switch_encap_info_t encap_info; /**< Logical network encap */ - - struct { - uint8_t ipv4_unicast_enabled:1; /**< v4 unicast enabled */ - uint8_t ipv6_unicast_enabled:1; /**< v6 unicast enabled */ - uint8_t ipv4_multicast_enabled:1; /**< v4 multicast enabled */ - uint8_t ipv6_multicast_enabled:1; /**< v6 multicast enabled */ - uint8_t igmp_snooping_enabled:1; /**< igmp snooping enabled */ - uint8_t mld_snooping_enabled:1; /**< mld snooping enabled */ - uint8_t flood_enabled:1; /**< default flood */ - uint8_t learn_enabled:1; /**< learn enabled */ - uint8_t core_bd:1; /**< code or edge vlan */ - uint8_t stats_enabled:1; - } flags; /**< vlan flags */ - - switch_vlan_flood_type_t flood_type; /**< flood type */ - unsigned int age_interval; /**< age interval for VLAN */ - unsigned int member_count; /**< Count of members */ - - uint16_t bd_label; /**< acl label for vlan */ - uint8_t mrpf_group; /**< multicast rpf group */ + switch_logical_network_type_t type; /**< Type of logical network */ + switch_handle_t vrf_handle; /**< VRF of domain */ + switch_handle_t rmac_handle; /**< RMAC Group */ + switch_encap_info_t encap_info; /**< Logical network encap */ + + struct { + uint8_t ipv4_unicast_enabled : 1; /**< v4 unicast enabled */ + uint8_t ipv6_unicast_enabled : 1; /**< v6 unicast enabled */ + uint8_t ipv4_multicast_enabled : 1; /**< v4 multicast enabled */ + uint8_t ipv6_multicast_enabled : 1; /**< v6 multicast enabled */ + uint8_t igmp_snooping_enabled : 1; /**< igmp snooping enabled */ + uint8_t mld_snooping_enabled : 1; /**< mld snooping enabled */ + uint8_t flood_enabled : 1; /**< default flood */ + uint8_t learn_enabled : 1; /**< learn enabled */ + uint8_t core_bd : 1; /**< code or edge vlan */ + uint8_t stats_enabled : 1; /**< stats enabled */ + } flags; /**< vlan flags */ + + switch_vlan_flood_type_t flood_type; /**< flood type */ + unsigned int age_interval; /**< age interval for VLAN */ + unsigned int member_count; /**< Count of members */ + + uint16_t bd_label; /**< acl label for vlan */ + uint8_t mrpf_group; /**< multicast rpf group */ } switch_logical_network_t; /** @defgroup VLAN VLAN configuration API @@ -148,7 +144,7 @@ typedef struct switch_logical_network_ { correspond to setting up broadcast domain and optionally ingress and egress VLAN translate tables. * @{ - */ // begin of VLAN + */ // begin of VLAN // VLAN @@ -157,7 +153,8 @@ typedef struct switch_logical_network_ { @param device device @param vlan_id Id of the VLAN */ -switch_handle_t switch_api_vlan_create(switch_device_t device, switch_vlan_t vlan_id); +switch_handle_t switch_api_vlan_create(switch_device_t device, + switch_vlan_t vlan_id); /** Delete VLAN @@ -165,7 +162,8 @@ switch_handle_t switch_api_vlan_create(switch_device_t device, switch_vlan_t vla @param vlan_handle handle of VLAN returned by create */ -switch_status_t switch_api_vlan_delete(switch_device_t device, switch_handle_t vlan_handle); +switch_status_t switch_api_vlan_delete(switch_device_t device, + switch_handle_t vlan_handle); /** Set a value for an attribute. There is a list of attributes @@ -175,8 +173,8 @@ switch_status_t switch_api_vlan_delete(switch_device_t device, switch_handle_t v @param value - Value of the attribute */ switch_status_t switch_api_vlan_attribute_set(switch_handle_t vlan_handle, - switch_vlan_attr_t attr_type, - uint64_t value); + switch_vlan_attr_t attr_type, + uint64_t value); /** Get a value for an attribute. There is a list of attributes @@ -186,15 +184,16 @@ switch_status_t switch_api_vlan_attribute_set(switch_handle_t vlan_handle, @param value - Value of the attribute */ switch_status_t switch_api_vlan_attribute_get(switch_handle_t vlan_handle, - switch_vlan_attr_t attr_type, - uint64_t *value); + switch_vlan_attr_t attr_type, + uint64_t *value); /** Set the flood type for vlan. Based on the flood type, flood lists are allocated. By default, none of the flood lists are created. @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of flood type */ -switch_status_t switch_api_vlan_flood_type_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_flood_type_set(switch_handle_t vlan_handle, + uint64_t value); /** Get the flood type for vlan. Based on the flood type, flood lists @@ -202,154 +201,176 @@ switch_status_t switch_api_vlan_flood_type_set(switch_handle_t vlan_handle, uint @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of flood type */ -switch_status_t switch_api_vlan_flood_type_get(switch_handle_t vlan_handle, uint64_t *value); +switch_status_t switch_api_vlan_flood_type_get(switch_handle_t vlan_handle, + uint64_t *value); /** Set the vrf handle for vlan. @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of vrf handle */ -switch_status_t switch_api_vlan_vrf_handle_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_vrf_handle_set(switch_handle_t vlan_handle, + uint64_t value); /** Get the vrf handle for vlan. @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of vrf handle */ -switch_status_t switch_api_vlan_vrf_handle_get(switch_handle_t vlan_handle, uint64_t *value); +switch_status_t switch_api_vlan_vrf_handle_get(switch_handle_t vlan_handle, + uint64_t *value); /** Set the logical network type of a vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of logical network type */ -switch_status_t switch_api_ln_network_type_set(switch_handle_t ln_handle, uint64_t value); +switch_status_t switch_api_ln_network_type_set(switch_handle_t ln_handle, + uint64_t value); /** Get the logical network type of a vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of logical network type */ -switch_status_t switch_api_ln_network_type_get(switch_handle_t ln_handle, uint64_t *value); +switch_status_t switch_api_ln_network_type_get(switch_handle_t ln_handle, + uint64_t *value); /** Set IPv4 unicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv4 unicast routing enabled */ -switch_status_t switch_api_ln_ipv4_unicast_enabled_set(switch_handle_t ln_handle, uint64_t value); +switch_status_t switch_api_ln_ipv4_unicast_enabled_set( + switch_handle_t ln_handle, uint64_t value); /** Get IPv4 unicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv4 unicast routing enabled */ -switch_status_t switch_api_ln_ipv4_unicast_enabled_get(switch_handle_t ln_handle, uint64_t *value); +switch_status_t switch_api_ln_ipv4_unicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value); /** Set IPv6 unicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv6 unicast routing enabled */ -switch_status_t switch_api_ln_ipv6_unicast_enabled_set(switch_handle_t ln_handle, uint64_t value); +switch_status_t switch_api_ln_ipv6_unicast_enabled_set( + switch_handle_t ln_handle, uint64_t value); /** Get IPv6 unicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv6 unicast routing enabled */ -switch_status_t switch_api_ln_ipv6_unicast_enabled_get(switch_handle_t ln_handle, uint64_t *value); +switch_status_t switch_api_ln_ipv6_unicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value); /** Set IPv4 multicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv4 multicast routing enabled */ -switch_status_t switch_api_ln_ipv4_multicast_enabled_set(switch_handle_t ln_handle, uint64_t value); +switch_status_t switch_api_ln_ipv4_multicast_enabled_set( + switch_handle_t ln_handle, uint64_t value); /** Get IPv4 multicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv4 multicast routing enabled */ -switch_status_t switch_api_ln_ipv4_multicast_enabled_get(switch_handle_t ln_handle, uint64_t *value); +switch_status_t switch_api_ln_ipv4_multicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value); /** Set IPv6 multicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv6 multicast routing enabled */ -switch_status_t switch_api_ln_ipv6_multicast_enabled_set(switch_handle_t ln_handle, uint64_t value); +switch_status_t switch_api_ln_ipv6_multicast_enabled_set( + switch_handle_t ln_handle, uint64_t value); /** Get IPv6 multicast routing enabled for vlan @param ln_handle - Vlan handle that identifies vlan uniquely @param value - Value of IPv6 multicast routing enabled */ -switch_status_t switch_api_ln_ipv6_multicast_enabled_get(switch_handle_t ln_handle, uint64_t *value); +switch_status_t switch_api_ln_ipv6_multicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value); /** Set mac learning enabled for vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mac learning enabled */ -switch_status_t switch_api_vlan_learning_enabled_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_learning_enabled_set( + switch_handle_t vlan_handle, uint64_t value); /** Get mac learning enabled on vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mac learning enabled */ -switch_status_t switch_api_vlan_learning_enabled_get(switch_handle_t vlan_handle, uint64_t *value); +switch_status_t switch_api_vlan_learning_enabled_get( + switch_handle_t vlan_handle, uint64_t *value); /** Set mac age interval on vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mac learning enabled */ -switch_status_t switch_api_vlan_aging_interval_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_aging_interval_set(switch_handle_t vlan_handle, + uint64_t value); /** Get mac age interval on vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mac age interval */ -switch_status_t switch_api_vlan_aging_interval_get(switch_handle_t vlan_handle, uint64_t *value); +switch_status_t switch_api_vlan_aging_interval_get(switch_handle_t vlan_handle, + uint64_t *value); /** Set igmp snooping enable flag for vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of igmp snooping enabled flag */ -switch_status_t switch_api_vlan_igmp_snooping_enabled_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_igmp_snooping_enabled_set( + switch_handle_t vlan_handle, uint64_t value); /** Get igmp snooping enable flag for vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of igmp snooping enabled flag */ -switch_status_t switch_api_vlan_igmp_snooping_enabled_get(switch_handle_t vlan_handle, uint64_t *value); +switch_status_t switch_api_vlan_igmp_snooping_enabled_get( + switch_handle_t vlan_handle, uint64_t *value); /** Set mld snooping enable flag for vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mld snooping enabled flag */ -switch_status_t switch_api_vlan_mld_snooping_enabled_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_mld_snooping_enabled_set( + switch_handle_t vlan_handle, uint64_t value); /** Get mld snooping enable flag for vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mld snooping enabled flag */ -switch_status_t switch_api_vlan_mld_snooping_enabled_get(switch_handle_t vlan_handle, uint64_t *value); +switch_status_t switch_api_vlan_mld_snooping_enabled_get( + switch_handle_t vlan_handle, uint64_t *value); /** Set mrpf group for vlan @param vlan_handle - Vlan handle that identifies vlan uniquely @param value - Value of mrpf group */ -switch_status_t switch_api_vlan_mrpf_group_set(switch_handle_t vlan_handle, uint64_t value); +switch_status_t switch_api_vlan_mrpf_group_set(switch_handle_t vlan_handle, + uint64_t value); /** Add ports to vlan. By default, ports will be added to the flood list @@ -359,8 +380,10 @@ switch_status_t switch_api_vlan_mrpf_group_set(switch_handle_t vlan_handle, uint @param port_count - Number of ports to be added to vlan @param vlan_port - List of interfaces/ports/lags */ -switch_status_t switch_api_vlan_ports_add(switch_device_t device, switch_handle_t vlan_handle, - uint16_t port_count, switch_vlan_port_t *vlan_port); +switch_status_t switch_api_vlan_ports_add(switch_device_t device, + switch_handle_t vlan_handle, + uint16_t port_count, + switch_vlan_port_t *vlan_port); /** Remove ports from vlan. By default, ports will be removed from flood list @@ -370,8 +393,10 @@ switch_status_t switch_api_vlan_ports_add(switch_device_t device, switch_handle_ @param port_count - Number of ports to be removed from vlan @param vlan_port- List of interfaces/ports/lags */ -switch_status_t switch_api_vlan_ports_remove(switch_device_t device, switch_handle_t vlan_handle, - uint16_t port_count, switch_vlan_port_t *vlan_port); +switch_status_t switch_api_vlan_ports_remove(switch_device_t device, + switch_handle_t vlan_handle, + uint16_t port_count, + switch_vlan_port_t *vlan_port); /** Get the list of interfaces that belong to a vlan. @@ -381,17 +406,17 @@ switch_status_t switch_api_vlan_ports_remove(switch_device_t device, switch_hand @param mbrs - List of interfaces */ switch_status_t switch_api_vlan_interfaces_get(switch_device_t device, - switch_handle_t vlan_handle, - uint16_t *mbr_count, - switch_vlan_interface_t **mbrs); + switch_handle_t vlan_handle, + uint16_t *mbr_count, + switch_vlan_interface_t **mbrs); /** Create a Logical network @param device - device to be programmed @param ln_info - Logical network information */ -switch_handle_t switch_api_logical_network_create(switch_device_t device, - switch_logical_network_t *ln_info); +switch_handle_t switch_api_logical_network_create( + switch_device_t device, switch_logical_network_t *ln_info); /** Update a Logical network @@ -399,16 +424,18 @@ switch_handle_t switch_api_logical_network_create(switch_device_t device, @param network_handle handle of logical network @param ln_info - Logical network information */ -switch_status_t switch_api_logical_network_update(switch_device_t device, - switch_handle_t network_handle, - switch_logical_network_t *ln_info); +switch_status_t switch_api_logical_network_update( + switch_device_t device, + switch_handle_t network_handle, + switch_logical_network_t *ln_info); /** Delete a Logical network @param device - device to be programmed @param network_handle handle of logical network */ -switch_status_t switch_api_logical_network_delete(switch_device_t device, switch_handle_t network_handle); +switch_status_t switch_api_logical_network_delete( + switch_device_t device, switch_handle_t network_handle); /** Set vlan id to vlan handle mapping @@ -443,14 +470,16 @@ switch_status_t switch_api_vlan_print_all(void); @param device device to be programmed @param vlan_handle Vlan handle that identifies vlan uniquely */ -switch_status_t switch_api_vlan_stats_enable(switch_device_t device, switch_handle_t vlan_handle); +switch_status_t switch_api_vlan_stats_enable(switch_device_t device, + switch_handle_t vlan_handle); /** Enable vlan statistics @param device device to be programmed @param vlan_handle Vlan handle that identifies vlan uniquely */ -switch_status_t switch_api_vlan_stats_disable(switch_device_t device, switch_handle_t vlan_handle); +switch_status_t switch_api_vlan_stats_disable(switch_device_t device, + switch_handle_t vlan_handle); /** Get vlan statistics @@ -460,14 +489,13 @@ switch_status_t switch_api_vlan_stats_disable(switch_device_t device, switch_han @param counter_ids list of counter ids @param counters counter values to be returned */ -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); - -/** @} */ // end of VLAN +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); + +/** @} */ // end of VLAN #ifdef __cplusplus } diff --git a/switchapi/inc/switchapi/switch_vrf.h b/switchapi/include/switchapi/switch_vrf.h similarity index 63% rename from switchapi/inc/switchapi/switch_vrf.h rename to switchapi/include/switchapi/switch_vrf.h index b82bcb9..d0e4b0b 100644 --- a/switchapi/inc/switchapi/switch_vrf.h +++ b/switchapi/include/switchapi/switch_vrf.h @@ -22,35 +22,33 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - -//VRF + +// VRF /** @defgroup VRF VRF API * API functions define and manipulate vrf * @{ - */ // begin of VRF API + */ // begin of VRF API /** VRF information */ typedef struct switch_vrf_info_ { - switch_vrf_id_t vrf_id; /**< user VRF */ - switch_mac_addr_t mac; /**< mac address */ - struct { - uint8_t v4_enabled; /**< v4 enable */ - uint8_t v6_enabled; /**< v6 enable */ - uint8_t vrf_type; /**< core or edge vrf */ - } flags; /**< vrf flags */ + switch_vrf_id_t vrf_id; /**< user VRF */ + switch_mac_addr_t mac; /**< mac address */ + struct { + uint8_t v4_enabled; /**< v4 enable */ + uint8_t v6_enabled; /**< v6 enable */ + uint8_t vrf_type; /**< core or edge vrf */ + } flags; /**< vrf flags */ } switch_vrf_info_t; /** Vrf type */ -typedef enum switch_vrf_type_ -{ - SWITCH_VRF_TYPE_CORE, /**< core vrf */ - SWITCH_VRF_TYPE_EDGE /**< edge vrf */ +typedef enum switch_vrf_type_ { + SWITCH_VRF_TYPE_CORE, /**< core vrf */ + SWITCH_VRF_TYPE_EDGE /**< edge vrf */ } switch_vrf_type_t; /** Vrf attributes */ -typedef enum switch_vrf_attr_ -{ - SWITCH_VRF_ATTR_VRF_TYPE /**< Vrf type - edge or core */ +typedef enum switch_vrf_attr_ { + SWITCH_VRF_ATTR_VRF_TYPE /**< Vrf type - edge or core */ } switch_vrf_attr_t; /** @@ -58,14 +56,16 @@ typedef enum switch_vrf_attr_ @param device - device that programs the VRF @param vrf_id - Vrf Id */ -switch_handle_t switch_api_vrf_create(switch_device_t device, switch_vrf_id_t vrf_id); +switch_handle_t switch_api_vrf_create(switch_device_t device, + switch_vrf_id_t vrf_id); /** Delete a VRF @param device - device that programs the VRF @param vrf_handle Vrf handle */ -switch_status_t switch_api_vrf_delete(switch_device_t device, switch_handle_t vrf_handle); +switch_status_t switch_api_vrf_delete(switch_device_t device, + switch_handle_t vrf_handle); /** Set an attribute for a Vrf @@ -74,8 +74,8 @@ switch_status_t switch_api_vrf_delete(switch_device_t device, switch_handle_t vr @param value - Value of the attribute */ switch_status_t switch_api_vrf_attribute_set(switch_handle_t vrf_handle, - switch_vrf_attr_t attr_type, - uint64_t value); + switch_vrf_attr_t attr_type, + uint64_t value); /** Get an attribute for a Vrf @@ -84,24 +84,26 @@ switch_status_t switch_api_vrf_attribute_set(switch_handle_t vrf_handle, @param value - Value of the attribute */ switch_status_t switch_api_vrf_attribute_get(switch_handle_t vrf_handle, - switch_vrf_attr_t attr_type, - uint64_t *value); + switch_vrf_attr_t attr_type, + uint64_t *value); /** Set vrf type on vrf @param vrf_handle - vrf handle that identifies vrf uniquely @param value - Value of vrf type */ -switch_status_t switch_api_vrf_type_set(switch_handle_t vrf_handle, uint64_t value); +switch_status_t switch_api_vrf_type_set(switch_handle_t vrf_handle, + uint64_t value); /** Get vrf type on vrf @param vrf_handle - vrf handle that identifies vrf uniquely @param value - Value of vrf type */ -switch_status_t switch_api_vrf_type_get(switch_handle_t vrf_handle, uint64_t *value); +switch_status_t switch_api_vrf_type_get(switch_handle_t vrf_handle, + uint64_t *value); -/** @} */ // end of VRF API +/** @} */ // end of VRF API #ifdef __cplusplus } diff --git a/switchapi/src/switch_INT.c b/switchapi/src/switch_INT.c index 9ba728d..6daaefa 100644 --- a/switchapi/src/switch_INT.c +++ b/switchapi/src/switch_INT.c @@ -23,122 +23,117 @@ limitations under the License. #ifdef P4_INT_TRANSIT_ENABLE static void *switch_int_proto_entry_handles = NULL; -static bool -switch_int_entry_hdl_get(switch_device_t device, p4_pd_entry_hdl_t *hdl) -{ - void *temp = NULL; - // check if already created - JLG(temp, switch_int_proto_entry_handles, device); - if(temp) { - *hdl = (p4_pd_entry_hdl_t)*(p4_pd_entry_hdl_t *)temp; - return true; - } - return false; +static bool switch_int_entry_hdl_get(switch_device_t device, + p4_pd_entry_hdl_t *hdl) { + void *temp = NULL; + // check if already created + JLG(temp, switch_int_proto_entry_handles, device); + if (temp) { + *hdl = (p4_pd_entry_hdl_t) * (p4_pd_entry_hdl_t *)temp; + return true; + } + return false; } #endif -switch_status_t -switch_int_transit_enable(switch_device_t device, int32_t switch_id, int32_t enable) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_int_transit_enable(switch_device_t device, + int32_t switch_id, + int32_t enable) { + switch_status_t status = SWITCH_STATUS_SUCCESS; #ifdef P4_INT_TRANSIT_ENABLE - p4_pd_entry_hdl_t entry_hdl; - if (enable) { - void *temp = NULL; - // check if already created - if (switch_int_entry_hdl_get(device, &entry_hdl)) { - return SWITCH_STATUS_ITEM_ALREADY_EXISTS; - } - // use the lowest priority entry for transit - status = switch_pd_int_transit_enable(device, switch_id, 1, &entry_hdl); - if (status == SWITCH_STATUS_SUCCESS) { - JLI(temp, switch_int_proto_entry_handles, device); - if(!temp) { - return SWITCH_STATUS_NO_MEMORY; - } - *(p4_pd_entry_hdl_t *)temp = entry_hdl; - } - } else { - // disable - int rc; - if (!switch_int_entry_hdl_get(device, &entry_hdl)) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - status = switch_pd_int_transit_disable(device, entry_hdl); - if (status == SWITCH_STATUS_SUCCESS) { - JLD(rc, switch_int_proto_entry_handles, device); - } + p4_pd_entry_hdl_t entry_hdl; + if (enable) { + void *temp = NULL; + // check if already created + if (switch_int_entry_hdl_get(device, &entry_hdl)) { + return SWITCH_STATUS_ITEM_ALREADY_EXISTS; + } + // use the lowest priority entry for transit + status = switch_pd_int_transit_enable(device, switch_id, 1, &entry_hdl); + if (status == SWITCH_STATUS_SUCCESS) { + JLI(temp, switch_int_proto_entry_handles, device); + if (!temp) { + return SWITCH_STATUS_NO_MEMORY; + } + *(p4_pd_entry_hdl_t *)temp = entry_hdl; + } + } else { + // disable + int rc; + if (!switch_int_entry_hdl_get(device, &entry_hdl)) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + status = switch_pd_int_transit_disable(device, entry_hdl); + if (status == SWITCH_STATUS_SUCCESS) { + JLD(rc, switch_int_proto_entry_handles, device); } + } #else - (void)device, (void)switch_id, (void)enable; + (void)device, (void)switch_id, (void)enable; #endif - return status; + return status; } -switch_status_t -switch_int_src_enable(switch_device_t device, int32_t switch_id, - switch_ip_addr_t *src, - switch_ip_addr_t *dst, - uint8_t max_hop, uint16_t ins_mask - ) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_int_src_enable(switch_device_t device, + int32_t switch_id, + switch_ip_addr_t *src, + switch_ip_addr_t *dst, + uint8_t max_hop, + uint16_t ins_mask) { + switch_status_t status = SWITCH_STATUS_SUCCESS; #ifdef P4_INT_EP_ENABLE - p4_pd_entry_hdl_t entry_hdl; - status = switch_pd_int_src_enable(device, switch_id, - src, dst, - max_hop, ins_mask, - 0, &entry_hdl, false/*vtep_src*/); - // INT and VTEP src together is not supported yet + p4_pd_entry_hdl_t entry_hdl; + status = switch_pd_int_src_enable(device, + switch_id, + src, + dst, + max_hop, + ins_mask, + 0, + &entry_hdl, + false /*vtep_src*/); +// INT and VTEP src together is not supported yet #else - (void)device, (void)switch_id, - (void) src, (void) dst, - (void) max_hop, (void) ins_mask; + (void)device, (void)switch_id, (void)src, (void)dst, (void)max_hop, + (void)ins_mask; #endif - return status; + return status; } -switch_status_t -switch_int_src_disable(switch_device_t device, - switch_ip_addr_t *src, - switch_ip_addr_t *dst) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_int_src_disable(switch_device_t device, + switch_ip_addr_t *src, + switch_ip_addr_t *dst) { + switch_status_t status = SWITCH_STATUS_SUCCESS; #ifdef P4_INT_EP_ENABLE - // TBD +// TBD #else - (void)device, (void)dst, (void)src, (void)dst; + (void)device, (void)dst, (void)src, (void)dst; #endif - return status; + return status; } -switch_status_t -switch_int_sink_enable(switch_device_t device, - switch_ip_addr_t *dst, - int32_t mirror_id - ) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_int_sink_enable(switch_device_t device, + switch_ip_addr_t *dst, + int32_t mirror_id) { + switch_status_t status = SWITCH_STATUS_SUCCESS; #ifdef P4_INT_EP_ENABLE - p4_pd_entry_hdl_t entry_hdl; - status = switch_pd_int_sink_enable(device, dst, - mirror_id, - 0, &entry_hdl, true/*use_client_ip*/); - // INT sink based on tunnel IP is not supported yet. + p4_pd_entry_hdl_t entry_hdl; + status = switch_pd_int_sink_enable( + device, dst, mirror_id, 0, &entry_hdl, true /*use_client_ip*/); +// INT sink based on tunnel IP is not supported yet. #else - (void)device, (void)dst, (void)mirror_id; + (void)device, (void)dst, (void)mirror_id; #endif - return status; + return status; } -switch_status_t -switch_int_sink_disable(switch_device_t device, switch_ip_addr_t *dst) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_int_sink_disable(switch_device_t device, + switch_ip_addr_t *dst) { + switch_status_t status = SWITCH_STATUS_SUCCESS; #ifdef P4_INT_EP_ENABLE - // TBD +// TBD #else - (void)device, (void)dst; + (void)device, (void)dst; #endif - return status; + return status; } diff --git a/switchapi/src/switch_acl.c b/switchapi/src/switch_acl.c index c0f9f3b..8bf5890 100644 --- a/switchapi/src/switch_acl.c +++ b/switchapi/src/switch_acl.c @@ -28,866 +28,870 @@ extern "C" { static void *switch_acl_array; switch_api_id_allocator *acl_counter_index = NULL; -switch_status_t -switch_acl_init(switch_device_t device) -{ - switch_acl_array = NULL; - switch_handle_type_init(SWITCH_HANDLE_TYPE_ACL, (4*1024)); - switch_handle_type_init(SWITCH_HANDLE_TYPE_ACE, (4*1024)); - acl_counter_index = switch_api_id_allocator_new(4 * 1024, FALSE); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_acl_init(switch_device_t device) { + switch_acl_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_ACL, (4 * 1024)); + switch_handle_type_init(SWITCH_HANDLE_TYPE_ACE, (4 * 1024)); + acl_counter_index = switch_api_id_allocator_new(4 * 1024, FALSE); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_acl_free(switch_device_t device) -{ - switch_api_id_allocator_destroy(acl_counter_index); - switch_handle_type_free(SWITCH_HANDLE_TYPE_ACE); - switch_handle_type_free(SWITCH_HANDLE_TYPE_ACL); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_acl_free(switch_device_t device) { + switch_api_id_allocator_destroy(acl_counter_index); + switch_handle_type_free(SWITCH_HANDLE_TYPE_ACE); + switch_handle_type_free(SWITCH_HANDLE_TYPE_ACL); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_acl_create() -{ - switch_handle_t acl_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_ACL, switch_acl_info_t, switch_acl_array, NULL, acl_handle); - return acl_handle; +switch_handle_t switch_acl_create() { + switch_handle_t acl_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_ACL, + switch_acl_info_t, + switch_acl_array, + NULL, + acl_handle); + return acl_handle; } -switch_acl_info_t * -switch_acl_get(switch_handle_t acl_handle) -{ - switch_acl_info_t *acl_info = NULL; - _switch_handle_get(switch_acl_info_t, switch_acl_array, acl_handle, acl_info); - return acl_info; +switch_acl_info_t *switch_acl_get(switch_handle_t acl_handle) { + switch_acl_info_t *acl_info = NULL; + _switch_handle_get(switch_acl_info_t, switch_acl_array, acl_handle, acl_info); + return acl_info; } -switch_status_t -switch_acl_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_acl_info_t, switch_acl_array, handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_acl_delete(switch_handle_t handle) { + _switch_handle_delete(switch_acl_info_t, switch_acl_array, handle); + return SWITCH_STATUS_SUCCESS; } -unsigned int switch_acl_counter_index_allocate() -{ - return switch_api_id_allocator_allocate(acl_counter_index); +unsigned int switch_acl_counter_index_allocate() { + return switch_api_id_allocator_allocate(acl_counter_index); } -void switch_acl_counter_index_free(unsigned int index) -{ - switch_api_id_allocator_release(acl_counter_index, index); +void switch_acl_counter_index_free(unsigned int index) { + switch_api_id_allocator_release(acl_counter_index, index); } +switch_handle_t switch_api_acl_list_create(switch_device_t device, + switch_acl_type_t type) { + switch_acl_info_t *acl_info = NULL; + switch_handle_t acl_handle; -switch_handle_t -switch_api_acl_list_create(switch_device_t device, switch_acl_type_t type) -{ - switch_acl_info_t *acl_info = NULL; - switch_handle_t acl_handle; - - acl_handle = switch_acl_create(); - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_NO_MEMORY; - } - acl_info->type = type; - acl_info->rules = NULL; - tommy_list_init(&(acl_info->interface_list)); - return acl_handle; + acl_handle = switch_acl_create(); + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_NO_MEMORY; + } + acl_info->type = type; + acl_info->rules = NULL; + tommy_list_init(&(acl_info->interface_list)); + return acl_handle; } -switch_handle_t -switch_api_acl_list_update(switch_device_t device, - switch_handle_t acl_handle, - switch_acl_type_t type) -{ - switch_acl_info_t *acl_info = NULL; +switch_handle_t switch_api_acl_list_update(switch_device_t device, + switch_handle_t acl_handle, + switch_acl_type_t type) { + switch_acl_info_t *acl_info = NULL; - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - acl_info->type = type; - return acl_handle; + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + acl_info->type = type; + return acl_handle; } -switch_status_t -switch_api_acl_list_delete(switch_device_t device, switch_handle_t acl_handle) -{ - switch_acl_info_t *acl_info = NULL; - - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - switch_acl_delete(acl_handle); - return SWITCH_STATUS_SUCCESS; -} +switch_status_t switch_api_acl_list_delete(switch_device_t device, + switch_handle_t acl_handle) { + switch_acl_info_t *acl_info = NULL; + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + switch_acl_delete(acl_handle); + return SWITCH_STATUS_SUCCESS; +} // redundant typedef below! TBD remove it -typedef switch_acl_rule_t switch_ace_info_t; +typedef switch_acl_rule_t switch_ace_info_t; static void *switch_ace_array; -static switch_handle_t -switch_ace_create() -{ - switch_handle_t ace_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_ACE, switch_ace_info_t, switch_ace_array, NULL, ace_handle); - return ace_handle; -} - -static switch_ace_info_t * -switch_ace_get(switch_handle_t ace_handle) -{ - switch_ace_info_t *ace_info = NULL; - _switch_handle_get(switch_ace_info_t, switch_ace_array, ace_handle, ace_info); - return ace_info; -} - -static switch_status_t -switch_ace_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_ace_info_t, switch_ace_array, handle); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t -switch_acl_ip_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_ip_key_value_pair_t *ip_acl = NULL; - switch_interface_info_t *intf_info = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (interface_handle) { - if(switch_handle_get_type(interface_handle)== SWITCH_HANDLE_TYPE_PORT) { - if_label = handle_to_id(interface_handle); - } - else { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; - break; - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } - } +static switch_handle_t switch_ace_create() { + switch_handle_t ace_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_ACE, + switch_ace_info_t, + switch_ace_array, + NULL, + ace_handle); + return ace_handle; +} + +static switch_ace_info_t *switch_ace_get(switch_handle_t ace_handle) { + switch_ace_info_t *ace_info = NULL; + _switch_handle_get(switch_ace_info_t, switch_ace_array, ace_handle, ace_info); + return ace_info; +} + +static switch_status_t switch_ace_delete(switch_handle_t handle) { + _switch_handle_delete(switch_ace_info_t, switch_ace_array, handle); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t switch_acl_ip_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_ip_key_value_pair_t *ip_acl = NULL; + switch_interface_info_t *intf_info = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + uint8_t nat_mode = SWITCH_NAT_MODE_NONE; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + if (switch_handle_get_type(interface_handle) == SWITCH_HANDLE_TYPE_PORT) { + if_label = handle_to_id(interface_handle); + } else { + intf_info = switch_api_interface_get(interface_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_INTERFACE: + if_label = intf_info->api_intf_info.u.port_lag_handle; + break; + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; + } + status = switch_api_interface_nat_mode_get(interface_handle, &nat_mode); + if (status == SWITCH_STATUS_SUCCESS) { + p->opt_action_params.nat_mode = nat_mode; + } } - ip_acl = (switch_acl_ip_key_value_pair_t *)p->fields; - - status = switch_pd_ipv4_acl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - ip_acl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); - return status; -} - -static switch_status_t -switch_acl_ipv6_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_ipv6_key_value_pair_t *ipv6_acl=NULL; - switch_interface_info_t *intf_info = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (interface_handle) { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; - break; - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + } + ip_acl = (switch_acl_ip_key_value_pair_t *)p->fields; + + status = switch_pd_ipv4_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ip_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + return status; +} + +static switch_status_t switch_acl_ipv6_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_ipv6_key_value_pair_t *ipv6_acl = NULL; + switch_interface_info_t *intf_info = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + intf_info = switch_api_interface_get(interface_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; } - ipv6_acl = (switch_acl_ipv6_key_value_pair_t *)p->fields; - status = switch_pd_ipv6_acl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - ipv6_acl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); - return status; -} - -static switch_status_t -switch_acl_mac_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_mac_key_value_pair_t *mac_acl=NULL; - switch_interface_info_t *intf_info = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (interface_handle) { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; - break; - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_INTERFACE: + if_label = intf_info->api_intf_info.u.port_lag_handle; + break; + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; } - - mac_acl = (switch_acl_mac_key_value_pair_t *)p->fields; - status = switch_pd_mac_acl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - mac_acl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); - return status; -} - -static switch_status_t -switch_acl_ip_racl_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_ip_racl_key_value_pair_t *ip_racl = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if(interface_handle) { - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + } + ipv6_acl = (switch_acl_ipv6_key_value_pair_t *)p->fields; + status = switch_pd_ipv6_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ipv6_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + return status; +} + +static switch_status_t switch_acl_mac_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_mac_key_value_pair_t *mac_acl = NULL; + switch_interface_info_t *intf_info = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + intf_info = switch_api_interface_get(interface_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; } - ip_racl = (switch_acl_ip_racl_key_value_pair_t *)p->fields; - status = switch_pd_ipv4_racl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - ip_racl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); - return status; -} - -static switch_status_t -switch_acl_ipv6_racl_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_ipv6_racl_key_value_pair_t *ipv6_racl=NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if(interface_handle) { - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - break; - } + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_INTERFACE: + if_label = intf_info->api_intf_info.u.port_lag_handle; + break; + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; } - ipv6_racl = (switch_acl_ipv6_racl_key_value_pair_t *)p->fields; - status = switch_pd_ipv6_racl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - ipv6_racl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); - return status; -} - -static switch_status_t -switch_acl_qos_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_qos_key_value_pair_t *qos_acl = NULL; - switch_interface_info_t *intf_info = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (interface_handle) { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = handle_to_id(interface_handle); - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + } + + mac_acl = (switch_acl_mac_key_value_pair_t *)p->fields; + status = switch_pd_mac_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + mac_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + return status; +} + +static switch_status_t switch_acl_ip_racl_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_ip_racl_key_value_pair_t *ip_racl = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; } - qos_acl = (switch_acl_qos_key_value_pair_t *)p->fields; - status = switch_pd_qos_acl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - qos_acl, - p->action, - entry); - return status; -} - -static switch_status_t -switch_acl_system_set_fields_actions(switch_device_t device, switch_acl_rule_t *p, - switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) -{ - switch_acl_system_key_value_pair_t *system_acl = NULL; - switch_interface_info_t *intf_info = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (interface_handle) { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; - break; - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + } + ip_racl = (switch_acl_ip_racl_key_value_pair_t *)p->fields; + status = switch_pd_ipv4_racl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ip_racl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + return status; +} + +static switch_status_t switch_acl_ipv6_racl_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_ipv6_racl_key_value_pair_t *ipv6_racl = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; + break; } - system_acl = (switch_acl_system_key_value_pair_t *)p->fields; - status = switch_pd_system_acl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - system_acl, - p->action, - &p->action_params, - &p->opt_action_params, - entry); - return status; -} - -static switch_status_t -switch_acl_egr_set_fields_actions(switch_device_t device, - switch_acl_rule_t *p, - switch_handle_t interface_handle, - p4_pd_entry_hdl_t *entry) -{ - switch_acl_egr_key_value_pair_t *egr_acl = NULL; - switch_interface_info_t *intf_info = NULL; - uint16_t bd_label = 0; - uint16_t if_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (interface_handle) { - if(switch_handle_get_type(interface_handle)== SWITCH_HANDLE_TYPE_PORT) { - if_label = handle_to_id(interface_handle); - } else { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch(switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; - break; - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle);; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } - } + } + ipv6_racl = (switch_acl_ipv6_racl_key_value_pair_t *)p->fields; + status = switch_pd_ipv6_racl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ipv6_racl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + return status; +} + +static switch_status_t switch_acl_system_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_system_key_value_pair_t *system_acl = NULL; + switch_interface_info_t *intf_info = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + intf_info = switch_api_interface_get(interface_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; } - egr_acl = (switch_acl_egr_key_value_pair_t *)p->fields; - - status = switch_pd_egr_acl_table_add_entry( - device, - if_label, - bd_label, - p->priority, - p->field_count, - egr_acl, - p->action, - &p->action_params, - &p->opt_action_params, - entry); - return status; -} - -static switch_status_t -acl_hw_set(switch_device_t device, switch_acl_info_t *acl_info, - switch_acl_rule_t *p, switch_acl_interface_t *intf, - switch_handle_t interface_handle, switch_handle_t ace_handle) -{ - p4_pd_entry_hdl_t entry; - switch_status_t status = SWITCH_STATUS_SUCCESS; - unsigned long *hw_entry = NULL; - - switch (acl_info->type) { - case SWITCH_ACL_TYPE_SYSTEM: - status = switch_acl_system_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_IP: - status = switch_acl_ip_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_IPV6: - status = switch_acl_ipv6_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_IP_RACL: - status = switch_acl_ip_racl_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_IPV6_RACL: - status = switch_acl_ipv6_racl_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_MAC: - status = switch_acl_mac_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_QOS: - status = switch_acl_qos_set_fields_actions(device, p, interface_handle, &entry); - break; - case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - status = switch_acl_egr_set_fields_actions(device, p, interface_handle, &entry); - break; + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_INTERFACE: + if_label = intf_info->api_intf_info.u.port_lag_handle; + break; + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; + } + } + system_acl = (switch_acl_system_key_value_pair_t *)p->fields; + status = switch_pd_system_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + system_acl, + p->action, + &p->action_params, + &p->opt_action_params, + entry); + return status; +} + +static switch_status_t switch_acl_egr_set_fields_actions( + switch_device_t device, + switch_acl_rule_t *p, + switch_handle_t interface_handle, + p4_pd_entry_hdl_t *entry) { + switch_acl_egr_key_value_pair_t *egr_acl = NULL; + switch_interface_info_t *intf_info = NULL; + uint16_t bd_label = 0; + uint16_t if_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (interface_handle) { + if (switch_handle_get_type(interface_handle) == SWITCH_HANDLE_TYPE_PORT) { + if_label = handle_to_id(interface_handle); + } else { + intf_info = switch_api_interface_get(interface_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_INTERFACE: + if_label = intf_info->api_intf_info.u.port_lag_handle; + break; + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle); + ; + break; default: - break; + return SWITCH_STATUS_INVALID_HANDLE; + } } - - if (intf) { - // use the ace_handle from rule list in the interface entries - JLI(hw_entry, intf->entries, ace_handle); - *(unsigned long *)hw_entry = entry; + } + egr_acl = (switch_acl_egr_key_value_pair_t *)p->fields; + + status = switch_pd_egr_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + egr_acl, + p->action, + &p->action_params, + &p->opt_action_params, + entry); + return status; +} + +static switch_status_t acl_hw_set(switch_device_t device, + switch_acl_info_t *acl_info, + switch_acl_rule_t *p, + switch_acl_interface_t *intf, + switch_handle_t interface_handle, + switch_handle_t ace_handle) { + p4_pd_entry_hdl_t entry; + switch_status_t status = SWITCH_STATUS_SUCCESS; + unsigned long *hw_entry = NULL; + + switch (acl_info->type) { + case SWITCH_ACL_TYPE_SYSTEM: + status = switch_acl_system_set_fields_actions( + device, p, interface_handle, &entry); + break; + case SWITCH_ACL_TYPE_IP: + status = + switch_acl_ip_set_fields_actions(device, p, interface_handle, &entry); + break; + case SWITCH_ACL_TYPE_IPV6: + status = switch_acl_ipv6_set_fields_actions( + device, p, interface_handle, &entry); + break; + case SWITCH_ACL_TYPE_IP_RACL: + status = switch_acl_ip_racl_set_fields_actions( + device, p, interface_handle, &entry); + break; + case SWITCH_ACL_TYPE_IPV6_RACL: + status = switch_acl_ipv6_racl_set_fields_actions( + device, p, interface_handle, &entry); + break; + case SWITCH_ACL_TYPE_MAC: + status = switch_acl_mac_set_fields_actions( + device, p, interface_handle, &entry); + break; + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: + status = switch_acl_egr_set_fields_actions( + device, p, interface_handle, &entry); + break; + default: + break; + } + + if (intf) { + // use the ace_handle from rule list in the interface entries + JLI(hw_entry, intf->entries, ace_handle); + *(unsigned long *)hw_entry = entry; + } else { + // if there is no interface, store hw handle with ace data + switch_acl_rule_t *rule = NULL; + rule = switch_ace_get(ace_handle); + rule->hw_entry = entry; + } + return status; +} + +static switch_status_t acl_hw_del(switch_device_t device, + switch_acl_info_t *acl_info, + switch_acl_interface_t *intf, + switch_handle_t ace_handle) { + unsigned long *hw_entry = NULL; + int ret = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!intf) { + // in case there is no interface, hw handle is stored with ace + if (acl_info->type != SWITCH_ACL_TYPE_SYSTEM) + return SWITCH_STATUS_UNSUPPORTED_TYPE; + + return switch_pd_system_acl_table_delete_entry( + device, switch_ace_get(ace_handle)->hw_entry); + } + + JLG(hw_entry, intf->entries, ace_handle); + if (hw_entry) { + switch (acl_info->type) { + case SWITCH_ACL_TYPE_SYSTEM: + status = switch_pd_system_acl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + case SWITCH_ACL_TYPE_IP: + status = switch_pd_ipv4_acl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + case SWITCH_ACL_TYPE_IPV6: + status = switch_pd_ipv6_acl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + case SWITCH_ACL_TYPE_IP_RACL: + status = switch_pd_ipv4_racl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + case SWITCH_ACL_TYPE_IPV6_RACL: + status = switch_pd_ipv6_racl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + case SWITCH_ACL_TYPE_MAC: + status = switch_pd_mac_acl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: + status = switch_pd_egr_acl_table_delete_entry( + device, *(unsigned long *)hw_entry); + break; + default: + break; } - return status; -} - -static switch_status_t -acl_hw_del(switch_device_t device, switch_acl_info_t *acl_info, - switch_acl_interface_t *intf, switch_handle_t ace_handle) -{ - unsigned long *hw_entry = NULL; - int ret = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - JLG(hw_entry, intf->entries, ace_handle); - if(hw_entry) { - switch(acl_info->type) { - case SWITCH_ACL_TYPE_SYSTEM: - status = switch_pd_system_acl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_IP: - status = switch_pd_ipv4_acl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_IPV6: - status = switch_pd_ipv6_acl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_IP_RACL: - status = switch_pd_ipv4_racl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_IPV6_RACL: - status = switch_pd_ipv6_racl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_MAC: - status = switch_pd_mac_acl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_QOS: - status = switch_pd_qos_acl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - status = switch_pd_egr_acl_table_delete_entry(device, *(unsigned long *) hw_entry); - break; - default: - break; + } + JLD(ret, intf->entries, ace_handle); + return status; +} + +switch_status_t switch_api_acl_rule_create( + switch_device_t device, + switch_handle_t acl_handle, + unsigned int priority, + unsigned int key_value_count, + void *acl_kvp, + switch_acl_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + switch_handle_t *ace) { + switch_acl_info_t *acl_info = NULL; + switch_acl_ip_key_value_pair_t *ip_acl = NULL; + switch_acl_system_key_value_pair_t *system_acl = NULL; + switch_acl_ipv6_key_value_pair_t *ipv6_acl = NULL; + switch_acl_mac_key_value_pair_t *mac_acl = NULL; + switch_acl_egr_key_value_pair_t *egr_acl = NULL; + unsigned long *jp = NULL; + void *fields = NULL; + switch_acl_rule_t *p = NULL; + tommy_node *node = NULL; + switch_acl_interface_t *intf = NULL; + unsigned int i = 0; + switch_handle_t ace_handle = -1; + + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + // create an ace entry + ace_handle = switch_ace_create(); + if (!ace_handle) { + return SWITCH_STATUS_NO_MEMORY; + } + + p = switch_ace_get(ace_handle); + + JLI(jp, acl_info->rules, ace_handle); + if (jp) { + switch (acl_info->type) { + case SWITCH_ACL_TYPE_IP: + ip_acl = (switch_acl_ip_key_value_pair_t *)acl_kvp; + fields = switch_malloc( + sizeof(switch_acl_ip_key_value_pair_t) * SWITCH_ACL_IP_FIELD_MAX, + 1); + if (!fields) { + return SWITCH_STATUS_NO_MEMORY; } - } - JLD(ret, intf->entries, ace_handle); - return status; -} - -switch_status_t -switch_api_acl_rule_create(switch_device_t device, switch_handle_t acl_handle, - unsigned int priority, unsigned int key_value_count, - void *acl_kvp, switch_acl_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - switch_handle_t *ace) -{ - switch_acl_info_t *acl_info = NULL; - switch_acl_ip_key_value_pair_t *ip_acl = NULL; - switch_acl_system_key_value_pair_t *system_acl = NULL; - switch_acl_ipv6_key_value_pair_t *ipv6_acl =NULL; - switch_acl_mac_key_value_pair_t *mac_acl = NULL; - switch_acl_egr_key_value_pair_t *egr_acl = NULL; - unsigned long *jp = NULL; - void *fields = NULL; - switch_acl_rule_t *p = NULL; - tommy_node *node = NULL; - switch_acl_interface_t *intf = NULL; - unsigned int i = 0; - switch_handle_t ace_handle=-1; - - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - // create an ace entry - ace_handle = switch_ace_create(); - if (!ace_handle) { - return SWITCH_STATUS_NO_MEMORY; - } - - p = switch_ace_get(ace_handle); - - JLI(jp, acl_info->rules, ace_handle); - if (jp) { - switch (acl_info->type) { - case SWITCH_ACL_TYPE_IP: - ip_acl = (switch_acl_ip_key_value_pair_t *)acl_kvp; - fields = switch_malloc(sizeof(switch_acl_ip_key_value_pair_t )*SWITCH_ACL_IP_FIELD_MAX, 1); - if (!fields) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(fields, 0, sizeof(switch_acl_ip_key_value_pair_t )*SWITCH_ACL_IP_FIELD_MAX); - break; - case SWITCH_ACL_TYPE_SYSTEM: - system_acl = (switch_acl_system_key_value_pair_t *)acl_kvp; - fields = switch_malloc(sizeof(switch_acl_system_key_value_pair_t )*SWITCH_ACL_SYSTEM_FIELD_MAX, 1); - if (!fields) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(fields, 0, sizeof(switch_acl_system_key_value_pair_t )*SWITCH_ACL_SYSTEM_FIELD_MAX); - break; - case SWITCH_ACL_TYPE_IPV6: - ipv6_acl = (switch_acl_ipv6_key_value_pair_t *)acl_kvp; - fields = switch_malloc(sizeof(switch_acl_ipv6_key_value_pair_t )*SWITCH_ACL_IPV6_FIELD_MAX, 1); - if (!fields) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(fields, 0, sizeof(switch_acl_ipv6_key_value_pair_t )*SWITCH_ACL_IPV6_FIELD_MAX); - break; - case SWITCH_ACL_TYPE_MAC: - mac_acl = (switch_acl_mac_key_value_pair_t *)acl_kvp; - fields = switch_malloc(sizeof(switch_acl_mac_key_value_pair_t )*SWITCH_ACL_MAC_FIELD_MAX, 1); - if (!fields) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(fields, 0, sizeof(switch_acl_mac_key_value_pair_t )*SWITCH_ACL_MAC_FIELD_MAX); - break; - case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - egr_acl = (switch_acl_egr_key_value_pair_t *)acl_kvp; - fields = switch_malloc(sizeof(switch_acl_egr_key_value_pair_t )*SWITCH_ACL_EGR_FIELD_MAX, 1); - if (!fields) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(fields, 0, sizeof(switch_acl_egr_key_value_pair_t )*SWITCH_ACL_EGR_FIELD_MAX); - break; - default: - break; + memset( + fields, + 0, + sizeof(switch_acl_ip_key_value_pair_t) * SWITCH_ACL_IP_FIELD_MAX); + break; + case SWITCH_ACL_TYPE_SYSTEM: + system_acl = (switch_acl_system_key_value_pair_t *)acl_kvp; + fields = switch_malloc(sizeof(switch_acl_system_key_value_pair_t) * + SWITCH_ACL_SYSTEM_FIELD_MAX, + 1); + if (!fields) { + return SWITCH_STATUS_NO_MEMORY; } + memset(fields, + 0, + sizeof(switch_acl_system_key_value_pair_t) * + SWITCH_ACL_SYSTEM_FIELD_MAX); + break; + case SWITCH_ACL_TYPE_IPV6: + ipv6_acl = (switch_acl_ipv6_key_value_pair_t *)acl_kvp; + fields = switch_malloc(sizeof(switch_acl_ipv6_key_value_pair_t) * + SWITCH_ACL_IPV6_FIELD_MAX, + 1); if (!fields) { - return SWITCH_STATUS_NO_MEMORY; + return SWITCH_STATUS_NO_MEMORY; } - if (p) { - memset(p, 0, sizeof(switch_acl_rule_t)); - // walk the list and set the structs - for (i=0;itype) { - case SWITCH_ACL_TYPE_IP: - *((switch_acl_ip_key_value_pair_t *)fields + i) = ip_acl[i]; - break; - case SWITCH_ACL_TYPE_SYSTEM: - *((switch_acl_system_key_value_pair_t *)fields + i) = system_acl[i]; - break; - case SWITCH_ACL_TYPE_IPV6: - *((switch_acl_ipv6_key_value_pair_t *)fields + i) = ipv6_acl[i]; - break; - case SWITCH_ACL_TYPE_MAC: - *((switch_acl_mac_key_value_pair_t *)fields + i) = mac_acl[i]; - break; - case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - *((switch_acl_egr_key_value_pair_t *)fields + i) = egr_acl[i]; - break; - default: - break; - } - } - p->acl_handle = acl_handle; - p->field_count = key_value_count; - p->fields = fields; - p->action = action; - p->action_params = *action_params; - p->opt_action_params = *opt_action_params; - p->priority = priority; + memset(fields, + 0, + sizeof(switch_acl_ipv6_key_value_pair_t) * + SWITCH_ACL_IPV6_FIELD_MAX); + break; + case SWITCH_ACL_TYPE_MAC: + mac_acl = (switch_acl_mac_key_value_pair_t *)acl_kvp; + fields = switch_malloc( + sizeof(switch_acl_mac_key_value_pair_t) * SWITCH_ACL_MAC_FIELD_MAX, + 1); + if (!fields) { + return SWITCH_STATUS_NO_MEMORY; } - *(unsigned long *)jp = (unsigned long)p; - - // if interface referenced then make the hardware table changes - if (acl_info->interface_list) { - node = tommy_list_head(&(acl_info->interface_list)); - while (node) { - intf = (switch_acl_interface_t *)node->data; - // update ACL H/W entries - acl_hw_set(device, acl_info, p, intf, intf->interface, ace_handle); - node = node->next; - } - } else { - if ((acl_info->type == SWITCH_ACL_TYPE_SYSTEM)) { - // update system ACL H/W entries - acl_hw_set(device, acl_info, p, NULL, 0, ace_handle); - } + memset( + fields, + 0, + sizeof(switch_acl_mac_key_value_pair_t) * SWITCH_ACL_MAC_FIELD_MAX); + break; + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: + egr_acl = (switch_acl_egr_key_value_pair_t *)acl_kvp; + fields = switch_malloc( + sizeof(switch_acl_egr_key_value_pair_t) * SWITCH_ACL_EGR_FIELD_MAX, + 1); + if (!fields) { + return SWITCH_STATUS_NO_MEMORY; } + memset( + fields, + 0, + sizeof(switch_acl_egr_key_value_pair_t) * SWITCH_ACL_EGR_FIELD_MAX); + break; + default: + break; } - *ace = ace_handle; - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_acl_rule_delete(switch_device_t device, - switch_handle_t acl_handle, - switch_handle_t ace_handle) -{ - switch_acl_info_t *acl_info = NULL; - switch_acl_rule_t *p = NULL; - tommy_node *node = NULL; - unsigned long *jp = NULL; - switch_acl_interface_t *intf = NULL; - int ret = 0; - switch_ace_info_t *ace_info = NULL; - - if(acl_handle == 0) { - ace_info = switch_ace_get(ace_handle); - acl_handle = ace_info->acl_handle; - } - - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_INVALID_HANDLE; + if (!fields) { + return SWITCH_STATUS_NO_MEMORY; } - - JLG(jp, acl_info->rules, ace_handle); - if (jp) { - p = (switch_acl_rule_t *) (*(unsigned long *)jp); - JLD(ret, acl_info->rules, ace_handle); - if (p) { - // if interface referenced then make the hardware table changes - if (acl_info->interface_list) { - node = tommy_list_head(&(acl_info->interface_list)); - while (node) { - intf = (switch_acl_interface_t *)node->data; - // update ACL H/W entries - acl_hw_del(device, acl_info, intf, ace_handle); - node = node->next; - } - } - if (p->fields) { - switch_free(p->fields); - } - switch_ace_delete(ace_handle); + if (p) { + memset(p, 0, sizeof(switch_acl_rule_t)); + // walk the list and set the structs + for (i = 0; i < key_value_count; i++) { + switch (acl_info->type) { + case SWITCH_ACL_TYPE_IP: + *((switch_acl_ip_key_value_pair_t *)fields + i) = ip_acl[i]; + break; + case SWITCH_ACL_TYPE_SYSTEM: + *((switch_acl_system_key_value_pair_t *)fields + i) = system_acl[i]; + break; + case SWITCH_ACL_TYPE_IPV6: + *((switch_acl_ipv6_key_value_pair_t *)fields + i) = ipv6_acl[i]; + break; + case SWITCH_ACL_TYPE_MAC: + *((switch_acl_mac_key_value_pair_t *)fields + i) = mac_acl[i]; + break; + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: + *((switch_acl_egr_key_value_pair_t *)fields + i) = egr_acl[i]; + break; + default: + break; } + } + p->acl_handle = acl_handle; + p->field_count = key_value_count; + p->fields = fields; + p->action = action; + p->action_params = *action_params; + p->opt_action_params = *opt_action_params; + p->priority = priority; } - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_acl_renumber(switch_device_t device, - switch_handle_t acl_handle, - int increment_priority) -{ - // modify priority in reverse order for priority > 0 or increasing order if - // walk the list of entries and modify the priority - when supported - // in pipe_mgr library - if (increment_priority < 0) { - // go in ascending order - } else { - // go in descending order - } - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_acl_reference(switch_device_t device, - switch_handle_t acl_handle, - switch_handle_t interface_handle) -{ - switch_acl_interface_t *intf = NULL; - switch_acl_info_t *acl_info = NULL; - unsigned long *jp = NULL; - switch_handle_t ace_handle = -1; - - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if (acl_info->type == SWITCH_ACL_TYPE_SYSTEM) - return SWITCH_STATUS_ITEM_ALREADY_EXISTS; + *(unsigned long *)jp = (unsigned long)p; - intf = (switch_acl_interface_t *)switch_malloc(sizeof(switch_acl_interface_t), 1); - if (!intf) { - return SWITCH_STATUS_NO_MEMORY; - } - - intf->entries = NULL; - JLL(jp, acl_info->rules, ace_handle); - while (jp) { - acl_hw_set(device, acl_info, (switch_acl_rule_t *)(*(unsigned long *)jp), intf, interface_handle, ace_handle); - // walk the table - JLP(jp, acl_info->rules, ace_handle); - } - intf->interface = interface_handle; - tommy_list_insert_head(&(acl_info->interface_list), &(intf->node), intf); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_acl_remove(switch_device_t device, - switch_handle_t acl_handle, - switch_handle_t interface_handle) -{ - switch_acl_info_t *acl_info = NULL; - switch_acl_interface_t *intf = NULL; - tommy_node *node = NULL; - unsigned long *jp = NULL; - switch_handle_t ace_handle = -1; - - acl_info = switch_acl_get(acl_handle); - if (!acl_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - // Delete the rules - node = tommy_list_head(&(acl_info->interface_list)); - while (node) { + // if interface referenced then make the hardware table changes + if (acl_info->interface_list) { + node = tommy_list_head(&(acl_info->interface_list)); + while (node) { intf = (switch_acl_interface_t *)node->data; - if (intf->interface == interface_handle) - break; + // update ACL H/W entries + acl_hw_set(device, acl_info, p, intf, intf->interface, ace_handle); node = node->next; + } + } else { + if ((acl_info->type == SWITCH_ACL_TYPE_SYSTEM)) { + // update system ACL H/W entries + acl_hw_set(device, acl_info, p, NULL, 0, ace_handle); + } } - if(!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - JLL(jp, acl_info->rules, ace_handle); - while (jp) { - acl_hw_del(device, acl_info, intf, ace_handle); - JLP(jp, acl_info->rules, ace_handle); + } + *ace = ace_handle; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_acl_rule_delete(switch_device_t device, + switch_handle_t acl_handle, + switch_handle_t ace_handle) { + switch_acl_info_t *acl_info = NULL; + switch_acl_rule_t *p = NULL; + tommy_node *node = NULL; + unsigned long *jp = NULL; + switch_acl_interface_t *intf = NULL; + int ret = 0; + switch_ace_info_t *ace_info = NULL; + + if (acl_handle == 0) { + ace_info = switch_ace_get(ace_handle); + acl_handle = ace_info->acl_handle; + } + + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + JLG(jp, acl_info->rules, ace_handle); + if (jp) { + p = (switch_acl_rule_t *)(*(unsigned long *)jp); + JLD(ret, acl_info->rules, ace_handle); + if (p) { + // if interface referenced then make the hardware table changes + if (acl_info->interface_list) { + node = tommy_list_head(&(acl_info->interface_list)); + while (node) { + intf = (switch_acl_interface_t *)node->data; + // update ACL H/W entries + acl_hw_del(device, acl_info, intf, ace_handle); + node = node->next; + } + } else { + acl_hw_del(device, acl_info, NULL, ace_handle); + } + if (p->fields) { + switch_free(p->fields); + } + switch_ace_delete(ace_handle); } - // remove from interface list - tommy_list_remove_existing(&(acl_info->interface_list), node); - switch_free(intf); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_drop_stats_get(switch_device_t device, - int *num_counters, - uint64_t **counters) -{ - *num_counters = 256; - *counters = (uint64_t *)malloc(sizeof(uint64_t) * (*num_counters)); - memset(*counters, 0, sizeof(uint64_t) * (*num_counters)); - switch_pd_drop_stats_get(device, *num_counters, *counters); - return SWITCH_STATUS_SUCCESS; -} - -switch_handle_t -switch_api_acl_counter_create( - switch_device_t device) -{ - switch_handle_t counter_handle = 0; - unsigned int id = 0; - - id = switch_acl_counter_index_allocate(); - counter_handle = id_to_handle(SWITCH_HANDLE_TYPE_ACL_COUNTER, id); - return counter_handle; -} - -switch_status_t -switch_api_acl_counter_delete( - switch_device_t device, - switch_handle_t counter_handle) -{ - unsigned int id = 0; - - id = handle_to_id(counter_handle); - switch_acl_counter_index_free(id); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_acl_stats_get( - switch_device_t device, - switch_handle_t counter_handle, - switch_counter_t *counter) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - status = switch_pd_acl_stats_get( - device, - handle_to_id(counter_handle), - counter); - return status; + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_acl_renumber(switch_device_t device, + switch_handle_t acl_handle, + int increment_priority) { + // modify priority in reverse order for priority > 0 or increasing order if + // walk the list of entries and modify the priority - when supported + // in pipe_mgr library + if (increment_priority < 0) { + // go in ascending order + } else { + // go in descending order + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_acl_reference(switch_device_t device, + switch_handle_t acl_handle, + switch_handle_t interface_handle) { + switch_acl_interface_t *intf = NULL; + switch_acl_info_t *acl_info = NULL; + unsigned long *jp = NULL; + switch_handle_t ace_handle = -1; + + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if (acl_info->type == SWITCH_ACL_TYPE_SYSTEM) + return SWITCH_STATUS_ITEM_ALREADY_EXISTS; + + intf = (switch_acl_interface_t *)switch_malloc(sizeof(switch_acl_interface_t), + 1); + if (!intf) { + return SWITCH_STATUS_NO_MEMORY; + } + + intf->entries = NULL; + JLL(jp, acl_info->rules, ace_handle); + while (jp) { + acl_hw_set(device, + acl_info, + (switch_acl_rule_t *)(*(unsigned long *)jp), + intf, + interface_handle, + ace_handle); + // walk the table + JLP(jp, acl_info->rules, ace_handle); + } + intf->interface = interface_handle; + tommy_list_insert_head(&(acl_info->interface_list), &(intf->node), intf); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_acl_remove(switch_device_t device, + switch_handle_t acl_handle, + switch_handle_t interface_handle) { + switch_acl_info_t *acl_info = NULL; + switch_acl_interface_t *intf = NULL; + tommy_node *node = NULL; + unsigned long *jp = NULL; + switch_handle_t ace_handle = -1; + + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + // Delete the rules + node = tommy_list_head(&(acl_info->interface_list)); + while (node) { + intf = (switch_acl_interface_t *)node->data; + if (intf->interface == interface_handle) break; + node = node->next; + } + if (!node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + JLL(jp, acl_info->rules, ace_handle); + while (jp) { + acl_hw_del(device, acl_info, intf, ace_handle); + JLP(jp, acl_info->rules, ace_handle); + } + // remove from interface list + tommy_list_remove_existing(&(acl_info->interface_list), node); + switch_free(intf); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_drop_stats_get(switch_device_t device, + int *num_counters, + uint64_t **counters) { + *num_counters = 256; + *counters = (uint64_t *)malloc(sizeof(uint64_t) * (*num_counters)); + memset(*counters, 0, sizeof(uint64_t) * (*num_counters)); + switch_pd_drop_stats_get(device, *num_counters, *counters); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_api_acl_counter_create(switch_device_t device) { + switch_handle_t counter_handle = 0; + unsigned int id = 0; + + id = switch_acl_counter_index_allocate(); + counter_handle = id_to_handle(SWITCH_HANDLE_TYPE_ACL_COUNTER, id); + return counter_handle; +} + +switch_status_t switch_api_acl_counter_delete(switch_device_t device, + switch_handle_t counter_handle) { + unsigned int id = 0; + + id = handle_to_id(counter_handle); + switch_acl_counter_index_free(id); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_acl_stats_get(switch_device_t device, + switch_handle_t counter_handle, + switch_counter_t *counter) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + status = + switch_pd_acl_stats_get(device, handle_to_id(counter_handle), counter); + return status; +} + +switch_acl_type_t switch_acl_type_get(switch_device_t device, + switch_handle_t acl_handle) { + switch_acl_info_t *acl_info = NULL; + acl_info = switch_acl_get(acl_handle); + if (!acl_info) { + return 0; + } + + return acl_info->type; } #ifdef __cplusplus diff --git a/switchapi/src/switch_acl_int.h b/switchapi/src/switch_acl_int.h index 187b102..34a5dd8 100644 --- a/switchapi/src/switch_acl_int.h +++ b/switchapi/src/switch_acl_int.h @@ -19,28 +19,30 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" +#include "switch_pd_types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -#define SWITCH_ACL_HASH_TABLE_SIZE (64*1024) +#define SWITCH_ACL_HASH_TABLE_SIZE (64 * 1024) typedef struct switch_acl_interface_ { - tommy_node node; - switch_handle_t interface; - void *entries; + tommy_node node; + switch_handle_t interface; + void *entries; } switch_acl_interface_t; typedef struct switch_acl_rule_ { - switch_handle_t acl_handle; - int priority; - unsigned int field_count; - void *fields; - switch_acl_action_t action; - unsigned int action_param_size; - switch_acl_action_params_t action_params; - switch_acl_opt_action_params_t opt_action_params; + switch_handle_t acl_handle; + int priority; + unsigned int field_count; + void *fields; + switch_acl_action_t action; + unsigned int action_param_size; + switch_acl_action_params_t action_params; + switch_acl_opt_action_params_t opt_action_params; + p4_pd_entry_hdl_t hw_entry; } switch_acl_rule_t; switch_status_t switch_acl_init(switch_device_t device); diff --git a/switchapi/src/switch_api.thrift b/switchapi/src/switch_api.thrift index 390cb00..16c47c6 100644 --- a/switchapi/src/switch_api.thrift +++ b/switchapi/src/switch_api.thrift @@ -90,6 +90,7 @@ typedef i32 switcht_stp_state_t typedef i32 switcht_intf_attr_t typedef i16 switcht_nat_mode_t +typedef i16 switcht_nat_rw_type_t typedef i16 switcht_mcast_mode_t typedef i32 switcht_urpf_group_t @@ -121,6 +122,7 @@ struct switcht_ip_addr_t { struct switcht_flow_t { 1: switcht_ip_addr_t src_ip; 2: switcht_ip_addr_t dst_ip; + 3: bool is_local_flow; } typedef list switcht_flow_list_t @@ -138,12 +140,12 @@ struct switcht_vlan_interface_t { typedef i32 switcht_protocol_t struct switcht_udp_t { - 1: i16 src_port; + 1: i16 src_port; 2: i16 dst_port; } struct switcht_tcp_t { - 1: i16 src_port; + 1: i16 src_port; 2: i16 dst_port; } @@ -217,6 +219,21 @@ struct switcht_neighbor_info_t { 9: switcht_neighbor_rw_type_t rw_type; } +struct switcht_nat_info_t { + 1: switcht_nat_rw_type_t nat_rw_type; + 2: switcht_ip_addr_t src_ip; + 3: switcht_ip_addr_t dst_ip; + 4: i32 src_port; + 5: i32 dst_port; + 6: i16 protocol; + 7: switcht_handle_t vrf_handle; + 9: switcht_handle_t nhop_handle; + 10: switcht_ip_addr_t rw_src_ip; + 11: switcht_ip_addr_t rw_dst_ip; + 12: i32 rw_src_port; + 13: i32 rw_dst_port; +} + struct switcht_vxlan_id_t { 1: i32 vnid; } @@ -382,8 +399,9 @@ struct switcht_nhop_key_t { } struct switcht_hostif_group_t { - 1: i32 egress_queue; + 1: i32 queue_id; 2: i32 priority; + 3: i32 policer_handle; } struct switcht_counter_t { @@ -473,6 +491,42 @@ struct switcht_api_meter_info_t { 10: switcht_acl_action_t red_action; } +struct switcht_api_buffer_profile_t { + 1: byte threshold_mode; + 2: i32 threshold; + 3: switcht_handle_t pool_handle; + 4: i32 buffer_size; + 5: i32 xoff_threshold; + 6: i32 xon_threshold; +} + +typedef i16 switcht_qos_map_type_t +typedef byte switcht_color_t + +struct switcht_qos_map_t { + 1: byte dscp; + 2: byte pcp; + 3: i16 tc; + 4: switcht_color_t color; + 5: byte icos; + 6: byte qid; +} + +typedef byte switcht_scheduler_type_t +typedef byte switcht_shaper_type_t + +struct switcht_scheduler_info_t { + 1: switcht_scheduler_type_t scheduler_type; + 2: switcht_shaper_type_t shaper_type; + 3: i32 priority; + 4: i32 rem_bw_priority; + 5: i32 weight; + 6: i32 min_burst_size; + 7: i32 min_rate; + 8: i32 max_burst_size; + 9: i32 max_rate; +} + service switch_api_rpc { /* init */ switcht_status_t switcht_api_init(1:switcht_device_t device); @@ -492,10 +546,51 @@ service switch_api_rpc { 1: switcht_device_t device, 2: switcht_handle_t meter_handle, 3: list counter_ids); + switcht_status_t switcht_api_port_trust_dscp_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: bool trust_dscp); + switcht_status_t switcht_api_port_trust_pcp_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: bool trust_pcp); + switcht_status_t switcht_api_port_drop_limit_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: i32 num_bytes); + switcht_status_t switcht_api_port_drop_hysteresis_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: i32 num_bytes); + switcht_status_t switcht_api_port_pfc_cos_mapping( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: list cos_to_icos); + switcht_status_t switcht_api_port_tc_default_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: i16 tc); + switcht_status_t switcht_api_port_color_default_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_color_t color); + switcht_status_t switcht_api_port_qos_group_ingress_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t qos_handle); + switcht_status_t switcht_api_port_qos_group_tc_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t qos_handle); + switcht_status_t switcht_api_port_qos_group_egress_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t qos_handle); /* vpn */ switcht_handle_t switcht_api_vrf_create(1:switcht_device_t device, 2:switcht_vrf_id_t vrf); switcht_status_t switcht_api_vrf_delete(1:switcht_device_t device, 2:switcht_handle_t vrf_handle); + switcht_handle_t switcht_api_default_vrf_get(); /* router mac */ switcht_handle_t switcht_api_router_mac_group_create(1:switcht_device_t device); @@ -514,6 +609,9 @@ service switch_api_rpc { switcht_status_t switcht_api_interface_ipv4_urpf_mode_set(1: switcht_handle_t intf_handle, 2: i64 value); switcht_status_t switcht_api_interface_ipv6_urpf_mode_set(1: switcht_handle_t intf_handle, 2: i64 value); + /* get interface handle by vrf + ip */ + switcht_handle_t switcht_api_l3_route_nhop_intf_get(1:switcht_device_t device, 2:switcht_handle_t vrf, 3:switcht_ip_addr_t ip_addr); + /* ip address */ switcht_status_t switcht_api_l3_interface_address_add(1:switcht_device_t device, 2:switcht_interface_handle_t interface_handle, 3:switcht_handle_t vrf, 4:switcht_ip_addr_t ip_addr); switcht_status_t switcht_api_l3_interface_address_delete(1:switcht_device_t device, 2:switcht_interface_handle_t interface_handle, 3:switcht_handle_t vrf, 4:switcht_ip_addr_t ip_addr); @@ -531,6 +629,7 @@ service switch_api_rpc { /* L3 */ switcht_status_t switcht_api_l3_route_add(1:switcht_device_t device, 2:switcht_handle_t vrf, 3:switcht_ip_addr_t ip_addr, 4: switcht_handle_t nhop_handle); switcht_status_t switcht_api_l3_route_delete(1:switcht_device_t device, 2:switcht_handle_t vrf, 3:switcht_ip_addr_t ip_addr, 4: switcht_handle_t nhop_handle); + switcht_handle_t switcht_api_l3_route_lookup(1:switcht_device_t device, 2:switcht_handle_t vrf, 3:switcht_ip_addr_t ip_addr); switcht_status_t switcht_api_l3_routes_print_all() /* VLAN */ @@ -598,6 +697,10 @@ service switch_api_rpc { 3:switcht_handle_t intf_handle); switcht_status_t switcht_api_stp_group_print_all(); + /* NAT API */ + switcht_status_t switcht_api_nat_create(1:switcht_device_t device, 2:switcht_nat_info_t nat_info); + switcht_status_t switcht_api_nat_delete(1:switcht_device_t device, 2:switcht_nat_info_t nat_info); + /* ACL API */ switcht_handle_t switcht_api_acl_list_create(1:switcht_device_t device, 2:switcht_acl_type_t type); switcht_status_t switcht_api_acl_list_delete(1:switcht_device_t device, 2:switcht_handle_t handle); @@ -702,6 +805,14 @@ service switch_api_rpc { switcht_handle_t switcht_api_hostif_create(1:switcht_device_t device, 2:switcht_hostif_t hostif); switcht_status_t switcht_api_hostif_delete(1:switcht_device_t device, 2:switcht_handle_t hostif_handle); + switcht_handle_t switcht_api_hostif_meter_create( + 1: switcht_device_t device, + 2: switcht_api_meter_info_t api_meter_info); + + switcht_status_t switcht_api_hostif_meter_delete( + 1: switcht_device_t device, + 2: switcht_handle_t meter_handle); + /* Multicast API */ switcht_handle_t switcht_api_multicast_tree_create(1:switcht_device_t device); switcht_status_t switcht_api_multicast_tree_delete(1:switcht_device_t device, 2:switcht_handle_t mgid_handle); @@ -784,4 +895,145 @@ service switch_api_rpc { 1:switcht_device_t device, 2:switcht_handle_t sflow_handle 3:switcht_handle_t entry_hdl); + + switcht_status_t switcht_api_sflow_session_sample_count_reset( + 1:switcht_device_t device, + 2:switcht_handle_t sflow_handle, + 3:switcht_handle_t entry_handle); + + switcht_counter_t switcht_api_sflow_session_sample_count_get( + 1:switcht_device_t device, + 2:switcht_handle_t sflow_handle, + 3:switcht_handle_t entry_handle); + + + /* PPG */ + switcht_status_t switcht_api_port_cos_mapping( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t ppg_handle, + 4: byte cos_bmp); + switcht_status_t switcht_api_ppg_lossless_enable( + 1: switcht_device_t device, + 2: switcht_handle_t ppg_handle, + 3: bool enabled); + list switcht_api_ppg_get( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle); + switcht_status_t switcht_api_ppg_guaranteed_limit_set( + 1: switcht_device_t device, + 2: switcht_handle_t ppg_handle, + 3: i32 num_bytes); + switcht_status_t switcht_api_ppg_skid_limit_set( + 1: switcht_device_t device, + 2: switcht_handle_t ppg_handle, + 3: i32 num_bytes); + switcht_status_t switcht_api_ppg_skid_hysteresis_set( + 1: switcht_device_t device, + 2: switcht_handle_t ppg_handle, + 3: i32 num_bytes); + + /* Buffer */ + switcht_handle_t switcht_api_buffer_pool_create( + 1: switcht_device_t device, + 2: switcht_direction_t direction, + 3: i16 pool_size); + switcht_status_t switcht_api_buffer_pool_delete( + 1: switcht_device_t device, + 2: switcht_handle_t buffer_pool_handle); + switcht_handle_t switcht_api_buffer_profile_create( + 1: switcht_device_t device, + 2: switcht_api_buffer_profile_t api_buffer_info); + switcht_status_t switcht_api_buffer_profile_delete( + 1: switcht_device_t device, + 2: switcht_handle_t buffer_profile_handle); + switcht_status_t switcht_api_ppg_buffer_profile_set( + 1: switcht_device_t device, + 2: switcht_handle_t ppg_handle, + 3: switcht_handle_t buffer_profile_handle); + switcht_status_t switcht_api_queue_buffer_profile_set( + 1: switcht_device_t device, + 2: switcht_handle_t queue_handle, + 3: switcht_handle_t buffer_profile_handle); + switcht_status_t switcht_api_buffer_skid_limit_set( + 1: switcht_device_t device, + 2: i32 num_bytes); + switcht_status_t switcht_api_buffer_skid_hysteresis_set( + 1: switcht_device_t device, + 2: i32 num_bytes); + switcht_status_t switcht_api_buffer_pool_pfc_limit( + 1: switcht_device_t device, + 2: switcht_handle_t pool_handle, + 3: byte icos, + 4: i32 num_bytes); + switcht_status_t switcht_api_buffer_pool_color_drop_enable( + 1: switcht_device_t device, + 2: switcht_handle_t pool_handle, + 3: bool enable); + switcht_status_t switcht_api_buffer_pool_color_limit_set( + 1: switcht_device_t device, + 2: switcht_handle_t pool_handle, + 3: switcht_color_t color, + 4: i32 num_bytes); + switcht_status_t switcht_api_buffer_pool_color_hysteresis_set( + 1: switcht_device_t device, + 2: switcht_color_t color, + 3: i32 num_bytes); + + + /* Qos */ + switcht_handle_t switcht_api_qos_map_ingress_create( + 1: switcht_device_t device, + 2: switcht_qos_map_type_t qos_map_type, + 3: list qos_map); + switcht_status_t switcht_api_qos_map_ingress_delete( + 1: switcht_device_t device, + 2: switcht_handle_t qos_map_handle); + switcht_handle_t switcht_api_qos_map_egress_create( + 1: switcht_device_t device, + 2: switcht_qos_map_type_t qos_map_type, + 3: list qos_map); + switcht_status_t switcht_api_qos_map_egress_delete( + 1: switcht_device_t device, + 2: switcht_handle_t qos_map_handle); + + /* Scheduler */ + switcht_handle_t switcht_api_scheduler_create( + 1: switcht_device_t device, + 2: switcht_scheduler_info_t api_scheduler_info); + switcht_status_t switcht_api_scheduler_delete( + 1: switcht_device_t device, + 2: switcht_handle_t scheduler_handle); + + /* Queues */ + list switcht_api_queues_get( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle); + switcht_status_t switcht_api_queue_color_drop_enable( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t queue_handle, + 4: bool enable); + switcht_status_t switcht_api_queue_color_limit_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t queue_handle, + 4: switcht_color_t color, + 5: i32 limit); + switcht_status_t switcht_api_queue_color_hysteresis_set( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t queue_handle, + 4: switcht_color_t color, + 5: i32 limit); + switcht_status_t switcht_api_queue_pfc_cos_mapping( + 1: switcht_device_t device, + 2: switcht_handle_t port_handle, + 3: switcht_handle_t queue_handle, + 4: byte cos); + /* MTU */ + switcht_status_t switcht_api_mtu_entry_create( + 1: switcht_device_t device, + 2: i16 mtu_index, + 3: i32 mtu); } diff --git a/switchapi/src/switch_api_rpc_server.cpp b/switchapi/src/switch_api_rpc_server.cpp index 25e79a4..e695887 100644 --- a/switchapi/src/switch_api_rpc_server.cpp +++ b/switchapi/src/switch_api_rpc_server.cpp @@ -28,6 +28,7 @@ limitations under the License. #include "switchapi/switch_tunnel.h" #include "switchapi/switch_vrf.h" #include "switchapi/switch_nhop.h" +#include "switchapi/switch_nat.h" #include "switchapi/switch_hostif.h" #include "switchapi/switch_acl.h" #include "switchapi/switch_mcast.h" @@ -38,6 +39,10 @@ limitations under the License. #include "switchapi/switch_protocol.h" #include "switchapi/switch_meter.h" #include "switchapi/switch_sflow.h" +#include "switchapi/switch_capability.h" +#include "switchapi/switch_qos.h" +#include "switchapi/switch_buffer.h" +#include "switchapi/switch_queue.h" #include "arpa/inet.h" #define SWITCH_API_RPC_SERVER_PORT (9091) @@ -192,6 +197,84 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return; } + switcht_status_t + switcht_api_port_trust_dscp_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const bool trust_dscp) { + return switch_api_port_trust_dscp_set(device, port_handle, trust_dscp); + } + + switcht_status_t + switcht_api_port_trust_pcp_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const bool trust_pcp) { + return switch_api_port_trust_dscp_set(device, port_handle, trust_pcp); + } + + switcht_status_t switcht_api_port_drop_limit_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const int32_t num_bytes) { + return switch_api_port_drop_limit_set( + device, + port_handle, + num_bytes); + } + + switcht_status_t switcht_api_port_drop_hysteresis_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const int32_t num_bytes) { + return switch_api_port_drop_hysteresis_set( + device, + port_handle, + num_bytes); + } + + switcht_status_t switcht_api_port_pfc_cos_mapping( + const switcht_device_t device, + const switcht_handle_t port_handle, + const std::vector & cos_to_icos) { + return 0; + } + + switcht_status_t switcht_api_port_tc_default_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const int16_t tc) { + return switch_api_port_tc_default_set(device, port_handle, tc); + } + + switcht_status_t switcht_api_port_color_default_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_color_t color) { + return switch_api_port_color_default_set(device, port_handle, (switch_color_t) color); + } + + switcht_status_t switcht_api_port_qos_group_ingress_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t qos_handle) { + return switch_api_port_qos_group_ingress_set(device, port_handle, qos_handle); + } + + switcht_status_t switcht_api_port_qos_group_tc_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t qos_handle) { + return switch_api_port_qos_group_tc_set(device, port_handle, qos_handle); + } + + switcht_status_t switcht_api_port_qos_group_egress_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t qos_handle) { + return switch_api_port_qos_group_egress_set(device, port_handle, qos_handle); + } + switcht_status_t switcht_api_vrf_create(const switcht_device_t device, const switcht_vrf_id_t vrf) { printf("switcht_api_l3_vrf_create\n"); return switch_api_vrf_create(device, vrf); @@ -202,6 +285,11 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_vrf_delete(device, vrf_handle); } + switcht_handle_t switcht_api_default_vrf_get() { + printf("switcht_api_l3_default_vrf_get\n"); + return switch_api_default_vrf_internal(); + } + switcht_handle_t switcht_api_router_mac_group_create(const switcht_device_t device) { printf("switcht_api_router_mac_group_create\n"); return switch_api_router_mac_group_create(device); @@ -239,6 +327,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { i_info.rmac_handle = interface_info.rmac_handle; i_info.flags.core_intf = interface_info.flags.core_intf; i_info.ipv4_urpf_mode = (switch_urpf_mode_t) interface_info.v4_urpf_mode; + i_info.nat_mode = interface_info.nat_mode; if (i_info.type == SWITCH_API_INTERFACE_L3_PORT_VLAN || i_info.type == SWITCH_API_INTERFACE_L2_PORT_VLAN) { i_info.u.port_vlan.port_lag_handle = interface_info.u.port_vlan.port_lag_handle; @@ -292,6 +381,16 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_interface_ipv6_urpf_mode_set(interface_handle, (uint64_t) value); } + switcht_handle_t switcht_api_l3_route_nhop_intf_get(const switcht_device_t device, const switcht_handle_t vrf, const switcht_ip_addr_t& ip_addr) { + printf("switcht_api_l3_route_nhop_intf_get\n"); + switch_handle_t intf_handle = SWITCH_API_INVALID_HANDLE; + switch_status_t status; + switch_ip_addr_t lip_addr; + switch_parse_ip_address(ip_addr, &lip_addr); + status = switch_api_l3_route_nhop_intf_get(device, vrf, &lip_addr, &intf_handle); + return intf_handle; + } + switcht_status_t switcht_api_l3_interface_address_add(const switcht_device_t device, const switcht_interface_handle_t interface_handle, const switcht_handle_t vrf, const switcht_ip_addr_t& ip_addr) { printf("switcht_api_l3_interface_address_add\n"); switch_ip_addr_t lip_addr; @@ -365,6 +464,16 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_l3_route_delete(device, vrf, &lip_addr, nhop_handle); } + switcht_handle_t switcht_api_l3_route_lookup(const switcht_device_t device, const switcht_handle_t vrf, const switcht_ip_addr_t& ip_addr) { + switch_handle_t nhop_handle = SWITCH_API_INVALID_HANDLE; + switch_status_t status; + switch_ip_addr_t lip_addr; + printf("switcht_api_l3_route_lookup\n"); + switch_parse_ip_address(ip_addr, &lip_addr); + status = switch_api_l3_route_lookup(device, vrf, &lip_addr, &nhop_handle); + return nhop_handle; + } + switcht_status_t switcht_api_l3_routes_print_all() { printf("switcht_api_l3_routes_print_all\n"); return switch_api_l3_routes_print_all(); @@ -752,6 +861,117 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_stp_port_state_clear(device, stg_handle, intf_handle); } + switcht_status_t switcht_api_nat_create(const switcht_device_t device, + const switcht_nat_info_t& info) { + printf("switcht_api_nat_create\n"); + switch_api_nat_info_t nat_info; + memset(&nat_info, 0, sizeof(switch_api_nat_info_t)); + + nat_info.nat_rw_type = (switch_nat_rw_type_t) info.nat_rw_type; + switch (nat_info.nat_rw_type) { + case SWITCH_NAT_RW_TYPE_SRC_TCP: + case SWITCH_NAT_RW_TYPE_SRC_UDP: + nat_info.protocol = info.protocol; + nat_info.src_port = info.src_port; + nat_info.rw_src_port = info.rw_src_port; + case SWITCH_NAT_RW_TYPE_SRC: + nat_info.src_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.src_ip.ipaddr, + &nat_info.src_ip.ip.v4addr); + nat_info.rw_src_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.rw_src_ip.ipaddr, + &nat_info.rw_src_ip.ip.v4addr); + break; + + case SWITCH_NAT_RW_TYPE_DST_TCP: + case SWITCH_NAT_RW_TYPE_DST_UDP: + nat_info.protocol = info.protocol; + nat_info.dst_port = info.dst_port; + nat_info.rw_dst_port = info.rw_dst_port; + case SWITCH_NAT_RW_TYPE_DST: + nat_info.dst_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.dst_ip.ipaddr, + &nat_info.dst_ip.ip.v4addr); + nat_info.rw_dst_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.rw_dst_ip.ipaddr, + &nat_info.rw_dst_ip.ip.v4addr); + break; + + case SWITCH_NAT_RW_TYPE_SRC_DST_TCP: + case SWITCH_NAT_RW_TYPE_SRC_DST_UDP: + nat_info.protocol = info.protocol; + nat_info.src_port = info.src_port; + nat_info.dst_port = info.dst_port; + nat_info.rw_src_port = info.rw_src_port; + nat_info.rw_dst_port = info.rw_dst_port; + case SWITCH_NAT_RW_TYPE_SRC_DST: + nat_info.src_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.src_ip.ipaddr, + &nat_info.src_ip.ip.v4addr); + nat_info.dst_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.dst_ip.ipaddr, + &nat_info.dst_ip.ip.v4addr); + nat_info.rw_src_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.rw_src_ip.ipaddr, + &nat_info.rw_src_ip.ip.v4addr); + nat_info.rw_dst_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.rw_dst_ip.ipaddr, + &nat_info.rw_dst_ip.ip.v4addr); + break; + } + + nat_info.vrf_handle = info.vrf_handle; + nat_info.nhop_handle = info.nhop_handle; + return (switch_api_nat_add(device, &nat_info)); + } + + switcht_status_t switcht_api_nat_delete(const switcht_device_t device, + const switcht_nat_info_t& info) { + printf("switcht_api_nat_delete\n"); + switch_api_nat_info_t nat_info; + memset(&nat_info, 0, sizeof(switch_api_nat_info_t)); + + nat_info.nat_rw_type = (switch_nat_rw_type_t) info.nat_rw_type; + switch (nat_info.nat_rw_type) { + case SWITCH_NAT_RW_TYPE_SRC_TCP: + case SWITCH_NAT_RW_TYPE_SRC_UDP: + nat_info.protocol = info.protocol; + nat_info.src_port = info.src_port; + case SWITCH_NAT_RW_TYPE_SRC: + nat_info.src_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.src_ip.ipaddr, + &nat_info.src_ip.ip.v4addr); + break; + + case SWITCH_NAT_RW_TYPE_DST_TCP: + case SWITCH_NAT_RW_TYPE_DST_UDP: + nat_info.protocol = info.protocol; + nat_info.dst_port = info.dst_port; + case SWITCH_NAT_RW_TYPE_DST: + nat_info.dst_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.dst_ip.ipaddr, + &nat_info.dst_ip.ip.v4addr); + break; + + case SWITCH_NAT_RW_TYPE_SRC_DST_TCP: + case SWITCH_NAT_RW_TYPE_SRC_DST_UDP: + nat_info.protocol = info.protocol; + nat_info.src_port = info.src_port; + nat_info.dst_port = info.dst_port; + case SWITCH_NAT_RW_TYPE_SRC_DST: + nat_info.src_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.src_ip.ipaddr, + &nat_info.src_ip.ip.v4addr); + nat_info.dst_ip.type = SWITCH_API_IP_ADDR_V4; + switch_string_to_v4_ip(info.dst_ip.ipaddr, + &nat_info.dst_ip.ip.v4addr); + break; + } + + nat_info.vrf_handle = info.vrf_handle; + return (switch_api_nat_delete(device, &nat_info)); + } + // ACL switcht_handle_t switcht_api_acl_list_create(const switcht_device_t device, const switcht_acl_type_t type) { @@ -787,16 +1007,16 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { case SWITCH_ACL_MAC_FIELD_SOURCE_MAC: case SWITCH_ACL_MAC_FIELD_DEST_MAC: { - unsigned char *mac = (unsigned char *) (((switch_acl_mac_key_value_pair_t *) fields + i)->value.source_mac); + unsigned char *mac = (unsigned char *) (((switch_acl_mac_key_value_pair_t *) fields + i)->value.source_mac.mac_addr); switch_string_to_mac(f->value.value_str, mac); - unsigned char *mac_mask = (unsigned char *) (((switch_acl_mac_key_value_pair_t *) fields + i)->mask.u.mac_mask); + unsigned char *mac_mask = (unsigned char *) (((switch_acl_mac_key_value_pair_t *) fields + i)->mask.u.mask); switch_string_to_mac(f->mask.value_str, mac_mask); break; } default: { unsigned long long v = (unsigned long long)((switch_acl_mac_field_t)f->value.value_num); - memcpy((((switch_acl_mac_key_value_pair_t *)fields+i)->value.source_mac), &v, sizeof(switch_acl_mac_value)); + memcpy((((switch_acl_mac_key_value_pair_t *)fields+i)->value.source_mac.mac_addr), &v, sizeof(switch_acl_mac_value)); ((switch_acl_mac_key_value_pair_t *)fields+i)->mask.u.mask16 = (switch_acl_mac_field_t)f->mask.value_num; break; } @@ -912,6 +1132,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { break; } + memset(&oap, 0, sizeof(switch_acl_opt_action_params_t)); oap.mirror_handle = opt_action_params.mirror_handle; oap.meter_handle = opt_action_params.meter_handle; oap.counter_handle = opt_action_params.counter_handle; @@ -1443,6 +1664,31 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { (switch_handle_t)((uint32_t)entry_handle)); } + switcht_status_t switcht_api_sflow_session_sample_count_reset( + const switcht_device_t device, + const switcht_handle_t sflow_handle, + const switcht_handle_t entry_handle) { + return switch_api_sflow_session_sample_count_reset(device, + (switch_handle_t)((uint32_t)sflow_handle), + (switch_handle_t)((uint32_t)entry_handle)); + } + + void switcht_api_sflow_session_sample_count_get( + switcht_counter_t& _counter, + const switcht_device_t device, + const switcht_handle_t sflow_handle, + const switcht_handle_t entry_handle) { + switch_counter_t counter; + printf("switcht_api_sflow_session_sample_count_get\n"); + switch_api_sflow_session_sample_count_get(device, + (switch_handle_t)((uint32_t)sflow_handle), + (switch_handle_t)((uint32_t)entry_handle), + &counter); + + _counter.num_packets = counter.num_packets; + _counter.num_bytes = counter.num_bytes; + } + switcht_status_t switcht_api_mac_table_set_learning_timeout(const switcht_device_t device, const int32_t timeout) { printf("switcht_api_mac_table_set_learning_timeout\n"); return (switch_api_mac_table_set_learning_timeout(device, timeout)); @@ -1539,8 +1785,9 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { switcht_handle_t switcht_api_hostif_group_create(const switcht_device_t device, const switcht_hostif_group_t& hostif_group) { printf("switcht_api_hostif_group_create\n"); switch_hostif_group_t lhostif_group; - lhostif_group.egress_queue = hostif_group.egress_queue; + lhostif_group.queue_id = hostif_group.queue_id; lhostif_group.priority = hostif_group.priority; + lhostif_group.policer_handle = hostif_group.policer_handle; return switch_api_hostif_group_create(device, &lhostif_group); } @@ -1577,6 +1824,34 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_hostif_delete(device, hostif_handle); } + switcht_handle_t switcht_api_hostif_meter_create( + const switcht_device_t device, + const switcht_api_meter_info_t& api_meter_info) { + printf("switcht_api_hostif_meter_create\n"); + switch_handle_t meter_handle = 0; + switch_api_meter_t api_meter; + memset(&api_meter, 0, sizeof(switch_api_meter_t)); + api_meter.meter_mode = (switch_meter_mode_t) api_meter_info.meter_mode; + api_meter.color_source = (switch_meter_color_source_t) api_meter_info.color_source; + api_meter.meter_type = (switch_meter_type_t) api_meter_info.meter_type; + api_meter.cbs = api_meter_info.cbs; + api_meter.pbs = api_meter_info.pbs; + api_meter.cir = api_meter_info.cir; + api_meter.pir = api_meter_info.pir; + api_meter.action[SWITCH_COLOR_GREEN] = (switch_acl_action_t) api_meter_info.green_action; + api_meter.action[SWITCH_COLOR_YELLOW] = (switch_acl_action_t) api_meter_info.yellow_action; + api_meter.action[SWITCH_COLOR_RED] = (switch_acl_action_t) api_meter_info.red_action; + switch_api_hostif_meter_create(device, &api_meter, &meter_handle); + return meter_handle; + } + + switcht_status_t switcht_api_hostif_meter_delete( + const switcht_device_t device, + const switcht_handle_t meter_handle) { + printf("switcht_api_hostif_meter_delete\n"); + return switch_api_hostif_meter_delete(device, meter_handle); + } + switcht_handle_t switcht_api_meter_create( const switcht_device_t device, const switcht_api_meter_info_t& api_meter_info) { @@ -1590,9 +1865,9 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { api_meter.pbs = api_meter_info.pbs; api_meter.cir = api_meter_info.cir; api_meter.pir = api_meter_info.pir; - api_meter.action[SWITCH_METER_COLOR_GREEN] = (switch_acl_action_t) api_meter_info.green_action; - api_meter.action[SWITCH_METER_COLOR_YELLOW] = (switch_acl_action_t) api_meter_info.yellow_action; - api_meter.action[SWITCH_METER_COLOR_RED] = (switch_acl_action_t) api_meter_info.red_action; + api_meter.action[SWITCH_COLOR_GREEN] = (switch_acl_action_t) api_meter_info.green_action; + api_meter.action[SWITCH_COLOR_YELLOW] = (switch_acl_action_t) api_meter_info.yellow_action; + api_meter.action[SWITCH_COLOR_RED] = (switch_acl_action_t) api_meter_info.red_action; return switch_api_meter_create(device, &api_meter); } @@ -1610,9 +1885,9 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { api_meter.pbs = api_meter_info.pbs; api_meter.cir = api_meter_info.cir; api_meter.pir = api_meter_info.pir; - api_meter.action[SWITCH_METER_COLOR_GREEN] = (switch_acl_action_t) api_meter_info.green_action; - api_meter.action[SWITCH_METER_COLOR_YELLOW] = (switch_acl_action_t) api_meter_info.yellow_action; - api_meter.action[SWITCH_METER_COLOR_RED] = (switch_acl_action_t) api_meter_info.red_action; + api_meter.action[SWITCH_COLOR_GREEN] = (switch_acl_action_t) api_meter_info.green_action; + api_meter.action[SWITCH_COLOR_YELLOW] = (switch_acl_action_t) api_meter_info.yellow_action; + api_meter.action[SWITCH_COLOR_RED] = (switch_acl_action_t) api_meter_info.red_action; return switch_api_meter_update(device, meter_handle, &api_meter); } @@ -1648,6 +1923,401 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return; } + switcht_status_t + switcht_api_port_cos_mapping( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t ppg_handle, + const int8_t cos_bmp) { + return switch_api_port_cos_mapping( + device, + port_handle, + ppg_handle, + cos_bmp); + } + + switcht_status_t + switcht_api_ppg_lossless_enable( + const switcht_device_t device, + const switcht_handle_t ppg_handle, + const bool enable) { + return switch_api_ppg_lossless_enable(device, ppg_handle, enable); + } + + void switcht_api_ppg_get( + std::vector & ppg_handles, + const switcht_device_t device, + const switcht_handle_t port_handle) { + + switch_handle_t *ppg_handles_tmp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint8_t num_ppg = 0; + + ppg_handles_tmp = (switch_handle_t *) switch_malloc(sizeof(switch_handle_t), SWITCH_MAX_PPG); + status = switch_api_ppg_get( + device, + port_handle, + &num_ppg, + ppg_handles_tmp); + for (uint32_t i = 0; i < num_ppg; i++) { + ppg_handles.push_back(ppg_handles_tmp[i]); + } + + free(ppg_handles_tmp); + return; + } + + switcht_status_t switcht_api_ppg_guaranteed_limit_set( + const switcht_device_t device, + const switcht_handle_t ppg_handle, + const int32_t num_bytes) { + return switch_api_ppg_guaranteed_limit_set( + device, + ppg_handle, + num_bytes); + } + + switcht_status_t switcht_api_ppg_skid_limit_set( + const switcht_device_t device, + const switcht_handle_t ppg_handle, + const int32_t num_bytes) { + return switch_api_ppg_skid_limit_set( + device, + ppg_handle, + num_bytes); + } + + switcht_status_t switcht_api_ppg_skid_hysteresis_set( + const switcht_device_t device, + const switcht_handle_t ppg_handle, + const int32_t num_bytes) { + return switch_api_ppg_skid_hysteresis_set( + device, + ppg_handle, + num_bytes); + } + + switcht_handle_t switcht_api_buffer_pool_create( + const switcht_device_t device, + const switcht_direction_t direction, + const int16_t pool_size) { + return switch_api_buffer_pool_create( + device, + (switch_direction_t) direction, + pool_size); + } + + switcht_status_t switcht_api_buffer_pool_delete( + const switcht_device_t device, + const switcht_handle_t buffer_pool_handle) { + return switch_api_buffer_pool_delete(device, buffer_pool_handle); + } + + switcht_handle_t switcht_api_buffer_profile_create( + const switcht_device_t device, + const switcht_api_buffer_profile_t& api_buffer_info) { + switch_api_buffer_profile_t buffer_profile; + memset(&buffer_profile, 0x0, sizeof(buffer_profile)); + buffer_profile.threshold_mode = (switch_buffer_threshold_mode_t) api_buffer_info.threshold_mode; + buffer_profile.threshold = api_buffer_info.threshold; + buffer_profile.pool_handle = api_buffer_info.pool_handle; + buffer_profile.buffer_size = api_buffer_info.buffer_size; + buffer_profile.xoff_threshold = api_buffer_info.xoff_threshold; + buffer_profile.xon_threshold = api_buffer_info.xon_threshold; + return switch_api_buffer_profile_create(device, &buffer_profile); + } + + switcht_status_t switcht_api_buffer_profile_delete( + const switcht_device_t device, + const switcht_handle_t buffer_profile_handle) { + return switch_api_buffer_profile_delete(device, buffer_profile_handle); + } + + switcht_status_t switcht_api_ppg_buffer_profile_set( + const switcht_device_t device, + const switcht_handle_t ppg_handle, + const switcht_handle_t buffer_profile_handle) { + return switch_api_priority_group_buffer_profile_set(device, ppg_handle, buffer_profile_handle); + } + + switcht_status_t switcht_api_queue_buffer_profile_set( + const switcht_device_t device, + const switcht_handle_t queue_handle, + const switcht_handle_t buffer_profile_handle) { + return switch_api_queue_buffer_profile_set(device, queue_handle, buffer_profile_handle); + } + + switcht_status_t switcht_api_buffer_skid_limit_set( + const switcht_device_t device, + const int32_t num_bytes) { + return switch_api_buffer_skid_limit_set(device, num_bytes); + } + + switcht_status_t switcht_api_buffer_skid_hysteresis_set( + const switcht_device_t device, + const int32_t num_bytes) { + return switch_api_buffer_skid_hysteresis_set(device, num_bytes); + } + + switcht_status_t switcht_api_buffer_pool_pfc_limit( + const switcht_device_t device, + const switcht_handle_t pool_handle, + const int8_t icos, + const int32_t num_bytes) { + return switch_api_buffer_pool_pfc_limit(device, pool_handle, icos, num_bytes); + } + + switcht_status_t switcht_api_buffer_pool_color_drop_enable( + const switcht_device_t device, + const switcht_handle_t pool_handle, + const bool enable) { + return switch_api_buffer_pool_color_drop_enable(device, pool_handle, enable); + } + + switcht_status_t switcht_api_buffer_pool_color_limit_set( + const switcht_device_t device, + const switcht_handle_t pool_handle, + const switcht_color_t color, + const int32_t num_bytes) { + return switch_api_buffer_pool_color_limit_set( + device, + pool_handle, + (switch_color_t) color, + num_bytes); + } + + switcht_status_t switcht_api_buffer_pool_color_hysteresis_set( + const switcht_device_t device, + const switcht_color_t color, + const int32_t num_bytes) { + return switch_api_buffer_pool_color_hysteresis_set( + device, + (switch_color_t) color, + num_bytes); + } + + switcht_handle_t switcht_api_qos_map_ingress_create( + const switcht_device_t device, + const switcht_qos_map_type_t qos_map_type, + const std::vector &qos_map) { + switch_status_t status=0; + switcht_handle_t qos_map_handle = 0; + std::vector::const_iterator it = qos_map.begin(); + + switch_qos_map_t *qos_map_list = (switch_qos_map_t *) malloc(sizeof(switch_qos_map_t) * qos_map.size()); + memset(qos_map_list, 0x0, sizeof(switch_qos_map_t) * qos_map.size()); + + for(uint32_t i = 0; i < qos_map.size(); i++, it++) { + const switcht_qos_map_t qos_map_tmp = *it; + switch (qos_map_type) { + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC: + qos_map_list[i].dscp = qos_map_tmp.dscp; + qos_map_list[i].tc = qos_map_tmp.tc; + break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC: + qos_map_list[i].pcp = qos_map_tmp.pcp; + qos_map_list[i].tc = qos_map_tmp.tc; + break; + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR: + qos_map_list[i].dscp = qos_map_tmp.dscp; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR: + qos_map_list[i].pcp = qos_map_tmp.pcp; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC_AND_COLOR: + qos_map_list[i].dscp = qos_map_tmp.dscp; + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC_AND_COLOR: + qos_map_list[i].pcp = qos_map_tmp.pcp; + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS: + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].icos = qos_map_tmp.icos; + break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE: + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].qid = qos_map_tmp.qid; + break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS_AND_QUEUE: + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].icos = qos_map_tmp.icos; + qos_map_list[i].qid = qos_map_tmp.qid; + break; + } + } + qos_map_handle = switch_api_qos_map_ingress_create( + device, + (switch_qos_map_ingress_t) qos_map_type, + qos_map.size(), + qos_map_list); + free(qos_map_list); + return qos_map_handle; + } + + switcht_status_t switcht_api_qos_map_ingress_delete( + const switcht_device_t device, + const switcht_handle_t qos_map_handle) { + return switch_api_qos_map_ingress_delete(device, qos_map_handle); + } + + switcht_handle_t switcht_api_qos_map_egress_create( + const switcht_device_t device, + const switcht_qos_map_type_t qos_map_type, + const std::vector &qos_map) { + switch_status_t status=0; + switcht_handle_t qos_map_handle = 0; + std::vector::const_iterator it = qos_map.begin(); + + switch_qos_map_t *qos_map_list = (switch_qos_map_t *) malloc(sizeof(switch_qos_map_t) * qos_map.size()); + memset(qos_map_list, 0x0, sizeof(switch_qos_map_t) * qos_map.size()); + + for(uint32_t i = 0; i < qos_map.size(); i++, it++) { + const switcht_qos_map_t qos_map_tmp = *it; + switch (qos_map_type) { + case SWITCH_QOS_MAP_EGRESS_TC_TO_DSCP: + qos_map_list[i].dscp = qos_map_tmp.dscp; + qos_map_list[i].tc = qos_map_tmp.tc; + break; + case SWITCH_QOS_MAP_EGRESS_TC_TO_PCP: + qos_map_list[i].pcp = qos_map_tmp.pcp; + qos_map_list[i].tc = qos_map_tmp.tc; + break; + case SWITCH_QOS_MAP_EGRESS_COLOR_TO_DSCP: + qos_map_list[i].dscp = qos_map_tmp.dscp; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_EGRESS_COLOR_TO_PCP: + qos_map_list[i].pcp = qos_map_tmp.pcp; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_DSCP: + qos_map_list[i].dscp = qos_map_tmp.dscp; + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + case SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_PCP: + qos_map_list[i].pcp = qos_map_tmp.pcp; + qos_map_list[i].tc = qos_map_tmp.tc; + qos_map_list[i].color = (switch_color_t) qos_map_tmp.color; + break; + } + } + qos_map_handle = switch_api_qos_map_egress_create( + device, + (switch_qos_map_egress_t) qos_map_type, + qos_map.size(), + qos_map_list); + free(qos_map_list); + return qos_map_handle; + } + + switcht_status_t switcht_api_qos_map_egress_delete( + const switcht_device_t device, + const switcht_handle_t qos_map_handle) { + return switch_api_qos_map_egress_delete(device, qos_map_handle); + } + + switcht_handle_t switcht_api_scheduler_create( + const switcht_device_t device, + const switcht_scheduler_info_t& api_scheduler_info) { + printf("switcht_api_scheduler_create\n"); + return 0; + } + + switcht_status_t switcht_api_scheduler_delete( + const switcht_device_t device, + const switcht_handle_t scheduler_handle) { + printf("switcht_api_scheduler_delete\n"); + return 0; + } + + void switcht_api_queues_get( + std::vector & queue_handles, + const switcht_device_t device, + const switcht_handle_t port_handle) { + + switch_handle_t *queue_handles_tmp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t num_queues = 0; + + queue_handles_tmp = (switch_handle_t *) switch_malloc(sizeof(switch_handle_t), SWITCH_MAX_QUEUE); + status = switch_api_queues_get( + device, + port_handle, + &num_queues, + queue_handles_tmp); + for (uint32_t i = 0; i < num_queues; i++) { + queue_handles.push_back(queue_handles_tmp[i]); + } + + free(queue_handles_tmp); + return; + } + + switcht_status_t switcht_api_queue_color_drop_enable( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t queue_handle, + const bool enable) { + return switch_api_queue_color_drop_enable( + device, + port_handle, + queue_handle, + enable); + } + + switcht_status_t switcht_api_queue_color_limit_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t queue_handle, + const switcht_color_t color, + const int32_t limit) { + return switch_api_queue_color_limit_set( + device, + port_handle, + queue_handle, + (switch_color_t) color, + limit); + } + + switcht_status_t switcht_api_queue_color_hysteresis_set( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t queue_handle, + const switcht_color_t color, + const int32_t limit) { + return switch_api_queue_color_hysteresis_set( + device, + port_handle, + queue_handle, + (switch_color_t) color, + limit); + } + + switcht_status_t switcht_api_queue_pfc_cos_mapping( + const switcht_device_t device, + const switcht_handle_t port_handle, + const switcht_handle_t queue_handle, + const int8_t cos) { + return switch_api_queue_pfc_cos_mapping( + device, + port_handle, + queue_handle, + cos); + } + + switcht_status_t switcht_api_mtu_entry_create( + const switcht_device_t device, + const int16_t mtu_index, + const int32_t mtu) { + return switch_api_mtu_create_entry(device, mtu_index, mtu); + } }; static void *api_rpc_server_thread(void *args) { @@ -1680,4 +2350,3 @@ extern "C" { return start_switch_api_rpc_server(); } } - diff --git a/switchapi/src/switch_buffer.c b/switchapi/src/switch_buffer.c new file mode 100644 index 0000000..fa2d6c3 --- /dev/null +++ b/switchapi/src/switch_buffer.c @@ -0,0 +1,409 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_status.h" +#include "switchapi/switch_utils.h" +#include "switch_buffer_int.h" +#include "switch_pd.h" +#include "switch_queue_int.h" +#include "switch_log_int.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static void *switch_buffer_pool_array = NULL; +static void *switch_buffer_profile_array = NULL; +static switch_buffer_pool_usage_t pool_usage; + +switch_status_t switch_buffer_init(switch_device_t device) { + UNUSED(device); + switch_buffer_pool_array = NULL; + switch_buffer_profile_array = NULL; + memset(&pool_usage, 0, sizeof(switch_buffer_pool_usage_t)); + switch_pd_ingress_pool_init(device, pool_usage.ingress_pool_info); + switch_pd_egress_pool_init(device, pool_usage.egress_pool_info); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_buffer_free(switch_device_t device) { + UNUSED(device); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_buffer_pool_handle_create(switch_device_t device, + switch_direction_t direction, + switch_pd_pool_id_t pool_id) { + switch_handle_t buffer_pool_handle = 0; + buffer_pool_handle = pool_id; + buffer_pool_handle |= ((direction & 0x1) << 16); + buffer_pool_handle |= (SWITCH_HANDLE_TYPE_BUFFER_POOL << HANDLE_TYPE_SHIFT); + return buffer_pool_handle; +} + +switch_status_t switch_buffer_pool_handle_delete( + switch_device_t device, switch_handle_t buffer_pool_handle) { + return SWITCH_STATUS_SUCCESS; +} + +switch_buffer_pool_info_t *switch_buffer_pool_get( + switch_handle_t buffer_pool_handle) { + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_buffer_pool_info_t *buffer_pool_info_tmp = NULL; + switch_direction_t direction = 0; + switch_pd_pool_id_t pool_id = 0; + uint16_t i = 0; + uint16_t pool_count = 0; + + direction = (buffer_pool_handle >> 16) & 0x1; + pool_id = buffer_pool_handle & 0xFFFF; + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + buffer_pool_info = pool_usage.ingress_pool_info; + pool_count = SWITCH_INGRESS_POOL_COUNT; + } else { + buffer_pool_info = pool_usage.egress_pool_info; + pool_count = SWITCH_EGRESS_POOL_COUNT; + } + + for (i = 0; i < pool_count; i++) { + if (buffer_pool_info[i].pool_id == pool_id) { + buffer_pool_info_tmp = &buffer_pool_info[i]; + break; + } + } + return buffer_pool_info_tmp; +} + +static switch_status_t switch_buffer_free_pool_get( + switch_direction_t direction, + uint32_t pool_size, + switch_pd_pool_id_t *pool_id) { + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool free_pool = FALSE; + uint16_t index = 0; + uint16_t pool_count = 0; + + *pool_id = 0; + + if ((direction == SWITCH_API_DIRECTION_INGRESS && + pool_usage.ingress_count == SWITCH_INGRESS_POOL_COUNT) || + (direction == SWITCH_API_DIRECTION_EGRESS && + pool_usage.egress_count == SWITCH_EGRESS_POOL_COUNT)) { + SWITCH_API_ERROR("failed to find free pool"); + return SWITCH_STATUS_INSUFFICIENT_RESOURCES; + } + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + buffer_pool_info = pool_usage.ingress_pool_info; + pool_count = SWITCH_INGRESS_POOL_COUNT; + } else { + buffer_pool_info = pool_usage.egress_pool_info; + pool_count = SWITCH_EGRESS_POOL_COUNT; + } + + for (index = 0; index < pool_count; index++) { + if (!buffer_pool_info[index].in_use) { + free_pool = TRUE; + *pool_id = buffer_pool_info[index].pool_id; + break; + } + } + + if (!free_pool) { + SWITCH_API_ERROR("failed to find free pool"); + return SWITCH_STATUS_INSUFFICIENT_RESOURCES; + } + + return status; +} + +switch_handle_t switch_api_buffer_pool_create(switch_device_t device, + switch_direction_t direction, + uint32_t pool_size) { + switch_handle_t buffer_pool_handle = 0; + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_pd_pool_id_t pool_id = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + status = switch_buffer_free_pool_get(direction, pool_size, &pool_id); + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to find pool for pool size %d", pool_size); + return status; + } + + buffer_pool_handle = + switch_buffer_pool_handle_create(device, direction, pool_id); + if (buffer_pool_handle) { + SWITCH_API_ERROR("failed to allocate handle!"); + return SWITCH_API_INVALID_HANDLE; + } + + buffer_pool_info = switch_buffer_pool_get(buffer_pool_handle); + buffer_pool_info->pool_id = pool_id; + buffer_pool_info->pool_size = pool_size; + buffer_pool_info->direction = direction; + + direction == SWITCH_API_DIRECTION_INGRESS ? pool_usage.ingress_count++ + : pool_usage.egress_count++; + + status = switch_pd_buffer_pool_set(device, pool_id, pool_size); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to set pool for pool size %d", pool_size); + return status; + } + + return buffer_pool_handle; +} + +switch_status_t switch_api_buffer_pool_delete(switch_device_t device, + switch_handle_t pool_handle) { + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + buffer_pool_info = switch_buffer_pool_get(pool_handle); + if (!buffer_pool_info) { + SWITCH_API_ERROR("invalid handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + buffer_pool_info->pool_size = 0; + buffer_pool_info->in_use = FALSE; + + buffer_pool_info->direction == SWITCH_API_DIRECTION_INGRESS + ? pool_usage.ingress_count-- + : pool_usage.egress_count--; + + status = switch_pd_buffer_pool_set(device, buffer_pool_info->pool_id, 0x0); + + switch_buffer_pool_handle_delete(device, pool_handle); + + return status; +} + +switch_status_t switch_api_buffer_pool_color_drop_enable( + switch_device_t device, switch_handle_t pool_handle, bool enable) { + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + buffer_pool_info = switch_buffer_pool_get(pool_handle); + if (!buffer_pool_info) { + SWITCH_API_ERROR("invalid handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_buffer_pool_color_drop_enable( + device, buffer_pool_info->pool_id, enable); + return status; +} + +switch_status_t switch_api_buffer_pool_color_limit_set( + switch_device_t device, + switch_handle_t pool_handle, + switch_color_t color, + uint32_t num_bytes) { + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + buffer_pool_info = switch_buffer_pool_get(pool_handle); + if (!buffer_pool_info) { + SWITCH_API_ERROR("invalid handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_buffer_pool_color_limit_set( + device, buffer_pool_info->pool_id, color, num_bytes); + return status; +} + +switch_status_t switch_api_buffer_pool_color_hysteresis_set( + switch_device_t device, switch_color_t color, uint32_t num_bytes) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + status = switch_pd_buffer_pool_color_hysteresis_set(device, color, num_bytes); + return status; +} + +switch_handle_t switch_buffer_profile_handle_create() { + switch_handle_t buffer_profile_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_BUFFER_PROFILE, + switch_api_buffer_profile_t, + switch_buffer_profile_array, + NULL, + buffer_profile_handle); + return buffer_profile_handle; +} + +switch_api_buffer_profile_t *switch_buffer_profile_info_get( + switch_handle_t buffer_profile_handle) { + switch_api_buffer_profile_t *buffer_info = NULL; + _switch_handle_get(switch_api_buffer_profile_t, + switch_buffer_profile_array, + buffer_profile_handle, + buffer_info); + return buffer_info; +} + +switch_status_t switch_buffer_profile_handle_delete( + switch_handle_t buffer_profile_handle) { + _switch_handle_delete(switch_api_buffer_profile_t, + switch_buffer_profile_array, + buffer_profile_handle); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_api_buffer_profile_create( + switch_device_t device, switch_api_buffer_profile_t *buffer_info) { + switch_api_buffer_profile_t *buffer_info_tmp = NULL; + switch_handle_t buffer_profile_handle = 0; + + buffer_profile_handle = switch_buffer_profile_handle_create(); + buffer_info_tmp = switch_buffer_profile_info_get(buffer_profile_handle); + if (!buffer_info_tmp) { + SWITCH_API_ERROR("no memory to allocate buffer profile handle"); + return SWITCH_API_INVALID_HANDLE; + } + + memcpy(buffer_info_tmp, buffer_info, sizeof(switch_api_buffer_profile_t)); + return buffer_profile_handle; +} + +switch_status_t switch_api_buffer_profile_delete( + switch_device_t device, switch_handle_t buffer_profile_handle) { + switch_buffer_profile_handle_delete(buffer_profile_handle); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_priority_group_buffer_profile_set( + switch_device_t device, + switch_handle_t ppg_handle, + switch_handle_t buffer_profile_handle) { + switch_port_priority_group_t *ppg_info = NULL; + switch_buffer_pool_info_t *pool_info = NULL; + switch_api_buffer_profile_t *buffer_profile_info = NULL; + bool enable = true; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to get port_priority group"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + buffer_profile_info = switch_buffer_profile_info_get(buffer_profile_handle); + if (!buffer_profile_info) { + SWITCH_API_ERROR("failed to get buffer profile"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + pool_info = switch_buffer_pool_get(buffer_profile_info->pool_handle); + if (!pool_info) { + SWITCH_API_ERROR("failed to get buffer profile"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + ppg_info->buffer_profile_handle = buffer_profile_handle; + enable = buffer_profile_handle == 0 ? true : false; + + status = switch_pd_ppg_pool_usage_set(device, + ppg_info->tm_ppg_handle, + pool_info->pool_id, + buffer_profile_info, + enable); + + return status; +} + +switch_status_t switch_api_buffer_skid_limit_set(switch_device_t device, + uint32_t num_bytes) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + status = switch_pd_buffer_skid_limit_set(device, num_bytes); + return status; +} + +switch_status_t switch_api_buffer_skid_hysteresis_set(switch_device_t device, + uint32_t num_bytes) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + status = switch_pd_buffer_skid_hysteresis_set(device, num_bytes); + return status; +} + +switch_status_t switch_api_buffer_pool_pfc_limit(switch_device_t device, + switch_handle_t pool_handle, + uint8_t icos, + uint32_t num_bytes) { + switch_buffer_pool_info_t *buffer_pool_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + buffer_pool_info = switch_buffer_pool_get(pool_handle); + if (!buffer_pool_info) { + SWITCH_API_ERROR("invalid handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_buffer_pool_pfc_limit( + device, buffer_pool_info->pool_id, icos, num_bytes); + + return status; +} + +switch_status_t switch_api_queue_buffer_profile_set( + switch_device_t device, + switch_handle_t queue_handle, + switch_handle_t buffer_profile_handle) { + switch_queue_info_t *queue_info = NULL; + switch_buffer_pool_info_t *pool_info = NULL; + switch_api_buffer_profile_t *buffer_profile_info = NULL; + bool enable = true; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + queue_info = switch_queue_info_get(queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("failed to get queue"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + buffer_profile_info = switch_buffer_profile_info_get(buffer_profile_handle); + if (!buffer_profile_info) { + SWITCH_API_ERROR("failed to get buffer profile"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + pool_info = switch_buffer_pool_get(buffer_profile_info->pool_handle); + if (!pool_info) { + SWITCH_API_ERROR("failed to get buffer profile"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info->buffer_profile_handle = buffer_profile_handle; + enable = buffer_profile_handle == 0 ? true : false; + + status = switch_pd_queue_pool_usage_set(device, + queue_info->port_handle, + queue_info->queue_id, + pool_info->pool_id, + buffer_profile_info, + enable); + + return status; +} + +#ifdef __cplusplus +} +#endif diff --git a/switchapi/src/switch_buffer_int.h b/switchapi/src/switch_buffer_int.h new file mode 100644 index 0000000..b860661 --- /dev/null +++ b/switchapi/src/switch_buffer_int.h @@ -0,0 +1,51 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_buffer_int_h_ +#define _switch_buffer_int_h_ + +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_buffer.h" +#include "switch_pd_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct switch_buffer_pool_info_ { + uint32_t pool_size; + switch_direction_t direction; + switch_pd_pool_id_t pool_id; + bool in_use; +} switch_buffer_pool_info_t; + +#define SWITCH_INGRESS_POOL_COUNT 4 +#define SWITCH_EGRESS_POOL_COUNT 4 + +typedef struct switch_buffer_pool_usage_ { + switch_buffer_pool_info_t ingress_pool_info[SWITCH_INGRESS_POOL_COUNT]; + switch_buffer_pool_info_t egress_pool_info[SWITCH_EGRESS_POOL_COUNT]; + uint8_t ingress_count; + uint8_t egress_count; +} switch_buffer_pool_usage_t; + +switch_status_t switch_buffer_init(switch_device_t device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/src/switch_capability.c b/switchapi/src/switch_capability.c index a7a7462..d16e6a3 100644 --- a/switchapi/src/switch_capability.c +++ b/switchapi/src/switch_capability.c @@ -33,80 +33,78 @@ extern "C" { static switch_capability_info_t *switch_info = NULL; -switch_status_t -switch_capability_init(switch_device_t device) -{ - switch_api_capability_t *api_switch_info = NULL; - switch_port_info_t *port_info = NULL; - int index = 0; - - switch_info = switch_malloc(sizeof(switch_capability_info_t), 1); - if (!switch_info) { - return SWITCH_STATUS_NO_MEMORY; - } - api_switch_info = &switch_info->api_switch_info; - memset(switch_info, 0, sizeof(switch_capability_info_t)); - memset(api_switch_info, 0, sizeof(switch_api_capability_t)); - - // Create Default VLAN - api_switch_info->default_vlan = SWITCH_API_DEFAULT_VLAN; - switch_info->default_vlan_handle = switch_api_vlan_create(device, SWITCH_API_DEFAULT_VLAN); - - // Create Default Vrf - api_switch_info->default_vrf = SWITCH_API_DEFAULT_VRF; - switch_info->default_vrf_handle = switch_api_vrf_create(device, SWITCH_API_DEFAULT_VRF); - - api_switch_info->max_ports = switch_max_configured_ports; - for (index = 0; index < SWITCH_API_MAX_PORTS; index++) { - port_info = switch_api_port_get_internal((switch_port_t)index); - api_switch_info->port_list[index] = port_info->port_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_capability_init(switch_device_t device) { + switch_api_capability_t *api_switch_info = NULL; + switch_port_info_t *port_info = NULL; + int index = 0; + + switch_info = switch_malloc(sizeof(switch_capability_info_t), 1); + if (!switch_info) { + return SWITCH_STATUS_NO_MEMORY; + } + api_switch_info = &switch_info->api_switch_info; + memset(switch_info, 0, sizeof(switch_capability_info_t)); + memset(api_switch_info, 0, sizeof(switch_api_capability_t)); + + // Create Default VLAN + api_switch_info->default_vlan = SWITCH_API_DEFAULT_VLAN; + switch_info->default_vlan_handle = + switch_api_vlan_create(device, SWITCH_API_DEFAULT_VLAN); + + // Create Default Vrf + api_switch_info->default_vrf = SWITCH_API_DEFAULT_VRF; + switch_info->default_vrf_handle = + switch_api_vrf_create(device, SWITCH_API_DEFAULT_VRF); + + api_switch_info->max_ports = switch_max_configured_ports; + for (index = 0; index < SWITCH_API_MAX_PORTS; index++) { + port_info = switch_api_port_get_internal((switch_port_t)index); + api_switch_info->port_list[index] = port_info->port_handle; + } + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_default_vlan_internal() -{ - return switch_info->default_vlan_handle; +switch_handle_t switch_api_default_vlan_internal() { + return switch_info->default_vlan_handle; } -switch_handle_t -switch_api_default_vrf_internal() -{ - return switch_info->default_vrf_handle; +switch_handle_t switch_api_default_vrf_internal() { + return switch_info->default_vrf_handle; } -switch_handle_t -switch_api_capability_rmac_handle_get() -{ - return switch_info->rmac_handle; +switch_handle_t switch_api_capability_rmac_handle_get() { + return switch_info->rmac_handle; } -uint16_t -switch_api_capability_smac_index_get() -{ - return switch_info->smac_index; +uint16_t switch_api_capability_smac_index_get() { + return switch_info->smac_index; } -switch_status_t -switch_api_capability_set(switch_device_t device, switch_api_capability_t *api_switch_info) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_mac_addr_t mac; - - memset(&mac, 0, sizeof(switch_mac_addr_t)); - if (memcmp(&api_switch_info->switch_mac, &mac, ETH_LEN) != 0) { - memcpy(&switch_info->api_switch_info.switch_mac, &api_switch_info->switch_mac, ETH_LEN); - switch_info->rmac_handle = switch_api_router_mac_group_create(device); - status = switch_api_router_mac_add(device, switch_info->rmac_handle, &api_switch_info->switch_mac); - switch_info->smac_index = switch_smac_rewrite_index_from_rmac(switch_info->rmac_handle); - } - return status; +switch_status_t switch_api_capability_set( + switch_device_t device, switch_api_capability_t *api_switch_info) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_mac_addr_t mac; + + memset(&mac, 0, sizeof(switch_mac_addr_t)); + if (memcmp(&api_switch_info->switch_mac, &mac, ETH_LEN) != 0) { + memcpy(&switch_info->api_switch_info.switch_mac, + &api_switch_info->switch_mac, + ETH_LEN); + switch_info->rmac_handle = switch_api_router_mac_group_create(device); + status = switch_api_router_mac_add( + device, switch_info->rmac_handle, &api_switch_info->switch_mac); + switch_info->smac_index = + switch_smac_rewrite_index_from_rmac(switch_info->rmac_handle); + } + return status; } -switch_status_t -switch_api_capability_get(switch_device_t device, switch_api_capability_t *api_switch_info) { - memcpy(api_switch_info, &switch_info->api_switch_info, sizeof(switch_api_capability_t)); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_capability_get( + switch_device_t device, switch_api_capability_t *api_switch_info) { + memcpy(api_switch_info, + &switch_info->api_switch_info, + sizeof(switch_api_capability_t)); + return SWITCH_STATUS_SUCCESS; } #ifdef __cplusplus diff --git a/switchapi/src/switch_capability_int.h b/switchapi/src/switch_capability_int.h index 159c47a..e48603c 100644 --- a/switchapi/src/switch_capability_int.h +++ b/switchapi/src/switch_capability_int.h @@ -24,22 +24,21 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + /** Switch information */ typedef struct switch_capability_info_ { - switch_api_capability_t api_switch_info; - switch_mac_addr_t router_mac; /**< system router mac */ - bool oper_status; /**< operational status */ - switch_ecmp_hash_fields_t ecmp_hash; /**< system hash */ - switch_handle_t default_vrf_handle; - switch_handle_t default_vlan_handle; - switch_handle_t rmac_handle; - uint16_t smac_index; + switch_api_capability_t api_switch_info; + switch_mac_addr_t router_mac; /**< system router mac */ + bool oper_status; /**< operational status */ + switch_ecmp_hash_fields_t ecmp_hash; /**< system hash */ + switch_handle_t default_vrf_handle; + switch_handle_t default_vlan_handle; + switch_handle_t rmac_handle; + uint16_t smac_index; } switch_capability_info_t; switch_status_t switch_capability_init(switch_device_t device); switch_handle_t switch_api_default_vlan_internal(); -switch_handle_t switch_api_default_vrf_internal(); switch_handle_t switch_api_capability_rmac_handle_get(); uint16_t switch_api_capability_smac_index_get(); diff --git a/switchapi/src/switch_config.c b/switchapi/src/switch_config.c index 3e3a929..08459fc 100644 --- a/switchapi/src/switch_config.c +++ b/switchapi/src/switch_config.c @@ -28,44 +28,36 @@ limitations under the License. /* switch global configuration parameters */ static switch_config_param_t switch_config[SWITCH_MAX_DEVICE]; -switch_config_param_t * -switch_config_params_get(switch_device_t device) -{ - return &switch_config[device]; +switch_config_param_t *switch_config_params_get(switch_device_t device) { + return &switch_config[device]; } -void -switch_config_params_init (switch_device_t device) -{ - memset(switch_config_params_get(device), 0, sizeof(switch_config_param_t)); - /* Add default configuration parameters here */ - /* each config parameters becomes an action routine parameter so these are - * limited - */ - return; +void switch_config_params_init(switch_device_t device) { + memset(switch_config_params_get(device), 0, sizeof(switch_config_param_t)); + /* Add default configuration parameters here */ + /* each config parameters becomes an action routine parameter so these are + * limited + */ + return; } -void -switch_config_param_set_dod(switch_device_t device, bool dod) -{ - switch_config_params_get(device)->enable_dod = dod; - return; +void switch_config_param_set_dod(switch_device_t device, bool dod) { + switch_config_params_get(device)->enable_dod = dod; + return; } - -void -switch_config_action_populate(switch_device_t device, - p4_pd_dc_set_config_parameters_action_spec_t *action_sw_cfg) -{ - action_sw_cfg->action_enable_dod = switch_config_params_get(device)->enable_dod; - /* Add more parameters here */ - return; +void switch_config_action_populate( + switch_device_t device, + p4_pd_dc_set_config_parameters_action_spec_t *action_sw_cfg) { + action_sw_cfg->action_enable_dod = + switch_config_params_get(device)->enable_dod; + /* Add more parameters here */ + return; } /* exported APIs */ -switch_status_t -switch_api_set_deflect_on_drop(switch_device_t device, bool dod) -{ - switch_config_param_set_dod(device, dod); - return switch_pd_switch_config_params_update(device); +switch_status_t switch_api_set_deflect_on_drop(switch_device_t device, + bool dod) { + switch_config_param_set_dod(device, dod); + return switch_pd_switch_config_params_update(device); } diff --git a/switchapi/src/switch_config_int.h b/switchapi/src/switch_config_int.h index d71daad..c940b25 100644 --- a/switchapi/src/switch_config_int.h +++ b/switchapi/src/switch_config_int.h @@ -19,15 +19,13 @@ limitations under the License. /* Global configuration parameters for a switch */ typedef struct switch_config_param_ { - bool enable_dod; /* Enable Deflect-on-drop feature */ - /* Add more global information - such as switch-id etc in future */ + bool enable_dod; /* Enable Deflect-on-drop feature */ + /* Add more global information - such as switch-id etc in future */ } switch_config_param_t; -switch_config_param_t * -switch_config_params_get (switch_device_t device); -void -switch_config_params_init (switch_device_t device); -void -switch_config_action_populate(switch_device_t device, - p4_pd_dc_set_config_parameters_action_spec_t *action_sw_cfg); -#endif // _switch_config_int_ +switch_config_param_t *switch_config_params_get(switch_device_t device); +void switch_config_params_init(switch_device_t device); +void switch_config_action_populate( + switch_device_t device, + p4_pd_dc_set_config_parameters_action_spec_t *action_sw_cfg); +#endif // _switch_config_int_ diff --git a/switchapi/src/switch_defines.h b/switchapi/src/switch_defines.h index f779cc7..5de3949 100644 --- a/switchapi/src/switch_defines.h +++ b/switchapi/src/switch_defines.h @@ -20,87 +20,71 @@ extern "C" { typedef uint16_t switch_stats_idx_t; -#define SWITCH_DEV_ID 0x0 -#define SWITCH_DEV_PIPE_ID 0xFFFF +#define SWITCH_DEV_ID 0x0 +#define SWITCH_DEV_PIPE_ID 0xFFFF -#define SWITCH_LOGICAL_IFINDEX_SHIFT 12 -#define SWITCH_INTF_TUNNEL_IFINDEX 1 +#define SWITCH_LOGICAL_IFINDEX_SHIFT 12 +#define SWITCH_INTF_TUNNEL_IFINDEX 1 -//IP Encap defines -#define SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) \ - ip_encap->src_ip.type +// IP Encap defines +#define SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) ip_encap->src_ip.type -#define SWITCH_IP_ENCAP_DST_IP_TYPE(ip_encap) \ - ip_encap->dst_ip.type +#define SWITCH_IP_ENCAP_DST_IP_TYPE(ip_encap) ip_encap->dst_ip.type -#define SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap) \ - ip_encap->src_ip.ip.v4addr +#define SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap) ip_encap->src_ip.ip.v4addr -#define SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap) \ - ip_encap->dst_ip.ip.v4addr +#define SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap) ip_encap->dst_ip.ip.v4addr -#define SWITCH_IP_ENCAP_IPV6_SRC_IP(ip_encap) \ - ip_encap->src_ip.ip.v6addr +#define SWITCH_IP_ENCAP_IPV6_SRC_IP(ip_encap) ip_encap->src_ip.ip.v6addr -#define SWITCH_IP_ENCAP_IPV6_DST_IP(ip_encap) \ - ip_encap->dst_ip.ip.v6addr +#define SWITCH_IP_ENCAP_IPV6_DST_IP(ip_encap) ip_encap->dst_ip.ip.v6addr -#define SWITCH_IP_ENCAP_UDP_DST_PORT(ip_encap) \ - ip_encap->u.udp.dst_port +#define SWITCH_IP_ENCAP_UDP_DST_PORT(ip_encap) ip_encap->u.udp.dst_port -//Encap Info defines -#define SWITCH_ENCAP_VXLAN_VNI(encap_info) \ - encap_info->u.vxlan_info.vnid +// Encap Info defines +#define SWITCH_ENCAP_VXLAN_VNI(encap_info) encap_info->u.vxlan_info.vnid -#define SWITCH_ENCAP_NVGRE_VNI(encap_info) \ - encap_info->u.nvgre_info.tnid +#define SWITCH_ENCAP_NVGRE_VNI(encap_info) encap_info->u.nvgre_info.tnid -#define SWITCH_ENCAP_GENEVE_VNI(encap_info) \ - encap_info->u.geneve_info.vni +#define SWITCH_ENCAP_GENEVE_VNI(encap_info) encap_info->u.geneve_info.vni -#define SWITCH_ENCAP_VLAN_ID(encap_info) \ - encap_info->u.vlan_id +#define SWITCH_ENCAP_VLAN_ID(encap_info) encap_info->u.vlan_id // Tunnel defines #define SWITCH_INTF_TUNNEL_INFO(intf_info) \ - intf_info->api_intf_info.u.tunnel_info + intf_info->api_intf_info.u.tunnel_info #define SWITCH_INTF_TUNNEL_ENCAP_INFO(intf_info) \ - intf_info->api_intf_info.u.tunnel_info.encap_info + intf_info->api_intf_info.u.tunnel_info.encap_info // MPLS defines -#define SWITCH_MPLS_POP_HEADER_COUNT(mpls_encap) \ - mpls_encap->u.pop_info.count +#define SWITCH_MPLS_POP_HEADER_COUNT(mpls_encap) mpls_encap->u.pop_info.count -#define SWITCH_MPLS_PUSH_HEADER_COUNT(mpls_encap) \ - mpls_encap->u.push_info.count +#define SWITCH_MPLS_PUSH_HEADER_COUNT(mpls_encap) mpls_encap->u.push_info.count #define SWITCH_MPLS_SWAP_HEADER_COUNT(mpls_encap) 1 #define SWITCH_MPLS_SWAP_PUSH_HEADER_COUNT(mpls_encap) \ - mpls_encap->u.swap_push_info.count + mpls_encap->u.swap_push_info.count -#define SWITCH_MPLS_PUSH_HEADER(mpls_encap) \ - mpls_encap->u.push_info.tag +#define SWITCH_MPLS_PUSH_HEADER(mpls_encap) mpls_encap->u.push_info.tag #define SWITCH_MPLS_SWAP_NEW_LABEL(mpls_encap) \ - mpls_encap->u.swap_info.new_tag.label + mpls_encap->u.swap_info.new_tag.label #define SWITCH_MPLS_SWAP_PUSH_HEADER(mpls_encap) \ - mpls_encap->u.swap_push_info.new_tag + mpls_encap->u.swap_push_info.new_tag #define SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap) \ - mpls_encap->u.swap_info.old_tag.label + mpls_encap->u.swap_info.old_tag.label #define SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap) \ - mpls_encap->u.swap_push_info.old_tag.label + mpls_encap->u.swap_push_info.old_tag.label // LN defines -#define SWITCH_LN_ENCAP_INFO(bd_info) \ - bd_info->ln_info.encap_info +#define SWITCH_LN_ENCAP_INFO(bd_info) bd_info->ln_info.encap_info -#define SWITCH_LN_TUNNEL_VNI(bd_info) \ - bd_info->ln_info.encap_info.u.tunnel_vni +#define SWITCH_LN_TUNNEL_VNI(bd_info) bd_info->ln_info.encap_info.u.tunnel_vni #ifdef __cplusplus } diff --git a/switchapi/src/switch_handle.c b/switchapi/src/switch_handle.c index 9ddfd0e..a677313 100644 --- a/switchapi/src/switch_handle.c +++ b/switchapi/src/switch_handle.c @@ -23,117 +23,107 @@ extern "C" { static void *switch_handle_array; -int -switch_handle_type_init(switch_handle_type_t type, unsigned int size) -{ - return switch_handle_type_allocator_init(type, size*4, - true /*grow*/, false/*zero_based*/); +int switch_handle_type_init(switch_handle_type_t type, unsigned int size) { + return switch_handle_type_allocator_init( + type, size * 4, true /*grow*/, false /*zero_based*/); } -int -switch_handle_type_allocator_init(switch_handle_type_t type, - unsigned int num_handles, - bool grow_on_demand, bool zero_based) -{ - switch_handle_info_t *handle_info = NULL; - switch_api_id_allocator *allocator = NULL; - void *p = NULL; - unsigned int size = (num_handles+3)/4; - - handle_info = switch_malloc(sizeof(switch_handle_info_t), 1); - if (!handle_info) { - return SWITCH_STATUS_FAILURE; - } - allocator = switch_api_id_allocator_new (size, zero_based); - if (!allocator) { - switch_free(handle_info); - return -1; - } - handle_info->type = type; - handle_info->initial_size = size; - handle_info->allocator = allocator; - handle_info->num_in_use = 0; - handle_info->num_handles = num_handles; - handle_info->grow_on_demand = grow_on_demand; - handle_info->zero_based = zero_based; - JLI(p, switch_handle_array, (unsigned int)type); - if(p) { - *(unsigned long *)p = (unsigned long)handle_info; - return SWITCH_STATUS_SUCCESS; - } - switch_free(handle_info); +int switch_handle_type_allocator_init(switch_handle_type_t type, + unsigned int num_handles, + bool grow_on_demand, + bool zero_based) { + switch_handle_info_t *handle_info = NULL; + switch_api_id_allocator *allocator = NULL; + void *p = NULL; + unsigned int size = (num_handles + 3) / 4; + + handle_info = switch_malloc(sizeof(switch_handle_info_t), 1); + if (!handle_info) { return SWITCH_STATUS_FAILURE; + } + allocator = switch_api_id_allocator_new(size, zero_based); + if (!allocator) { + switch_free(handle_info); + return -1; + } + handle_info->type = type; + handle_info->initial_size = size; + handle_info->allocator = allocator; + handle_info->num_in_use = 0; + handle_info->num_handles = num_handles; + handle_info->grow_on_demand = grow_on_demand; + handle_info->zero_based = zero_based; + JLI(p, switch_handle_array, (unsigned int)type); + if (p) { + *(unsigned long *)p = (unsigned long)handle_info; + return SWITCH_STATUS_SUCCESS; + } + switch_free(handle_info); + return SWITCH_STATUS_FAILURE; } -void -switch_handle_type_free(switch_handle_type_t type) -{ - switch_handle_info_t *handle_info = NULL; - void *p = NULL; - int ret = 0; - - JLG(p, switch_handle_array, (unsigned int)type); - if((handle_info = (switch_handle_info_t *) (*(unsigned long *)p))) { - switch_api_id_allocator_destroy (handle_info->allocator); - JLD(ret, switch_handle_array, (unsigned int)type); - // assert(ret != 0); - switch_free(handle_info); - } +void switch_handle_type_free(switch_handle_type_t type) { + switch_handle_info_t *handle_info = NULL; + void *p = NULL; + int ret = 0; + + JLG(p, switch_handle_array, (unsigned int)type); + if ((handle_info = (switch_handle_info_t *)(*(unsigned long *)p))) { + switch_api_id_allocator_destroy(handle_info->allocator); + JLD(ret, switch_handle_array, (unsigned int)type); + // assert(ret != 0); + switch_free(handle_info); + } } -switch_handle_t -switch_handle_allocate(switch_handle_type_t type) -{ - switch_handle_info_t *handle_info = NULL; - void *p = NULL; - - JLG(p, switch_handle_array, (unsigned int)type); - if((handle_info = (switch_handle_info_t *) (*(unsigned long *)p))) { - if ((handle_info->num_in_use < handle_info->num_handles) || - handle_info->grow_on_demand) { - unsigned int id = switch_api_id_allocator_allocate (handle_info->allocator); - handle_info->num_in_use++; - return ((type << HANDLE_TYPE_SHIFT) | id); - } +switch_handle_t switch_handle_allocate(switch_handle_type_t type) { + switch_handle_info_t *handle_info = NULL; + void *p = NULL; + + JLG(p, switch_handle_array, (unsigned int)type); + if ((handle_info = (switch_handle_info_t *)(*(unsigned long *)p))) { + if ((handle_info->num_in_use < handle_info->num_handles) || + handle_info->grow_on_demand) { + unsigned int id = + switch_api_id_allocator_allocate(handle_info->allocator); + handle_info->num_in_use++; + return ((type << HANDLE_TYPE_SHIFT) | id); } - return SWITCH_API_INVALID_HANDLE; + } + return SWITCH_API_INVALID_HANDLE; } -switch_handle_t -switch_handle_set_and_allocate(switch_handle_t type, unsigned int id) -{ - switch_handle_info_t *handle_info = NULL; - void *p = NULL; - - JLG(p, switch_handle_array, (unsigned int)type); - if((handle_info = (switch_handle_info_t *) (*(unsigned long *)p))) { - switch_api_id_allocator_set(handle_info->allocator, id); - handle_info->num_in_use++; - return ((type << HANDLE_TYPE_SHIFT) | id); - } - return SWITCH_API_INVALID_HANDLE; +switch_handle_t switch_handle_set_and_allocate(switch_handle_t type, + unsigned int id) { + switch_handle_info_t *handle_info = NULL; + void *p = NULL; + + JLG(p, switch_handle_array, (unsigned int)type); + if ((handle_info = (switch_handle_info_t *)(*(unsigned long *)p))) { + switch_api_id_allocator_set(handle_info->allocator, id); + handle_info->num_in_use++; + return ((type << HANDLE_TYPE_SHIFT) | id); + } + return SWITCH_API_INVALID_HANDLE; } -void -switch_handle_free(switch_handle_t handle) -{ - switch_handle_type_t type = SWITCH_HANDLE_TYPE_NONE; - switch_handle_info_t *handle_info = NULL; - void *p = NULL; - - type = (handle & 0xF8000000) >> HANDLE_TYPE_SHIFT; - JLG(p, switch_handle_array, (unsigned int)type); - if((handle_info = (switch_handle_info_t *) (*(unsigned long *)p))) { - switch_api_id_allocator_release(handle_info->allocator, handle & 0x00FFFFFF); - handle_info->num_in_use--; - } +void switch_handle_free(switch_handle_t handle) { + switch_handle_type_t type = SWITCH_HANDLE_TYPE_NONE; + switch_handle_info_t *handle_info = NULL; + void *p = NULL; + + type = (handle & 0xF8000000) >> HANDLE_TYPE_SHIFT; + JLG(p, switch_handle_array, (unsigned int)type); + if ((handle_info = (switch_handle_info_t *)(*(unsigned long *)p))) { + switch_api_id_allocator_release(handle_info->allocator, + handle & 0x00FFFFFF); + handle_info->num_in_use--; + } } -switch_handle_type_t -switch_handle_get_type(switch_handle_t handle) -{ - switch_handle_type_t type = (handle & 0xF8000000) >> HANDLE_TYPE_SHIFT; - return type; +switch_handle_type_t switch_handle_get_type(switch_handle_t handle) { + switch_handle_type_t type = (handle & 0xF8000000) >> HANDLE_TYPE_SHIFT; + return type; } #ifdef SWITCH_HANDLE_TEST @@ -142,14 +132,13 @@ switch_handle_get_type(switch_handle_t handle) #include #include -int _handle_main (int argc, char **argv) -{ - switch_handle_type_init(SWITCH_HANDLE_TYPE_PORT, 10); - switch_handle_t id = switch_handle_allocate(SWITCH_HANDLE_TYPE_PORT); - printf("id = 0x%lx\n", id); - switch_handle_free(id); - switch_handle_type_free(SWITCH_HANDLE_TYPE_PORT); - return 0; +int _handle_main(int argc, char **argv) { + switch_handle_type_init(SWITCH_HANDLE_TYPE_PORT, 10); + switch_handle_t id = switch_handle_allocate(SWITCH_HANDLE_TYPE_PORT); + printf("id = 0x%lx\n", id); + switch_handle_free(id); + switch_handle_type_free(SWITCH_HANDLE_TYPE_PORT); + return 0; } #endif diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index c0b551d..31d4b28 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -20,6 +20,7 @@ limitations under the License. #include "switchapi/switch_hostif.h" #include "switchapi/switch_nhop.h" #include "switchapi/switch_mirror.h" +#include "switchapi/switch_meter.h" #include "switch_pd.h" #include "switch_log_int.h" #include "switch_hostif_int.h" @@ -38,966 +39,1462 @@ static switch_hostif_rx_callback_fn rx_packet; bool rx_callback_set = FALSE; switch_hostif_nhop_t hostif_nhop[SWITCH_HOSTIF_REASON_CODE_MAX]; -switch_status_t -switch_hostif_init(switch_device_t device) -{ - switch_hostif_rcode_info_t *rcode_info = NULL; - switch_api_hostif_rcode_info_t *rcode_api_info = NULL; - void *temp = NULL; - switch_handle_t mirror_handle; - switch_api_mirror_info_t api_mirror_info; - - switch_hostif_group_array = NULL; - switch_hostif_rcode_array = NULL; - switch_hostif_array = NULL; - switch_handle_type_init(SWITCH_HANDLE_TYPE_HOSTIF_GROUP, (1024)); - switch_handle_type_init(SWITCH_HANDLE_TYPE_HOSTIF, (1024)); - rcode_info = switch_malloc(sizeof(switch_hostif_rcode_info_t), 1); - if (!rcode_info) { - return SWITCH_STATUS_NO_MEMORY; - } - rcode_api_info = &rcode_info->rcode_api_info; - JLI(temp, switch_hostif_rcode_array, SWITCH_HOSTIF_REASON_CODE_NONE); - rcode_api_info->reason_code = SWITCH_HOSTIF_REASON_CODE_NONE; - *(unsigned long *)temp = (unsigned long) (rcode_info); - - switch_api_cpu_interface_create(device); - - // CPU port mirroring session - memset(&api_mirror_info, 0, sizeof(switch_api_mirror_info_t)); - api_mirror_info.session_id = SWITCH_CPU_MIRROR_SESSION_ID; - api_mirror_info.egress_port = CPU_PORT_ID; - api_mirror_info.direction = SWITCH_API_DIRECTION_BOTH; - api_mirror_info.session_type = SWITCH_MIRROR_SESSION_TYPE_SIMPLE; - api_mirror_info.mirror_type = SWITCH_MIRROR_TYPE_LOCAL; - mirror_handle = switch_api_mirror_session_create(device, &api_mirror_info); - (void) mirror_handle; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_hostif_init(switch_device_t device) { + switch_hostif_rcode_info_t *rcode_info = NULL; + switch_api_hostif_rcode_info_t *rcode_api_info = NULL; + void *temp = NULL; + switch_handle_t mirror_handle; + switch_api_mirror_info_t api_mirror_info; + + switch_hostif_group_array = NULL; + switch_hostif_rcode_array = NULL; + switch_hostif_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_HOSTIF_GROUP, (1024)); + switch_handle_type_init(SWITCH_HANDLE_TYPE_HOSTIF, (1024)); + rcode_info = switch_malloc(sizeof(switch_hostif_rcode_info_t), 1); + if (!rcode_info) { + return SWITCH_STATUS_NO_MEMORY; + } + rcode_api_info = &rcode_info->rcode_api_info; + JLI(temp, switch_hostif_rcode_array, SWITCH_HOSTIF_REASON_CODE_NONE); + rcode_api_info->reason_code = SWITCH_HOSTIF_REASON_CODE_NONE; + *(unsigned long *)temp = (unsigned long)(rcode_info); + + switch_api_cpu_interface_create(device); + + // CPU port mirroring session + memset(&api_mirror_info, 0, sizeof(switch_api_mirror_info_t)); + api_mirror_info.session_id = SWITCH_CPU_MIRROR_SESSION_ID; + api_mirror_info.egress_port = CPU_PORT_ID; + api_mirror_info.direction = SWITCH_API_DIRECTION_BOTH; + api_mirror_info.session_type = SWITCH_MIRROR_SESSION_TYPE_SIMPLE; + api_mirror_info.mirror_type = SWITCH_MIRROR_TYPE_LOCAL; + mirror_handle = switch_api_mirror_session_create(device, &api_mirror_info); + (void)mirror_handle; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_hostif_free(switch_device_t device) -{ - switch_handle_type_free(SWITCH_HANDLE_TYPE_HOSTIF_GROUP); - switch_handle_type_free(SWITCH_HANDLE_TYPE_HOSTIF); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_hostif_free(switch_device_t device) { + switch_handle_type_free(SWITCH_HANDLE_TYPE_HOSTIF_GROUP); + switch_handle_type_free(SWITCH_HANDLE_TYPE_HOSTIF); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_hostif_group_create() -{ - switch_handle_t hostif_group_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_HOSTIF_GROUP, switch_hostif_group_t, - switch_hostif_group_array, NULL, hostif_group_handle); - return hostif_group_handle; +switch_handle_t switch_hostif_group_create() { + switch_handle_t hostif_group_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_HOSTIF_GROUP, + switch_hostif_group_t, + switch_hostif_group_array, + NULL, + hostif_group_handle); + return hostif_group_handle; } -switch_hostif_group_t * -switch_hostif_group_get(switch_handle_t hostif_group_handle) -{ - switch_hostif_group_t *hostif_group = NULL; - _switch_handle_get(switch_hostif_group_t, switch_hostif_group_array, hostif_group_handle, hostif_group); - return hostif_group; +switch_hostif_group_t *switch_hostif_group_get( + switch_handle_t hostif_group_handle) { + switch_hostif_group_t *hostif_group = NULL; + _switch_handle_get(switch_hostif_group_t, + switch_hostif_group_array, + hostif_group_handle, + hostif_group); + return hostif_group; } -switch_status_t -switch_hostif_group_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_hostif_group_t, switch_hostif_group_array, handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_hostif_group_delete(switch_handle_t handle) { + _switch_handle_delete( + switch_hostif_group_t, switch_hostif_group_array, handle); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_hostif_group_create(switch_device_t device, switch_hostif_group_t *hostif_group) -{ - switch_handle_t hostif_group_handle = 0; - switch_hostif_group_t *hostif_group_temp = NULL; - - hostif_group_handle = switch_hostif_group_create(); - hostif_group_temp = switch_hostif_group_get(hostif_group_handle); - if (!hostif_group_temp) { - return SWITCH_API_INVALID_HANDLE; - } - memcpy(hostif_group_temp, hostif_group, sizeof(switch_hostif_group_t)); - return hostif_group_handle; +switch_handle_t switch_api_hostif_group_create( + switch_device_t device, switch_hostif_group_t *hostif_group) { + switch_handle_t hostif_group_handle = 0; + switch_hostif_group_t *hostif_group_temp = NULL; + + hostif_group_handle = switch_hostif_group_create(); + hostif_group_temp = switch_hostif_group_get(hostif_group_handle); + if (!hostif_group_temp) { + return SWITCH_API_INVALID_HANDLE; + } + memcpy(hostif_group_temp, hostif_group, sizeof(switch_hostif_group_t)); + return hostif_group_handle; } -switch_status_t -switch_api_hostif_group_delete(switch_device_t device, switch_handle_t hostif_group_handle) -{ - switch_hostif_group_t *hostif_group = NULL; +switch_status_t switch_api_hostif_group_delete( + switch_device_t device, switch_handle_t hostif_group_handle) { + switch_hostif_group_t *hostif_group = NULL; + + if (!SWITCH_HOSTIF_GROUP_HANDLE_VALID(hostif_group_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + hostif_group = switch_hostif_group_get(hostif_group_handle); + if (!hostif_group) { + return SWITCH_STATUS_INVALID_HANDLE; + } + switch_hostif_group_delete(hostif_group_handle); + return SWITCH_STATUS_SUCCESS; +} - if (!SWITCH_HOSTIF_GROUP_HANDLE_VALID(hostif_group_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_api_hostif_reason_code_create( + switch_device_t device, switch_api_hostif_rcode_info_t *rcode_api_info) { + switch_hostif_rcode_info_t *rcode_info = NULL; + void *temp = NULL; + switch_acl_action_t acl_action; + switch_acl_action_params_t action_params; + switch_acl_opt_action_params_t opt_action_params; + switch_handle_t acl_handle = 0; + switch_handle_t system_acl_handle = 0; + switch_handle_t system_ace_handle = 0; + int priority; + int field_count = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t ace_handle; + switch_hostif_group_t *hostif_group_info = NULL; + + JLG(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); + if (!temp) { + rcode_info = switch_malloc(sizeof(switch_hostif_rcode_info_t), 1); + if (!rcode_info) { + return SWITCH_STATUS_NO_MEMORY; } - hostif_group = switch_hostif_group_get(hostif_group_handle); - if (!hostif_group) { - return SWITCH_STATUS_INVALID_HANDLE; + JLI(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); + *(unsigned long *)temp = (unsigned long)(rcode_info); + } + rcode_info = (switch_hostif_rcode_info_t *)(*(unsigned long *)temp); + memcpy(&rcode_info->rcode_api_info, + rcode_api_info, + sizeof(switch_api_hostif_rcode_info_t)); + priority = rcode_api_info->priority; + memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); + + switch (rcode_api_info->reason_code) { + case SWITCH_HOSTIF_REASON_CODE_STP: { + // stp bpdu, redirect to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0x01; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0x80; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xC2; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0x00; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + acl_action = rcode_api_info->action; + field_count++; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - switch_hostif_group_delete(hostif_group_handle); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_hostif_reason_code_create(switch_device_t device, - switch_api_hostif_rcode_info_t *rcode_api_info) -{ - switch_hostif_rcode_info_t *rcode_info = NULL; - void *temp = NULL; - switch_acl_action_t acl_action; - switch_acl_action_params_t action_params; - switch_acl_opt_action_params_t opt_action_params; - switch_handle_t acl_handle = 0; - int priority; - int field_count = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t ace_handle; - - JLG(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); - if (!temp) { - rcode_info = switch_malloc(sizeof(switch_hostif_rcode_info_t), 1); - if (!rcode_info) { - return SWITCH_STATUS_NO_MEMORY; - } - JLI(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); - *(unsigned long *)temp = (unsigned long) (rcode_info); + case SWITCH_HOSTIF_REASON_CODE_LACP: { + // lacp bpdu, redirect to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0x01; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0x80; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xC2; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0x02; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + acl_action = rcode_api_info->action; + field_count++; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - rcode_info = (switch_hostif_rcode_info_t *) (*(unsigned long *)temp); - memcpy(&rcode_info->rcode_api_info, rcode_api_info, sizeof(switch_api_hostif_rcode_info_t)); - priority = rcode_api_info->priority; - memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); - - switch (rcode_api_info->reason_code) { - case SWITCH_HOSTIF_REASON_CODE_STP: { - // stp bpdu, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[0].value.dest_mac.mac_addr[0] = 0x01; - acl_kvp[0].value.dest_mac.mac_addr[1] = 0x80; - acl_kvp[0].value.dest_mac.mac_addr[2] = 0xC2; - acl_kvp[0].value.dest_mac.mac_addr[3] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[4] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[5] = 0x00; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - acl_action = rcode_api_info->action; - field_count = 1; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - break; - } - case SWITCH_HOSTIF_REASON_CODE_LACP: { - // lacp bpdu, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[0].value.dest_mac.mac_addr[0] = 0x01; - acl_kvp[0].value.dest_mac.mac_addr[1] = 0x80; - acl_kvp[0].value.dest_mac.mac_addr[2] = 0xC2; - acl_kvp[0].value.dest_mac.mac_addr[3] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[4] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[5] = 0x02; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - acl_action = rcode_api_info->action; - field_count = 1; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - break; - } - case SWITCH_HOSTIF_REASON_CODE_LLDP: { - // lacp frame, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[0].value.dest_mac.mac_addr[0] = 0x01; - acl_kvp[0].value.dest_mac.mac_addr[1] = 0x80; - acl_kvp[0].value.dest_mac.mac_addr[2] = 0xC2; - acl_kvp[0].value.dest_mac.mac_addr[3] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[4] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[5] = 0x0e; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE; - acl_kvp[1].value.eth_type = 0x88CC; - acl_kvp[1].mask.u.mask = 0xFFFF; - acl_action = rcode_api_info->action; - field_count = 2; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority++, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[0].value.dest_mac.mac_addr[0] = 0x01; - acl_kvp[0].value.dest_mac.mac_addr[1] = 0x80; - acl_kvp[0].value.dest_mac.mac_addr[2] = 0xC2; - acl_kvp[0].value.dest_mac.mac_addr[3] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[4] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[5] = 0x03; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE; - acl_kvp[1].value.eth_type = 0x88CC; - acl_kvp[1].mask.u.mask = 0xFFFF; - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority++, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[0].value.dest_mac.mac_addr[0] = 0x01; - acl_kvp[0].value.dest_mac.mac_addr[1] = 0x80; - acl_kvp[0].value.dest_mac.mac_addr[2] = 0xC2; - acl_kvp[0].value.dest_mac.mac_addr[3] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[4] = 0x00; - acl_kvp[0].value.dest_mac.mac_addr[5] = 0x00; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - acl_kvp[1].field = SWITCH_ACL_MAC_FIELD_ETH_TYPE; - acl_kvp[1].value.eth_type = 0x88CC; - acl_kvp[1].mask.u.mask = 0xFFFF; - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - break; - } - case SWITCH_HOSTIF_REASON_CODE_OSPF: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); - switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; - - // All OSPF routers 224.0.0.5, copy to cpu - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IP_FIELD_IPV4_DEST; - acl_kvp[0].value.ipv4_dest = 0xE0000005; - acl_kvp[0].mask.u.mask = 0xFFFFFFFF; - acl_kvp[1].field = SWITCH_ACL_IP_FIELD_IP_PROTO; - acl_kvp[1].value.ip_proto = 89; - acl_kvp[1].mask.u.mask = 0xFF; - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - // All OSPF designated routes (DRs) 224.0.0.6, copy to cpu - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IP_FIELD_IPV4_DEST; - acl_kvp[0].value.ipv4_dest = 0xE0000006; - acl_kvp[0].mask.u.mask = 0xFFFFFFFF; - acl_kvp[1].field = SWITCH_ACL_IP_FIELD_IP_PROTO; - acl_kvp[1].value.ip_proto = 89; - acl_kvp[1].mask.u.mask = 0xFF; - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - switch_api_acl_reference(device, acl_handle, 0); - break; - } - case SWITCH_HOSTIF_REASON_CODE_OSPFV6: { - // All OSPFv3 routers ff02::5, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IPV6); - switch_acl_ipv6_key_value_pair_t acl_kvp[SWITCH_ACL_IPV6_FIELD_MAX]; - - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; - acl_kvp[0].value.ip_proto = 89; - acl_kvp[0].mask.u.mask.u.addr8[0] = 0xFF; - acl_kvp[1].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; - inet_pton(AF_INET6, "FF02::5", acl_kvp[1].value.ipv6_dest.u.addr8); - memset(acl_kvp[1].mask.u.mask.u.addr8, 0xFF, 16); - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority++, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - // All OSPFv3 designated routes (DRs) ff02::6, copy to cpu - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; - acl_kvp[0].value.ip_proto = 89; - acl_kvp[0].mask.u.mask.u.addr8[0] = 0xFF; - acl_kvp[1].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; - inet_pton(AF_INET6, "FF02::6", acl_kvp[1].value.ipv6_dest.u.addr8); - memset(acl_kvp[1].mask.u.mask.u.addr8, 0xFF, 16); - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - switch_api_acl_reference(device, acl_handle, 0); - break; - } - case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: { - // IPV6 ND packet, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IPV6); - switch_acl_ipv6_key_value_pair_t acl_kvp[SWITCH_ACL_IPV6_FIELD_MAX]; - - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; - acl_kvp[0].value.ip_proto = 58; - acl_kvp[0].mask.u.mask.u.addr8[0] = 0xFF; - acl_kvp[1].field = SWITCH_ACL_IPV6_FIELD_ICMP_TYPE; - acl_kvp[1].value.icmp_type = 135; - acl_kvp[1].mask.u.mask.u.addr8[0] = 0xFF; - acl_kvp[2].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; - inet_pton(AF_INET6, "FF02::1:FF00:0", acl_kvp[2].value.ipv6_dest.u.addr8); - inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00:0", - acl_kvp[2].mask.u.mask.u.addr8); - field_count = 3; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority++, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; - acl_kvp[0].value.ip_proto = 58; - acl_kvp[0].mask.u.mask.u.addr8[0] = 0xFF; - acl_kvp[1].field = SWITCH_ACL_IPV6_FIELD_ICMP_TYPE; - acl_kvp[1].value.icmp_type = 136; - acl_kvp[1].mask.u.mask.u.addr8[0] = 0xFF; - acl_kvp[2].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; - inet_pton(AF_INET6, "FF02::1:FF00:0", acl_kvp[2].value.ipv6_dest.u.addr8); - inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00:0", - acl_kvp[2].mask.u.mask.u.addr8); - field_count = 3; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - switch_api_acl_reference(device, acl_handle, 0); - break; - } - case SWITCH_HOSTIF_REASON_CODE_PIM: { - // PIM packet, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); - switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IP_FIELD_IP_PROTO; - acl_kvp[0].value.ip_proto = 103; - acl_kvp[0].mask.u.mask = 0xFF; - acl_action = rcode_api_info->action; - field_count = 1; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - switch_api_acl_reference(device, acl_handle, 0); - break; - } - case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: { - // IGMPv2 report packet, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); - switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_IP_FIELD_IP_PROTO; - acl_kvp[0].value.ip_proto = 2; - acl_kvp[0].mask.u.mask = 0xFF; - acl_action = rcode_api_info->action; - field_count = 1; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - switch_api_acl_reference(device, acl_handle, 0); - break; - } - case SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE; - acl_kvp[0].value.eth_type = 0x806; - acl_kvp[0].mask.u.mask = 0xFFFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[1].value.dest_mac.mac_addr[0] = 0xFF; - acl_kvp[1].value.dest_mac.mac_addr[1] = 0xFF; - acl_kvp[1].value.dest_mac.mac_addr[2] = 0xFF; - acl_kvp[1].value.dest_mac.mac_addr[3] = 0xFF; - acl_kvp[1].value.dest_mac.mac_addr[4] = 0xFf; - acl_kvp[1].value.dest_mac.mac_addr[5] = 0xFF; - acl_kvp[1].mask.u.mask = 0xFFFFFFFFFFFF; - acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; - acl_kvp[2].value.ipv4_enabled = 1; - acl_kvp[2].mask.u.mask = 0xFFFFFFFF; - field_count = 3; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - break; - } - case SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE; - acl_kvp[0].value.eth_type = 0x806; - acl_kvp[0].mask.u.mask = 0xFFFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_RMAC_HIT; - acl_kvp[1].value.rmac_hit = 1; - acl_kvp[1].mask.u.mask = 0xFF; - acl_action = rcode_api_info->action; - field_count = 2; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - break; - } - case SWITCH_HOSTIF_REASON_CODE_TTL_ERROR: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_TTL; - acl_kvp[0].value.ttl = 0x0; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[1].value.routed = 1; - acl_kvp[1].mask.u.mask = 0xFF; - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - - memset(&acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_TTL; - acl_kvp[0].value.ttl = 0x1; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[1].value.routed = 1; - acl_kvp[1].mask.u.mask = 0xFF; - field_count = 2; - acl_action = rcode_api_info->action; - action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; - switch_api_acl_rule_create(device, acl_handle, - priority, field_count, - acl_kvp, acl_action, - &action_params, - &opt_action_params, - &ace_handle); - break; - } - case SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE: { - // SFLOW reasoncode is generated from different ACLs, which are created - // when SFLOW session is created, the acl_handle is not stored here. - rcode_info->acl_handle = SWITCH_API_INVALID_HANDLE; - break; - } - case SWITCH_HOSTIF_REASON_CODE_L3_REDIRECT: { - rcode_info->acl_handle = SWITCH_API_INVALID_HANDLE; - break; - } - default: - status = SWITCH_STATUS_NOT_SUPPORTED; - break; + case SWITCH_HOSTIF_REASON_CODE_LLDP: { + // lacp frame, redirect to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0x01; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0x80; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xC2; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0x0e; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_ETH_TYPE; + acl_kvp[field_count].value.eth_type = 0x88CC; + acl_kvp[field_count].mask.u.mask = 0xFFFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0x01; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0x80; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xC2; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0x03; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_ETH_TYPE; + acl_kvp[field_count].value.eth_type = 0x88CC; + acl_kvp[field_count].mask.u.mask = 0xFFFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0x01; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0x80; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xC2; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0x00; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0x00; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_ETH_TYPE; + acl_kvp[field_count].value.eth_type = 0x88CC; + acl_kvp[field_count].mask.u.mask = 0xFFFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - return status; -} - -switch_status_t -switch_api_hostif_reason_code_update(switch_device_t device, switch_api_hostif_rcode_info_t *rcode_api_info) -{ - switch_hostif_rcode_info_t *rcode_info = NULL; - void *temp = NULL; - switch_api_hostif_rcode_info_t *rcode_api_info_temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - bool action_set = FALSE; - int priority = 1000; - - JLG(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); - if (!temp) { - rcode_info = switch_malloc(sizeof(switch_hostif_rcode_info_t), 1); - if (!rcode_info) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(rcode_info, 0, sizeof(switch_hostif_rcode_info_t)); - JLI(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); - *(unsigned long *)temp = (unsigned long) (rcode_info); - rcode_info->rcode_api_info.reason_code = rcode_api_info->reason_code; + case SWITCH_HOSTIF_REASON_CODE_OSPF: { + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); + switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; + + // All OSPF routers 224.0.0.5, copy to cpu + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IP_FIELD_IPV4_DEST; + acl_kvp[field_count].value.ipv4_dest = 0xE0000005; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IP_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 89; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + // All OSPF designated routes (DRs) 224.0.0.6, copy to cpu + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IP_FIELD_IPV4_DEST; + acl_kvp[field_count].value.ipv4_dest = 0xE0000006; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IP_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 89; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; + system_acl_kvp[field_count].value.ipv4_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - rcode_info = (switch_hostif_rcode_info_t *) (*(unsigned long *)temp); - rcode_api_info_temp = &rcode_info->rcode_api_info; - - if (rcode_api_info->action) { - rcode_api_info_temp->action = rcode_api_info->action; - action_set = TRUE; + case SWITCH_HOSTIF_REASON_CODE_OSPFV6: { + // All OSPFv3 routers ff02::5, copy to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IPV6); + switch_acl_ipv6_key_value_pair_t acl_kvp[SWITCH_ACL_IPV6_FIELD_MAX]; + + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 89; + acl_kvp[field_count].mask.u.mask.u.addr8[0] = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; + inet_pton( + AF_INET6, "FF02::5", acl_kvp[field_count].value.ipv6_dest.u.addr8); + memset(acl_kvp[field_count].mask.u.mask.u.addr8, 0xFF, 16); + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + // All OSPFv3 designated routes (DRs) ff02::6, copy to cpu + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 89; + acl_kvp[field_count].mask.u.mask.u.addr8[0] = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; + inet_pton( + AF_INET6, "FF02::6", acl_kvp[field_count].value.ipv6_dest.u.addr8); + memset(acl_kvp[field_count].mask.u.mask.u.addr8, 0xFF, 16); + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV6_ENABLED; + system_acl_kvp[field_count].value.ipv6_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - - if (rcode_api_info->priority) { - rcode_api_info_temp->priority = rcode_api_info->priority; - } else { - rcode_api_info_temp->priority = priority; + case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: { + // IPV6 ND packet, copy to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IPV6); + switch_acl_ipv6_key_value_pair_t acl_kvp[SWITCH_ACL_IPV6_FIELD_MAX]; + + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 58; + acl_kvp[field_count].mask.u.mask.u.addr8[0] = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_ICMP_TYPE; + acl_kvp[field_count].value.icmp_type = 135; + acl_kvp[field_count].mask.u.mask.u.addr8[0] = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; + inet_pton(AF_INET6, + "FF02::1:FF00:0", + acl_kvp[field_count].value.ipv6_dest.u.addr8); + inet_pton(AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00:0", + acl_kvp[field_count].mask.u.mask.u.addr8); + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 58; + acl_kvp[field_count].mask.u.mask.u.addr8[0] = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_ICMP_TYPE; + acl_kvp[field_count].value.icmp_type = 136; + acl_kvp[field_count].mask.u.mask.u.addr8[0] = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_IPV6_FIELD_IPV6_DEST; + inet_pton(AF_INET6, + "FF02::1:FF00:0", + acl_kvp[field_count].value.ipv6_dest.u.addr8); + inet_pton(AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00:0", + acl_kvp[field_count].mask.u.mask.u.addr8); + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV6_ENABLED; + system_acl_kvp[field_count].value.ipv6_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - - if (rcode_api_info->channel) { - rcode_api_info_temp->channel = rcode_api_info->channel; + case SWITCH_HOSTIF_REASON_CODE_PIM: { + // PIM packet, copy to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); + switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IP_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 103; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; + system_acl_kvp[field_count].value.ipv4_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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++, + 1, + system_acl_kvp, + acl_action, + &action_params, + &opt_action_params, + &system_ace_handle); + break; } - - if (rcode_api_info->hostif_group_id) { - rcode_api_info_temp->hostif_group_id = rcode_api_info->hostif_group_id; + case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: { + // IGMPv2 report packet, copy to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); + switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_IP_FIELD_IP_PROTO; + acl_kvp[field_count].value.ip_proto = 2; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; } - - if (action_set) { - status = switch_api_hostif_reason_code_create(device, rcode_api_info_temp); + case SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST: { + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_ETH_TYPE; + acl_kvp[field_count].value.eth_type = 0x806; + acl_kvp[field_count].mask.u.mask = 0xFFFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0xFf; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0xFF; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; + system_acl_kvp[field_count].value.ipv4_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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++, + 1, + system_acl_kvp, + acl_action, + &action_params, + &opt_action_params, + &system_ace_handle); + break; } - return status; + case SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE: { + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_ETH_TYPE; + acl_kvp[field_count].value.eth_type = 0x806; + acl_kvp[field_count].mask.u.mask = 0xFFFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_RMAC_HIT; + system_acl_kvp[field_count].value.rmac_hit = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; + system_acl_kvp[field_count].value.ipv4_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; + } + case SWITCH_HOSTIF_REASON_CODE_TTL_ERROR: { + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_TTL; + acl_kvp[field_count].value.ttl = 0x0; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[field_count].value.routed = 1; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + acl_action, + &action_params, + &opt_action_params, + &ace_handle); + + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_TTL; + acl_kvp[field_count].value.ttl = 0x1; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[field_count].value.routed = 1; + acl_kvp[field_count].mask.u.mask = 0xFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + acl_action, + &action_params, + &opt_action_params, + &system_ace_handle); + break; + } + case SWITCH_HOSTIF_REASON_CODE_BROADCAST: { + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; + memset(&acl_kvp, 0, sizeof(acl_kvp)); + field_count = 0; + acl_kvp[field_count].field = SWITCH_ACL_MAC_FIELD_DEST_MAC; + acl_kvp[field_count].value.dest_mac.mac_addr[0] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[1] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[2] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[3] = 0xFF; + acl_kvp[field_count].value.dest_mac.mac_addr[4] = 0xFf; + acl_kvp[field_count].value.dest_mac.mac_addr[5] = 0xFF; + acl_kvp[field_count].mask.u.mask = 0xFFFFFFFFFFFF; + field_count++; + acl_action = rcode_api_info->action; + action_params.cpu_redirect.reason_code = rcode_api_info->reason_code; + switch_api_acl_rule_create(device, + acl_handle, + priority, + field_count, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &ace_handle); + switch_api_acl_reference(device, acl_handle, 0); + + system_acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + switch_acl_system_key_value_pair_t + system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; + memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); + field_count = 0; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_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++; + system_acl_kvp[field_count].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; + system_acl_kvp[field_count].value.ipv4_enabled = TRUE; + system_acl_kvp[field_count].mask.u.mask = 0xFFFFFFFF; + field_count++; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + 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; + } + case SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE: { + // SFLOW reasoncode is generated from different ACLs, which are created + // when SFLOW session is created, the acl_handle is not stored here. + rcode_info->acl_handle = SWITCH_API_INVALID_HANDLE; + break; + } + default: + status = SWITCH_STATUS_NOT_SUPPORTED; + break; + } + + rcode_info->acl_handle = acl_handle; + rcode_info->system_acl_handle = system_acl_handle; + rcode_info->system_ace_handle = system_ace_handle; + + return status; } -switch_status_t -switch_api_hostif_reason_code_delete(switch_device_t device, switch_hostif_reason_code_t reason_code) -{ - switch_hostif_rcode_info_t *rcode_info = NULL; - switch_api_hostif_rcode_info_t *rcode_api_info = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - int priority_shift = 8; - int priority = 0; - - JLG(temp, switch_hostif_rcode_array, reason_code); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - rcode_info = (switch_hostif_rcode_info_t *) (*(unsigned long *)temp); - rcode_api_info = &rcode_info->rcode_api_info; - priority = rcode_api_info->priority << priority_shift; - switch (rcode_api_info->reason_code) { - case SWITCH_HOSTIF_REASON_CODE_STP: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - case SWITCH_HOSTIF_REASON_CODE_LACP: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - case SWITCH_HOSTIF_REASON_CODE_LLDP: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - priority++; - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - priority++; - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - case SWITCH_HOSTIF_REASON_CODE_OSPF: - case SWITCH_HOSTIF_REASON_CODE_OSPFV6: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - priority++; - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - priority++; - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - case SWITCH_HOSTIF_REASON_CODE_PIM: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: - status = switch_api_acl_rule_delete(device, rcode_info->acl_handle, priority); - status = switch_api_acl_remove(device, rcode_info->acl_handle, 0); - break; - default: - status = SWITCH_STATUS_NOT_SUPPORTED; - break; +switch_status_t switch_api_hostif_reason_code_update( + switch_device_t device, switch_api_hostif_rcode_info_t *rcode_api_info) { + switch_hostif_rcode_info_t *rcode_info = NULL; + void *temp = NULL; + switch_api_hostif_rcode_info_t *rcode_api_info_temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool action_set = FALSE; + int priority = 1000; + + JLG(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); + if (!temp) { + rcode_info = switch_malloc(sizeof(switch_hostif_rcode_info_t), 1); + if (!rcode_info) { + return SWITCH_STATUS_NO_MEMORY; } - return status; + memset(rcode_info, 0, sizeof(switch_hostif_rcode_info_t)); + JLI(temp, switch_hostif_rcode_array, rcode_api_info->reason_code); + *(unsigned long *)temp = (unsigned long)(rcode_info); + rcode_info->rcode_api_info.reason_code = rcode_api_info->reason_code; + } + rcode_info = (switch_hostif_rcode_info_t *)(*(unsigned long *)temp); + rcode_api_info_temp = &rcode_info->rcode_api_info; + + if (rcode_api_info->action) { + rcode_api_info_temp->action = rcode_api_info->action; + action_set = TRUE; + } + + if (rcode_api_info->priority) { + rcode_api_info_temp->priority = rcode_api_info->priority; + } else { + rcode_api_info_temp->priority = priority; + } + + if (rcode_api_info->channel) { + rcode_api_info_temp->channel = rcode_api_info->channel; + } + + if (rcode_api_info->hostif_group_id) { + rcode_api_info_temp->hostif_group_id = rcode_api_info->hostif_group_id; + } + + if (action_set) { + status = switch_api_hostif_reason_code_create(device, rcode_api_info_temp); + } + return status; } -switch_status_t -switch_api_hostif_register_rx_callback(switch_device_t device, switch_hostif_rx_callback_fn cb_fn) -{ - rx_packet = cb_fn; - rx_callback_set = TRUE; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_hostif_reason_code_delete( + switch_device_t device, switch_hostif_reason_code_t reason_code) { + switch_hostif_rcode_info_t *rcode_info = NULL; + switch_api_hostif_rcode_info_t *rcode_api_info = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + JLG(temp, switch_hostif_rcode_array, reason_code); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + rcode_info = (switch_hostif_rcode_info_t *)(*(unsigned long *)temp); + rcode_api_info = &rcode_info->rcode_api_info; + + switch (rcode_api_info->reason_code) { + case SWITCH_HOSTIF_REASON_CODE_STP: + case SWITCH_HOSTIF_REASON_CODE_LACP: + case SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST: + case SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE: + case SWITCH_HOSTIF_REASON_CODE_LLDP: + case SWITCH_HOSTIF_REASON_CODE_OSPF: + case SWITCH_HOSTIF_REASON_CODE_OSPFV6: + case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: + case SWITCH_HOSTIF_REASON_CODE_PIM: + case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: + 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( + device, rcode_info->system_acl_handle, rcode_info->system_ace_handle); + status = switch_api_acl_remove(device, rcode_info->system_acl_handle, 0); + break; + default: + status = SWITCH_STATUS_NOT_SUPPORTED; + break; + } + + return status; } +switch_status_t switch_api_hostif_register_rx_callback( + switch_device_t device, switch_hostif_rx_callback_fn cb_fn) { + rx_packet = cb_fn; + rx_callback_set = TRUE; + return SWITCH_STATUS_SUCCESS; +} -switch_status_t -switch_api_hostif_deregister_rx_callback(switch_device_t device, switch_hostif_rx_callback_fn cb_fn) -{ - rx_callback_set = FALSE; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_hostif_deregister_rx_callback( + switch_device_t device, switch_hostif_rx_callback_fn cb_fn) { + rx_callback_set = FALSE; + return SWITCH_STATUS_SUCCESS; } -const char * -switch_api_hostif_code_string(switch_hostif_reason_code_t reason_code) -{ - switch (reason_code) { - case SWITCH_HOSTIF_REASON_CODE_STP: - return "stp"; - case SWITCH_HOSTIF_REASON_CODE_LACP: - return "lacp"; - case SWITCH_HOSTIF_REASON_CODE_LLDP: - return "lldp"; - case SWITCH_HOSTIF_REASON_CODE_OSPF: - return "ospf"; - case SWITCH_HOSTIF_REASON_CODE_OSPFV6: - return "ospf6"; - case SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST: - return "arp-request"; - case SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE: - return "arp-response"; - case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: - return "ipv6nd"; - case SWITCH_HOSTIF_REASON_CODE_PIM: - return "pim"; - case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: - return "igmpv2-report"; - case SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE: - return "sflow-sample"; - default: - return "unknown"; - } +const char *switch_api_hostif_code_string( + switch_hostif_reason_code_t reason_code) { + switch (reason_code) { + case SWITCH_HOSTIF_REASON_CODE_STP: + return "stp"; + case SWITCH_HOSTIF_REASON_CODE_LACP: + return "lacp"; + case SWITCH_HOSTIF_REASON_CODE_LLDP: + return "lldp"; + case SWITCH_HOSTIF_REASON_CODE_OSPF: + return "ospf"; + case SWITCH_HOSTIF_REASON_CODE_OSPFV6: + return "ospf6"; + case SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST: + return "arp-request"; + case SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE: + return "arp-response"; + case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: + return "ipv6nd"; + case SWITCH_HOSTIF_REASON_CODE_PIM: + return "pim"; + case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: + return "igmpv2-report"; + case SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE: + return "sflow-sample"; + default: + return "unknown"; + } } -switch_status_t -switch_api_hostif_rx_packet_from_hw(switch_packet_header_t *packet_header, char *packet, int packet_size) -{ - switch_cpu_header_t *cpu_header = NULL; - switch_hostif_rcode_info_t *rcode_info = NULL; - void *temp = NULL; - switch_hostif_packet_t hostif_packet; - 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; - - JLG(temp, switch_hostif_rcode_array, cpu_header->reason_code); - if (!temp) { - SWITCH_API_ERROR("rx_packet w/ un-handled reason_code 0x%x\n", - cpu_header->reason_code); - return SWITCH_STATUS_ITEM_NOT_FOUND; +switch_status_t switch_api_hostif_rx_packet_from_hw( + switch_packet_header_t *packet_header, + switch_opt_header_t *opt_header, + char *packet, + int packet_size) { + switch_cpu_header_t *cpu_header = NULL; + switch_sflow_header_t *sflow_header = NULL; + switch_hostif_rcode_info_t *rcode_info = NULL; + void *temp = NULL; + switch_hostif_packet_t hostif_packet; + + memset(&hostif_packet, 0, sizeof(switch_hostif_packet_t)); + cpu_header = &packet_header->cpu_header; + + SWITCH_API_TRACE("Received packet with %s trap on ifindex %x\n", + switch_api_hostif_code_string(cpu_header->reason_code), + cpu_header->ingress_ifindex); + + JLG(temp, switch_hostif_rcode_array, cpu_header->reason_code); + if (!temp) { + SWITCH_API_TRACE( + "rx_packet w/ un-handled reason_code 0x%x, " + "setting reason_code to 0\n", + cpu_header->reason_code); + JLG(temp, switch_hostif_rcode_array, SWITCH_HOSTIF_REASON_CODE_NONE); + } + + rcode_info = (switch_hostif_rcode_info_t *)(*(unsigned long *)temp); + 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); + + 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_API_TRACE("Received packet with %s trap on ifindex %x\n", - switch_api_hostif_code_string(cpu_header->reason_code), - cpu_header->ingress_ifindex); - - rcode_info = (switch_hostif_rcode_info_t *) (*(unsigned long *)temp); - -#if 0 /* seems un-necessary check and failing for vlan 0 - checking it */ - 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 (SWITCH_IS_LAG_IFINDEX(cpu_header->ingress_ifindex)) { + hostif_packet.is_lag = TRUE; } -#endif + if (rx_callback_set) { + SWITCH_API_TRACE("Sending packet through cb\n"); - 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); - - if (SWITCH_IS_LAG_IFINDEX(cpu_header->ingress_ifindex)) { - hostif_packet.is_lag = TRUE; - } - if (rx_callback_set) { - SWITCH_API_TRACE("Sending packet through cb\n"); - rx_packet(&hostif_packet); - } - } + static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + switch_packet_rx_transform( + packet_header, in_packet, packet, &packet_size); - 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_rx_to_host(packet_header, packet, packet_size); + hostif_packet.pkt_size = packet_size; + hostif_packet.pkt = in_packet; + rx_packet(&hostif_packet); } - return SWITCH_STATUS_SUCCESS; + } + + 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_rx_to_host(packet_header, packet, packet_size); + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_hostif_tx_packet(switch_device_t device, switch_hostif_packet_t *hostif_packet) -{ - switch_packet_header_t packet_header; - switch_fabric_header_t *fabric_header = NULL; - switch_cpu_header_t *cpu_header = NULL; - switch_port_info_t *port_info = NULL; - - SWITCH_API_TRACE("Received packet from host port %lx through cb\n", - hostif_packet->handle); - - memset(&packet_header, 0, sizeof(switch_packet_header_t)); - fabric_header = &packet_header.fabric_header; - cpu_header = &packet_header.cpu_header; - fabric_header->dst_device = device; - if (hostif_packet->is_lag) { - // Pick a member for lag - } else { - port_info = switch_api_port_get_internal(hostif_packet->handle); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - fabric_header->dst_port_or_group = SWITCH_PORT_ID(port_info); +switch_status_t switch_api_hostif_tx_packet( + switch_device_t device, switch_hostif_packet_t *hostif_packet) { + switch_packet_header_t packet_header; + switch_fabric_header_t *fabric_header = NULL; + switch_cpu_header_t *cpu_header = NULL; + switch_port_info_t *port_info = NULL; + + SWITCH_API_TRACE("Received packet from host port %lx through cb\n", + hostif_packet->handle); + + memset(&packet_header, 0, sizeof(switch_packet_header_t)); + fabric_header = &packet_header.fabric_header; + cpu_header = &packet_header.cpu_header; + fabric_header->dst_device = device; + if (hostif_packet->is_lag) { + // Pick a member for lag + } else { + port_info = switch_api_port_get_internal(hostif_packet->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; - cpu_header->tx_bypass = hostif_packet->tx_bypass; + fabric_header->dst_port_or_group = SWITCH_PORT_ID(port_info); + } + 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; + if (cpu_header->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_packet_tx_to_hw( + &packet_header, hostif_packet->pkt, hostif_packet->pkt_size); + } else { + cpu_header->reason_code = 0; + switch_packet_tx_switched( + &packet_header, hostif_packet->pkt, hostif_packet->pkt_size); + } + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_hostif_create() -{ - switch_handle_t hostif_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_HOSTIF, switch_hostif_info_t, - switch_hostif_array, NULL, hostif_handle); - return hostif_handle; +switch_handle_t switch_hostif_create() { + switch_handle_t hostif_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_HOSTIF, + switch_hostif_info_t, + switch_hostif_array, + NULL, + hostif_handle); + return hostif_handle; } -switch_hostif_info_t * -switch_hostif_get(switch_handle_t hostif_handle) -{ - switch_hostif_info_t *hostif_info = NULL; - _switch_handle_get(switch_hostif_info_t, switch_hostif_array, hostif_handle, hostif_info); - return hostif_info; +switch_hostif_info_t *switch_hostif_get(switch_handle_t hostif_handle) { + switch_hostif_info_t *hostif_info = NULL; + _switch_handle_get( + switch_hostif_info_t, switch_hostif_array, hostif_handle, hostif_info); + return hostif_info; } -switch_status_t -switch_hostif_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_hostif_info_t, switch_hostif_array, handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_hostif_delete(switch_handle_t handle) { + _switch_handle_delete(switch_hostif_info_t, switch_hostif_array, handle); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -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; - - hostif_handle = switch_hostif_create(); - hostif_info = switch_hostif_get(hostif_handle); - memcpy(&hostif_info->hostif, hostif, sizeof(switch_hostif_t)); - status = switch_packet_hostif_create(device, hostif_info); - if (status != SWITCH_STATUS_SUCCESS) { - // delete handle - switch_hostif_delete(hostif_handle); - return SWITCH_API_INVALID_HANDLE; - } +switch_handle_t 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; + + hostif_handle = switch_hostif_create(); + hostif_info = switch_hostif_get(hostif_handle); + memcpy(&hostif_info->hostif, hostif, sizeof(switch_hostif_t)); + status = switch_packet_hostif_create(device, hostif_info); + if (status != SWITCH_STATUS_SUCCESS) { + // delete handle + switch_hostif_delete(hostif_handle); + return SWITCH_API_INVALID_HANDLE; + } - SWITCH_API_TRACE("Host interface created %lu\n", hostif_handle); - return hostif_handle; + SWITCH_API_TRACE("Host interface created %lu\n", hostif_handle); + return hostif_handle; } -switch_status_t -switch_api_hostif_delete(switch_device_t device, switch_handle_t hostif_handle) -{ - switch_hostif_info_t *hostif_info = NULL; +switch_status_t switch_api_hostif_delete(switch_device_t device, + switch_handle_t hostif_handle) { + switch_hostif_info_t *hostif_info = NULL; - if (!SWITCH_HOSTIF_HANDLE_VALID(hostif_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_HOSTIF_HANDLE_VALID(hostif_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } - hostif_info = switch_hostif_get(hostif_handle); - if (!hostif_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - switch_packet_hostif_delete(device, hostif_info); - switch_hostif_delete(hostif_handle); + hostif_info = switch_hostif_get(hostif_handle); + if (!hostif_info) { + return SWITCH_STATUS_INVALID_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; + SWITCH_API_TRACE("Host interface deleted %lu\n", hostif_handle); + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_cpu_nhop_create(switch_device_t device, switch_hostif_reason_code_t rcode) -{ - switch_api_interface_info_t api_intf_info; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_nhop_key_t nhop_key; - switch_interface_info_t *intf_info = NULL; - switch_ifindex_t ifindex; - switch_handle_t intf_handle; - - memset(&api_intf_info, 0, sizeof(switch_api_interface_info_t)); - memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); - api_intf_info.u.port_lag_handle = CPU_PORT_ID; - api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_ACCESS; - intf_handle = switch_api_interface_create(device, &api_intf_info); - if (intf_handle == SWITCH_API_INVALID_HANDLE) { - return SWITCH_STATUS_FAILURE; - } - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_FAILURE; - } - ifindex = SWITCH_HOSTIF_COMPUTE_IFINDEX(handle_to_id(intf_handle)); - intf_info->ifindex = ifindex; - - memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); - nhop_key.intf_handle = intf_handle; - nhop_key.ip_addr_valid = 0; - hostif_nhop[rcode].nhop_handle = switch_api_nhop_create(device, &nhop_key); - - hostif_nhop[rcode].ifindex = ifindex; - hostif_nhop[rcode].intf_handle = intf_handle; - - status = switch_pd_lag_group_table_add_entry(device, - hostif_nhop[rcode].ifindex, - CPU_PORT_ID, - &(hostif_nhop[rcode].mbr_hdl), - &(hostif_nhop[rcode].lag_entry)); - return status; +static switch_status_t switch_cpu_nhop_create( + switch_device_t device, switch_hostif_reason_code_t rcode) { + switch_api_interface_info_t api_intf_info; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_nhop_key_t nhop_key; + switch_interface_info_t *intf_info = NULL; + switch_ifindex_t ifindex; + switch_handle_t intf_handle; + + memset(&api_intf_info, 0, sizeof(switch_api_interface_info_t)); + memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); + api_intf_info.u.port_lag_handle = CPU_PORT_ID; + api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_ACCESS; + intf_handle = switch_api_interface_create(device, &api_intf_info); + if (intf_handle == SWITCH_API_INVALID_HANDLE) { + return SWITCH_STATUS_FAILURE; + } + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_FAILURE; + } + ifindex = SWITCH_HOSTIF_COMPUTE_IFINDEX(handle_to_id(intf_handle)); + intf_info->ifindex = ifindex; + + memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); + nhop_key.intf_handle = intf_handle; + nhop_key.ip_addr_valid = 0; + hostif_nhop[rcode].nhop_handle = switch_api_nhop_create(device, &nhop_key); + + hostif_nhop[rcode].ifindex = ifindex; + hostif_nhop[rcode].intf_handle = intf_handle; + + status = switch_pd_lag_group_table_add_entry(device, + hostif_nhop[rcode].ifindex, + CPU_PORT_ID, + &(hostif_nhop[rcode].mbr_hdl), + &(hostif_nhop[rcode].lag_entry)); + return status; } -switch_status_t -switch_api_cpu_interface_create(switch_device_t device) -{ - switch_handle_t intf_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_port_info_t *port_info = NULL; - - status = switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_NONE); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - intf_handle = hostif_nhop[SWITCH_HOSTIF_REASON_CODE_NONE].intf_handle; +switch_status_t switch_api_cpu_interface_create(switch_device_t device) { + switch_handle_t intf_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_port_info_t *port_info = NULL; - port_info = switch_api_port_get_internal(CPU_PORT_ID); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - status = switch_pd_rewrite_table_fabric_add_entry(device, - SWITCH_EGRESS_TUNNEL_TYPE_CPU, - handle_to_id(intf_handle), - &port_info->rw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + status = switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_NONE); + if (status != SWITCH_STATUS_SUCCESS) { + 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; + } + status = + switch_pd_rewrite_table_fabric_add_entry(device, + SWITCH_EGRESS_TUNNEL_TYPE_CPU, + handle_to_id(intf_handle), + &port_info->rw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } - status = switch_pd_tunnel_rewrite_cpu_add_entry(device, - handle_to_id(intf_handle), - &port_info->tunnel_rw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + status = switch_pd_tunnel_rewrite_cpu_add_entry( + device, handle_to_id(intf_handle), &port_info->tunnel_rw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } - status = switch_pd_ingress_fabric_table_add_entry(device); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + status = switch_pd_ingress_fabric_table_add_entry(device); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } - switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_GLEAN); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_GLEAN); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } - switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_MYIP); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_MYIP); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } - switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_NULL_DROP); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + switch_cpu_nhop_create(device, SWITCH_HOSTIF_REASON_CODE_NULL_DROP); + if (status != SWITCH_STATUS_SUCCESS) { return status; + } + return status; } - -switch_handle_t switch_api_cpu_nhop_get(switch_hostif_reason_code_t rcode) -{ - if (rcode > SWITCH_HOSTIF_REASON_CODE_MAX) { - return SWITCH_API_INVALID_HANDLE; - } - return hostif_nhop[rcode].nhop_handle; +switch_handle_t switch_api_cpu_nhop_get(switch_hostif_reason_code_t rcode) { + if (rcode > SWITCH_HOSTIF_REASON_CODE_MAX) { + return SWITCH_API_INVALID_HANDLE; + } + return hostif_nhop[rcode].nhop_handle; } switch_ifindex_t switch_api_cpu_glean_ifindex() { - return hostif_nhop[SWITCH_HOSTIF_REASON_CODE_GLEAN].ifindex; + return hostif_nhop[SWITCH_HOSTIF_REASON_CODE_GLEAN].ifindex; } switch_ifindex_t switch_api_cpu_myip_ifindex() { - return hostif_nhop[SWITCH_HOSTIF_REASON_CODE_MYIP].ifindex; + return hostif_nhop[SWITCH_HOSTIF_REASON_CODE_MYIP].ifindex; } switch_ifindex_t switch_api_drop_ifindex() { - return hostif_nhop[SWITCH_HOSTIF_REASON_CODE_NULL_DROP].ifindex; + return hostif_nhop[SWITCH_HOSTIF_REASON_CODE_NULL_DROP].ifindex; +} + +switch_status_t switch_api_hostif_meter_create( + switch_device_t device, + switch_api_meter_t *api_meter_info, + switch_handle_t *meter_handle) { + switch_meter_info_t *meter_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + *meter_handle = switch_meter_create(); + meter_info = switch_meter_info_get(*meter_handle); + if (!meter_info) { + return SWITCH_STATUS_NO_MEMORY; + } + + memcpy( + &meter_info->api_meter_info, api_meter_info, sizeof(switch_api_meter_t)); + + status = switch_pd_hostif_meter_set( + device, handle_to_id(*meter_handle), meter_info, TRUE); + return status; +} + +switch_status_t switch_api_hostif_meter_delete(switch_device_t device, + switch_handle_t meter_handle) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_meter_info_t *meter_info = NULL; + + meter_info = switch_meter_info_get(meter_handle); + if (!meter_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + status = switch_pd_hostif_meter_set( + device, handle_to_id(meter_handle), meter_info, FALSE); + switch_meter_delete(meter_handle); + return status; } #ifdef __cplusplus diff --git a/switchapi/src/switch_hostif_int.h b/switchapi/src/switch_hostif_int.h index 340766e..f44f574 100644 --- a/switchapi/src/switch_hostif_int.h +++ b/switchapi/src/switch_hostif_int.h @@ -20,6 +20,7 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" #include "switchapi/switch_hostif.h" +#include "switch_pd_types.h" #ifdef __cplusplus extern "C" { @@ -29,81 +30,99 @@ extern "C" { #define SWITCH_FABRIC_HEADER_ETHTYPE 0x9000 typedef struct switch_hostif_rcode_info_ { - switch_handle_t acl_handle; - switch_api_hostif_rcode_info_t rcode_api_info; + switch_handle_t acl_handle; + switch_handle_t system_acl_handle; + switch_handle_t system_ace_handle; + switch_api_hostif_rcode_info_t rcode_api_info; } switch_hostif_rcode_info_t; typedef struct switch_hostif_info_ { - switch_hostif_t hostif; - switch_handle_t intf_handle; - int intf_fd; + switch_hostif_t hostif; + switch_handle_t intf_handle; + int intf_fd; } switch_hostif_info_t; typedef enum switch_fabric_header_type_ { - SWITCH_FABRIC_HEADER_TYPE_NONE = 0, - SWITCH_FABRIC_HEADER_TYPE_UNICAST = 1, - SWITCH_FABRIC_HEADER_TYPE_MULTICAST = 2, - SWITCH_FABRIC_HEADER_TYPE_MIRROR = 3, - SWITCH_FABRIC_HEADER_TYPE_CONTROL = 4, - SWITCH_FABRIC_HEADER_TYPE_CPU = 5 + SWITCH_FABRIC_HEADER_TYPE_NONE = 0, + SWITCH_FABRIC_HEADER_TYPE_UNICAST = 1, + SWITCH_FABRIC_HEADER_TYPE_MULTICAST = 2, + SWITCH_FABRIC_HEADER_TYPE_MIRROR = 3, + SWITCH_FABRIC_HEADER_TYPE_CONTROL = 4, + SWITCH_FABRIC_HEADER_TYPE_CPU = 5 } switch_fabric_header_type_t; typedef struct __attribute__((__packed__)) switch_fabric_header_ { - uint16_t ether_type; - uint8_t pad1 : 1; - uint8_t packet_version : 2; - uint8_t header_version : 2; - uint8_t packet_type : 3; - uint8_t fabric_color : 3; - uint8_t fabric_qos : 5; - uint8_t dst_device; - uint16_t dst_port_or_group; + uint16_t ether_type; + uint8_t pad1 : 1; + uint8_t packet_version : 2; + uint8_t header_version : 2; + uint8_t packet_type : 3; + uint8_t fabric_color : 3; + uint8_t fabric_qos : 5; + uint8_t dst_device; + uint16_t dst_port_or_group; } switch_fabric_header_t; typedef struct __attribute__((__packed__)) switch_cpu_header_ { - uint16_t reserved : 2; - uint16_t tx_bypass : 1; - uint16_t egress_queue : 5; - uint16_t ingress_port; - uint16_t ingress_ifindex; - uint16_t ingress_bd; - uint16_t reason_code; + uint16_t reserved : 2; + uint16_t tx_bypass : 1; + uint16_t egress_queue : 5; + uint16_t ingress_port; + uint16_t ingress_ifindex; + uint16_t ingress_bd; + uint16_t reason_code; } switch_cpu_header_t; +typedef struct __attribute__((__packed__)) switch_sflow_header_ { + uint16_t sflow_session_id; + uint16_t sflow_egress_ifindex; +} switch_sflow_header_t; + +typedef union __attribute__((__packed__)) switch_opt_header_ { + switch_sflow_header_t sflow_header; +} switch_opt_header_t; + typedef struct __attribute__((__packed__)) switch_packet_header_ { - switch_fabric_header_t fabric_header; - switch_cpu_header_t cpu_header; + switch_fabric_header_t fabric_header; + switch_cpu_header_t cpu_header; } switch_packet_header_t; typedef struct switch_hostif_nhop_ { - switch_handle_t intf_handle; - switch_handle_t nhop_handle; - switch_ifindex_t ifindex; - p4_pd_entry_hdl_t lag_entry; - p4_pd_mbr_hdl_t mbr_hdl; + switch_handle_t intf_handle; + switch_handle_t nhop_handle; + switch_ifindex_t ifindex; + p4_pd_entry_hdl_t lag_entry; + p4_pd_mbr_hdl_t mbr_hdl; } switch_hostif_nhop_t; #define SWITCH_HOSTIF_COMPUTE_IFINDEX(index) \ - ((SWITCH_IFINDEX_TYPE_CPU << SWITCH_IFINDEX_PORT_WIDTH) | index) + ((SWITCH_IFINDEX_TYPE_CPU << SWITCH_IFINDEX_PORT_WIDTH) | index) /* * Internal API's */ +void switch_packet_rx_transform(switch_packet_header_t *packet_header, + char *transformed_packet, + char *packet, + int *packet_size); + switch_status_t switch_hostif_init(switch_device_t device); 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_hostif_info_t * -switch_hostif_get(switch_handle_t hostif_handle); -void -switch_packet_rx_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); +switch_status_t switch_api_hostif_rx_packet_from_hw( + switch_packet_header_t *packet_header, + switch_opt_header_t *opt_header, + char *packet, + int packet_size); +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); +void switch_packet_rx_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); switch_ifindex_t switch_api_cpu_glean_ifindex(); switch_ifindex_t switch_api_cpu_myip_ifindex(); diff --git a/switchapi/src/switch_id.c b/switchapi/src/switch_id.c index 37b6a24..7bc8279 100644 --- a/switchapi/src/switch_id.c +++ b/switchapi/src/switch_id.c @@ -23,82 +23,71 @@ limitations under the License. extern "C" { #endif /* __cplusplus */ -switch_api_id_allocator * -switch_api_id_allocator_new(unsigned int initial_size, bool zero_based) -{ - switch_api_id_allocator *allocator = switch_malloc(sizeof(switch_api_id_allocator), 1); - allocator->n_words = initial_size; - allocator->data = switch_malloc(sizeof(uint32_t), initial_size); - allocator->zero_based = zero_based; - if (allocator->data) { - memset(allocator->data, 0x0, initial_size*sizeof(uint32_t)); - } - return allocator; +switch_api_id_allocator *switch_api_id_allocator_new(unsigned int initial_size, + bool zero_based) { + switch_api_id_allocator *allocator = + switch_malloc(sizeof(switch_api_id_allocator), 1); + allocator->n_words = initial_size; + allocator->data = switch_malloc(sizeof(uint32_t), initial_size); + allocator->zero_based = zero_based; + if (allocator->data) { + memset(allocator->data, 0x0, initial_size * sizeof(uint32_t)); + } + return allocator; } -void -switch_api_id_allocator_destroy(switch_api_id_allocator *allocator) -{ - switch_free(allocator->data); - switch_free(allocator); +void switch_api_id_allocator_destroy(switch_api_id_allocator *allocator) { + switch_free(allocator->data); + switch_free(allocator); } -static inline int -_fit_width( uint32_t val, unsigned width) -{ - unsigned offset = 32; - uint32_t mask = 0; - uint32_t b = 0; - - while(offset >= width) - { - mask = (((uint32_t)1 << width) - 1) << (offset - width); - b = val & mask; - if (!b) - return offset; - offset = __builtin_ctz(b); - } - return -1; +static inline int _fit_width(uint32_t val, unsigned width) { + unsigned offset = 32; + uint32_t mask = 0; + uint32_t b = 0; + + while (offset >= width) { + mask = (((uint32_t)1 << width) - 1) << (offset - width); + b = val & mask; + if (!b) return offset; + offset = __builtin_ctz(b); + } + return -1; } -unsigned int -switch_api_id_allocator_allocate_contiguous (switch_api_id_allocator *allocator, uint8_t count) -{ - unsigned int i; - for (i = 0; i < allocator->n_words; i++) - { - if (allocator->data[i] != 0xFFFFFFFF) - { - unsigned pos=-1; - if ((pos=_fit_width(allocator->data[i], count)) > 0) { - // set the bitmap to 1s - allocator->data[i] |= (0xFFFFFFFF << (pos - count)) & 0xFFFFFFFF; - return 32 * i + (32 - pos) + - (allocator->zero_based ? 0 : 1); - } - } +unsigned int switch_api_id_allocator_allocate_contiguous( + switch_api_id_allocator *allocator, uint8_t count) { + unsigned int i; + for (i = 0; i < allocator->n_words; i++) { + if (allocator->data[i] != 0xFFFFFFFF) { + unsigned pos = -1; + if ((pos = _fit_width(allocator->data[i], count)) > 0) { + // set the bitmap to 1s + allocator->data[i] |= (0xFFFFFFFF << (pos - count)) & 0xFFFFFFFF; + return 32 * i + (32 - pos) + (allocator->zero_based ? 0 : 1); + } } - uint32_t n_words = allocator->n_words; - allocator->data = switch_realloc(allocator->data, n_words * 2 *sizeof(uint32_t)); - memset (&allocator->data[n_words], 0x0, n_words * sizeof (uint32_t)); - allocator->n_words = n_words * 2; - allocator->data[n_words] |= (0xFFFFFFFF << (32 - count)) & 0xFFFFFFFF; - return 32 * n_words + (allocator->zero_based ? 0 : 1); + } + uint32_t n_words = allocator->n_words; + allocator->data = + switch_realloc(allocator->data, n_words * 2 * sizeof(uint32_t)); + memset(&allocator->data[n_words], 0x0, n_words * sizeof(uint32_t)); + allocator->n_words = n_words * 2; + allocator->data[n_words] |= (0xFFFFFFFF << (32 - count)) & 0xFFFFFFFF; + return 32 * n_words + (allocator->zero_based ? 0 : 1); } -unsigned int -switch_api_id_allocator_allocate(switch_api_id_allocator *allocator) -{ - return switch_api_id_allocator_allocate_contiguous(allocator, 1); +unsigned int switch_api_id_allocator_allocate( + switch_api_id_allocator *allocator) { + return switch_api_id_allocator_allocate_contiguous(allocator, 1); } -void -switch_api_id_allocator_release(switch_api_id_allocator *allocator, unsigned int id) -{ - if (allocator->zero_based != true) { - id = id > 0 ? id - 1 : 0; - } - allocator->data[id >> 5] &= ~(1 << (31 - id)); +void switch_api_id_allocator_release(switch_api_id_allocator *allocator, + unsigned int id) { + if (allocator->zero_based != true) { + id = id > 0 ? id - 1 : 0; + } + allocator->data[id >> 5] &= ~(1 << (31 - id)); } /** @@ -106,18 +95,16 @@ switch_api_id_allocator_release(switch_api_id_allocator *allocator, unsigned int * @param allocator allocator created with create * @param id id to set */ -void -switch_api_id_allocator_set(switch_api_id_allocator *allocator, unsigned int id) -{ - //assert (allocator != NULL); - if (allocator->zero_based != true) - { +void switch_api_id_allocator_set(switch_api_id_allocator *allocator, + unsigned int id) { + // assert (allocator != NULL); + if (allocator->zero_based != true) { /* For non-zero based allocator, an id of 0 is forbidden */ - //assert(id > 0); - id = id - 1; - } - //assert((id>>5) < allocator->n_words); - allocator->data[id >> 5] |= (1 << (31 - id)); + // assert(id > 0); + id = id - 1; + } + // assert((id>>5) < allocator->n_words); + allocator->data[id >> 5] |= (1 << (31 - id)); } /** @@ -125,20 +112,17 @@ switch_api_id_allocator_set(switch_api_id_allocator *allocator, unsigned int id) * @param allocator allocator created with create * @param id id to check */ -int -switch_api_id_allocator_is_set(switch_api_id_allocator *allocator, unsigned int id) -{ - //assert (allocator != NULL); - if (allocator->zero_based != true) - { - //assert(id > 0); - id = id - 1; - } - //assert((id>>5) < allocator->n_words); - return((allocator->data[id>>5] & (1 << (31 -id))) ? 1:0); +int switch_api_id_allocator_is_set(switch_api_id_allocator *allocator, + unsigned int id) { + // assert (allocator != NULL); + if (allocator->zero_based != true) { + // assert(id > 0); + id = id - 1; + } + // assert((id>>5) < allocator->n_words); + return ((allocator->data[id >> 5] & (1 << (31 - id))) ? 1 : 0); } - #ifdef SWITCH_ID_ALLOCATOR_TEST #include #include @@ -146,54 +130,50 @@ switch_api_id_allocator_is_set(switch_api_id_allocator *allocator, unsigned int #include #include -#define MAX_ID_TEST (16*1024) +#define MAX_ID_TEST (16 * 1024) #define INITIAL_WORDS 4 -int id_main (int argc, char **argv) -{ - unsigned int i; - unsigned int iter; - switch_api_id_allocator *allocator = switch_api_id_allocator_new (INITIAL_WORDS, FALSE); +int id_main(int argc, char **argv) { + unsigned int i; + unsigned int iter; + switch_api_id_allocator *allocator = + switch_api_id_allocator_new(INITIAL_WORDS, FALSE); - for(i=0;i<40;i++) - switch_api_id_allocator_allocate(allocator); + for (i = 0; i < 40; i++) switch_api_id_allocator_allocate(allocator); - printf("words are 0x%x, 0x%x\n", (uint32_t)allocator->data[0], (uint32_t)allocator->data[1]); + printf("words are 0x%x, 0x%x\n", + (uint32_t)allocator->data[0], + (uint32_t)allocator->data[1]); - for(i=0;i<40;i++) - switch_api_id_allocator_release(allocator, i+1); + for (i = 0; i < 40; i++) switch_api_id_allocator_release(allocator, i + 1); + for (i = 0; i < MAX_ID_TEST; i++) { + unsigned int id = switch_api_id_allocator_allocate(allocator); + assert(id == i + 1); + } - for (i = 0; i < MAX_ID_TEST; i++) - { - unsigned int id = switch_api_id_allocator_allocate (allocator); - assert (id == i+1); - } - - for (i = 0; i < MAX_ID_TEST; i++) - switch_api_id_allocator_release (allocator, i); + for (i = 0; i < MAX_ID_TEST; i++) + switch_api_id_allocator_release(allocator, i); - for (iter = 0; iter < MAX_ID_TEST; iter++) - { - for (i = 0; i < 1000; i++) - switch_api_id_allocator_allocate (allocator); + for (iter = 0; iter < MAX_ID_TEST; iter++) { + for (i = 0; i < 1000; i++) switch_api_id_allocator_allocate(allocator); - for (i = 0; i < 1000; i++) - switch_api_id_allocator_release (allocator, i); - } + for (i = 0; i < 1000; i++) switch_api_id_allocator_release(allocator, i); + } #define NUM_BLOCKS 20 #define BLOCK_SIZE 8 - for(i=0;idata[i/4]); - } - for(i=1;i<=NUM_BLOCKS*BLOCK_SIZE;i++) { - switch_api_id_allocator_release(allocator, i); - } - - switch_api_id_allocator_destroy (allocator); - return 0; + for (i = 0; i < NUM_BLOCKS; i++) { + unsigned int id = + switch_api_id_allocator_allocate_contiguous(allocator, BLOCK_SIZE); + printf("id = %d 0x%x\n", id, (uint32_t)allocator->data[i / 4]); + } + for (i = 1; i <= NUM_BLOCKS * BLOCK_SIZE; i++) { + switch_api_id_allocator_release(allocator, i); + } + + switch_api_id_allocator_destroy(allocator); + return 0; } #endif diff --git a/switchapi/src/switch_init.c b/switchapi/src/switch_init.c index 9a58c57..cb41a08 100644 --- a/switchapi/src/switch_init.c +++ b/switchapi/src/switch_init.c @@ -22,9 +22,9 @@ limitations under the License. #include "switch_vrf_int.h" #include "switch_nhop_int.h" #include "switch_mcast_int.h" -#include "switch_pd.h" #include "switch_neighbor_int.h" #include "switch_lag_int.h" +#include "switch_nat_int.h" #include "switch_stp_int.h" #include "switch_log_int.h" #include "switch_port_int.h" @@ -32,6 +32,11 @@ limitations under the License. #include "switch_acl_int.h" #include "switch_mirror_int.h" #include "switch_meter_int.h" +#include "switch_sflow_int.h" +#include "switch_qos_int.h" +#include "switch_buffer_int.h" +#include "switch_queue_int.h" +#include "switch_scheduler_int.h" #include "switch_pd.h" #include @@ -45,506 +50,542 @@ extern "C" { static int _api_lib_inited = 0; static int _dev_inited[SWITCH_MAX_DEVICE]; +typedef struct { + switch_handle_t acl_handle; + switch_handle_t ace_handle; + unsigned int priority; + unsigned int key_value_count; + switch_acl_system_key_value_pair_t acl_kvp[5]; + switch_acl_action_params_t action_params; +} switch_default_acl_t; + +static bool _switch_negative_mirroring = false; +#define SWITCH_INGRESS_ACL_ENTRIES 8 + +#define SWITCH_EGRESS_ACL_ENTRIES 2 +static switch_default_acl_t + _switch_system_acl_data[SWITCH_MAX_DEVICE][SWITCH_INGRESS_ACL_ENTRIES]; +static switch_default_acl_t + _switch_egress_acl_data[SWITCH_MAX_DEVICE][SWITCH_EGRESS_ACL_ENTRIES]; + extern unsigned int switch_max_configured_ports; static pthread_t stats_thread; -switch_status_t -switch_api_lib_init(switch_device_t device) -{ - switch_log_init(); - SWITCH_API_TRACE("Initializing switch api!!"); - switch_pd_client_init(device); - switch_router_mac_init(device); - switch_port_init(device); - switch_bd_init(device); - switch_lag_init(device); - switch_interface_init(device); - switch_mac_table_init(device); - switch_l3_init(device); - switch_vrf_init(device); - switch_neighbor_init(device); - switch_nhop_init(device); - switch_mcast_init(device); - switch_acl_init(device); - switch_stp_init(device); - switch_tunnel_init(device); - switch_mirror_init(device); - switch_hostif_init(device); - switch_capability_init(device); - switch_meter_init(device); - switch_packet_init(device); - switch_sflow_init(device); - - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_lib_init(switch_device_t device) { + switch_log_init(); + SWITCH_API_TRACE("Initializing switch api!!"); + switch_pd_client_init(device); + switch_router_mac_init(device); + switch_port_init(device); + switch_bd_init(device); + switch_lag_init(device); + switch_interface_init(device); + switch_mac_table_init(device); + switch_l3_init(device); + switch_vrf_init(device); + switch_neighbor_init(device); + switch_nhop_init(device); + switch_mcast_init(device); + switch_acl_init(device); + switch_nat_init(device); + switch_stp_init(device); + switch_tunnel_init(device); + switch_mirror_init(device); + switch_hostif_init(device); + switch_capability_init(device); + switch_meter_init(device); + switch_packet_init(device); + switch_sflow_init(device); + switch_qos_init(device); + switch_buffer_init(device); + switch_queue_init(device); + switch_scheduler_init(device); + switch_packet_init(device); + + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_init_default_entries(switch_device_t device) -{ - // Default Entries - SWITCH_API_TRACE("Programming default entries!!"); - switch_pd_validate_outer_ethernet_add_default_entry(device); - switch_pd_validate_outer_ip_add_default_entry(device); - switch_pd_storm_control_table_add_default_entry(device); - switch_pd_outer_rmac_table_add_default_entry(device); - switch_pd_src_vtep_table_add_default_entry(device); - switch_pd_dest_vtep_table_add_default_entry(device); - switch_pd_validate_packet_table_add_default_entry(device); - switch_pd_port_vlan_mapping_table_add_default_entry(device); - switch_pd_acl_table_add_default_entry(device); - switch_pd_inner_rmac_table_add_default_entry(device); - switch_pd_fwd_result_table_add_default_entry(device); - switch_pd_nexthop_table_add_default_entry(device); - switch_pd_lag_table_add_default_entry(device); - switch_pd_egress_filter_table_add_default_entry(device); - switch_pd_rid_table_add_default_entry(device); - switch_pd_replica_type_table_add_default_entry(device); - switch_pd_mac_table_add_default_entry(device); - switch_pd_egress_bd_map_table_add_default_entry(device); - switch_pd_egress_vni_table_add_default_entry(device); - switch_pd_ip_fib_add_default_entry(device); - switch_pd_ip_urpf_add_default_entry(device); - switch_pd_ip_mcast_add_default_entry(device); - switch_pd_rewrite_table_add_default_entry(device); - switch_pd_rewrite_multicast_table_add_default_entry(device); - switch_pd_egress_vlan_xlate_table_add_default_entry(device); - switch_pd_egress_acl_add_default_entry(device); - switch_pd_vlan_decap_table_add_default_entry(device); - switch_pd_tunnel_smac_rewrite_table_add_default_entry(device); - switch_pd_tunnel_dmac_rewrite_table_add_default_entry(device); - switch_pd_tunnel_rewrite_table_add_default_entry(device); - switch_pd_tunnel_src_rewrite_table_add_default_entry(device); - switch_pd_tunnel_dst_rewrite_table_add_default_entry(device); - switch_pd_tunnel_table_add_default_entry(device); - switch_pd_bd_stats_table_add_default_entry(device); - switch_pd_bd_flood_table_add_default_entry(device); - switch_pd_mirror_table_add_default_entry(device); - switch_pd_mtu_table_add_default_entry(device); - switch_pd_storm_control_table_add_default_entry(device); - switch_pd_meter_index_table_add_default_entry(device); - switch_pd_meter_action_table_add_default_entry(device); - switch_pd_l3_rewrite_table_add_default_entry(device); - - SWITCH_API_TRACE("Programming init entries!!"); - switch_pd_learn_notify_table_add_init_entry(device); - switch_pd_tunnel_decap_tables_init_entry(device); - switch_pd_tunnel_encap_tables_init_entry(device); - switch_pd_validate_outer_ethernet_table_init_entry(device); - switch_pd_vlan_decap_table_init_entry(device); - switch_pd_fwd_result_table_add_init_entry(device); - switch_pd_validate_mpls_packet_table_init_entry(device); - switch_pd_fabric_header_table_init_entry(device); - switch_pd_egress_port_mapping_table_init_entry(device); - switch_pd_compute_hashes_init_entry(device); - switch_pd_switch_config_params_table_init(device); - switch_pd_replica_type_table_init_entry(device); - switch_pd_rewrite_multicast_table_init_entry(device); - switch_pd_l3_rewrite_table_init_entry(device); +switch_status_t switch_api_init_default_entries(switch_device_t device) { + // Default Entries + SWITCH_API_TRACE("Programming default entries!!"); + switch_pd_validate_outer_ethernet_add_default_entry(device); + switch_pd_validate_outer_ip_add_default_entry(device); + switch_pd_storm_control_table_add_default_entry(device); + switch_pd_outer_rmac_table_add_default_entry(device); + switch_pd_src_vtep_table_add_default_entry(device); + switch_pd_dest_vtep_table_add_default_entry(device); + switch_pd_validate_packet_table_add_default_entry(device); + switch_pd_port_vlan_mapping_table_add_default_entry(device); + switch_pd_acl_table_add_default_entry(device); + switch_pd_inner_rmac_table_add_default_entry(device); + switch_pd_fwd_result_table_add_default_entry(device); + switch_pd_nexthop_table_add_default_entry(device); + switch_pd_lag_table_add_default_entry(device); + switch_pd_egress_filter_table_add_default_entry(device); + switch_pd_rid_table_add_default_entry(device); + switch_pd_replica_type_table_add_default_entry(device); + switch_pd_mac_table_add_default_entry(device); + switch_pd_egress_bd_map_table_add_default_entry(device); + switch_pd_egress_vni_table_add_default_entry(device); + switch_pd_ip_fib_add_default_entry(device); + switch_pd_ip_urpf_add_default_entry(device); + switch_pd_ip_mcast_add_default_entry(device); + switch_pd_rewrite_table_add_default_entry(device); + switch_pd_rewrite_multicast_table_add_default_entry(device); + switch_pd_egress_vlan_xlate_table_add_default_entry(device); + switch_pd_egress_acl_add_default_entry(device); + switch_pd_vlan_decap_table_add_default_entry(device); + switch_pd_tunnel_smac_rewrite_table_add_default_entry(device); + switch_pd_tunnel_dmac_rewrite_table_add_default_entry(device); + switch_pd_tunnel_rewrite_table_add_default_entry(device); + switch_pd_tunnel_src_rewrite_table_add_default_entry(device); + switch_pd_tunnel_dst_rewrite_table_add_default_entry(device); + switch_pd_tunnel_table_add_default_entry(device); + switch_pd_bd_stats_table_add_default_entry(device); + switch_pd_bd_flood_table_add_default_entry(device); + switch_pd_mirror_table_add_default_entry(device); + switch_pd_mtu_table_add_default_entry(device); + switch_pd_storm_control_table_add_default_entry(device); + switch_pd_meter_index_table_add_default_entry(device); + switch_pd_meter_action_table_add_default_entry(device); + switch_pd_l3_rewrite_table_add_default_entry(device); + switch_pd_adjust_lkp_fields_table_add_default_entry(device); + switch_pd_qos_default_entry_add(device); + + SWITCH_API_TRACE("Programming init entries!!"); + switch_pd_learn_notify_table_add_init_entry(device); + switch_pd_tunnel_decap_tables_init_entry(device); + switch_pd_tunnel_encap_tables_init_entry(device); + switch_pd_validate_outer_ethernet_table_init_entry(device); + switch_pd_vlan_decap_table_init_entry(device); + switch_pd_fwd_result_table_add_init_entry(device); + switch_pd_validate_mpls_packet_table_init_entry(device); + switch_pd_fabric_header_table_init_entry(device); + switch_pd_egress_port_mapping_table_init_entry(device); + switch_pd_compute_hashes_init_entry(device); + switch_pd_switch_config_params_table_init(device); + switch_pd_replica_type_table_init_entry(device); + switch_pd_rewrite_multicast_table_init_entry(device); + switch_pd_l3_rewrite_table_init_entry(device); + switch_pd_nat_init(device); + #ifdef P4_INT_ENABLE - // Setup INT tables - switch_pd_int_tables_init(device); + switch_pd_int_tables_init(device); #endif - switch_pd_sflow_tables_init(device); + switch_pd_sflow_tables_init(device); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_api_init_default_acl_entries(switch_device_t device) -{ - switch_acl_system_key_value_pair_t acl_kvp[5]; - switch_acl_egr_key_value_pair_t egr_acl_kvp[3]; - switch_acl_action_params_t action_params; - switch_acl_opt_action_params_t opt_action_params; - switch_handle_t acl_handle; - switch_handle_t handle; - int priority = 100; - - memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); - - // system acl for acl copy + dropped packets - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DROP; - acl_kvp[0].value.drop_flag = 1; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_ACL_COPY; - acl_kvp[1].value.acl_copy = true; - acl_kvp[1].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - switch_api_acl_rule_create(device, acl_handle, priority++, 2, - acl_kvp, SWITCH_ACL_ACTION_REDIRECT_TO_CPU, - &action_params, - &opt_action_params, - &handle); - - // system acl for dropped packets - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DROP; - acl_kvp[0].value.drop_flag = 1; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // mac sa is zero, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_SOURCE_MAC; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_SRC_MAC_ZERO; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // port vlan mapping miss, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS; - acl_kvp[0].value.port_vlan_mapping_miss = 1; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_PORT_VLAN_MAPPING_MISS; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // STP state == blocked, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; - acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_BLOCKING; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_STP_STATE_BLOCKING; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - // STP state == learning, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; - acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_LEARNING; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_STP_STATE_LEARNING; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // ACL deny, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ACL_DENY; - acl_kvp[0].value.acl_deny = 1; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_ACL_DENY; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // URPF check fail, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK; - acl_kvp[0].value.urpf_check_fail = 1; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_URPF_CHECK_FAIL; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // same if check fail, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_IF_CHECK; - acl_kvp[0].value.if_check = 0; - acl_kvp[0].mask.u.mask = 0xFFFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_BD_CHECK; - acl_kvp[1].value.bd_check = 0; - acl_kvp[1].mask.u.mask = 0xFFFF; - acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[2].value.routed = 0; - acl_kvp[2].mask.u.mask = 0xFFFF; - acl_kvp[3].field = SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK; - acl_kvp[3].value.tunnel_if_check = 0; - acl_kvp[3].mask.u.mask = 0xFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_SAME_IFINDEX; - switch_api_acl_rule_create(device, acl_handle, priority++, 4, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // egress ifindex is drop ifindex, drop - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; - acl_kvp[0].value.out_ifindex = switch_api_drop_ifindex(); - acl_kvp[0].mask.u.mask = 0xFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.drop.reason_code = DROP_IFINDEX; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_DROP, - &action_params, - &opt_action_params, - &handle); - - // routed, ttl == 1, egress_ifindex == cpu, permit - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[0].value.routed = true; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_TTL; - acl_kvp[1].value.ttl = 1; - acl_kvp[1].mask.u.mask = 0xFF; - acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; - acl_kvp[2].value.out_ifindex = switch_api_cpu_glean_ifindex(); - acl_kvp[2].mask.u.mask = 0xFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - switch_api_acl_rule_create(device, acl_handle, priority++, 3, - acl_kvp, SWITCH_ACL_ACTION_PERMIT, - &action_params, - &opt_action_params, - &handle); - - // routed, ttl == 1, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[0].value.routed = true; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_TTL; - acl_kvp[1].value.ttl = 1; - acl_kvp[1].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.cpu_redirect.reason_code = - SWITCH_HOSTIF_REASON_CODE_TTL_ERROR; - switch_api_acl_rule_create(device, acl_handle, priority++, 2, - acl_kvp, SWITCH_ACL_ACTION_REDIRECT_TO_CPU, - &action_params, - &opt_action_params, - &handle); - - // routed, ipv6_src_is_link_local == 1, egress_ifindex == cpu, permit - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[0].value.routed = true; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL; - acl_kvp[1].value.src_is_link_local = 1; - acl_kvp[1].mask.u.mask = 0xFF; - acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; - acl_kvp[2].value.out_ifindex = switch_api_cpu_glean_ifindex(); - acl_kvp[2].mask.u.mask = 0xFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.cpu_redirect.reason_code = - SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL; - switch_api_acl_rule_create(device, acl_handle, priority++, 3, - acl_kvp, SWITCH_ACL_ACTION_PERMIT, - &action_params, - &opt_action_params, - &handle); - - // routed, ipv6_src_is_link_local == 1, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[0].value.routed = true; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL; - acl_kvp[1].value.src_is_link_local = 1; - acl_kvp[1].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.cpu_redirect.reason_code = - SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL; - switch_api_acl_rule_create(device, acl_handle, priority++, 2, - acl_kvp, SWITCH_ACL_ACTION_REDIRECT_TO_CPU, - &action_params, - &opt_action_params, - &handle); - - // routed, ingress bd == egress bd, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; - acl_kvp[0].value.routed = true; - acl_kvp[0].mask.u.mask = 0xFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_BD_CHECK; - acl_kvp[1].value.bd_check = 0; - acl_kvp[1].mask.u.mask = 0xFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.cpu_redirect.reason_code = - SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT; - switch_api_acl_rule_create(device, acl_handle, priority++, 2, - acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, - &action_params, - &opt_action_params, - &handle); - - // acl_copy, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ACL_COPY; - acl_kvp[0].value.acl_copy = true; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, - &action_params, - &opt_action_params, - &handle); - - // l3_copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_L3_COPY; - acl_kvp[0].value.l3_copy = true; - acl_kvp[0].mask.u.mask = 0xFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, - &action_params, - &opt_action_params, - &handle); - - // Broadcast packet on routed interfaces, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); - memset(acl_kvp, 0, sizeof(acl_kvp)); - acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DEST_MAC; - acl_kvp[0].value.dest_mac.mac_addr[0] = 0xFF; - acl_kvp[0].value.dest_mac.mac_addr[1] = 0xFF; - acl_kvp[0].value.dest_mac.mac_addr[2] = 0xFF; - acl_kvp[0].value.dest_mac.mac_addr[3] = 0xFF; - acl_kvp[0].value.dest_mac.mac_addr[4] = 0xFF; - acl_kvp[0].value.dest_mac.mac_addr[5] = 0xFF; - acl_kvp[0].mask.u.mask = 0xFFFFFFFFFFFF; - acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED; - acl_kvp[1].value.ipv4_enabled = 1; - acl_kvp[1].mask.u.mask = 0xFFFFFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.cpu_redirect.reason_code = 0; - switch_api_acl_rule_create(device, acl_handle, - 2000, /* keep priority lower than reason-codes */ - 2, - acl_kvp, SWITCH_ACL_ACTION_COPY_TO_CPU, - &action_params, - &opt_action_params, - &handle); - // egress l3_mtu_check - acl_handle = switch_api_acl_list_create(device, - SWITCH_ACL_TYPE_EGRESS_SYSTEM); - memset(egr_acl_kvp, 0, sizeof(egr_acl_kvp)); - egr_acl_kvp[0].field = SWITCH_ACL_EGR_L3_MTU_CHECK; - egr_acl_kvp[0].value.l3_mtu_check = 0; - egr_acl_kvp[0].mask.u.mask = 0xFFFF; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - action_params.cpu_redirect.reason_code = - SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR; - switch_api_acl_rule_create(device, acl_handle, priority++, 1, - egr_acl_kvp, - SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU, - &action_params, - &opt_action_params, - &handle); - switch_api_acl_reference(device, acl_handle, 0); +void switch_system_acl_entries_delete(switch_device_t device) { + // go over the array, delete dynamic entries + switch_default_acl_t *acl = &_switch_system_acl_data[device][0]; - return SWITCH_STATUS_SUCCESS; + for (int i = 0; i < SWITCH_INGRESS_ACL_ENTRIES; i++) { + switch_api_acl_rule_delete(device, acl->acl_handle, acl->ace_handle); + acl++; + } } -void * -switch_api_stats_poll(void *args) -{ - switch_device_t device = SWITCH_DEV_ID; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - while (true) { - status = switch_pd_stats_update(device); - if (status != SWITCH_STATUS_SUCCESS) { - break; - } - sleep(60); - } +void switch_system_acl_entries_add(switch_device_t device) { + switch_acl_action_t action; + switch_acl_opt_action_params_t opt_action_params; + switch_default_acl_t *acl = &_switch_system_acl_data[device][0]; + + memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); + action = SWITCH_ACL_ACTION_DROP; + + for (int i = 0; i < SWITCH_INGRESS_ACL_ENTRIES; i++) { + switch_api_acl_rule_create(device, + acl->acl_handle, + acl->priority, + acl->key_value_count, + acl->acl_kvp, + action, + &acl->action_params, + &opt_action_params, + &acl->ace_handle); + acl++; + } +} + +void switch_egress_acl_entries_delete(switch_device_t device) { + switch_default_acl_t *acl = &_switch_egress_acl_data[device][0]; - return NULL; + for (int i = 0; i < SWITCH_EGRESS_ACL_ENTRIES; i++) { + switch_api_acl_rule_delete(device, acl->acl_handle, acl->ace_handle); + acl++; + } } -switch_status_t -switch_api_stats_poll_server(void) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - UNUSED(stats_thread); - - pthread_create( - &stats_thread, - NULL, - switch_api_stats_poll, - NULL); - return status; +void switch_egress_acl_entries_add(switch_device_t device) { + switch_acl_opt_action_params_t opt_action_params; + switch_default_acl_t *acl = &_switch_egress_acl_data[device][0]; + switch_acl_egr_key_value_pair_t egr_acl_kvp[3]; + + memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); + // add copy to cpu rule for mtu check + memset(egr_acl_kvp, 0, sizeof(egr_acl_kvp)); + egr_acl_kvp[0].field = SWITCH_ACL_EGR_L3_MTU_CHECK; + egr_acl_kvp[0].value.l3_mtu_check = 0; + egr_acl_kvp[0].mask.u.mask = 0xFFFF; + memset(&acl->action_params, 0, sizeof(switch_acl_action_params_t)); + acl->action_params.cpu_redirect.reason_code = + SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR; + switch_api_acl_rule_create(device, + acl->acl_handle, + acl->priority, + acl->key_value_count, + egr_acl_kvp, + SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU, + &acl->action_params, + &opt_action_params, + &acl->ace_handle); } -switch_status_t -switch_api_init(switch_device_t device, unsigned int num_ports) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_negative_mirroring_set(switch_device_t device, + bool negative_mirroring) { + if (_switch_negative_mirroring == negative_mirroring) + return SWITCH_STATUS_ITEM_ALREADY_EXISTS; - if (device > SWITCH_MAX_DEVICE) { - return SWITCH_STATUS_INVALID_DEVICE; - } + _switch_negative_mirroring = negative_mirroring; - if (num_ports) { - switch_max_configured_ports = num_ports; - } + switch_system_acl_entries_delete(device); + switch_system_acl_entries_add(device); + switch_egress_acl_entries_delete(device); + switch_egress_acl_entries_add(device); - if(_api_lib_inited == 0) { - switch_api_lib_init(device); - _api_lib_inited = 1; - switch_api_stats_poll_server(); - } + return SWITCH_STATUS_SUCCESS; +} - if (_dev_inited[device] == 0) { - status = switch_api_init_default_acl_entries(device); - status = switch_api_init_default_entries(device); - _dev_inited[device] = 1; - } +static switch_status_t switch_api_init_default_acl_entries( + switch_device_t device) { + switch_acl_system_key_value_pair_t acl_kvp[5]; + switch_acl_action_params_t action_params; + switch_acl_opt_action_params_t opt_action_params; + switch_handle_t acl_handle; + switch_handle_t handle; + int priority = 100; + switch_default_acl_t *dacl = &_switch_system_acl_data[device][0]; + + memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); + + // system acl for dropped packets + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DROP; + dacl->acl_kvp[0].value.drop_flag = 1; + dacl->acl_kvp[0].mask.u.mask = 0xFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl++; + + // port vlan mapping miss, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS; + dacl->acl_kvp[0].value.port_vlan_mapping_miss = 1; + dacl->acl_kvp[0].mask.u.mask = 0xFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_PORT_VLAN_MAPPING_MISS; + dacl++; + + // STP state == blocked, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; + dacl->acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_BLOCKING; + dacl->acl_kvp[0].mask.u.mask = 0xFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_STP_STATE_BLOCKING; + dacl++; + + // STP state == learning, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; + dacl->acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_LEARNING; + dacl->acl_kvp[0].mask.u.mask = 0xFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_STP_STATE_LEARNING; + dacl++; + + // ACL deny, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ACL_DENY; + dacl->acl_kvp[0].value.acl_deny = 1; + dacl->acl_kvp[0].mask.u.mask = 0xFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_ACL_DENY; + dacl++; + + // URPF check fail, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK; + dacl->acl_kvp[0].value.urpf_check_fail = 1; + dacl->acl_kvp[0].mask.u.mask = 0xFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_URPF_CHECK_FAIL; + dacl++; + + // same if check fail, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_IF_CHECK; + dacl->acl_kvp[0].value.if_check = 0; + dacl->acl_kvp[0].mask.u.mask = 0xFFFF; + dacl->acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_BD_CHECK; + dacl->acl_kvp[1].value.bd_check = 0; + dacl->acl_kvp[1].mask.u.mask = 0xFFFF; + dacl->acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + dacl->acl_kvp[2].value.routed = 0; + dacl->acl_kvp[2].mask.u.mask = 0xFFFF; + dacl->acl_kvp[3].field = SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK; + dacl->acl_kvp[3].value.tunnel_if_check = 0; + dacl->acl_kvp[3].mask.u.mask = 0xFFFF; + dacl->priority = priority++; + dacl->key_value_count = 4; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_SAME_IFINDEX; + dacl++; + + // egress ifindex is drop ifindex, drop + dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); + dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; + dacl->acl_kvp[0].value.out_ifindex = switch_api_drop_ifindex(); + dacl->acl_kvp[0].mask.u.mask = 0xFFFF; + dacl->priority = priority++; + dacl->key_value_count = 1; + memset(&dacl->action_params, 0, sizeof(switch_acl_action_params_t)); + dacl->action_params.drop.reason_code = DROP_IFINDEX; + dacl++; + + switch_system_acl_entries_add(device); + + // routed, ttl == 1, egress_ifindex == cpu, permit + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(acl_kvp, 0, sizeof(acl_kvp)); + acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[0].value.routed = true; + acl_kvp[0].mask.u.mask = 0xFF; + acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_TTL; + acl_kvp[1].value.ttl = 1; + acl_kvp[1].mask.u.mask = 0xFF; + acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; + acl_kvp[2].value.out_ifindex = switch_api_cpu_glean_ifindex(); + acl_kvp[2].mask.u.mask = 0xFFFF; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + switch_api_acl_rule_create(device, + acl_handle, + priority++, + 3, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &handle); + + // routed, ttl == 1, redirect to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(acl_kvp, 0, sizeof(acl_kvp)); + acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[0].value.routed = true; + acl_kvp[0].mask.u.mask = 0xFF; + acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_TTL; + acl_kvp[1].value.ttl = 1; + acl_kvp[1].mask.u.mask = 0xFF; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + action_params.cpu_redirect.reason_code = SWITCH_HOSTIF_REASON_CODE_TTL_ERROR; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + 2, + acl_kvp, + SWITCH_ACL_ACTION_REDIRECT_TO_CPU, + &action_params, + &opt_action_params, + &handle); + + // routed, ipv6_src_is_link_local == 1, egress_ifindex == cpu, permit + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(acl_kvp, 0, sizeof(acl_kvp)); + acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[0].value.routed = true; + acl_kvp[0].mask.u.mask = 0xFF; + acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL; + acl_kvp[1].value.src_is_link_local = 1; + acl_kvp[1].mask.u.mask = 0xFF; + acl_kvp[2].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; + acl_kvp[2].value.out_ifindex = switch_api_cpu_glean_ifindex(); + acl_kvp[2].mask.u.mask = 0xFFFF; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + action_params.cpu_redirect.reason_code = + SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + 3, + acl_kvp, + SWITCH_ACL_ACTION_PERMIT, + &action_params, + &opt_action_params, + &handle); + + // routed, ipv6_src_is_link_local == 1, redirect to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(acl_kvp, 0, sizeof(acl_kvp)); + acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[0].value.routed = true; + acl_kvp[0].mask.u.mask = 0xFF; + acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL; + acl_kvp[1].value.src_is_link_local = 1; + acl_kvp[1].mask.u.mask = 0xFF; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + action_params.cpu_redirect.reason_code = + SWITCH_HOSTIF_REASON_CODE_SRC_IS_LINK_LOCAL; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + 2, + acl_kvp, + SWITCH_ACL_ACTION_REDIRECT_TO_CPU, + &action_params, + &opt_action_params, + &handle); + + // routed, ingress bd == egress bd, copy to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(acl_kvp, 0, sizeof(acl_kvp)); + acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; + acl_kvp[0].value.routed = true; + acl_kvp[0].mask.u.mask = 0xFF; + acl_kvp[1].field = SWITCH_ACL_SYSTEM_FIELD_BD_CHECK; + acl_kvp[1].value.bd_check = 0; + acl_kvp[1].mask.u.mask = 0xFFFF; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + action_params.cpu_redirect.reason_code = + SWITCH_HOSTIF_REASON_CODE_ICMP_REDIRECT; + switch_api_acl_rule_create(device, + acl_handle, + priority++, + 2, + acl_kvp, + SWITCH_ACL_ACTION_COPY_TO_CPU, + &action_params, + &opt_action_params, + &handle); + + // l3_copy to cpu + acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + memset(acl_kvp, 0, sizeof(acl_kvp)); + acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_L3_COPY; + acl_kvp[0].value.l3_copy = true; + acl_kvp[0].mask.u.mask = 0xFF; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + switch_api_acl_rule_create(device, + acl_handle, + priority++, + 1, + acl_kvp, + SWITCH_ACL_ACTION_COPY_TO_CPU, + &action_params, + &opt_action_params, + &handle); + + switch_default_acl_t *egr_acl = &_switch_egress_acl_data[device][0]; + // set acl handler and priority for egress mtu check rule + egr_acl->acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_EGRESS_SYSTEM); + egr_acl->priority = priority++; + egr_acl->key_value_count = 1; + switch_api_acl_reference(device, egr_acl->acl_handle, 0); + egr_acl++; + + // set acl handler and priority for egress dod rule + egr_acl->acl_handle = + switch_api_acl_list_create(device, SWITCH_ACL_TYPE_EGRESS_SYSTEM); + egr_acl->priority = priority; + egr_acl->key_value_count = 1; + switch_egress_acl_entries_add(device); + switch_api_acl_reference(device, egr_acl->acl_handle, 0); + + return SWITCH_STATUS_SUCCESS; +} + +void *switch_api_stats_poll(void *args) { + switch_device_t device = SWITCH_DEV_ID; + switch_status_t status = SWITCH_STATUS_SUCCESS; + while (true) { + status = switch_pd_stats_update(device); if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FAILURE; + break; } + sleep(60); + } + + return NULL; +} + +switch_status_t switch_api_stats_poll_server(void) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + UNUSED(stats_thread); + + pthread_create(&stats_thread, NULL, switch_api_stats_poll, NULL); + return status; +} + +switch_status_t switch_api_init(switch_device_t device, + unsigned int num_ports) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (device > SWITCH_MAX_DEVICE) { + return SWITCH_STATUS_INVALID_DEVICE; + } + + if (num_ports) { + switch_max_configured_ports = num_ports; + } + + if (_api_lib_inited == 0) { + switch_api_lib_init(device); + _api_lib_inited = 1; + switch_api_stats_poll_server(); + } + + if (_dev_inited[device] == 0) { + status = switch_api_init_default_acl_entries(device); + status = switch_api_init_default_entries(device); + _dev_inited[device] = 1; + } + + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FAILURE; + } - return status; + return status; } -switch_status_t -switch_api_init0(char *args) -{ - switch_device_t device = 0; - unsigned int num_ports; - sscanf(args, "%c %d", &device, &num_ports); - return switch_api_init(device, num_ports); +switch_status_t switch_api_init0(char *args) { + switch_device_t device = 0; + unsigned int num_ports; + sscanf(args, "%c %d", &device, &num_ports); + return switch_api_init(device, num_ports); } #ifdef __cplusplus diff --git a/switchapi/src/switch_interface.c b/switchapi/src/switch_interface.c index cbc6add..42ab5c3 100644 --- a/switchapi/src/switch_interface.c +++ b/switchapi/src/switch_interface.c @@ -37,1252 +37,1310 @@ extern "C" { static void *switch_interface_array; -switch_status_t -switch_interface_init(switch_device_t device) -{ - UNUSED(device); - return switch_handle_type_init(SWITCH_HANDLE_TYPE_INTERFACE, (16*1024)); +switch_status_t switch_interface_init(switch_device_t device) { + UNUSED(device); + return switch_handle_type_init(SWITCH_HANDLE_TYPE_INTERFACE, (16 * 1024)); } -switch_status_t -switch_interface_free(switch_device_t device) -{ - UNUSED(device); - switch_handle_type_free(SWITCH_HANDLE_TYPE_INTERFACE); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_interface_free(switch_device_t device) { + UNUSED(device); + switch_handle_type_free(SWITCH_HANDLE_TYPE_INTERFACE); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_interface_handle_create() -{ - switch_handle_t handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_INTERFACE, switch_interface_info_t, - switch_interface_array, NULL, handle); - return handle; +switch_handle_t switch_interface_handle_create() { + switch_handle_t handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_INTERFACE, + switch_interface_info_t, + switch_interface_array, + NULL, + handle); + return handle; } -switch_interface_info_t * -switch_api_interface_get(switch_handle_t interface_handle) -{ - switch_interface_info_t *interface_info = NULL; - _switch_handle_get(switch_interface_info_t, switch_interface_array, - interface_handle, interface_info); - return interface_info; +switch_interface_info_t *switch_api_interface_get( + switch_handle_t interface_handle) { + switch_interface_info_t *interface_info = NULL; + _switch_handle_get(switch_interface_info_t, + switch_interface_array, + interface_handle, + interface_info); + return interface_info; } -switch_status_t -switch_api_interface_get_type(switch_handle_t intf_handle, - switch_interface_type_t *type) -{ - switch_interface_info_t * intf_info = NULL; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_api_interface_get_type(switch_handle_t intf_handle, + switch_interface_type_t *type) { + switch_interface_info_t *intf_info = NULL; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } - *type = SWITCH_INTF_TYPE(intf_info); - return SWITCH_STATUS_SUCCESS; + *type = SWITCH_INTF_TYPE(intf_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_interface_get_port_handle(switch_handle_t intf_handle, - switch_handle_t *port_handle) -{ - switch_interface_info_t * intf_info = NULL; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_PORT_VLAN) { - *port_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); - } else { - *port_handle = SWITCH_INTF_PORT_HANDLE(intf_info); - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_get_port_handle( + switch_handle_t intf_handle, switch_handle_t *port_handle) { + switch_interface_info_t *intf_info = NULL; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_PORT_VLAN) { + *port_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); + } else { + *port_handle = SWITCH_INTF_PORT_HANDLE(intf_info); + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_interface_get_vlan_handle(switch_handle_t intf_handle, - switch_handle_t *vlan_handle) -{ - switch_interface_info_t * intf_info = NULL; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - *vlan_handle = intf_info->bd_handle; - return SWITCH_STATUS_SUCCESS; -} +switch_status_t switch_api_interface_get_vlan_handle( + switch_handle_t intf_handle, switch_handle_t *vlan_handle) { + switch_interface_info_t *intf_info = NULL; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } -switch_handle_t -switch_api_interface_get_from_ifindex( - switch_ifindex_t ifindex, - switch_handle_t bd_handle) -{ - switch_handle_t intf_handle = 0; - switch_handle_t port_lag_handle = 0; - uint16_t tunnel_id = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - 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 { - 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; + *vlan_handle = intf_info->bd_handle; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_interface_create_l2(switch_device_t device, switch_handle_t intf_handle, - switch_interface_info_t *intf_info) -{ - switch_port_info_t *port_info = NULL; - switch_lag_info_t *lag_info = NULL; - 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_lag_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); - } else { - port_lag_handle = SWITCH_INTF_PORT_HANDLE(intf_info); - } - 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; +switch_handle_t switch_api_interface_get_from_ifindex( + switch_ifindex_t ifindex, switch_handle_t bd_handle) { + switch_handle_t intf_handle = 0; + switch_handle_t port_lag_handle = 0; + uint16_t tunnel_id = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + 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 { + if (SWITCH_IS_LAG_IFINDEX(ifindex)) { + port_lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_LAG, + SWITCH_LAG_ID_FROM_IFINDEX(ifindex)); } else { - port_info = switch_api_port_get_internal(SWITCH_INTF_PORT_HANDLE(intf_info)); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - 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; - } + port_lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, (ifindex - 1)); } - // 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 ? - /* - vlan_handle = switch_api_default_vlan_internal(); - status = switch_api_add_ports_to_vlan(vlan_handle, 1, &intf_handle); + status = + switch_interface_handle_get(port_lag_handle, bd_handle, &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { - // TODO: Do the intf_handle cleanup - return status; + SWITCH_API_ERROR("interface handle get failed for port_lag_handle %lx", + port_lag_handle); } - */ - return status; + } + return intf_handle; } -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_lag_handle = 0; - switch_logical_network_t ln_info_tmp; - switch_logical_network_t *ln_info = NULL; - switch_port_info_t *port_info = NULL; - switch_bd_info_t *bd_info = NULL; - 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)); - api_intf_info = &intf_info->api_intf_info; - - switch (SWITCH_INTF_TYPE(intf_info)) { - case SWITCH_API_INTERFACE_L3: - 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; - } +switch_status_t switch_api_interface_create_l2( + switch_device_t device, + switch_handle_t intf_handle, + switch_interface_info_t *intf_info) { + switch_port_info_t *port_info = NULL; + switch_lag_info_t *lag_info = NULL; + 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_lag_handle = SWITCH_INTF_PV_PORT_HANDLE(intf_info); + } else { + port_lag_handle = SWITCH_INTF_PORT_HANDLE(intf_info); + } + 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; + } else { + port_info = + switch_api_port_get_internal(SWITCH_INTF_PORT_HANDLE(intf_info)); + if (!port_info) { + return SWITCH_STATUS_INVALID_PORT_NUMBER; + } + 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 ? + /* + vlan_handle = switch_api_default_vlan_internal(); + status = switch_api_add_ports_to_vlan(vlan_handle, 1, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + // TODO: Do the intf_handle cleanup + return status; + } + */ + return status; +} - 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; +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_lag_handle = 0; + switch_logical_network_t ln_info_tmp; + switch_logical_network_t *ln_info = NULL; + switch_port_info_t *port_info = NULL; + switch_bd_info_t *bd_info = NULL; + 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)); + api_intf_info = &intf_info->api_intf_info; + + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L3: + 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; + } + + 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; + } else { + port_info = + switch_api_port_get_internal(SWITCH_INTF_PORT_HANDLE(intf_info)); + if (!port_info) { + return SWITCH_STATUS_INVALID_PORT_NUMBER; + } + 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; + } + } + + ln_info = &ln_info_tmp; + memset(ln_info, 0, sizeof(switch_logical_network_t)); + ln_info->type = SWITCH_LOGICAL_NETWORK_TYPE_L3; + ln_info->vrf_handle = api_intf_info->vrf_handle; + ln_info->rmac_handle = api_intf_info->rmac_handle; + ln_info->flags.ipv4_unicast_enabled = TRUE; + ln_info->flags.ipv6_unicast_enabled = TRUE; + ln_info->flags.ipv4_multicast_enabled = api_intf_info->ipv4_multicast_enabled; + ln_info->flags.ipv6_multicast_enabled = api_intf_info->ipv6_multicast_enabled; + if (!api_intf_info->rmac_handle) { + if (api_intf_info->mac_valid) { + api_intf_info->rmac_handle = switch_api_router_mac_group_create(device); + status = switch_api_router_mac_add( + device, api_intf_info->rmac_handle, &api_intf_info->mac); } else { - port_info = switch_api_port_get_internal(SWITCH_INTF_PORT_HANDLE(intf_info)); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - port_lag_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, port_lag_handle); - intf_info->ifindex = port_info->ifindex; + api_intf_info->rmac_handle = switch_api_capability_rmac_handle_get(); } + } + ln_info->rmac_handle = api_intf_info->rmac_handle; + intf_info->bd_handle = switch_api_logical_network_create(device, ln_info); - 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; - } - } + if (intf_info->bd_handle == SWITCH_API_INVALID_HANDLE) { + status = SWITCH_STATUS_INVALID_HANDLE; + SWITCH_API_ERROR( + "interface create failed. " + "bd allocation failed"); + return status; + } + + switch_api_interface_ipv4_urpf_mode_set(intf_handle, + api_intf_info->ipv4_urpf_mode); + switch_api_interface_nat_mode_set(intf_handle, api_intf_info->nat_mode); + bd_info = switch_bd_get(intf_info->bd_handle); + if (!bd_info) { + status = SWITCH_STATUS_INVALID_HANDLE; + SWITCH_API_ERROR( + "interface create failed. " + "bd allocation failed"); + 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; - } + status = switch_pd_port_vlan_mapping_table_add_entry( + device, vlan_id, 0, intf_info, bd_info->bd_entry, &(intf_info->pv_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("bd programming failed for l3 intf %lx", intf_handle); + return status; + } + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_PORT_VLAN) { + status = switch_pd_egress_vlan_xlate_table_add_entry( + device, + intf_info->ifindex, + handle_to_id(intf_info->bd_handle), + vlan_id, + &intf_info->xlate_entry); - ln_info = &ln_info_tmp; - memset(ln_info, 0, sizeof(switch_logical_network_t)); - ln_info->type = SWITCH_LOGICAL_NETWORK_TYPE_L3; - ln_info->vrf_handle = api_intf_info->vrf_handle; - ln_info->rmac_handle = api_intf_info->rmac_handle; - ln_info->flags.ipv4_unicast_enabled = TRUE; - ln_info->flags.ipv6_unicast_enabled = TRUE; - ln_info->flags.ipv4_multicast_enabled = - api_intf_info->ipv4_multicast_enabled; - ln_info->flags.ipv6_multicast_enabled = - api_intf_info->ipv6_multicast_enabled; - if (!api_intf_info->rmac_handle) { - if (api_intf_info->mac_valid) { - api_intf_info->rmac_handle = switch_api_router_mac_group_create(device); - status = switch_api_router_mac_add(device, api_intf_info->rmac_handle, - &api_intf_info->mac); - } else { - api_intf_info->rmac_handle = switch_api_capability_rmac_handle_get(); - } - } - ln_info->rmac_handle = api_intf_info->rmac_handle; - intf_info->bd_handle = switch_api_logical_network_create(device, ln_info); - switch_api_interface_ipv4_urpf_mode_set(intf_handle, - api_intf_info->ipv4_urpf_mode); - bd_info = switch_bd_get(intf_info->bd_handle); - status = switch_pd_port_vlan_mapping_table_add_entry(device, vlan_id, 0, - intf_info, - bd_info->bd_entry, - &(intf_info->pv_entry)); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("bd programming failed for l3 intf %lx", intf_handle); - return status; + SWITCH_API_ERROR("xlate programming failed for l3 vlan intf %lx", + intf_handle); + return status; } + } - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_PORT_VLAN) { - status = switch_pd_egress_vlan_xlate_table_add_entry( - device, - intf_info->ifindex, - handle_to_id(intf_info->bd_handle), - vlan_id, - &intf_info->xlate_entry); - - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("xlate programming failed for l3 vlan intf %lx", intf_handle); - 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; + } - bd_info->l3_intf_handle = intf_handle; + bd_info->l3_intf_handle = intf_handle; - return status; + return status; } -switch_status_t -switch_api_interface_create_vlan_interface(switch_device_t device, - switch_handle_t intf_handle, - switch_interface_info_t *intf_info) -{ - switch_api_interface_info_t *api_intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_vlan_t vlan_id = 0; - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - switch_handle_t bd_handle = 0; - - vlan_id = SWITCH_INTF_VLAN_ID(intf_info); - status = switch_api_vlan_id_to_handle_get(vlan_id, &bd_handle); - //Assumption here is vlan is already created - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - api_intf_info = &intf_info->api_intf_info; - ln_info = &bd_info->ln_info; - ln_info->vrf_handle = api_intf_info->vrf_handle; - ln_info->flags.ipv4_unicast_enabled = api_intf_info->ipv4_unicast_enabled; - ln_info->flags.ipv6_unicast_enabled = api_intf_info->ipv6_unicast_enabled; - ln_info->flags.ipv4_multicast_enabled = - api_intf_info->ipv4_multicast_enabled; - ln_info->flags.ipv6_multicast_enabled = - api_intf_info->ipv6_multicast_enabled; - if (!api_intf_info->rmac_handle) { - if (api_intf_info->mac_valid) { - api_intf_info->rmac_handle = switch_api_router_mac_group_create(device); - status = switch_api_router_mac_add(device, api_intf_info->rmac_handle, - &api_intf_info->mac); - } else { - api_intf_info->rmac_handle = switch_api_capability_rmac_handle_get(); - } +switch_status_t switch_api_interface_create_vlan_interface( + switch_device_t device, + switch_handle_t intf_handle, + switch_interface_info_t *intf_info) { + switch_api_interface_info_t *api_intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_vlan_t vlan_id = 0; + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + switch_handle_t bd_handle = 0; + + vlan_id = SWITCH_INTF_VLAN_ID(intf_info); + status = switch_api_vlan_id_to_handle_get(vlan_id, &bd_handle); + // Assumption here is vlan is already created + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + api_intf_info = &intf_info->api_intf_info; + ln_info = &bd_info->ln_info; + ln_info->vrf_handle = api_intf_info->vrf_handle; + ln_info->flags.ipv4_unicast_enabled = api_intf_info->ipv4_unicast_enabled; + ln_info->flags.ipv6_unicast_enabled = api_intf_info->ipv6_unicast_enabled; + ln_info->flags.ipv4_multicast_enabled = api_intf_info->ipv4_multicast_enabled; + ln_info->flags.ipv6_multicast_enabled = api_intf_info->ipv6_multicast_enabled; + if (!api_intf_info->rmac_handle) { + if (api_intf_info->mac_valid) { + api_intf_info->rmac_handle = switch_api_router_mac_group_create(device); + status = switch_api_router_mac_add( + device, api_intf_info->rmac_handle, &api_intf_info->mac); + } else { + api_intf_info->rmac_handle = switch_api_capability_rmac_handle_get(); } - ln_info->rmac_handle = api_intf_info->rmac_handle; - 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); + } + ln_info->rmac_handle = api_intf_info->rmac_handle; + 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; + bd_info->l3_intf_handle = intf_handle; - return status; + return status; } -switch_handle_t -switch_api_interface_create(switch_device_t device, switch_api_interface_info_t *api_intf_info) -{ - switch_handle_t intf_handle; - switch_handle_t encap_if_handle; - switch_interface_info_t *intf_info = NULL; - switch_interface_info_t *encap_if = NULL; - - intf_handle = switch_interface_handle_create(); - intf_info = switch_api_interface_get(intf_handle); - - if (!intf_info) { - return SWITCH_STATUS_NO_MEMORY; - } - - memset(intf_info, 0, sizeof(switch_interface_info_t)); - memcpy(&intf_info->api_intf_info, api_intf_info, sizeof(switch_api_interface_info_t)); +switch_handle_t switch_api_interface_create( + switch_device_t device, switch_api_interface_info_t *api_intf_info) { + switch_handle_t intf_handle; + switch_handle_t encap_if_handle; + switch_interface_info_t *intf_info = NULL; + switch_interface_info_t *encap_if = NULL; + + intf_handle = switch_interface_handle_create(); + intf_info = switch_api_interface_get(intf_handle); + + if (!intf_info) { + return SWITCH_STATUS_NO_MEMORY; + } + + memset(intf_info, 0, sizeof(switch_interface_info_t)); + memcpy(&intf_info->api_intf_info, + api_intf_info, + sizeof(switch_api_interface_info_t)); + + 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_create_l2(device, intf_handle, intf_info); + break; + case SWITCH_API_INTERFACE_L3: // Pure L3 Port + case SWITCH_API_INTERFACE_L3_PORT_VLAN: // L3 Sub-Intf + switch_api_interface_create_l3(device, intf_handle, intf_info); + break; + + case SWITCH_API_INTERFACE_L3_VLAN: + switch_api_interface_create_vlan_interface( + device, intf_handle, intf_info); + break; + + case SWITCH_API_INTERFACE_TUNNEL: // L3 tunnel + // TODO: Derive a new BD and return + encap_if_handle = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); + encap_if = switch_api_interface_get(encap_if_handle); + if (!encap_if) { + SWITCH_API_TRACE( + "%s:%d: invalid encap interface handle", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_HANDLE; + } + intf_info->ifindex = SWITCH_INTF_COMPUTE_TUNNEL_IFINDEX(intf_handle); + break; - 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_create_l2(device, intf_handle, intf_info); - break; - case SWITCH_API_INTERFACE_L3: // Pure L3 Port - case SWITCH_API_INTERFACE_L3_PORT_VLAN: // L3 Sub-Intf - switch_api_interface_create_l3(device, intf_handle, intf_info); - break; - - case SWITCH_API_INTERFACE_L3_VLAN: - switch_api_interface_create_vlan_interface(device, intf_handle, intf_info); - break; - - case SWITCH_API_INTERFACE_TUNNEL: // L3 tunnel - // TODO: Derive a new BD and return - encap_if_handle = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); - encap_if = switch_api_interface_get(encap_if_handle); - if (!encap_if) { - SWITCH_API_TRACE("%s:%d: invalid encap interface handle", - __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_HANDLE; - } - intf_info->ifindex = SWITCH_INTF_COMPUTE_TUNNEL_IFINDEX(intf_handle); - break; - - break; - default: - intf_info->bd_handle = 0; - } + break; + default: + intf_info->bd_handle = 0; + } - return intf_handle; + 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; - } +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; - 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); - } + 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); - } + 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; + 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_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) -{ - switch_interface_info_t *intf_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_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; - } - bd_info = switch_bd_get(intf_info->bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - //Disable L3 on BD - ln_info = &bd_info->ln_info; - ln_info->vrf_handle = 0; - ln_info->flags.ipv4_unicast_enabled = FALSE; - ln_info->flags.ipv6_unicast_enabled = FALSE; - ln_info->rmac_handle = 0; - status = switch_pd_bd_table_update_entry(device, - handle_to_id(intf_info->bd_handle), - bd_info); - bd_info->l3_intf_handle = 0; - - return status; +switch_status_t switch_api_interface_delete_vlan_interface( + switch_device_t device, switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_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; + } + bd_info = switch_bd_get(intf_info->bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + // Disable L3 on BD + ln_info = &bd_info->ln_info; + ln_info->vrf_handle = 0; + ln_info->flags.ipv4_unicast_enabled = FALSE; + ln_info->flags.ipv6_unicast_enabled = FALSE; + ln_info->rmac_handle = 0; + status = switch_pd_bd_table_update_entry( + device, handle_to_id(intf_info->bd_handle), bd_info); + bd_info->l3_intf_handle = 0; + + return status; } -switch_status_t -switch_api_interface_delete_l3_interface(switch_device_t device, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_api_interface_info_t *api_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; - } - bd_info = switch_bd_get(intf_info->bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; +switch_status_t switch_api_interface_delete_l3_interface( + switch_device_t device, switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_api_interface_info_t *api_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; + } + bd_info = switch_bd_get(intf_info->bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + switch_pd_port_vlan_mapping_table_delete_entry(device, intf_info->pv_entry); + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_PORT_VLAN) { + status = switch_pd_egress_vlan_xlate_table_delete_entry( + device, intf_info->xlate_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("xlate entry delete failed for l3 intf %lx", + intf_handle); } + } - switch_pd_port_vlan_mapping_table_delete_entry(device, intf_info->pv_entry); + switch_api_logical_network_delete(device, intf_info->bd_handle); + intf_info->bd_handle = 0; + api_intf_info = &intf_info->api_intf_info; + if (api_intf_info->mac_valid) { + status = switch_api_router_mac_delete( + device, api_intf_info->rmac_handle, &api_intf_info->mac); + status = + switch_api_router_mac_group_delete(device, api_intf_info->rmac_handle); + } - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_PORT_VLAN) { - status = switch_pd_egress_vlan_xlate_table_delete_entry( - device, - intf_info->xlate_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("xlate entry delete failed for l3 intf %lx", intf_handle); - } - } + switch_api_interface_handle_reset(device, intf_handle); - switch_api_logical_network_delete(device, intf_info->bd_handle); - intf_info->bd_handle = 0; - api_intf_info = &intf_info->api_intf_info; - if (api_intf_info->mac_valid) { - status = switch_api_router_mac_delete(device, - api_intf_info->rmac_handle, - &api_intf_info->mac); - status = switch_api_router_mac_group_delete(device, - api_intf_info->rmac_handle); - } + bd_info->l3_intf_handle = 0; - switch_api_interface_handle_reset(device, intf_handle); + return status; +} - bd_info->l3_intf_handle = 0; +switch_status_t switch_api_interface_delete(switch_device_t device, + switch_handle_t handle) { + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_INTERFACE_HANDLE_VALID(handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + intf_info = switch_api_interface_get(handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + 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); + break; + case SWITCH_API_INTERFACE_L3_VLAN: + switch_api_interface_delete_vlan_interface(device, handle); + break; + default: + break; + } + + _switch_handle_delete( + switch_interface_info_t, switch_interface_array, handle); + return status; +} - return status; +switch_status_t switch_api_interface_attribute_set(switch_handle_t intf_handle, + switch_intf_attr_t attr_type, + uint64_t value) { + 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; + } + + switch (attr_type) { + case SWITCH_INTF_ATTR_V4_UNICAST: + status = + switch_api_interface_ipv4_unicast_enabled_set(intf_handle, value); + break; + case SWITCH_INTF_ATTR_V6_UNICAST: + status = + switch_api_interface_ipv6_unicast_enabled_set(intf_handle, value); + break; + case SWITCH_INTF_ATTR_NATIVE_VLAN: + status = switch_api_interface_native_vlan_set(intf_handle, value); + break; + default: + status = SWITCH_STATUS_INVALID_ATTRIBUTE; + break; + } + return status; } -switch_status_t -switch_api_interface_delete(switch_device_t device, switch_handle_t handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_attribute_get(switch_handle_t intf_handle, + switch_intf_attr_t attr_type, + uint64_t *value) { + 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; + } + + switch (attr_type) { + case SWITCH_INTF_ATTR_V4_UNICAST: + status = + switch_api_interface_ipv4_unicast_enabled_get(intf_handle, value); + break; + case SWITCH_INTF_ATTR_V6_UNICAST: + status = + switch_api_interface_ipv6_unicast_enabled_get(intf_handle, value); + break; + case SWITCH_INTF_ATTR_NATIVE_VLAN: + status = switch_api_interface_native_vlan_get(intf_handle, value); + break; + case SWITCH_INTF_ATTR_VRF: + switch_api_interface_vrf_get(intf_handle, value); + break; + case SWITCH_INTF_ATTR_TYPE: + // not sure yet + break; + case SWITCH_INTF_ATTR_PORT_ID: + switch_api_interface_port_id_get(intf_handle, value); + break; + case SWITCH_INTF_ATTR_VLAN_ID: + switch_api_interface_vlan_id_get(intf_handle, value); + break; + case SWITCH_INTF_ATTR_RMAC_ADDR: + status = switch_api_interface_rmac_addr_get(intf_handle, value); + break; + default: + status = SWITCH_STATUS_INVALID_ATTRIBUTE; + break; + } + return status; +} - if (!SWITCH_INTERFACE_HANDLE_VALID(handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_api_interface_ipv4_unicast_enabled_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->ipv4_unicast_enabled = value; + status = switch_bd_ipv4_unicast_enabled_set(intf_info->bd_handle, value); + return status; +} - intf_info = switch_api_interface_get(handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } +switch_status_t switch_api_interface_ipv4_unicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - 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); + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - case SWITCH_API_INTERFACE_L3: - case SWITCH_API_INTERFACE_L3_PORT_VLAN: - switch_api_interface_delete_l3_interface(device, handle); - break; - case SWITCH_API_INTERFACE_L3_VLAN: - switch_api_interface_delete_vlan_interface(device, handle); - break; - default: - break; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - _switch_handle_delete(switch_interface_info_t, switch_interface_array, handle); - return status; + status = switch_bd_ipv4_unicast_enabled_get(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_attribute_set(switch_handle_t intf_handle, - switch_intf_attr_t attr_type, - uint64_t value) -{ - 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; - } - - switch (attr_type) { - case SWITCH_INTF_ATTR_V4_UNICAST: - status = switch_api_interface_ipv4_unicast_enabled_set( - intf_handle, value); - break; - case SWITCH_INTF_ATTR_V6_UNICAST: - status = switch_api_interface_ipv6_unicast_enabled_set( - intf_handle, value); - break; - case SWITCH_INTF_ATTR_NATIVE_VLAN: - status = switch_api_interface_native_vlan_set(intf_handle, value); - break; - default: - status = SWITCH_STATUS_INVALID_ATTRIBUTE; - break; - } - return status; +switch_status_t switch_api_interface_ipv6_unicast_enabled_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->ipv6_unicast_enabled = value; + status = switch_bd_ipv6_unicast_enabled_set(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_attribute_get(switch_handle_t intf_handle, - switch_intf_attr_t attr_type, - uint64_t *value) -{ - 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; - } +switch_status_t switch_api_interface_ipv6_unicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - switch (attr_type) { - case SWITCH_INTF_ATTR_V4_UNICAST: - status = switch_api_interface_ipv4_unicast_enabled_get( - intf_handle, value); - break; - case SWITCH_INTF_ATTR_V6_UNICAST: - status = switch_api_interface_ipv6_unicast_enabled_get( - intf_handle, value); - break; - case SWITCH_INTF_ATTR_NATIVE_VLAN: - status = switch_api_interface_native_vlan_get(intf_handle, value); - break; - default: - status = SWITCH_STATUS_INVALID_ATTRIBUTE; - break; - } - return status; -} + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } -switch_status_t -switch_api_interface_ipv4_unicast_enabled_set(switch_handle_t intf_handle, - uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_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; + } - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + status = switch_bd_ipv6_unicast_enabled_get(intf_info->bd_handle, value); + return status; +} - api_intf_info->ipv4_unicast_enabled = value; - status = switch_bd_ipv4_unicast_enabled_set(intf_info->bd_handle, value); - return status; +switch_status_t switch_api_interface_ipv4_multicast_enabled_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->ipv4_multicast_enabled = value; + status = switch_bd_ipv4_multicast_enabled_set(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv4_unicast_enabled_get(switch_handle_t intf_handle, - uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_ipv4_multicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value) { + 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; - } + 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; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_bd_ipv4_unicast_enabled_get(intf_info->bd_handle, value); - return status; + status = switch_bd_ipv4_multicast_enabled_get(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv6_unicast_enabled_set(switch_handle_t intf_handle, - uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_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; - } - - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - api_intf_info->ipv6_unicast_enabled = value; - status = switch_bd_ipv6_unicast_enabled_set(intf_info->bd_handle, value); - return status; +switch_status_t switch_api_interface_ipv6_multicast_enabled_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->ipv6_multicast_enabled = value; + status = switch_bd_ipv6_multicast_enabled_set(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv6_unicast_enabled_get(switch_handle_t intf_handle, - uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_ipv6_multicast_enabled_get( + switch_handle_t intf_handle, uint64_t *value) { + 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; - } + 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; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_bd_ipv6_unicast_enabled_get(intf_info->bd_handle, value); - return status; + status = switch_bd_ipv6_multicast_enabled_get(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv4_multicast_enabled_set(switch_handle_t intf_handle, - uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_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; - } - - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - api_intf_info->ipv4_multicast_enabled = value; - status = switch_bd_ipv4_multicast_enabled_set(intf_info->bd_handle, value); - return status; +switch_status_t switch_api_interface_ipv4_urpf_mode_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->ipv4_urpf_mode = value; + status = switch_bd_ipv4_urpf_mode_set(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv4_multicast_enabled_get(switch_handle_t intf_handle, - uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_ipv4_urpf_mode_get( + switch_handle_t intf_handle, uint64_t *value) { + 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; - } + 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; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_bd_ipv4_multicast_enabled_get(intf_info->bd_handle, value); - return status; + status = switch_bd_ipv4_urpf_mode_get(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv6_multicast_enabled_set(switch_handle_t intf_handle, - uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_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; - } - - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - api_intf_info->ipv6_multicast_enabled = value; - status = switch_bd_ipv6_multicast_enabled_set(intf_info->bd_handle, value); - return status; +switch_status_t switch_api_interface_ipv6_urpf_mode_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->ipv6_urpf_mode = value; + status = switch_bd_ipv6_urpf_mode_set(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv6_multicast_enabled_get(switch_handle_t intf_handle, - uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_ipv6_urpf_mode_get( + switch_handle_t intf_handle, uint64_t *value) { + 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; - } + 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; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_bd_ipv6_multicast_enabled_get(intf_info->bd_handle, value); - return status; + status = switch_bd_ipv6_urpf_mode_get(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv4_urpf_mode_set(switch_handle_t intf_handle, - uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_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; - } - - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - api_intf_info->ipv4_urpf_mode = value; - status = switch_bd_ipv4_urpf_mode_set(intf_info->bd_handle, value); - return status; +switch_status_t switch_api_interface_nat_mode_set(switch_handle_t intf_handle, + uint8_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info->nat_mode = value; + status = switch_bd_nat_mode_set(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv4_urpf_mode_get(switch_handle_t intf_handle, - uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_nat_mode_get(switch_handle_t intf_handle, + uint8_t *value) { + 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; - } + 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; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_bd_ipv4_urpf_mode_get(intf_info->bd_handle, value); - return status; + status = switch_bd_nat_mode_get(intf_info->bd_handle, value); + return status; } -switch_status_t -switch_api_interface_ipv6_urpf_mode_set(switch_handle_t intf_handle, - uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_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; - } +switch_status_t switch_api_interface_native_vlan_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - api_intf_info->ipv6_urpf_mode = value; - status = switch_bd_ipv6_urpf_mode_set(intf_info->bd_handle, value); - return status; + if (SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) = (switch_handle_t)value; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_interface_ipv6_urpf_mode_get(switch_handle_t intf_handle, - uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_native_vlan_get( + switch_handle_t intf_handle, uint64_t *value) { + switch_interface_info_t *intf_info = NULL; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + 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; - } + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_bd_ipv6_urpf_mode_get(intf_info->bd_handle, value); - return status; + *value = (uint64_t)SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_interface_native_vlan_set(switch_handle_t intf_handle, uint64_t value) -{ - switch_interface_info_t *intf_info = NULL; +switch_status_t switch_api_interface_vrf_get(switch_handle_t intf_handle, + uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; - } + 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; - } + api_intf_info = &intf_info->api_intf_info; - SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) = (switch_handle_t) value; - return SWITCH_STATUS_SUCCESS; + *value = api_intf_info->vrf_handle; + + return status; } -switch_status_t -switch_api_interface_native_vlan_get(switch_handle_t intf_handle, uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; +switch_status_t switch_api_interface_port_id_get(switch_handle_t intf_handle, + uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_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; + } + + api_intf_info = &intf_info->api_intf_info; + if ((!SWITCH_INTF_IS_PORT_L3(intf_info)) && + (!SWITCH_INTF_IS_PORT_L2(intf_info))) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + *value = api_intf_info->u.port_lag_handle; + + return status; +} - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } +switch_status_t switch_api_interface_vlan_id_get(switch_handle_t intf_handle, + uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info = &intf_info->api_intf_info; + if (SWITCH_INTF_IS_PORT_L3(intf_info) || SWITCH_INTF_IS_PORT_L2(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + *value = api_intf_info->u.vlan_id; - *value = (uint64_t) SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info); - return SWITCH_STATUS_SUCCESS; + return status; } -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; +switch_status_t switch_api_interface_rmac_addr_get(switch_handle_t intf_handle, + uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - 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; - } + api_intf_info = &intf_info->api_intf_info; - JLI(temp, *array, intf_handle); - *(unsigned long *) temp = (unsigned long) intf_handle; - return SWITCH_STATUS_SUCCESS; + memcpy((uint8_t *)value, api_intf_info->mac.mac_addr, 6); + + return status; } -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; +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; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + 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; +} - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("intf array insert failed. invalid interface handle"); +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; - JLD(status, *array, intf_handle); - return status; + 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; +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: - 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); + break; + } } + JLN(temp, *array, tmp_intf_handle); + } - return SWITCH_STATUS_ITEM_NOT_FOUND; + return SWITCH_STATUS_ITEM_NOT_FOUND; } -switch_status_t -switch_api_interface_l3_ifs_get(switch_l3_interfaces_iterator_fn iterator_fn) -{ - switch_interface_info_t *intf_info = NULL; - void *temp = NULL; - switch_handle_t intf_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - JLF(temp, switch_interface_array, intf_handle); - while (temp) { - if (SWITCH_INTF_IS_PORT_L3(intf_info)) { - intf_info = switch_api_interface_get(intf_handle); - if (intf_info) { - iterator_fn(intf_info->api_intf_info); - } - } - JLN(temp, switch_interface_array, intf_handle); - } - return status; -} +switch_status_t switch_api_interface_l3_ifs_get( + switch_l3_interfaces_iterator_fn iterator_fn) { + switch_interface_info_t *intf_info = NULL; + void *temp = NULL; + switch_handle_t intf_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; -switch_status_t -switch_api_interface_get_entry(switch_handle_t intf_handle, char *entry, int entry_length) -{ - switch_interface_info_t *intf_info = NULL; - int bytes_output = 0; - - UNUSED(entry_length); - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - bytes_output += sprintf(entry + bytes_output, "\nintf_handle: %x", (unsigned int) intf_handle); - bytes_output += sprintf(entry + bytes_output, "\nifindex: %x", intf_info->ifindex); - bytes_output += sprintf(entry + bytes_output, "intf_type: %x", SWITCH_INTF_TYPE(intf_info)); - return SWITCH_STATUS_SUCCESS; + JLF(temp, switch_interface_array, intf_handle); + while (temp) { + if (SWITCH_INTF_IS_PORT_L3(intf_info)) { + intf_info = switch_api_interface_get(intf_handle); + if (intf_info) { + iterator_fn(intf_info->api_intf_info); + } + } + JLN(temp, switch_interface_array, intf_handle); + } + return status; } -switch_status_t -switch_api_interface_print_entry(switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_intf_info = NULL; +switch_status_t switch_api_interface_get_entry(switch_handle_t intf_handle, + char *entry, + int entry_length) { + switch_interface_info_t *intf_info = NULL; + int bytes_output = 0; + + UNUSED(entry_length); + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + bytes_output += sprintf( + entry + bytes_output, "\nintf_handle: %x", (unsigned int)intf_handle); + bytes_output += + sprintf(entry + bytes_output, "\nifindex: %x", intf_info->ifindex); + bytes_output += sprintf( + entry + bytes_output, "intf_type: %x", SWITCH_INTF_TYPE(intf_info)); + return SWITCH_STATUS_SUCCESS; +} - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - api_intf_info = &intf_info->api_intf_info; - printf("\n\n intf_handle: %x", (unsigned int) intf_handle); - printf("\n ifindex %x intf type %x", - intf_info->ifindex, SWITCH_INTF_TYPE(intf_info)); - printf("\n v4 %d v6 %d", - api_intf_info->ipv4_unicast_enabled, - api_intf_info->ipv6_unicast_enabled); - printf("\n v4 urpf %d v6 urpf %d", - api_intf_info->ipv4_urpf_mode, - api_intf_info->ipv6_urpf_mode); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_print_entry(switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_intf_info = NULL; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + api_intf_info = &intf_info->api_intf_info; + printf("\n\n intf_handle: %x", (unsigned int)intf_handle); + printf("\n ifindex %x intf type %x", + intf_info->ifindex, + SWITCH_INTF_TYPE(intf_info)); + printf("\n v4 %d v6 %d", + api_intf_info->ipv4_unicast_enabled, + api_intf_info->ipv6_unicast_enabled); + printf("\n v4 urpf %d v6 urpf %d", + api_intf_info->ipv4_urpf_mode, + api_intf_info->ipv6_urpf_mode); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_interface_print_all(void) -{ - switch_handle_t intf_handle = 0; - switch_handle_t next_intf_handle = 0; - - switch_handle_get_first(switch_interface_array, intf_handle); - while (intf_handle) { - switch_api_interface_print_entry(intf_handle); - switch_handle_get_next(switch_interface_array, intf_handle, next_intf_handle); - intf_handle = next_intf_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_print_all(void) { + switch_handle_t intf_handle = 0; + switch_handle_t next_intf_handle = 0; + + switch_handle_get_first(switch_interface_array, intf_handle); + while (intf_handle) { + switch_api_interface_print_entry(intf_handle); + switch_handle_get_next( + switch_interface_array, intf_handle, next_intf_handle); + intf_handle = next_intf_handle; + } + 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; - } +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; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_api_bd_stats_enable(device, intf_info->bd_handle); - return status; + 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; - } +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; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - status = switch_api_bd_stats_disable(device, intf_info->bd_handle); - return status; -} + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } -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_disable(device, intf_info->bd_handle); + return status; +} - status = switch_api_bd_stats_get( - device, - intf_info->bd_handle, - count, - counter_ids, - counters); - 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) -{ - switch_interface_info_t info; +int _switch_interface_main(int argc, char **argv) { + switch_interface_info_t info; - switch_interface_init(); + switch_interface_init(); - info.type = SWITCH_API_INTERFACE_L3; + info.type = SWITCH_API_INTERFACE_L3; - info.u.port = 0; - switch_handle_t id1 = switch_interface_create(0, &info); + info.u.port = 0; + switch_handle_t id1 = switch_interface_create(0, &info); - info.u.port = 0; - switch_handle_t id2 = switch_interface_create(0, &info); + info.u.port = 0; + switch_handle_t id2 = switch_interface_create(0, &info); - printf("id1 = 0x%lx id2 0x%lx\n", id1, id2); + printf("id1 = 0x%lx id2 0x%lx\n", id1, id2); - switch_api_interface_delete(id1); - switch_api_interface_delete(id2); + switch_api_interface_delete(id1); + switch_api_interface_delete(id2); - switch_interface_free(); - return 0; + switch_interface_free(); + return 0; } #endif - + #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_interface_int.h b/switchapi/src/switch_interface_int.h index 8cb637e..45281fe 100644 --- a/switchapi/src/switch_interface_int.h +++ b/switchapi/src/switch_interface_int.h @@ -20,6 +20,7 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" #include "switchapi/switch_interface.h" +#include "switch_pd_types.h" #ifdef __cplusplus extern "C" { @@ -27,145 +28,133 @@ extern "C" { typedef struct switch_ip_encap_pd_hdl_ { #ifdef SWITCH_PD - // ingress - p4_pd_entry_hdl_t src_hw_entry; - p4_pd_entry_hdl_t dst_hw_entry; - // egress - p4_pd_entry_hdl_t src_rw_hw_entry; - p4_pd_entry_hdl_t dst_rw_hw_entry; + // ingress + p4_pd_entry_hdl_t src_hw_entry; + p4_pd_entry_hdl_t dst_hw_entry; + // egress + p4_pd_entry_hdl_t src_rw_hw_entry; + p4_pd_entry_hdl_t dst_rw_hw_entry; #endif } switch_ip_encap_pd_hdl_t; /** Interface information */ typedef struct switch_interface_info_ { - switch_device_t device; /**< For now, just one device */ - switch_ifindex_t ifindex; - switch_api_interface_info_t api_intf_info; - switch_ip_encap_pd_hdl_t ip_encap_hdl; - unsigned int ip_addr_count; /**< number of IP addresses on interface */ - tommy_list ip_addr; /**< List of IP addresses */ - unsigned int acl_label; /**< ACL label */ - switch_handle_t bd_handle; /**< L3 Port Implicit BD Handle */ - 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; + switch_device_t device; /**< For now, just one device */ + switch_ifindex_t ifindex; + switch_api_interface_info_t api_intf_info; + switch_ip_encap_pd_hdl_t ip_encap_hdl; + unsigned int ip_addr_count; /**< number of IP addresses on interface */ + tommy_list ip_addr; /**< List of IP addresses */ + unsigned int acl_label; /**< ACL label */ + switch_handle_t bd_handle; /**< L3 Port Implicit BD Handle */ + 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; + switch_direction_t direction; #ifdef SWITCH_PD - p4_pd_entry_hdl_t nhop_type_entry; - p4_pd_entry_hdl_t lag_group_entry; - p4_pd_entry_hdl_t pv_entry; - p4_pd_entry_hdl_t xlate_entry; + p4_pd_entry_hdl_t nhop_type_entry; + p4_pd_entry_hdl_t lag_group_entry; + p4_pd_entry_hdl_t pv_entry; + p4_pd_entry_hdl_t xlate_entry; #endif } switch_interface_info_t; -#define SWITCH_INTF_TYPE(info) \ - info->api_intf_info.type +#define SWITCH_INTF_TYPE(info) info->api_intf_info.type #define SWITCH_INTF_TUNNEL_ENCAP_TYPE(info) \ - info->api_intf_info.u.tunnel_info.encap_info.encap_type + info->api_intf_info.u.tunnel_info.encap_info.encap_type #define SWITCH_INTF_TUNNEL_IP_ENCAP(info) \ - info->api_intf_info.u.tunnel_info.u.ip_encap + info->api_intf_info.u.tunnel_info.u.ip_encap #define SWITCH_INTF_TUNNEL_MPLS_ENCAP(info) \ - info->api_intf_info.u.tunnel_info.u.mpls_encap + info->api_intf_info.u.tunnel_info.u.mpls_encap #define SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(info) \ - info->api_intf_info.u.tunnel_info.out_if + info->api_intf_info.u.tunnel_info.out_if -#define SWITCH_INTF_PORT_HANDLE(info) \ - info->api_intf_info.u.port_lag_handle +#define SWITCH_INTF_PORT_HANDLE(info) info->api_intf_info.u.port_lag_handle -#define SWITCH_INTF_VLAN_ID(info) \ - info->api_intf_info.u.vlan_id +#define SWITCH_INTF_VLAN_ID(info) info->api_intf_info.u.vlan_id #define SWITCH_INTF_PV_PORT_HANDLE(info) \ - info->api_intf_info.u.port_vlan.port_lag_handle + info->api_intf_info.u.port_vlan.port_lag_handle -#define SWITCH_INTF_PV_VLAN_ID(info) \ - info->api_intf_info.u.port_vlan.vlan_id +#define SWITCH_INTF_PV_VLAN_ID(info) info->api_intf_info.u.port_vlan.vlan_id #define SWITCH_INTF_L2_LAG_INDEX(info) \ - handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) + handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) -#define SWITCH_INTF_L2_PORT(info) \ - handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) +#define SWITCH_INTF_L2_PORT(info) handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) #define SWITCH_INTF_L3_LAG_INDEX(info) \ - handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) + handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) -#define SWITCH_INTF_L3_PORT(info) \ - handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) +#define SWITCH_INTF_L3_PORT(info) handle_to_id(SWITCH_INTF_PORT_HANDLE(info)) -#define SWITCH_INTF_IS_PORT_L3(info) \ - ((info->api_intf_info.type == SWITCH_API_INTERFACE_L3) || \ - (info->api_intf_info.type == SWITCH_API_INTERFACE_L3_PORT_VLAN) || \ - (info->api_intf_info.type == SWITCH_API_INTERFACE_TUNNEL)) +#define SWITCH_INTF_IS_PORT_L3(info) \ + ((info->api_intf_info.type == SWITCH_API_INTERFACE_L3) || \ + (info->api_intf_info.type == SWITCH_API_INTERFACE_L3_PORT_VLAN) || \ + (info->api_intf_info.type == SWITCH_API_INTERFACE_TUNNEL)) -#define SWITCH_INTF_IS_PORT_L2(info) \ - (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_ACCESS) || \ - (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_TRUNK) +#define SWITCH_INTF_IS_PORT_L2(info) \ + (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_ACCESS) || \ + (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_TRUNK) -#define SWITCH_INTF_NATIVE_VLAN_HANDLE(info) \ - info->api_intf_info.native_vlan +#define SWITCH_INTF_NATIVE_VLAN_HANDLE(info) info->api_intf_info.native_vlan #define SWITCH_INTF_IS_PORT_L2_ACCESS(info) \ - (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_ACCESS) + (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_ACCESS) #define SWITCH_INTF_IS_PORT_L2_TRUNK(info) \ - (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_TRUNK) + (info->api_intf_info.type == SWITCH_API_INTERFACE_L2_VLAN_TRUNK) -#define SWITCH_INTF_IS_CORE(info) \ - info->api_intf_info.flags.core_intf +#define SWITCH_INTF_IS_CORE(info) info->api_intf_info.flags.core_intf -#define SWITCH_INTF_FLOOD_ENABLED(info) \ - info->api_intf_info.flags.flood_enabled +#define SWITCH_INTF_FLOOD_ENABLED(info) info->api_intf_info.flags.flood_enabled -#define SWITCH_INTF_COMPUTE_TUNNEL_IFINDEX(handle) \ - handle_to_id(handle) | \ - (SWITCH_INTF_TUNNEL_IFINDEX << SWITCH_LOGICAL_IFINDEX_SHIFT) +#define SWITCH_INTF_COMPUTE_TUNNEL_IFINDEX(handle) \ + handle_to_id(handle) | \ + (SWITCH_INTF_TUNNEL_IFINDEX << SWITCH_LOGICAL_IFINDEX_SHIFT) #define SWITCH_INTF_IS_TUNNEL_IFINDEX(ifindex) \ - ifindex & (SWITCH_INTF_TUNNEL_IFINDEX << SWITCH_LOGICAL_IFINDEX_SHIFT) + ifindex &(SWITCH_INTF_TUNNEL_IFINDEX << SWITCH_LOGICAL_IFINDEX_SHIFT) #define SWITCH_INTF_TUNNEL_ID(ifindex) \ - ifindex & ~(SWITCH_INTF_TUNNEL_IFINDEX << SWITCH_LOGICAL_IFINDEX_SHIFT) + ifindex & ~(SWITCH_INTF_TUNNEL_IFINDEX << SWITCH_LOGICAL_IFINDEX_SHIFT) -#define SWITCH_VLAN_INTERFACE_COMPUTE_IFINDEX(handle) \ - (handle_to_id(handle) | \ - (SWITCH_IFINDEX_TYPE_VLAN_INTERFACE << SWITCH_IFINDEX_PORT_WIDTH)) +#define SWITCH_VLAN_INTERFACE_COMPUTE_IFINDEX(handle) \ + (handle_to_id(handle) | \ + (SWITCH_IFINDEX_TYPE_VLAN_INTERFACE << SWITCH_IFINDEX_PORT_WIDTH)) // 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 bd_handle); +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, - switch_interface_info_t *intf_info); -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); +switch_status_t switch_api_interface_create_l2( + switch_device_t device, + switch_handle_t intf_handle, + switch_interface_info_t *intf_info); +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 } diff --git a/switchapi/src/switch_l2.c b/switchapi/src/switch_l2.c index 858ac75..b4974b7 100644 --- a/switchapi/src/switch_l2.c +++ b/switchapi/src/switch_l2.c @@ -40,445 +40,450 @@ static void *intf_mac_hdl_array = NULL; static switch_mac_cb_fn_t switch_mac_cb_fn; static switch_mac_global_params_t mac_params; -static inline -void switch_mac_table_entry_key_init(uchar *key, switch_handle_t vlan, - switch_mac_addr_t *mac, uint32_t *len, - uint32_t *hash) -{ - *len=0; - memset(key, 0, 10); - *(unsigned int *)(&key[0]) = (unsigned int)handle_to_id(vlan); - *len += sizeof(unsigned int); - memcpy(&key[4], mac->mac_addr, ETH_LEN); - *len += ETH_LEN; - *hash = MurmurHash2(key, *len, 0x98761234); +static inline void switch_mac_table_entry_key_init(uchar *key, + switch_handle_t vlan, + switch_mac_addr_t *mac, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, 10); + *(unsigned int *)(&key[0]) = (unsigned int)handle_to_id(vlan); + *len += sizeof(unsigned int); + memcpy(&key[4], mac->mac_addr, ETH_LEN); + *len += ETH_LEN; + *hash = MurmurHash2(key, *len, 0x98761234); } -static inline -int switch_mac_entry_hash_cmp(const void *key1, - const void *key2) -{ - return memcmp(key1, key2, 10); +static inline int switch_mac_entry_hash_cmp(const void *key1, + const void *key2) { + return memcmp(key1, key2, 10); } -static inline void switch_print_mac_table_entry(switch_api_mac_entry_t *mac_entry, - char *buffer, int buffer_size) -{ - switch_mac_addr_t *mac = NULL; - - mac = &mac_entry->mac; - snprintf(buffer, buffer_size, - "type: %s vlan handle: %lx mac: %02x:%02x:%02x:%02x:%02x:%02x -> handle: %lx", - mac_entry->entry_type == SWITCH_MAC_ENTRY_STATIC ? "static" : "dynamic", - mac_entry->vlan_handle, - mac->mac_addr[0], mac->mac_addr[1], mac->mac_addr[2], - mac->mac_addr[3], mac->mac_addr[4], mac->mac_addr[5], - mac_entry->handle); +static inline void switch_print_mac_table_entry( + switch_api_mac_entry_t *mac_entry, char *buffer, int buffer_size) { + switch_mac_addr_t *mac = NULL; + + mac = &mac_entry->mac; + snprintf( + buffer, + buffer_size, + "type: %s vlan handle: %lx mac: %02x:%02x:%02x:%02x:%02x:%02x -> handle: " + "%lx", + mac_entry->entry_type == SWITCH_MAC_ENTRY_STATIC ? "static" : "dynamic", + mac_entry->vlan_handle, + mac->mac_addr[0], + mac->mac_addr[1], + mac->mac_addr[2], + mac->mac_addr[3], + mac->mac_addr[4], + mac->mac_addr[5], + mac_entry->handle); } -static switch_status_t -switch_mac_insert_into_vlan_list(switch_mac_info_t *mac_info) -{ - switch_mac_vlan_list_t *mac_vlan_list = NULL; - switch_api_mac_entry_t *mac_entry = NULL; - void *temp = NULL; - - mac_entry = &mac_info->mac_entry; - JLG(temp, vlan_mac_hdl_array, mac_entry->vlan_handle); - if (!temp) { - mac_vlan_list = switch_malloc(sizeof(switch_mac_vlan_list_t), 1); - if (!mac_vlan_list) { - SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_NO_MEMORY; - } - tommy_list_init(&(mac_vlan_list->mac_entries)); - mac_vlan_list->num_entries = 0; - JLI(temp, vlan_mac_hdl_array, mac_entry->vlan_handle); - *(unsigned long *)temp = (unsigned long) (mac_vlan_list); - } - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); - tommy_list_insert_tail(&(mac_vlan_list->mac_entries), &(mac_info->vlan_node), mac_info); - mac_vlan_list->num_entries++; - return SWITCH_STATUS_SUCCESS; +static switch_status_t switch_mac_insert_into_vlan_list( + switch_mac_info_t *mac_info) { + switch_mac_vlan_list_t *mac_vlan_list = NULL; + switch_api_mac_entry_t *mac_entry = NULL; + void *temp = NULL; + + mac_entry = &mac_info->mac_entry; + JLG(temp, vlan_mac_hdl_array, mac_entry->vlan_handle); + if (!temp) { + mac_vlan_list = switch_malloc(sizeof(switch_mac_vlan_list_t), 1); + if (!mac_vlan_list) { + SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_NO_MEMORY; + } + tommy_list_init(&(mac_vlan_list->mac_entries)); + mac_vlan_list->num_entries = 0; + JLI(temp, vlan_mac_hdl_array, mac_entry->vlan_handle); + *(unsigned long *)temp = (unsigned long)(mac_vlan_list); + } + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); + tommy_list_insert_tail( + &(mac_vlan_list->mac_entries), &(mac_info->vlan_node), mac_info); + mac_vlan_list->num_entries++; + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_mac_insert_into_interface_list(switch_mac_info_t *mac_info) -{ - switch_mac_intf_list_t *mac_intf_list = NULL; - switch_api_mac_entry_t *mac_entry = NULL; - void *temp = NULL; - - mac_entry = &mac_info->mac_entry; - JLG(temp, intf_mac_hdl_array, mac_entry->handle); - if (!temp) { - mac_intf_list = switch_malloc(sizeof(switch_mac_intf_list_t), 1); - if (!mac_intf_list) { - SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_NO_MEMORY; - } - tommy_list_init(&(mac_intf_list->mac_entries)); - mac_intf_list->num_entries = 0; - JLI(temp, intf_mac_hdl_array, mac_entry->handle); - *(unsigned long *)temp = (unsigned long) mac_intf_list; - } - mac_intf_list = (switch_mac_intf_list_t *) (*(unsigned long *)temp); - tommy_list_insert_tail(&(mac_intf_list->mac_entries), &(mac_info->interface_node), mac_info); - mac_intf_list->num_entries++; - return SWITCH_STATUS_SUCCESS; +static switch_status_t switch_mac_insert_into_interface_list( + switch_mac_info_t *mac_info) { + switch_mac_intf_list_t *mac_intf_list = NULL; + switch_api_mac_entry_t *mac_entry = NULL; + void *temp = NULL; + + mac_entry = &mac_info->mac_entry; + JLG(temp, intf_mac_hdl_array, mac_entry->handle); + if (!temp) { + mac_intf_list = switch_malloc(sizeof(switch_mac_intf_list_t), 1); + if (!mac_intf_list) { + SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_NO_MEMORY; + } + tommy_list_init(&(mac_intf_list->mac_entries)); + mac_intf_list->num_entries = 0; + JLI(temp, intf_mac_hdl_array, mac_entry->handle); + *(unsigned long *)temp = (unsigned long)mac_intf_list; + } + mac_intf_list = (switch_mac_intf_list_t *)(*(unsigned long *)temp); + tommy_list_insert_tail( + &(mac_intf_list->mac_entries), &(mac_info->interface_node), mac_info); + mac_intf_list->num_entries++; + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_mac_remove_from_vlan_list(switch_mac_info_t *mac_info) -{ - switch_mac_vlan_list_t *mac_vlan_list = NULL; - switch_api_mac_entry_t *mac_entry = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - mac_entry = &mac_info->mac_entry; - JLG(temp, vlan_mac_hdl_array, mac_entry->vlan_handle); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); - tommy_list_remove_existing(&(mac_vlan_list->mac_entries), &(mac_info->vlan_node)); - mac_vlan_list->num_entries--; - if (mac_vlan_list->num_entries == 0) { - JLD(status, vlan_mac_hdl_array, mac_entry->vlan_handle); - } - return SWITCH_STATUS_SUCCESS; +static switch_status_t switch_mac_remove_from_vlan_list( + switch_mac_info_t *mac_info) { + switch_mac_vlan_list_t *mac_vlan_list = NULL; + switch_api_mac_entry_t *mac_entry = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + mac_entry = &mac_info->mac_entry; + JLG(temp, vlan_mac_hdl_array, mac_entry->vlan_handle); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); + tommy_list_remove_existing(&(mac_vlan_list->mac_entries), + &(mac_info->vlan_node)); + mac_vlan_list->num_entries--; + if (mac_vlan_list->num_entries == 0) { + JLD(status, vlan_mac_hdl_array, mac_entry->vlan_handle); + } + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_mac_remove_from_interface_list(switch_mac_info_t *mac_info) -{ - switch_mac_intf_list_t *mac_intf_list = NULL; - switch_api_mac_entry_t *mac_entry = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - mac_entry = &mac_info->mac_entry; - JLG(temp, intf_mac_hdl_array, mac_entry->handle); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - mac_intf_list = (switch_mac_intf_list_t *) (*(unsigned long *)temp); - tommy_list_remove_existing(&(mac_intf_list->mac_entries), &(mac_info->interface_node)); - mac_intf_list->num_entries--; - if (mac_intf_list->num_entries == 0) { - JLD(status, intf_mac_hdl_array, mac_entry->handle); - } - return SWITCH_STATUS_SUCCESS; +static switch_status_t switch_mac_remove_from_interface_list( + switch_mac_info_t *mac_info) { + switch_mac_intf_list_t *mac_intf_list = NULL; + switch_api_mac_entry_t *mac_entry = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + mac_entry = &mac_info->mac_entry; + JLG(temp, intf_mac_hdl_array, mac_entry->handle); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + mac_intf_list = (switch_mac_intf_list_t *)(*(unsigned long *)temp); + tommy_list_remove_existing(&(mac_intf_list->mac_entries), + &(mac_info->interface_node)); + mac_intf_list->num_entries--; + if (mac_intf_list->num_entries == 0) { + JLD(status, intf_mac_hdl_array, mac_entry->handle); + } + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_mac_table_entry_insert(switch_api_mac_entry_t *mac_entry, switch_mac_info_t **mac_info) -{ - switch_api_mac_entry_t *tmp_mac_entry = NULL; - unsigned char key[10]; - unsigned int len = 0; - uint32_t hash = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_mac_table_entry_key_init(key, - mac_entry->vlan_handle, - &(mac_entry->mac), - &len, &hash); - *mac_info = switch_malloc(sizeof(switch_mac_info_t), 1); - if (!(*mac_info)) { - status = SWITCH_STATUS_NO_MEMORY; - goto cleanup; - } - - memset(*mac_info, 0, sizeof(switch_mac_info_t)); - tmp_mac_entry = &(*mac_info)->mac_entry; - tmp_mac_entry->vlan_handle = mac_entry->vlan_handle; - tmp_mac_entry->handle = mac_entry->handle; - tmp_mac_entry->entry_type = mac_entry->entry_type; - memcpy(&(tmp_mac_entry->mac), &(mac_entry->mac), ETH_LEN); +static switch_status_t switch_mac_table_entry_insert( + switch_api_mac_entry_t *mac_entry, switch_mac_info_t **mac_info) { + switch_api_mac_entry_t *tmp_mac_entry = NULL; + unsigned char key[10]; + unsigned int len = 0; + uint32_t hash = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_mac_table_entry_key_init( + key, mac_entry->vlan_handle, &(mac_entry->mac), &len, &hash); + *mac_info = switch_malloc(sizeof(switch_mac_info_t), 1); + if (!(*mac_info)) { + status = SWITCH_STATUS_NO_MEMORY; + goto cleanup; + } + + memset(*mac_info, 0, sizeof(switch_mac_info_t)); + tmp_mac_entry = &(*mac_info)->mac_entry; + tmp_mac_entry->vlan_handle = mac_entry->vlan_handle; + tmp_mac_entry->handle = mac_entry->handle; + tmp_mac_entry->entry_type = mac_entry->entry_type; + memcpy(&(tmp_mac_entry->mac), &(mac_entry->mac), ETH_LEN); #ifdef SWITCH_PD - (*mac_info)->smac_entry = 0; - (*mac_info)->dmac_entry = 0; + (*mac_info)->smac_entry = 0; + (*mac_info)->dmac_entry = 0; #endif - memcpy((*mac_info)->key, key, 10); - tommy_hashtable_insert(&switch_mac_hash_table, &((*mac_info)->node), *mac_info, hash); - status = switch_mac_insert_into_vlan_list(*mac_info); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - status = switch_mac_insert_into_interface_list(*mac_info); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - return status; + memcpy((*mac_info)->key, key, 10); + tommy_hashtable_insert( + &switch_mac_hash_table, &((*mac_info)->node), *mac_info, hash); + status = switch_mac_insert_into_vlan_list(*mac_info); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + status = switch_mac_insert_into_interface_list(*mac_info); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + return status; cleanup: - SWITCH_API_ERROR("%s:%d: unable to insert mac hash\n", - __FUNCTION__, __LINE__); - return status; + SWITCH_API_ERROR( + "%s:%d: unable to insert mac hash\n", __FUNCTION__, __LINE__); + return status; } -static switch_status_t -switch_mac_table_entry_delete(switch_api_mac_entry_t *mac_entry) -{ - switch_mac_info_t *mac_info = NULL; - unsigned char key[10]; - unsigned int len = 0; - uint32_t hash = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_mac_table_entry_key_init(key, - mac_entry->vlan_handle, - &(mac_entry->mac), - &len, &hash); - mac_info = tommy_hashtable_remove(&switch_mac_hash_table, - switch_mac_entry_hash_cmp, - key, hash); - status = switch_mac_remove_from_vlan_list(mac_info); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - status = switch_mac_remove_from_interface_list(mac_info); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - switch_free(mac_info); - return status; +static switch_status_t switch_mac_table_entry_delete( + switch_api_mac_entry_t *mac_entry) { + switch_mac_info_t *mac_info = NULL; + unsigned char key[10]; + unsigned int len = 0; + uint32_t hash = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_mac_table_entry_key_init( + key, mac_entry->vlan_handle, &(mac_entry->mac), &len, &hash); + mac_info = tommy_hashtable_remove( + &switch_mac_hash_table, switch_mac_entry_hash_cmp, key, hash); + status = switch_mac_remove_from_vlan_list(mac_info); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + status = switch_mac_remove_from_interface_list(mac_info); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + switch_free(mac_info); + return status; cleanup: - SWITCH_API_ERROR("%s:%d: failed to delete mac hash\n", - __FUNCTION__, __LINE__); - return status; + SWITCH_API_ERROR( + "%s:%d: failed to delete mac hash\n", __FUNCTION__, __LINE__); + return status; } -switch_mac_info_t * -switch_mac_table_entry_find(switch_api_mac_entry_t *mac_entry) -{ - switch_mac_info_t *mac_info = NULL; - unsigned char key[10]; - unsigned int len = 0; - uint32_t hash = 0; - - switch_mac_table_entry_key_init(key, - mac_entry->vlan_handle, - &(mac_entry->mac), - &len, &hash); - mac_info = tommy_hashtable_search(&switch_mac_hash_table, - switch_mac_entry_hash_cmp, - key, hash); - return mac_info; +switch_mac_info_t *switch_mac_table_entry_find( + switch_api_mac_entry_t *mac_entry) { + switch_mac_info_t *mac_info = NULL; + unsigned char key[10]; + unsigned int len = 0; + uint32_t hash = 0; + + switch_mac_table_entry_key_init( + key, mac_entry->vlan_handle, &(mac_entry->mac), &len, &hash); + mac_info = tommy_hashtable_search( + &switch_mac_hash_table, switch_mac_entry_hash_cmp, key, hash); + return mac_info; } #ifndef P4_L2_DISABLE -p4_pd_status_t -switch_mac_learn_notify_cb(p4_pd_sess_hdl_t sess_hdl, - p4_pd_dc_mac_learn_digest_digest_msg_t *msg, - void *client_data) -{ - p4_pd_dc_mac_learn_digest_digest_entry_t *learn_entry = NULL; - switch_mac_info_t *mac_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_api_mac_entry_t mac_entry; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; - switch_handle_t intf_handle = 0; - int index = 0; - - SWITCH_API_TRACE("%s:%d: Received %d learn notifications!", - __FUNCTION__, __LINE__, msg->num_entries); - - for (index = 0; index < msg->num_entries; index++) { - learn_entry = &(msg->entries[index]); - SWITCH_API_TRACE("%s:%d:MAC learn BD: 0x%d, MAC: 0x%02x:%02x:%02x:%02x:%02x:%02x => If: %d\n", - __FUNCTION__, __LINE__, - learn_entry->ingress_metadata_bd, - learn_entry->l2_metadata_lkp_mac_sa[0], - learn_entry->l2_metadata_lkp_mac_sa[1], - learn_entry->l2_metadata_lkp_mac_sa[2], - learn_entry->l2_metadata_lkp_mac_sa[3], - learn_entry->l2_metadata_lkp_mac_sa[4], - learn_entry->l2_metadata_lkp_mac_sa[5], - learn_entry->ingress_metadata_ifindex); - memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t)); - mac_entry.vlan_handle = id_to_handle(SWITCH_HANDLE_TYPE_BD, learn_entry->ingress_metadata_bd); - bd_info = switch_bd_get(mac_entry.vlan_handle); - if (!bd_info) { - SWITCH_API_TRACE("%s:%d: Ignoring the mac. vlan not found!", __FUNCTION__, __LINE__); - continue; - } +p4_pd_status_t switch_mac_learn_notify_cb( + p4_pd_sess_hdl_t sess_hdl, + p4_pd_dc_mac_learn_digest_digest_msg_t *msg, + void *client_data) { + p4_pd_dc_mac_learn_digest_digest_entry_t *learn_entry = NULL; + switch_mac_info_t *mac_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_api_mac_entry_t mac_entry; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + switch_handle_t intf_handle = 0; + int index = 0; + + SWITCH_API_TRACE("%s:%d: Received %d learn notifications!", + __FUNCTION__, + __LINE__, + msg->num_entries); + + for (index = 0; index < msg->num_entries; index++) { + learn_entry = &(msg->entries[index]); + SWITCH_API_TRACE( + "%s:%d:MAC learn BD: 0x%d, MAC: 0x%02x:%02x:%02x:%02x:%02x:%02x => If: " + "%d\n", + __FUNCTION__, + __LINE__, + learn_entry->ingress_metadata_bd, + learn_entry->l2_metadata_lkp_mac_sa[0], + learn_entry->l2_metadata_lkp_mac_sa[1], + learn_entry->l2_metadata_lkp_mac_sa[2], + learn_entry->l2_metadata_lkp_mac_sa[3], + learn_entry->l2_metadata_lkp_mac_sa[4], + learn_entry->l2_metadata_lkp_mac_sa[5], + learn_entry->ingress_metadata_ifindex); + memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t)); + mac_entry.vlan_handle = + id_to_handle(SWITCH_HANDLE_TYPE_BD, learn_entry->ingress_metadata_bd); + bd_info = switch_bd_get(mac_entry.vlan_handle); + if (!bd_info) { + SWITCH_API_TRACE( + "%s:%d: Ignoring the mac. vlan not found!", __FUNCTION__, __LINE__); + continue; + } - if (!SWITCH_LN_LEARN_ENABLED(bd_info)) { - SWITCH_API_TRACE("%s:%d: Ignoring the mac. learning disabled on vlan!", __FUNCTION__, __LINE__); - continue; - } + if (!SWITCH_LN_LEARN_ENABLED(bd_info)) { + SWITCH_API_TRACE("%s:%d: Ignoring the mac. learning disabled on vlan!", + __FUNCTION__, + __LINE__); + continue; + } - 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; - } + 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; + } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_TRACE("%s:%d: Ignoring the mac. invalid interface!", __FUNCTION__, __LINE__); - continue; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_TRACE("%s:%d: Ignoring the mac. invalid interface!", + __FUNCTION__, + __LINE__); + continue; + } - memcpy(&mac_entry.mac, learn_entry->l2_metadata_lkp_mac_sa, ETH_LEN); - mac_entry.handle = intf_handle; - mac_entry.entry_type = SWITCH_MAC_ENTRY_DYNAMIC; - mac_info = switch_mac_table_entry_find(&mac_entry); - if (!mac_info) { - status = switch_api_mac_table_entry_add(device, &mac_entry); - } else { - status = switch_api_mac_table_entry_update(device, &mac_entry); - } - if (switch_mac_cb_fn.mac_learn_notify_cb) { - switch_mac_cb_fn.mac_learn_notify_cb(&mac_entry); - } + memcpy(&mac_entry.mac, learn_entry->l2_metadata_lkp_mac_sa, ETH_LEN); + mac_entry.handle = intf_handle; + mac_entry.entry_type = SWITCH_MAC_ENTRY_DYNAMIC; + mac_info = switch_mac_table_entry_find(&mac_entry); + if (!mac_info) { + status = switch_api_mac_table_entry_add(device, &mac_entry); + } else { + status = switch_api_mac_table_entry_update(device, &mac_entry); } + if (switch_mac_cb_fn.mac_learn_notify_cb) { + switch_mac_cb_fn.mac_learn_notify_cb(&mac_entry); + } + } - // ack the entries - p4_pd_dc_mac_learn_digest_notify_ack(sess_hdl, msg); - return status; + // ack the entries + p4_pd_dc_mac_learn_digest_notify_ack(sess_hdl, msg); + return status; } #endif -void -switch_mac_aging_notify_cb(p4_pd_entry_hdl_t entry_hdl, void *client_data) -{ - switch_mac_info_t *mac_info = NULL; - void *temp = NULL; - switch_api_mac_entry_t *mac_entry = NULL; - switch_device_t device = SWITCH_DEV_ID; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - JLG(temp, dmac_entry_hdl_array, entry_hdl); - if (!temp) { - SWITCH_API_ERROR("%s%d: Invalid dmac entry handle", __FUNCTION__, __LINE__); - return; - } - - mac_info = (switch_mac_info_t *) (*(unsigned long *)temp); - mac_entry = &(mac_info->mac_entry); - SWITCH_API_TRACE("%s:%d: Received aging notification %x - (%lx, 0x%02x:%02x:%02x:%02x:%02x:%02x) -> %lx)", - __FUNCTION__, __LINE__, entry_hdl, - mac_entry->vlan_handle, - mac_entry->mac.mac_addr[0], - mac_entry->mac.mac_addr[1], - mac_entry->mac.mac_addr[2], - mac_entry->mac.mac_addr[3], - mac_entry->mac.mac_addr[4], - mac_entry->mac.mac_addr[5], - mac_entry->handle); - - if (switch_mac_cb_fn.mac_aging_notify_cb) { - switch_mac_cb_fn.mac_aging_notify_cb(mac_entry); - } - status = switch_api_mac_table_entry_delete(device, &(mac_info->mac_entry)); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: failed to delete mac!", __FUNCTION__, __LINE__); - } +void switch_mac_aging_notify_cb(p4_pd_entry_hdl_t entry_hdl, + void *client_data) { + switch_mac_info_t *mac_info = NULL; + void *temp = NULL; + switch_api_mac_entry_t *mac_entry = NULL; + switch_device_t device = SWITCH_DEV_ID; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + JLG(temp, dmac_entry_hdl_array, entry_hdl); + if (!temp) { + SWITCH_API_ERROR("%s%d: Invalid dmac entry handle", __FUNCTION__, __LINE__); return; + } + + mac_info = (switch_mac_info_t *)(*(unsigned long *)temp); + mac_entry = &(mac_info->mac_entry); + SWITCH_API_TRACE( + "%s:%d: Received aging notification %x - (%lx, " + "0x%02x:%02x:%02x:%02x:%02x:%02x) -> %lx)", + __FUNCTION__, + __LINE__, + entry_hdl, + mac_entry->vlan_handle, + mac_entry->mac.mac_addr[0], + mac_entry->mac.mac_addr[1], + mac_entry->mac.mac_addr[2], + mac_entry->mac.mac_addr[3], + mac_entry->mac.mac_addr[4], + mac_entry->mac.mac_addr[5], + mac_entry->handle); + + if (switch_mac_cb_fn.mac_aging_notify_cb) { + switch_mac_cb_fn.mac_aging_notify_cb(mac_entry); + } + status = switch_api_mac_table_entry_delete(device, &(mac_info->mac_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: failed to delete mac!", __FUNCTION__, __LINE__); + } + return; } -switch_api_mac_entry_t * -switch_mac_aging_poll_entries(switch_device_t device) -{ - switch_mac_info_t *mac_info = NULL; - void *temp = NULL; - p4_pd_entry_hdl_t entry_hdl = 0; +switch_api_mac_entry_t *switch_mac_aging_poll_entries(switch_device_t device) { + switch_mac_info_t *mac_info = NULL; + void *temp = NULL; + p4_pd_entry_hdl_t entry_hdl = 0; #ifndef P4_L2_DISABLE - p4_pd_sess_hdl_t sess_hdl = 0; - p4_pd_hit_state_t hit_state = ENTRY_IDLE; + p4_pd_sess_hdl_t sess_hdl = 0; + p4_pd_hit_state_t hit_state = ENTRY_IDLE; #endif - p4_pd_status_t status = 0; + p4_pd_status_t status = 0; - JLF(temp, dmac_entry_hdl_array, *((Word_t *)&entry_hdl)); - while (temp) { + Word_t h = 0; + JLF(temp, dmac_entry_hdl_array, h); + while (temp) { + entry_hdl = (p4_pd_entry_hdl_t)h; #ifndef P4_L2_DISABLE - status = p4_pd_dc_dmac_get_hit_state(sess_hdl, entry_hdl, &hit_state); + status = p4_pd_dc_dmac_get_hit_state(sess_hdl, entry_hdl, &hit_state); #endif /* P4_L2_DISABLE */ - if (!status) { - SWITCH_API_ERROR("%s:%d: failed to get hit state for entry %x", - __FUNCTION__, __LINE__, entry_hdl); - } - JLN(temp, dmac_entry_hdl_array, *((Word_t *)&entry_hdl)); - mac_info = (switch_mac_info_t *) (*(unsigned long *) temp); - } - return &(mac_info->mac_entry); + if (!status) { + SWITCH_API_ERROR("%s:%d: failed to get hit state for entry %x", + __FUNCTION__, + __LINE__, + entry_hdl); + } + JLN(temp, dmac_entry_hdl_array, h); + mac_info = (switch_mac_info_t *)(*(unsigned long *)temp); + } + return &(mac_info->mac_entry); } -uint32_t -switch_api_mac_get_default_aging_time_internal() -{ - return mac_params.aging_time; +uint32_t switch_api_mac_get_default_aging_time_internal() { + return mac_params.aging_time; } -switch_status_t -switch_mac_table_init(switch_device_t device) -{ +switch_status_t switch_mac_table_init(switch_device_t device) { #ifndef P4_L2_DISABLE - p4_pd_sess_hdl_t sess_hdl = 0; + p4_pd_sess_hdl_t sess_hdl = 0; #endif - switch_mac_cb_fn.mac_learn_notify_cb = NULL; - switch_mac_cb_fn.mac_aging_notify_cb = NULL; - switch_api_mac_table_aging_time_set(SWITCH_MAC_TABLE_DEFAULT_AGING_TIME); - tommy_hashtable_init(&switch_mac_hash_table, SWITCH_L2_HASH_TABLE_SIZE); -#ifdef SWITCH_PD + switch_mac_cb_fn.mac_learn_notify_cb = NULL; + switch_mac_cb_fn.mac_aging_notify_cb = NULL; + switch_api_mac_table_aging_time_set(SWITCH_MAC_TABLE_DEFAULT_AGING_TIME); + tommy_hashtable_init(&switch_mac_hash_table, SWITCH_L2_HASH_TABLE_SIZE); +#ifdef SWITCH_PD #ifndef P4_L2_DISABLE - p4_pd_dc_mac_learn_digest_register(sess_hdl, (uint8_t)device, switch_mac_learn_notify_cb, NULL); - p4_pd_dc_dmac_enable_entry_timeout(sess_hdl, switch_mac_aging_notify_cb, mac_params.aging_time, NULL); + p4_pd_dc_mac_learn_digest_register( + sess_hdl, (uint8_t)device, switch_mac_learn_notify_cb, NULL); + p4_pd_dc_dmac_enable_entry_timeout( + sess_hdl, switch_mac_aging_notify_cb, mac_params.aging_time, NULL); #endif /* P4_L2_DISABLE */ -#endif - return SWITCH_STATUS_SUCCESS; +#endif + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_mac_table_free(void) -{ - tommy_hashtable_done(&switch_mac_hash_table); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_mac_table_free(void) { + tommy_hashtable_done(&switch_mac_hash_table); + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_mac_update_nhop(switch_device_t device, - switch_handle_t intf_handle, - switch_api_mac_entry_t *mac_entry) -{ - switch_interface_info_t *intf_info = NULL; - switch_neighbor_dmac_t *neighbor_dmac = NULL; - switch_neighbor_info_t *neighbor_info = NULL; - switch_handle_t nhop_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle)) { - return SWITCH_STATUS_SUCCESS; - } - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_SUCCESS; - } - - neighbor_dmac = switch_neighbor_dmac_search_hash(mac_entry->vlan_handle, &mac_entry->mac); - if (!neighbor_dmac) { - return SWITCH_STATUS_SUCCESS; - } +static switch_status_t switch_mac_update_nhop( + switch_device_t device, + switch_handle_t intf_handle, + switch_api_mac_entry_t *mac_entry) { + switch_interface_info_t *intf_info = NULL; + switch_neighbor_dmac_t *neighbor_dmac = NULL; + switch_neighbor_info_t *neighbor_info = NULL; + switch_handle_t nhop_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle)) { + return SWITCH_STATUS_SUCCESS; + } - neighbor_info = switch_neighbor_info_get(neighbor_dmac->neighbor_handle); - if (!neighbor_info) { - return SWITCH_STATUS_FAILURE; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_SUCCESS; + } - nhop_handle = neighbor_info->neighbor.nhop_handle; - if (SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - status = switch_api_nhop_update(device, nhop_handle); - } - return status; + neighbor_dmac = + switch_neighbor_dmac_search_hash(mac_entry->vlan_handle, &mac_entry->mac); + if (!neighbor_dmac) { + return SWITCH_STATUS_SUCCESS; + } + + neighbor_info = switch_neighbor_info_get(neighbor_dmac->neighbor_handle); + if (!neighbor_info) { + return SWITCH_STATUS_FAILURE; + } + + nhop_handle = neighbor_info->neighbor.nhop_handle; + if (SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + status = switch_api_nhop_update(device, nhop_handle); + } + return status; } /* @@ -490,775 +495,738 @@ switch_mac_update_nhop(switch_device_t device, @param device - device id @param mac_entry - Mac Entry */ -switch_status_t -switch_api_mac_table_entry_add(switch_device_t device, - switch_api_mac_entry_t *mac_entry) -{ - switch_interface_info_t *intf_info = NULL; - switch_mac_info_t *mac_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - switch_nhop_info_t *nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_type_t handle_type = 0; - uint16_t nhop_index = 0; - uint16_t mgid_index = 0; - uint32_t aging_time = 0; - switch_handle_t intf_handle = 0; - char buffer[200]; - - if ((!SWITCH_PORT_HANDLE_VALID(mac_entry->handle)) && - (!SWITCH_LAG_HANDLE_VALID(mac_entry->handle)) && - (!SWITCH_INTERFACE_HANDLE_VALID(mac_entry->handle)) && - (!SWITCH_MGID_HANDLE_VALID(mac_entry->handle)) && - (!SWITCH_NHOP_HANDLE_VALID(mac_entry->handle))) { - status = SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_api_mac_table_entry_add( + switch_device_t device, switch_api_mac_entry_t *mac_entry) { + switch_interface_info_t *intf_info = NULL; + switch_mac_info_t *mac_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_type_t handle_type = 0; + uint16_t nhop_index = 0; + uint16_t mgid_index = 0; + uint32_t aging_time = 0; + switch_handle_t intf_handle = 0; + char buffer[200]; + + if ((!SWITCH_PORT_HANDLE_VALID(mac_entry->handle)) && + (!SWITCH_LAG_HANDLE_VALID(mac_entry->handle)) && + (!SWITCH_INTERFACE_HANDLE_VALID(mac_entry->handle)) && + (!SWITCH_MGID_HANDLE_VALID(mac_entry->handle)) && + (!SWITCH_NHOP_HANDLE_VALID(mac_entry->handle))) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + mac_info = switch_mac_table_entry_find(mac_entry); + if (mac_info) { + status = SWITCH_STATUS_ITEM_ALREADY_EXISTS; + goto cleanup; + } + + handle_type = switch_handle_get_type(mac_entry->handle); + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + case SWITCH_HANDLE_TYPE_LAG: + status = + switch_interface_handle_get(mac_entry->handle, 0x0, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { goto cleanup; - } - - mac_info = switch_mac_table_entry_find(mac_entry); - if (mac_info) { - status = SWITCH_STATUS_ITEM_ALREADY_EXISTS; + } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; goto cleanup; - } - - handle_type = switch_handle_get_type(mac_entry->handle); - switch(handle_type) { - case SWITCH_HANDLE_TYPE_PORT: - case SWITCH_HANDLE_TYPE_LAG: - status = switch_interface_handle_get( - mac_entry->handle, - 0x0, - &intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - break; - case SWITCH_HANDLE_TYPE_INTERFACE: - mac_entry->mac_action = TRUE; - intf_handle = mac_entry->handle; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - nhop_info = switch_nhop_get(intf_info->nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; - } - nhop_index = handle_to_id(intf_info->nhop_handle); - } - break; - - case SWITCH_HANDLE_TYPE_NHOP: - mac_entry->mac_action = TRUE; - nhop_info = switch_nhop_get(mac_entry->handle); - if (!nhop_info) { - status = SWITCH_STATUS_INVALID_NHOP; - goto cleanup; - } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - nhop_index = handle_to_id(mac_entry->handle); - break; - - case SWITCH_HANDLE_TYPE_MGID: - mac_entry->mac_action = TRUE; - mgid_index = handle_to_id(mac_entry->handle); - break; - default: - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; - } - - bd_info = switch_bd_get(mac_entry->vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - ln_info = &bd_info->ln_info; - - status = switch_mac_table_entry_insert(mac_entry, &mac_info); - if (status != SWITCH_STATUS_SUCCESS) { + } + break; + case SWITCH_HANDLE_TYPE_INTERFACE: + mac_entry->mac_action = TRUE; + intf_handle = mac_entry->handle; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; goto cleanup; - } - - switch_mac_update_nhop(device, intf_handle, mac_entry); - - if (mac_entry->entry_type == SWITCH_MAC_ENTRY_DYNAMIC) { - aging_time = switch_api_mac_get_default_aging_time_internal(); - if (ln_info->age_interval) { - aging_time = ln_info->age_interval; + } + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + nhop_info = switch_nhop_get(intf_info->nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; } - } - -#ifdef SWITCH_PD - mac_info->smac_entry = SWITCH_HW_INVALID_HANDLE; - mac_info->dmac_entry = SWITCH_HW_INVALID_HANDLE; - status = switch_pd_dmac_table_add_entry(device, mac_entry, - nhop_index, mgid_index, - aging_time, intf_info, - &mac_info->dmac_entry); - if (status != SWITCH_STATUS_SUCCESS) { + nhop_index = handle_to_id(intf_info->nhop_handle); + } + break; + + case SWITCH_HANDLE_TYPE_NHOP: + mac_entry->mac_action = TRUE; + nhop_info = switch_nhop_get(mac_entry->handle); + if (!nhop_info) { + status = SWITCH_STATUS_INVALID_NHOP; goto cleanup; - } - - // Do not learn multicast macs on smac table - if (!mgid_index && SWITCH_LN_LEARN_ENABLED(bd_info)) { - status = switch_pd_smac_table_add_entry(device, mac_entry, - intf_info, - &mac_info->smac_entry); - } - if (status != SWITCH_STATUS_SUCCESS) { + } + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; goto cleanup; - } + } + nhop_index = handle_to_id(mac_entry->handle); + break; + + case SWITCH_HANDLE_TYPE_MGID: + mac_entry->mac_action = TRUE; + mgid_index = handle_to_id(mac_entry->handle); + break; + default: + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + bd_info = switch_bd_get(mac_entry->vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + ln_info = &bd_info->ln_info; + + status = switch_mac_table_entry_insert(mac_entry, &mac_info); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + + switch_mac_update_nhop(device, intf_handle, mac_entry); + + if (mac_entry->entry_type == SWITCH_MAC_ENTRY_DYNAMIC) { + aging_time = switch_api_mac_get_default_aging_time_internal(); + if (ln_info->age_interval) { + aging_time = ln_info->age_interval; + } + } + +#ifdef SWITCH_PD + mac_info->smac_entry = SWITCH_HW_INVALID_HANDLE; + mac_info->dmac_entry = SWITCH_HW_INVALID_HANDLE; + status = switch_pd_dmac_table_add_entry(device, + mac_entry, + nhop_index, + mgid_index, + aging_time, + intf_info, + &mac_info->dmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + + // Do not learn multicast macs on smac table + if (!mgid_index && SWITCH_LN_LEARN_ENABLED(bd_info)) { + status = switch_pd_smac_table_add_entry( + device, mac_entry, intf_info, &mac_info->smac_entry); + } + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } #endif - switch_print_mac_table_entry(mac_entry, buffer, 200); - SWITCH_API_TRACE("%s:%d Adding entry %s\n", - __FUNCTION__, __LINE__, - buffer); + switch_print_mac_table_entry(mac_entry, buffer, 200); + SWITCH_API_TRACE("%s:%d Adding entry %s\n", __FUNCTION__, __LINE__, buffer); - JLI(temp, dmac_entry_hdl_array, mac_info->dmac_entry); - *(unsigned long *)temp = (unsigned long) mac_info; - return status; + JLI(temp, dmac_entry_hdl_array, mac_info->dmac_entry); + *(unsigned long *)temp = (unsigned long)mac_info; + return status; cleanup: - switch_print_mac_table_entry(mac_entry, buffer, 200); - SWITCH_API_ERROR("%s:%d: unable to add mac entry %s. %s\n", - __FUNCTION__, __LINE__, - buffer, - switch_print_error(status)); - return status; - -} - -switch_status_t -switch_api_mac_table_entries_add(switch_device_t device, - uint16_t mac_entry_count, - switch_api_mac_entry_t *mac_entries) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - int count = 0; - - SWITCH_API_TRACE("%s:%d: Adding %d mac table entries\n", - __FUNCTION__, __LINE__, mac_entry_count); - - for (count = 0; count < mac_entry_count; count++) { - status = switch_api_mac_table_entry_add(device, &mac_entries[count]); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } - return SWITCH_STATUS_SUCCESS; + switch_print_mac_table_entry(mac_entry, buffer, 200); + SWITCH_API_ERROR("%s:%d: unable to add mac entry %s. %s\n", + __FUNCTION__, + __LINE__, + buffer, + switch_print_error(status)); + return status; } -switch_status_t -switch_api_mac_table_entry_update(switch_device_t device, - switch_api_mac_entry_t *mac_entry) -{ - switch_interface_info_t *intf_info = NULL; - switch_mac_info_t *mac_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_nhop_info_t *nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_type_t handle_type = 0; - uint16_t nhop_index = 0; - uint16_t mgid_index = 0; - switch_handle_t intf_handle = 0; - char buffer[200]; - switch_handle_t mac_entry_handle; - - mac_entry_handle = mac_entry->handle; - mac_info = switch_mac_table_entry_find(mac_entry); - if (!mac_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } +switch_status_t switch_api_mac_table_entries_add( + switch_device_t device, + uint16_t mac_entry_count, + switch_api_mac_entry_t *mac_entries) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + int count = 0; - if (!SWITCH_PORT_HANDLE_VALID(mac_entry->handle) && - !SWITCH_LAG_HANDLE_VALID(mac_entry->handle) && - !SWITCH_INTERFACE_HANDLE_VALID(mac_entry->handle) && - !SWITCH_MGID_HANDLE_VALID(mac_entry->handle) && - !SWITCH_NHOP_HANDLE_VALID(mac_entry->handle)) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; - } + SWITCH_API_TRACE("%s:%d: Adding %d mac table entries\n", + __FUNCTION__, + __LINE__, + mac_entry_count); - handle_type = switch_handle_get_type(mac_entry->handle); - switch(handle_type) { - case SWITCH_HANDLE_TYPE_PORT: - case SWITCH_HANDLE_TYPE_LAG: - status = switch_interface_handle_get( - mac_entry->handle, - 0x0, - &intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - mac_entry_handle = intf_handle; - break; - - case SWITCH_HANDLE_TYPE_INTERFACE: - intf_handle = mac_entry->handle; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - nhop_info = switch_nhop_get(intf_info->nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; - } - nhop_index = handle_to_id(intf_info->nhop_handle); - } - break; - - case SWITCH_HANDLE_TYPE_NHOP: - nhop_info = switch_nhop_get(mac_entry->handle); - if (!nhop_info) { - status = SWITCH_STATUS_INVALID_NHOP; - goto cleanup; - } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - nhop_index = handle_to_id(mac_entry->handle); - break; - - case SWITCH_HANDLE_TYPE_MGID: - mgid_index = handle_to_id(mac_entry->handle); - break; - - default: - return SWITCH_STATUS_INVALID_HANDLE; + for (count = 0; count < mac_entry_count; count++) { + status = switch_api_mac_table_entry_add(device, &mac_entries[count]); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } + } + return SWITCH_STATUS_SUCCESS; +} - bd_info = switch_bd_get(mac_entry->vlan_handle); - if (!bd_info) { - status = SWITCH_STATUS_INVALID_VLAN_ID; +switch_status_t switch_api_mac_table_entry_update( + switch_device_t device, switch_api_mac_entry_t *mac_entry) { + switch_interface_info_t *intf_info = NULL; + switch_mac_info_t *mac_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_type_t handle_type = 0; + uint16_t nhop_index = 0; + uint16_t mgid_index = 0; + switch_handle_t intf_handle = 0; + char buffer[200]; + switch_handle_t mac_entry_handle; + + mac_entry_handle = mac_entry->handle; + mac_info = switch_mac_table_entry_find(mac_entry); + if (!mac_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + if (!SWITCH_PORT_HANDLE_VALID(mac_entry->handle) && + !SWITCH_LAG_HANDLE_VALID(mac_entry->handle) && + !SWITCH_INTERFACE_HANDLE_VALID(mac_entry->handle) && + !SWITCH_MGID_HANDLE_VALID(mac_entry->handle) && + !SWITCH_NHOP_HANDLE_VALID(mac_entry->handle)) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + handle_type = switch_handle_get_type(mac_entry->handle); + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + case SWITCH_HANDLE_TYPE_LAG: + status = + switch_interface_handle_get(mac_entry->handle, 0x0, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { goto cleanup; - } - - status = switch_mac_remove_from_interface_list(mac_info); - assert(status == SWITCH_STATUS_SUCCESS); - mac_info->mac_entry.handle = mac_entry_handle; - status = switch_mac_insert_into_interface_list(mac_info); - assert(status == SWITCH_STATUS_SUCCESS); - switch_mac_update_nhop(device, intf_handle, &(mac_info->mac_entry)); - -#ifdef SWITCH_PD - status = switch_pd_dmac_table_update_entry(device, &(mac_info->mac_entry), - nhop_index, mgid_index, - intf_info, - mac_info->dmac_entry); - if (status != SWITCH_STATUS_SUCCESS) { + } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; goto cleanup; - } - // Do not learn multicast macs on smac table - if (!mgid_index && SWITCH_LN_LEARN_ENABLED(bd_info)) { - status = switch_pd_smac_table_update_entry(device, - &(mac_info->mac_entry), intf_info, - mac_info->smac_entry); - } - if (status != SWITCH_STATUS_SUCCESS) { + } + mac_entry_handle = intf_handle; + break; + + case SWITCH_HANDLE_TYPE_INTERFACE: + intf_handle = mac_entry->handle; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; goto cleanup; - } + } + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + nhop_info = switch_nhop_get(intf_info->nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; + } + nhop_index = handle_to_id(intf_info->nhop_handle); + } + break; + + case SWITCH_HANDLE_TYPE_NHOP: + nhop_info = switch_nhop_get(mac_entry->handle); + if (!nhop_info) { + status = SWITCH_STATUS_INVALID_NHOP; + goto cleanup; + } + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; + goto cleanup; + } + nhop_index = handle_to_id(mac_entry->handle); + break; + + case SWITCH_HANDLE_TYPE_MGID: + mgid_index = handle_to_id(mac_entry->handle); + break; + + default: + return SWITCH_STATUS_INVALID_HANDLE; + } + + bd_info = switch_bd_get(mac_entry->vlan_handle); + if (!bd_info) { + status = SWITCH_STATUS_INVALID_VLAN_ID; + goto cleanup; + } + + status = switch_mac_remove_from_interface_list(mac_info); + assert(status == SWITCH_STATUS_SUCCESS); + mac_info->mac_entry.handle = mac_entry_handle; + status = switch_mac_insert_into_interface_list(mac_info); + assert(status == SWITCH_STATUS_SUCCESS); + switch_mac_update_nhop(device, intf_handle, &(mac_info->mac_entry)); + +#ifdef SWITCH_PD + status = switch_pd_dmac_table_update_entry(device, + &(mac_info->mac_entry), + nhop_index, + mgid_index, + intf_info, + mac_info->dmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } + // Do not learn multicast macs on smac table + if (!mgid_index && SWITCH_LN_LEARN_ENABLED(bd_info)) { + status = switch_pd_smac_table_update_entry( + device, &(mac_info->mac_entry), intf_info, mac_info->smac_entry); + } + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; + } #endif - switch_print_mac_table_entry(&(mac_info->mac_entry), buffer, 200); - SWITCH_API_TRACE("%s:%d Updating entry %s\n", - __FUNCTION__, __LINE__, - buffer); - return status; + switch_print_mac_table_entry(&(mac_info->mac_entry), buffer, 200); + SWITCH_API_TRACE("%s:%d Updating entry %s\n", __FUNCTION__, __LINE__, buffer); + return status; cleanup: - switch_print_mac_table_entry(&(mac_info->mac_entry), buffer, 200); - SWITCH_API_ERROR("%s:%d: unable to update mac entry %s. %s\n", - __FUNCTION__, __LINE__, - buffer, - switch_print_error(status)); - return status; + switch_print_mac_table_entry(&(mac_info->mac_entry), buffer, 200); + SWITCH_API_ERROR("%s:%d: unable to update mac entry %s. %s\n", + __FUNCTION__, + __LINE__, + buffer, + switch_print_error(status)); + return status; } -switch_status_t -switch_api_mac_table_entries_update(switch_device_t device, - uint16_t mac_entry_count, - switch_api_mac_entry_t *mac_entries) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - int count = 0; - - SWITCH_API_TRACE("%s:%d: Updating %d mac table entries\n", - __FUNCTION__, __LINE__, mac_entry_count); - - for (count = 0; count < mac_entry_count; count++) { - status = switch_api_mac_table_entry_update(device, &mac_entries[count]); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } +switch_status_t switch_api_mac_table_entries_update( + switch_device_t device, + uint16_t mac_entry_count, + switch_api_mac_entry_t *mac_entries) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + int count = 0; + + SWITCH_API_TRACE("%s:%d: Updating %d mac table entries\n", + __FUNCTION__, + __LINE__, + mac_entry_count); + + for (count = 0; count < mac_entry_count; count++) { + status = switch_api_mac_table_entry_update(device, &mac_entries[count]); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } - return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_table_entry_delete(switch_device_t device, - switch_api_mac_entry_t *mac_entry) -{ - switch_mac_info_t *mac_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_interface_info_t *intf_info = NULL; - switch_handle_t intf_handle = 0; - switch_handle_t handle = 0; - switch_handle_type_t handle_type = 0; - char buffer[200]; - - mac_info = switch_mac_table_entry_find(mac_entry); - if (!mac_info) { - status = SWITCH_STATUS_ITEM_NOT_FOUND; +switch_status_t switch_api_mac_table_entry_delete( + switch_device_t device, switch_api_mac_entry_t *mac_entry) { + switch_mac_info_t *mac_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_interface_info_t *intf_info = NULL; + switch_handle_t intf_handle = 0; + switch_handle_t handle = 0; + switch_handle_type_t handle_type = 0; + char buffer[200]; + + mac_info = switch_mac_table_entry_find(mac_entry); + if (!mac_info) { + status = SWITCH_STATUS_ITEM_NOT_FOUND; + goto cleanup; + } + + handle = mac_info->mac_entry.handle; + handle_type = switch_handle_get_type(handle); + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + case SWITCH_HANDLE_TYPE_LAG: + status = switch_interface_handle_get(handle, 0x0, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { goto cleanup; - } - - handle = mac_info->mac_entry.handle; - handle_type = switch_handle_get_type(handle); - switch(handle_type) { - case SWITCH_HANDLE_TYPE_PORT: - case SWITCH_HANDLE_TYPE_LAG: - status = switch_interface_handle_get( - handle, - 0x0, - &intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - break; - case SWITCH_HANDLE_TYPE_INTERFACE: - intf_handle = handle; - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - status = SWITCH_STATUS_INVALID_INTERFACE; - goto cleanup; - } - break; - default: - intf_handle = 0; - } + } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; + goto cleanup; + } + break; + case SWITCH_HANDLE_TYPE_INTERFACE: + intf_handle = handle; + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + status = SWITCH_STATUS_INVALID_INTERFACE; + goto cleanup; + } + break; + default: + intf_handle = 0; + } #ifdef SWITCH_PD - if (mac_info->smac_entry != SWITCH_HW_INVALID_HANDLE) { - status = switch_pd_smac_table_delete_entry(device, mac_info->smac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - status = SWITCH_STATUS_FAILURE; - goto cleanup; - } + if (mac_info->smac_entry != SWITCH_HW_INVALID_HANDLE) { + status = switch_pd_smac_table_delete_entry(device, mac_info->smac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FAILURE; + goto cleanup; } - if (mac_info->dmac_entry != SWITCH_HW_INVALID_HANDLE) { - status = switch_pd_dmac_table_delete_entry(device, mac_info->dmac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - status = SWITCH_STATUS_FAILURE; - goto cleanup; - } + } + if (mac_info->dmac_entry != SWITCH_HW_INVALID_HANDLE) { + status = switch_pd_dmac_table_delete_entry(device, mac_info->dmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + status = SWITCH_STATUS_FAILURE; + goto cleanup; } + } #endif - JLD(status, dmac_entry_hdl_array, mac_info->dmac_entry); - switch_print_mac_table_entry(&mac_info->mac_entry, buffer, 200); - SWITCH_API_TRACE("%s:%d Deleting entry %s\n", - __FUNCTION__, __LINE__, - buffer); - status = switch_mac_table_entry_delete(&mac_info->mac_entry); - switch_mac_update_nhop(device, intf_handle, mac_entry); - return status; + JLD(status, dmac_entry_hdl_array, mac_info->dmac_entry); + switch_print_mac_table_entry(&mac_info->mac_entry, buffer, 200); + SWITCH_API_TRACE("%s:%d Deleting entry %s\n", __FUNCTION__, __LINE__, buffer); + status = switch_mac_table_entry_delete(&mac_info->mac_entry); + switch_mac_update_nhop(device, intf_handle, mac_entry); + return status; cleanup: - switch_print_mac_table_entry(mac_entry, buffer, 200); - SWITCH_API_ERROR("%s:%d: unable to delete mac entry for handle %s. %s\n", - __FUNCTION__, __LINE__, - buffer, - switch_print_error(status)); - return status; + switch_print_mac_table_entry(mac_entry, buffer, 200); + SWITCH_API_ERROR("%s:%d: unable to delete mac entry for handle %s. %s\n", + __FUNCTION__, + __LINE__, + buffer, + switch_print_error(status)); + return status; } -switch_status_t -switch_api_multicast_l2mac_add(switch_device_t device, - switch_api_mac_entry_t *mac_entry) -{ - return switch_api_mac_table_entry_add(device, mac_entry); +switch_status_t switch_api_multicast_l2mac_add( + switch_device_t device, switch_api_mac_entry_t *mac_entry) { + return switch_api_mac_table_entry_add(device, mac_entry); } -switch_status_t -switch_api_multicast_l2mac_delete(switch_device_t device, - switch_api_mac_entry_t *mac_entry) -{ - return switch_api_mac_table_entry_delete(device, mac_entry); +switch_status_t switch_api_multicast_l2mac_delete( + switch_device_t device, switch_api_mac_entry_t *mac_entry) { + return switch_api_mac_table_entry_delete(device, mac_entry); } -switch_status_t -switch_api_mac_entries_delete(switch_device_t device, - uint16_t mac_entry_count, - switch_api_mac_entry_t *mac_entries) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - int count = 0; - - SWITCH_API_TRACE("%s:%d: Deleting %d mac table entries\n", - __FUNCTION__, __LINE__, mac_entry_count); - - for (count = 0; count < mac_entry_count; count++) { - status = switch_api_mac_table_entry_delete(device, &mac_entries[count]); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } - return SWITCH_STATUS_SUCCESS; -} +switch_status_t switch_api_mac_entries_delete( + switch_device_t device, + uint16_t mac_entry_count, + switch_api_mac_entry_t *mac_entries) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + int count = 0; -switch_status_t -switch_api_mac_table_entries_delete_all(switch_device_t device) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t vlan_handle = 0; - void *temp = NULL; - - SWITCH_API_TRACE("%s:%d: Deleting all mac table entries\n", - __FUNCTION__, __LINE__); - - JLF(temp, vlan_mac_hdl_array, vlan_handle); - while (temp) { - status = switch_api_mac_table_entries_delete_by_vlan(device, - vlan_handle); - JLN(temp, vlan_mac_hdl_array, vlan_handle); - } - return status; -} + SWITCH_API_TRACE("%s:%d: Deleting %d mac table entries\n", + __FUNCTION__, + __LINE__, + mac_entry_count); -switch_status_t -switch_api_mac_table_entries_delete_by_vlan(switch_device_t device, - switch_handle_t vlan_handle) -{ - switch_mac_vlan_list_t *mac_vlan_list = NULL; - switch_mac_info_t *mac_info = NULL; - switch_bd_info_t *bd_info = NULL; - tommy_node *node = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; - } - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; + for (count = 0; count < mac_entry_count; count++) { + status = switch_api_mac_table_entry_delete(device, &mac_entries[count]); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } + } + return SWITCH_STATUS_SUCCESS; +} - SWITCH_API_TRACE("%s:%d: Deleting mac table entries by vlan %lx", - __FUNCTION__, __LINE__, vlan_handle); - - JLG(temp, vlan_mac_hdl_array, vlan_handle); - if (!temp) { - SWITCH_API_TRACE("%s:%d: No macs to delete!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_SUCCESS; - } +switch_status_t switch_api_mac_table_entries_delete_all( + switch_device_t device) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t vlan_handle = 0; + void *temp = NULL; + + SWITCH_API_TRACE( + "%s:%d: Deleting all mac table entries\n", __FUNCTION__, __LINE__); + + JLF(temp, vlan_mac_hdl_array, vlan_handle); + while (temp) { + status = switch_api_mac_table_entries_delete_by_vlan(device, vlan_handle); + JLN(temp, vlan_mac_hdl_array, vlan_handle); + } + return status; +} - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(mac_vlan_list->mac_entries)); - while (node) { - mac_info = node->data; - node = node->next; - status = switch_api_mac_table_entry_delete(device, &mac_info->mac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } +switch_status_t switch_api_mac_table_entries_delete_by_vlan( + switch_device_t device, switch_handle_t vlan_handle) { + switch_mac_vlan_list_t *mac_vlan_list = NULL; + switch_mac_info_t *mac_info = NULL; + switch_bd_info_t *bd_info = NULL; + tommy_node *node = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + SWITCH_API_TRACE("%s:%d: Deleting mac table entries by vlan %lx", + __FUNCTION__, + __LINE__, + vlan_handle); + + JLG(temp, vlan_mac_hdl_array, vlan_handle); + if (!temp) { + SWITCH_API_TRACE("%s:%d: No macs to delete!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_SUCCESS; + } + + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(mac_vlan_list->mac_entries)); + while (node) { + mac_info = node->data; + node = node->next; + status = switch_api_mac_table_entry_delete(device, &mac_info->mac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; } - return status; + } + return status; cleanup: - SWITCH_API_ERROR("%s:%d: unable to delete macs for vlan %lx. %s", - __FUNCTION__, __LINE__, - vlan_handle, - switch_print_error(status)); - return status; + SWITCH_API_ERROR("%s:%d: unable to delete macs for vlan %lx. %s", + __FUNCTION__, + __LINE__, + vlan_handle, + switch_print_error(status)); + return status; } -switch_status_t -switch_api_mac_table_entries_delete_by_interface(switch_device_t device, - switch_handle_t handle) -{ - switch_mac_intf_list_t *mac_intf_list = NULL; - switch_mac_info_t *mac_info = NULL; - tommy_node *node = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t intf_handle = 0; - switch_handle_type_t handle_type = 0; - - if (!SWITCH_PORT_HANDLE_VALID(handle) && - !SWITCH_LAG_HANDLE_VALID(handle) && - !SWITCH_INTERFACE_HANDLE_VALID(handle)) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; - } - - handle_type = switch_handle_get_type(handle); - intf_handle = 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("mac table delete by interface failed"); - return status; - } - } - - JLG(temp, intf_mac_hdl_array, intf_handle); - if (!temp) { - SWITCH_API_TRACE("%s:%d: no macs to delete!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_table_entries_delete_by_interface( + switch_device_t device, switch_handle_t handle) { + switch_mac_intf_list_t *mac_intf_list = NULL; + switch_mac_info_t *mac_info = NULL; + tommy_node *node = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t intf_handle = 0; + switch_handle_type_t handle_type = 0; + + if (!SWITCH_PORT_HANDLE_VALID(handle) && !SWITCH_LAG_HANDLE_VALID(handle) && + !SWITCH_INTERFACE_HANDLE_VALID(handle)) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + handle_type = switch_handle_get_type(handle); + intf_handle = 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("mac table delete by interface failed"); + return status; } + } - mac_intf_list = (switch_mac_intf_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(mac_intf_list->mac_entries)); - while (node) { - mac_info = node->data; - node = node->next; - status = switch_api_mac_table_entry_delete(device, &mac_info->mac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - goto cleanup; - } + JLG(temp, intf_mac_hdl_array, intf_handle); + if (!temp) { + SWITCH_API_TRACE("%s:%d: no macs to delete!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_SUCCESS; + } + + mac_intf_list = (switch_mac_intf_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(mac_intf_list->mac_entries)); + while (node) { + mac_info = node->data; + node = node->next; + status = switch_api_mac_table_entry_delete(device, &mac_info->mac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + goto cleanup; } - return status; + } + return status; cleanup: - SWITCH_API_ERROR("%s:%d: unable to delete macs for handle %lx. %s", - __FUNCTION__, __LINE__, - handle, - switch_print_error(status)); - return status; + SWITCH_API_ERROR("%s:%d: unable to delete macs for handle %lx. %s", + __FUNCTION__, + __LINE__, + handle, + switch_print_error(status)); + return status; } -switch_status_t -switch_api_mac_table_entries_delete_by_interface_vlan(switch_device_t device, - switch_handle_t handle, - switch_handle_t vlan_handle) -{ - switch_mac_vlan_list_t *mac_vlan_list = NULL; - switch_mac_info_t *mac_info = NULL; - tommy_node *node = NULL; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t intf_handle = 0; - switch_handle_type_t handle_type = 0; - - if (!SWITCH_PORT_HANDLE_VALID(handle) && - !SWITCH_LAG_HANDLE_VALID(handle) && - !SWITCH_INTERFACE_HANDLE_VALID(handle)) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; - } - - if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { - status = SWITCH_STATUS_INVALID_HANDLE; - goto cleanup; - } +switch_status_t switch_api_mac_table_entries_delete_by_interface_vlan( + switch_device_t device, + switch_handle_t handle, + switch_handle_t vlan_handle) { + switch_mac_vlan_list_t *mac_vlan_list = NULL; + switch_mac_info_t *mac_info = NULL; + tommy_node *node = NULL; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t intf_handle = 0; + switch_handle_type_t handle_type = 0; + + if (!SWITCH_PORT_HANDLE_VALID(handle) && !SWITCH_LAG_HANDLE_VALID(handle) && + !SWITCH_INTERFACE_HANDLE_VALID(handle)) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { + status = SWITCH_STATUS_INVALID_HANDLE; + goto cleanup; + } + + JLG(temp, vlan_mac_hdl_array, vlan_handle); + if (!temp) { + SWITCH_API_TRACE("%s:%d: no macs to delete!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_SUCCESS; + } - JLG(temp, vlan_mac_hdl_array, vlan_handle); - if (!temp) { - SWITCH_API_TRACE("%s:%d: no macs to delete!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_SUCCESS; + handle_type = switch_handle_get_type(handle); + intf_handle = 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("mac table delete by vlan failed"); + return status; } + } - handle_type = switch_handle_get_type(handle); - intf_handle = 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("mac table delete by vlan failed"); - return status; - } + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(mac_vlan_list->mac_entries)); + while (node) { + mac_info = node->data; + node = node->next; + if (intf_handle != mac_info->mac_entry.handle) { + continue; } - - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(mac_vlan_list->mac_entries)); - while (node) { - mac_info = node->data; - node = node->next; - if (intf_handle != mac_info->mac_entry.handle) { - continue; - } - status = switch_api_mac_table_entry_delete(device, &mac_info->mac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + status = switch_api_mac_table_entry_delete(device, &mac_info->mac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } - return status; + } + return status; cleanup: - SWITCH_API_ERROR("%s:%d: unable to delete macs for handle %lx. %s", - __FUNCTION__, __LINE__, - handle, - switch_print_error(status)); - return status; -} - -switch_status_t -switch_api_mac_table_aging_time_set(uint64_t value) -{ - mac_params.aging_time = value; - return SWITCH_STATUS_SUCCESS; + SWITCH_API_ERROR("%s:%d: unable to delete macs for handle %lx. %s", + __FUNCTION__, + __LINE__, + handle, + switch_print_error(status)); + return status; } -switch_status_t -switch_api_mac_table_aging_time_get(uint64_t *value) -{ - *value = mac_params.aging_time; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_table_aging_time_set(uint64_t value) { + mac_params.aging_time = value; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_register_learning_callback(switch_mac_learn_entry_notify_cb cb_fn) -{ - switch_mac_cb_fn.mac_learn_notify_cb = cb_fn; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_table_aging_time_get(uint64_t *value) { + *value = mac_params.aging_time; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_register_aging_callback(switch_mac_aging_entry_notify_cb cb_fn) -{ - switch_mac_cb_fn.mac_aging_notify_cb = cb_fn; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_register_learning_callback( + switch_mac_learn_entry_notify_cb cb_fn) { + switch_mac_cb_fn.mac_learn_notify_cb = cb_fn; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_table_entries_get(switch_mac_table_iterator_fn iterator_fn) -{ - switch_mac_info_t *mac_info = NULL; - switch_mac_vlan_list_t *mac_vlan_list = NULL; - tommy_node *node = NULL; - void *temp = NULL; - switch_handle_t vlan_handle = 0; - - JLF(temp, vlan_mac_hdl_array, vlan_handle); - while (temp) { - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(mac_vlan_list->mac_entries)); - while (node) { - mac_info = node->data; - iterator_fn(&mac_info->mac_entry); - node = node->next; - } - JLN(temp, vlan_mac_hdl_array, vlan_handle); - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_register_aging_callback( + switch_mac_aging_entry_notify_cb cb_fn) { + switch_mac_cb_fn.mac_aging_notify_cb = cb_fn; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_table_entries_get_by_vlan(switch_handle_t vlan_handle, switch_mac_table_iterator_fn iterator_fn) -{ - switch_mac_info_t *mac_info = NULL; - switch_mac_vlan_list_t *mac_vlan_list = NULL; - tommy_node *node = NULL; - void *temp = NULL; - - JLG(temp, vlan_mac_hdl_array, vlan_handle); - if (!temp) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); +switch_status_t switch_api_mac_table_entries_get( + switch_mac_table_iterator_fn iterator_fn) { + switch_mac_info_t *mac_info = NULL; + switch_mac_vlan_list_t *mac_vlan_list = NULL; + tommy_node *node = NULL; + void *temp = NULL; + switch_handle_t vlan_handle = 0; + + JLF(temp, vlan_mac_hdl_array, vlan_handle); + while (temp) { + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); node = tommy_list_head(&(mac_vlan_list->mac_entries)); while (node) { - mac_info = node->data; - iterator_fn(&mac_info->mac_entry); - node = node->next; + mac_info = node->data; + iterator_fn(&mac_info->mac_entry); + node = node->next; } - return SWITCH_STATUS_SUCCESS; + JLN(temp, vlan_mac_hdl_array, vlan_handle); + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_table_entries_get_by_interface(switch_handle_t intf_handle, switch_mac_table_iterator_fn iterator_fn) -{ - switch_mac_info_t *mac_info = NULL; - switch_mac_intf_list_t *mac_intf_list = NULL; - tommy_node *node = NULL; - void *temp = NULL; - - JLG(temp, intf_mac_hdl_array, intf_handle); - if (!temp) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - mac_intf_list = (switch_mac_intf_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(mac_intf_list->mac_entries)); - while (node) { - mac_info = node->data; - iterator_fn(&mac_info->mac_entry); - node = node->next; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_table_entries_get_by_vlan( + switch_handle_t vlan_handle, switch_mac_table_iterator_fn iterator_fn) { + switch_mac_info_t *mac_info = NULL; + switch_mac_vlan_list_t *mac_vlan_list = NULL; + tommy_node *node = NULL; + void *temp = NULL; + + JLG(temp, vlan_mac_hdl_array, vlan_handle); + if (!temp) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(mac_vlan_list->mac_entries)); + while (node) { + mac_info = node->data; + iterator_fn(&mac_info->mac_entry); + node = node->next; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_table_set_learning_timeout(switch_device_t device, uint32_t timeout) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - mac_params.learn_timeout = timeout; - status = switch_pd_mac_table_set_learning_timeout(device, timeout); - return status; +switch_status_t switch_api_mac_table_entries_get_by_interface( + switch_handle_t intf_handle, switch_mac_table_iterator_fn iterator_fn) { + switch_mac_info_t *mac_info = NULL; + switch_mac_intf_list_t *mac_intf_list = NULL; + tommy_node *node = NULL; + void *temp = NULL; + + JLG(temp, intf_mac_hdl_array, intf_handle); + if (!temp) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + mac_intf_list = (switch_mac_intf_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(mac_intf_list->mac_entries)); + while (node) { + mac_info = node->data; + iterator_fn(&mac_info->mac_entry); + node = node->next; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_mac_table_print_all() -{ - switch_mac_info_t *mac_info = NULL; - switch_api_mac_entry_t *mac_entry = NULL; - switch_mac_vlan_list_t *mac_vlan_list = NULL; - tommy_node *node = NULL; - void *temp = NULL; - switch_handle_t vlan_handle = 0; - char buffer[200]; - - JLF(temp, vlan_mac_hdl_array, vlan_handle); - while (temp) { - mac_vlan_list = (switch_mac_vlan_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(mac_vlan_list->mac_entries)); - while (node) { - mac_info = node->data; - mac_entry = &mac_info->mac_entry; - switch_print_mac_table_entry(mac_entry, buffer, 200); - node = node->next; - } - JLN(temp, vlan_mac_hdl_array, vlan_handle); - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mac_table_set_learning_timeout( + switch_device_t device, uint32_t timeout) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + mac_params.learn_timeout = timeout; + status = switch_pd_mac_table_set_learning_timeout(device, timeout); + return status; +} + +switch_status_t switch_api_mac_table_print_all() { + switch_mac_info_t *mac_info = NULL; + switch_api_mac_entry_t *mac_entry = NULL; + switch_mac_vlan_list_t *mac_vlan_list = NULL; + tommy_node *node = NULL; + void *temp = NULL; + switch_handle_t vlan_handle = 0; + char buffer[200]; + + JLF(temp, vlan_mac_hdl_array, vlan_handle); + while (temp) { + mac_vlan_list = (switch_mac_vlan_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(mac_vlan_list->mac_entries)); + while (node) { + mac_info = node->data; + mac_entry = &mac_info->mac_entry; + switch_print_mac_table_entry(mac_entry, buffer, 200); + node = node->next; + } + JLN(temp, vlan_mac_hdl_array, vlan_handle); + } + return SWITCH_STATUS_SUCCESS; } #ifdef __cplusplus diff --git a/switchapi/src/switch_l2_int.h b/switchapi/src/switch_l2_int.h index d89f177..a991e90 100644 --- a/switchapi/src/switch_l2_int.h +++ b/switchapi/src/switch_l2_int.h @@ -26,39 +26,40 @@ extern "C" { #define SWITCH_MAC_MAXIMUM_BUFFER_SIZE 128 #define SWITCH_MAC_TABLE_DEFAULT_AGING_TIME 10000 -#define SWITCH_MAC_TABLE_MAX_AGING_TIME 90000 +#define SWITCH_MAC_TABLE_MAX_AGING_TIME 90000 typedef struct switch_mac_info_ { - unsigned char key[10]; - switch_api_mac_entry_t mac_entry; - tommy_hashtable_node node; - tommy_node interface_node; - tommy_node vlan_node; + unsigned char key[10]; + switch_api_mac_entry_t mac_entry; + tommy_hashtable_node node; + tommy_node interface_node; + tommy_node vlan_node; #ifdef SWITCH_PD - p4_pd_entry_hdl_t dmac_entry; - p4_pd_entry_hdl_t smac_entry; + p4_pd_entry_hdl_t dmac_entry; + p4_pd_entry_hdl_t smac_entry; #endif } switch_mac_info_t; typedef struct switch_mac_global_params_ { - uint32_t aging_time; - uint32_t learn_timeout; + uint32_t aging_time; + uint32_t learn_timeout; } switch_mac_global_params_t; typedef struct switch_mac_vlan_list_ { - tommy_list mac_entries; - uint32_t num_entries; + tommy_list mac_entries; + uint32_t num_entries; } switch_mac_vlan_list_t; typedef struct switch_mac_intf_list_ { - tommy_list mac_entries; - uint32_t num_entries; + tommy_list mac_entries; + uint32_t num_entries; } switch_mac_intf_list_t; switch_status_t switch_mac_table_init(switch_device_t device); switch_status_t switch_mac_table_free(void); uint32_t switch_api_mac_get_default_aging_time_internal(); -switch_mac_info_t * switch_mac_table_entry_find(switch_api_mac_entry_t *mac_entry); +switch_mac_info_t *switch_mac_table_entry_find( + switch_api_mac_entry_t *mac_entry); #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_l3.c b/switchapi/src/switch_l3.c index 2c47ab9..45835f0 100644 --- a/switchapi/src/switch_l3.c +++ b/switchapi/src/switch_l3.c @@ -23,6 +23,7 @@ limitations under the License. #include "switch_pd.h" #include "switch_nhop_int.h" #include "switch_l3_int.h" +#include "switch_lpm_int.h" #include "switch_hostif_int.h" #include "switch_log_int.h" #include "arpa/inet.h" @@ -37,599 +38,794 @@ static tommy_hashtable switch_l3_hash_table; static void *switch_vrf_v4_routes = NULL; static void *switch_vrf_v6_routes = NULL; -static inline unsigned int -prefix_to_v4_mask(unsigned int prefix) -{ - return (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF; +static void *switch_vrf_v4_lpm_tries = NULL; +static void *switch_vrf_v6_lpm_tries = NULL; + +static inline unsigned int prefix_to_v4_mask(unsigned int prefix) { + return (prefix ? ((0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF) : 0); } -static void -prefix_to_v6_mask(unsigned int prefix, uint8_t *mask) -{ - unsigned int i = 0; - memset(mask, 0, 16); - for (i = 0; i < prefix/16; i++) { - mask[i] = 0xFF; - } - if (i != 8) { - mask[i] = (0xFF << (128 - prefix)) & 0xFF; - } +static void prefix_to_v6_mask(unsigned int prefix, uint8_t *mask) { + unsigned int i = 0; + memset(mask, 0, 16); + for (i = 0; i < prefix / 16; i++) { + mask[i] = 0xFF; + } + if (i != 8) { + mask[i] = (0xFF << (128 - prefix)) & 0xFF; + } } -switch_status_t -switch_l3_init(switch_device_t device) -{ - UNUSED(device); - // IP + VRF Hash table init (V4 only for now!) - tommy_hashtable_init(&switch_l3_hash_table, SWITCH_L3_HASH_TABLE_SIZE); - switch_handle_type_init(SWITCH_HANDLE_TYPE_URPF, (4096)); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_l3_free(switch_device_t device) -{ - UNUSED(device); - tommy_hashtable_done(&switch_l3_hash_table); - switch_handle_type_free(SWITCH_HANDLE_TYPE_URPF); - return SWITCH_STATUS_SUCCESS; -} - -void -switch_l3_hash_key_init(uchar *key, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, uint32_t *len, - uint32_t *hash) -{ - *len=0; - memset(key, 0, SWITCH_L3_HASH_KEY_SIZE); - *(unsigned int *)(&key[0]) = (unsigned int)handle_to_id(vrf); - key[4] = ip_addr->type; - if(ip_addr->type == SWITCH_API_IP_ADDR_V4) { - *(unsigned int *)(&key[5]) = ip_addr->ip.v4addr; - *len = 9; - } - else { - memcpy(&key[5], ip_addr->ip.v6addr, 4*sizeof(unsigned int)); - *len = 21; - } - key[*len] = ip_addr->prefix_len; - (*len)++; - *hash = MurmurHash2(key, *len, 0x98761234); +static inline bool switch_l3_host_entry(switch_ip_addr_t *ip_addr) { + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) + return ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; + else + return ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; } -static switch_status_t -switch_l3_hash_key_decode(switch_l3_hash_t *hash_entry, switch_handle_t *vrf_handle, - switch_ip_addr_t *ip_addr) -{ - uint8_t len = 0; +switch_status_t switch_l3_init(switch_device_t device) { + UNUSED(device); + // IP + VRF Hash table init (V4 only for now!) + tommy_hashtable_init(&switch_l3_hash_table, SWITCH_L3_HASH_TABLE_SIZE); + switch_handle_type_init(SWITCH_HANDLE_TYPE_URPF, (4096)); + return SWITCH_STATUS_SUCCESS; +} - memset(ip_addr, 0, sizeof(switch_ip_addr_t)); - *vrf_handle = id_to_handle(SWITCH_HANDLE_TYPE_VRF, *(unsigned int *)(&hash_entry->key[len])); - len += 4; +switch_status_t switch_l3_free(switch_device_t device) { + UNUSED(device); + tommy_hashtable_done(&switch_l3_hash_table); + switch_handle_type_free(SWITCH_HANDLE_TYPE_URPF); + return SWITCH_STATUS_SUCCESS; +} - ip_addr->type = hash_entry->key[len]; - len += 1; +void switch_l3_hash_key_init(uchar *key, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, SWITCH_L3_HASH_KEY_SIZE); + *(unsigned int *)(&key[0]) = (unsigned int)handle_to_id(vrf); + key[4] = ip_addr->type; + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + *(unsigned int *)(&key[5]) = ip_addr->ip.v4addr; + *len = 9; + } else { + memcpy(&key[5], ip_addr->ip.v6addr, 4 * sizeof(unsigned int)); + *len = 21; + } + key[*len] = ip_addr->prefix_len; + (*len)++; + *hash = MurmurHash2(key, *len, 0x98761234); +} - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { - ip_addr->ip.v4addr = *(unsigned int *)(&hash_entry->key[len]); - len += 4; - } else { - memcpy(ip_addr->ip.v6addr, &hash_entry->key[len], 16); - len += 16; - } - ip_addr->prefix_len = hash_entry->key[len]; - return SWITCH_STATUS_SUCCESS; +static switch_status_t switch_l3_hash_key_decode(switch_l3_hash_t *hash_entry, + switch_handle_t *vrf_handle, + switch_ip_addr_t *ip_addr) { + uint8_t len = 0; + + memset(ip_addr, 0, sizeof(switch_ip_addr_t)); + unsigned int hash_key = 0; + memcpy(&hash_key, &hash_entry->key[len], 4); + *vrf_handle = id_to_handle(SWITCH_HANDLE_TYPE_VRF, hash_key); + len += 4; + + ip_addr->type = hash_entry->key[len]; + len += 1; + + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + memcpy(&(ip_addr->ip.v4addr), &hash_entry->key[len], 4); + len += 4; + } else { + memcpy(ip_addr->ip.v6addr, &hash_entry->key[len], 16); + len += 16; + } + ip_addr->prefix_len = hash_entry->key[len]; + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_l3_insert_into_vrf_list(switch_l3_hash_t *hash_entry) -{ - switch_vrf_route_list_t *vrf_route_list = NULL; - void *temp = NULL; - switch_ip_addr_t ip_addr; - switch_handle_t vrf_handle = 0; +static switch_status_t switch_l3_insert_into_vrf_list( + switch_l3_hash_t *hash_entry) { + switch_vrf_route_list_t *vrf_route_list = NULL; + void *temp = NULL; + switch_ip_addr_t ip_addr; + switch_handle_t vrf_handle = 0; - memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); - switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); - if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { - JLG(temp, switch_vrf_v4_routes, vrf_handle); - } else { - JLG(temp, switch_vrf_v6_routes, vrf_handle); - } + memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); + switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { + JLG(temp, switch_vrf_v4_routes, vrf_handle); + } else { + JLG(temp, switch_vrf_v6_routes, vrf_handle); + } - if (!temp) { - vrf_route_list = switch_malloc(sizeof(switch_vrf_route_list_t), 1); - if (!vrf_route_list) { - SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_NO_MEMORY; - } - tommy_list_init(&(vrf_route_list->routes)); - vrf_route_list->num_entries = 0; - if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { - JLI(temp, switch_vrf_v4_routes, vrf_handle); - } else { - JLI(temp, switch_vrf_v6_routes, vrf_handle); - } - *(unsigned long *)temp = (unsigned long) (vrf_route_list); + if (!temp) { + vrf_route_list = switch_malloc(sizeof(switch_vrf_route_list_t), 1); + if (!vrf_route_list) { + SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_NO_MEMORY; } - vrf_route_list = (switch_vrf_route_list_t *) (*(unsigned long *)temp); - tommy_list_insert_tail(&(vrf_route_list->routes), &(hash_entry->vrf_route_node), hash_entry); - vrf_route_list->num_entries++; - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t -switch_l3_remove_from_vrf_list(switch_l3_hash_t *hash_entry) -{ - switch_vrf_route_list_t *vrf_route_list = NULL; - void *temp = NULL; - switch_ip_addr_t ip_addr; - switch_handle_t vrf_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); - switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + tommy_list_init(&(vrf_route_list->routes)); + vrf_route_list->num_entries = 0; if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { - JLG(temp, switch_vrf_v4_routes, vrf_handle); + JLI(temp, switch_vrf_v4_routes, vrf_handle); } else { - JLG(temp, switch_vrf_v6_routes, vrf_handle); - } + JLI(temp, switch_vrf_v6_routes, vrf_handle); + } + *(unsigned long *)temp = (unsigned long)(vrf_route_list); + } + vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); + tommy_list_insert_tail( + &(vrf_route_list->routes), &(hash_entry->vrf_route_node), hash_entry); + vrf_route_list->num_entries++; + return SWITCH_STATUS_SUCCESS; +} - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } +static switch_status_t switch_l3_remove_from_vrf_list( + switch_l3_hash_t *hash_entry) { + switch_vrf_route_list_t *vrf_route_list = NULL; + void *temp = NULL; + switch_ip_addr_t ip_addr; + switch_handle_t vrf_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); + switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { + JLG(temp, switch_vrf_v4_routes, vrf_handle); + } else { + JLG(temp, switch_vrf_v6_routes, vrf_handle); + } + + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } - vrf_route_list = (switch_vrf_route_list_t *) (*(unsigned long *)temp); - tommy_list_remove_existing(&(vrf_route_list->routes), &(hash_entry->vrf_route_node)); - vrf_route_list->num_entries--; - if (vrf_route_list->num_entries == 0) { - if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { - JLD(status, switch_vrf_v4_routes, vrf_handle); - } else { - JLD(status, switch_vrf_v6_routes, vrf_handle); - } + vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); + tommy_list_remove_existing(&(vrf_route_list->routes), + &(hash_entry->vrf_route_node)); + vrf_route_list->num_entries--; + if (vrf_route_list->num_entries == 0) { + if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { + JLD(status, switch_vrf_v4_routes, vrf_handle); + } else { + JLD(status, switch_vrf_v6_routes, vrf_handle); } - return status; + } + return status; } -static switch_l3_hash_t * -switch_l3_insert_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr, - switch_handle_t interface) -{ - switch_l3_hash_t *hash_entry = NULL; - unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash; +static switch_status_t switch_l3_insert_into_lpm_trie( + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_l3_hash_t *hash_entry) { + switch_lpm_trie_t *lpm_trie = NULL; + void *temp = NULL; + size_t key_width_bytes; + char *prefix; + uint32_t v4addr; + + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + JLG(temp, switch_vrf_v4_lpm_tries, vrf); + key_width_bytes = 4; + v4addr = htonl(ip_addr->ip.v4addr); + prefix = (char *)(&v4addr); + } else { + JLG(temp, switch_vrf_v6_lpm_tries, vrf); + key_width_bytes = 16; + prefix = (char *)(ip_addr->ip.v6addr); + } + + if (!temp) { + lpm_trie = switch_lpm_trie_create(key_width_bytes, TRUE); + if (!lpm_trie) { + SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_NO_MEMORY; + } - switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); - hash_entry = switch_malloc(sizeof(switch_l3_hash_t), 1); - if (!hash_entry) { - return NULL; + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + JLI(temp, switch_vrf_v4_lpm_tries, vrf); + } else { + JLI(temp, switch_vrf_v6_lpm_tries, vrf); } - memcpy(hash_entry->key, key, SWITCH_L3_HASH_KEY_SIZE); - hash_entry->path_count = 1; - tommy_hashtable_insert(&switch_l3_hash_table, &(hash_entry->node), hash_entry, hash); - switch_l3_insert_into_vrf_list(hash_entry); - return hash_entry; -} + *(unsigned long *)temp = (unsigned long)(lpm_trie); + } -static inline int -switch_l3_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_L3_HASH_KEY_SIZE); + lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp); + switch_lpm_trie_insert( + lpm_trie, prefix, ip_addr->prefix_len, (unsigned long)hash_entry); + + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_l3_delete_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) -{ - switch_l3_hash_t *hash_entry = NULL; - unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash; - switch_status_t status = SWITCH_STATUS_SUCCESS; +static switch_status_t switch_l3_remove_from_lpm_trie( + switch_handle_t vrf, switch_ip_addr_t *ip_addr) { + switch_lpm_trie_t *lpm_trie = NULL; + void *temp = NULL; + char *prefix; + uint32_t v4addr; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + JLG(temp, switch_vrf_v4_lpm_tries, vrf); + v4addr = htonl(ip_addr->ip.v4addr); + prefix = (char *)(&v4addr); + } else { + JLG(temp, switch_vrf_v6_lpm_tries, vrf); + prefix = (char *)(ip_addr->ip.v6addr); + } + + if (!temp) { + SWITCH_API_ERROR( + "%s:%d: No LPM trie for this vrf %u!", __FUNCTION__, __LINE__, vrf); + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp); + switch_lpm_trie_delete(lpm_trie, prefix, ip_addr->prefix_len); + if (switch_lpm_trie_size(lpm_trie) == 0) { + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + JLD(status, switch_vrf_v4_lpm_tries, vrf); + } else { + JLD(status, switch_vrf_v6_lpm_tries, vrf); + } + } - switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); - hash_entry = tommy_hashtable_remove(&switch_l3_hash_table, switch_l3_hash_cmp, key, hash); - switch_l3_remove_from_vrf_list(hash_entry); - switch_free(hash_entry); - return status; + return status; } -static switch_l3_hash_t * -switch_l3_search_hash(switch_handle_t vrf, switch_ip_addr_t *ip_addr) -{ - unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - - switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); - switch_l3_hash_t *hash_entry = tommy_hashtable_search(&switch_l3_hash_table, switch_l3_hash_cmp, key, hash); +static switch_l3_hash_t *switch_l3_lookup_lpm_trie(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { + switch_lpm_trie_t *lpm_trie = NULL; + void *temp = NULL; + switch_l3_hash_t *hash_entry; + char *prefix; + uint32_t v4addr; + + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + JLG(temp, switch_vrf_v4_lpm_tries, vrf); + v4addr = htonl(ip_addr->ip.v4addr); + prefix = (char *)(&v4addr); + } else { + JLG(temp, switch_vrf_v6_lpm_tries, vrf); + prefix = (char *)(ip_addr->ip.v6addr); + } + + if (!temp) { + SWITCH_API_ERROR( + "%s:%d: No LPM trie for this vrf %u!", __FUNCTION__, __LINE__, vrf); + return NULL; + } + + lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp); + if (switch_lpm_trie_lookup(lpm_trie, prefix, (unsigned long *)(&hash_entry))) return hash_entry; -} -switch_status_t -switch_api_l3_interface_address_add(switch_device_t device, - switch_handle_t interface_handle, - switch_handle_t vrf_handle, - switch_ip_addr_t *ip_addr) -{ - switch_interface_info_t *info = NULL; - switch_ip_addr_info_t *ip_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - UNUSED(device); - info = switch_api_interface_get(interface_handle); - if (!info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + SWITCH_API_ERROR("%s: hash_entry not found.\n", __FUNCTION__); + return NULL; +} - ip_info = switch_malloc(sizeof(switch_ip_addr_info_t), 1); - if (!ip_info) { - return SWITCH_STATUS_NO_MEMORY; +static switch_l3_hash_t *switch_l3_insert_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t interface) { + switch_l3_hash_t *hash_entry = NULL; + unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); + hash_entry = switch_malloc(sizeof(switch_l3_hash_t), 1); + if (!hash_entry) { + return NULL; + } + memcpy(hash_entry->key, key, SWITCH_L3_HASH_KEY_SIZE); + hash_entry->path_count = 1; + + if (!switch_l3_host_entry(ip_addr)) { + status = switch_l3_insert_into_lpm_trie(vrf, ip_addr, hash_entry); + if (status != SWITCH_STATUS_SUCCESS) { + switch_free(hash_entry); + return NULL; } + } - ip_info->vrf_handle = vrf_handle; - ip_info->default_ip = TRUE; - ip_info->ip = *ip_addr; + tommy_hashtable_insert( + &switch_l3_hash_table, &(hash_entry->node), hash_entry, hash); + switch_l3_insert_into_vrf_list(hash_entry); + return hash_entry; +} - // append to list and increment member count - tommy_list_insert_head(&(info->ip_addr), &(ip_info->node), ip_info); - info->ip_addr_count++; +static inline int switch_l3_hash_cmp(const void *key1, const void *key2) { + return memcmp(key1, key2, SWITCH_L3_HASH_KEY_SIZE); +} - return status; +static switch_status_t switch_l3_delete_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { + switch_l3_hash_t *hash_entry = NULL; + unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!switch_l3_host_entry(ip_addr)) { + switch_l3_remove_from_lpm_trie(vrf, ip_addr); + } + + switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); + hash_entry = tommy_hashtable_remove( + &switch_l3_hash_table, switch_l3_hash_cmp, key, hash); + switch_l3_remove_from_vrf_list(hash_entry); + switch_free(hash_entry); + return status; } -switch_status_t -switch_api_l3_interface_address_delete(switch_device_t device, - switch_handle_t interface_handle, - switch_handle_t vrf_handle, - switch_ip_addr_t *ip_addr) -{ - switch_interface_info_t *info = NULL; - switch_ip_addr_info_t *ip_info = NULL; - tommy_node *node = NULL; - - UNUSED(device); - UNUSED(vrf_handle); - info = switch_api_interface_get(interface_handle); - if (!info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - // delete from list and decrement member count - node = tommy_list_head(&(info->ip_addr)); - while(node) { - ip_info = node->data; - if (SWITCH_L3_IP_TYPE(ip_info) == ip_addr->type && - SWITCH_L3_IP_IPV4_ADDRESS(ip_info) == ip_addr->ip.v4addr) { - break; - } - node = node->next; - } +static switch_l3_hash_t *switch_l3_search_hash(switch_handle_t vrf, + switch_ip_addr_t *ip_addr) { + unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; - if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } + switch_l3_hash_key_init(key, vrf, ip_addr, &len, &hash); + switch_l3_hash_t *hash_entry = tommy_hashtable_search( + &switch_l3_hash_table, switch_l3_hash_cmp, key, hash); + return hash_entry; +} - // remove from list - ip_info = tommy_list_remove_existing(&(info->ip_addr), node); - info->ip_addr_count--; +switch_status_t switch_api_l3_route_lookup(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t *nhop_handle) { + switch_l3_hash_t *hash_entry = NULL; + switch_nhop_info_t *nhop_info = NULL; - switch_free(ip_info); - return SWITCH_STATUS_SUCCESS; + if (switch_l3_host_entry(ip_addr)) { + // host entry, first search hash + hash_entry = switch_l3_search_hash(vrf, ip_addr); + } + + if (!hash_entry) { + // try LPM lookup + hash_entry = switch_l3_lookup_lpm_trie(vrf, ip_addr); + } + + if (!hash_entry) { + *nhop_handle = SWITCH_API_INVALID_HANDLE; + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + nhop_info = switch_nhop_get(hash_entry->nhop_handle); + if (!nhop_info) { + SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__); + *nhop_handle = SWITCH_API_INVALID_HANDLE; + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + *nhop_handle = hash_entry->nhop_handle; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_l3_route_add(switch_device_t device, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, switch_handle_t nhop_handle) -{ - switch_l3_hash_t *hash_entry = NULL; - switch_nhop_info_t *nhop_info = NULL; - uint32_t nhop_index = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - unsigned int v4_mask = 0; - uint8_t v6_mask[16]; - switch_ip_addr_t masked_ip; +switch_status_t switch_api_l3_route_nhop_intf_get( + switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t *intf_handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_handle_t nhop_handle = SWITCH_API_INVALID_HANDLE; + switch_status_t status; + + *intf_handle = SWITCH_API_INVALID_HANDLE; + + status = switch_api_l3_route_lookup(device, vrf, ip_addr, &nhop_handle); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + if (!spath_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + // additional check if intf_handle is valid + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + *intf_handle = spath_info->nhop_key.intf_handle; + return SWITCH_STATUS_SUCCESS; +} - if (!SWITCH_VRF_HANDLE_VALID(vrf)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_api_l3_interface_address_add( + switch_device_t device, + switch_handle_t interface_handle, + switch_handle_t vrf_handle, + switch_ip_addr_t *ip_addr) { + switch_interface_info_t *info = NULL; + switch_ip_addr_info_t *ip_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + UNUSED(device); + info = switch_api_interface_get(interface_handle); + if (!info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + ip_info = switch_malloc(sizeof(switch_ip_addr_info_t), 1); + if (!ip_info) { + return SWITCH_STATUS_NO_MEMORY; + } + + ip_info->vrf_handle = vrf_handle; + ip_info->default_ip = TRUE; + ip_info->ip = *ip_addr; + + // append to list and increment member count + tommy_list_insert_head(&(info->ip_addr), &(ip_info->node), ip_info); + info->ip_addr_count++; + + return status; +} - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_api_l3_interface_address_delete( + switch_device_t device, + switch_handle_t interface_handle, + switch_handle_t vrf_handle, + switch_ip_addr_t *ip_addr) { + switch_interface_info_t *info = NULL; + switch_ip_addr_info_t *ip_info = NULL; + tommy_node *node = NULL; + + UNUSED(device); + UNUSED(vrf_handle); + info = switch_api_interface_get(interface_handle); + if (!info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + // delete from list and decrement member count + node = tommy_list_head(&(info->ip_addr)); + while (node) { + ip_info = node->data; + if (SWITCH_L3_IP_TYPE(ip_info) == ip_addr->type && + SWITCH_L3_IP_IPV4_ADDRESS(ip_info) == ip_addr->ip.v4addr) { + break; + } + node = node->next; + } + + if (!node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + // remove from list + ip_info = tommy_list_remove_existing(&(info->ip_addr), node); + info->ip_addr_count--; + + switch_free(ip_info); + return SWITCH_STATUS_SUCCESS; +} - nhop_index = handle_to_id(nhop_handle); - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_ITEM_NOT_FOUND; +switch_status_t switch_api_l3_route_add(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t nhop_handle) { + switch_l3_hash_t *hash_entry = NULL; + switch_nhop_info_t *nhop_info = NULL; + uint32_t nhop_index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + unsigned int v4_mask = 0; + uint8_t v6_mask[16]; + switch_ip_addr_t masked_ip; + + if (!SWITCH_VRF_HANDLE_VALID(vrf)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + nhop_index = handle_to_id(nhop_handle); + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + hash_entry = switch_l3_search_hash(vrf, ip_addr); + if (hash_entry) { + hash_entry->nhop_handle = nhop_handle; +#ifdef SWITCH_PD + status = switch_pd_ip_fib_update_entry(device, + handle_to_id(vrf), + ip_addr, + SWITCH_NHOP_TYPE_IS_ECMP(nhop_info), + nhop_index, + hash_entry->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } - hash_entry = switch_l3_search_hash(vrf, ip_addr); - if (hash_entry) { -#ifdef SWITCH_PD - status = switch_pd_ip_fib_update_entry(device, handle_to_id(vrf), - ip_addr, - SWITCH_NHOP_TYPE_IS_ECMP(nhop_info), - nhop_index, - hash_entry->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - - status = switch_pd_urpf_update_entry(device, handle_to_id(vrf), - ip_addr, handle_to_id(nhop_handle), - hash_entry->urpf_entry); + status = switch_pd_urpf_update_entry(device, + handle_to_id(vrf), + ip_addr, + handle_to_id(nhop_handle), + hash_entry->urpf_entry); #endif + } else { + memcpy(&masked_ip, ip_addr, sizeof(switch_ip_addr_t)); + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + v4_mask = prefix_to_v4_mask(ip_addr->prefix_len); + masked_ip.ip.v4addr = ip_addr->ip.v4addr & v4_mask; } else { - memcpy(&masked_ip, ip_addr, sizeof(switch_ip_addr_t)); - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { - v4_mask = prefix_to_v4_mask(ip_addr->prefix_len); - masked_ip.ip.v4addr = ip_addr->ip.v4addr & v4_mask; - } else { - int i = 0; - prefix_to_v6_mask(ip_addr->prefix_len, v6_mask); - for (i = 0; i < 16; i++) { - masked_ip.ip.v6addr[i] = ip_addr->ip.v6addr[i] & v6_mask[i]; - } - } - hash_entry = switch_l3_insert_hash(vrf, ip_addr, nhop_handle); - if (!hash_entry) { - return SWITCH_STATUS_NO_MEMORY; - } - hash_entry->nhop_handle = nhop_handle; -#ifdef SWITCH_PD - // set the HW entry - status = switch_pd_ip_fib_add_entry(device, handle_to_id(vrf), - ip_addr, - SWITCH_NHOP_TYPE_IS_ECMP(nhop_info), - nhop_index, - &hash_entry->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - - status = switch_pd_urpf_add_entry(device, handle_to_id(vrf), - ip_addr, handle_to_id(nhop_handle), - &hash_entry->urpf_entry); -#endif + int i = 0; + prefix_to_v6_mask(ip_addr->prefix_len, v6_mask); + for (i = 0; i < 16; i++) { + masked_ip.ip.v6addr[i] = ip_addr->ip.v6addr[i] & v6_mask[i]; + } } - return status; -} - -switch_status_t -switch_api_l3_route_delete(switch_device_t device, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, switch_handle_t nhop_handle) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_l3_hash_t *hash_entry = NULL; - - if (!SWITCH_VRF_HANDLE_VALID(vrf)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - UNUSED(nhop_handle); - hash_entry = switch_l3_search_hash(vrf, ip_addr); + hash_entry = switch_l3_insert_hash(vrf, ip_addr, nhop_handle); if (!hash_entry) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + return SWITCH_STATUS_NO_MEMORY; } + hash_entry->nhop_handle = nhop_handle; #ifdef SWITCH_PD - status = switch_pd_ip_fib_delete_entry(device, ip_addr, hash_entry->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - status = switch_pd_urpf_delete_entry(device, handle_to_id(vrf), - ip_addr, - hash_entry->urpf_entry); + // set the HW entry + status = switch_pd_ip_fib_add_entry(device, + handle_to_id(vrf), + ip_addr, + SWITCH_NHOP_TYPE_IS_ECMP(nhop_info), + nhop_index, + &hash_entry->hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - return status; + return status; } + + status = switch_pd_urpf_add_entry(device, + handle_to_id(vrf), + ip_addr, + handle_to_id(nhop_handle), + &hash_entry->urpf_entry); #endif - status = switch_l3_delete_hash(vrf, ip_addr); - return status; + } + return status; } -switch_status_t -switch_api_l3_v4_route_entries_get_by_vrf(switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn) -{ - switch_l3_hash_t *hash_entry = NULL; - tommy_node *node = NULL; - switch_vrf_route_list_t *vrf_route_list = NULL; - void *temp = NULL; - switch_ip_addr_t ip_addr; +switch_status_t switch_api_l3_route_delete(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_handle_t nhop_handle) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_l3_hash_t *hash_entry = NULL; + + if (!SWITCH_VRF_HANDLE_VALID(vrf)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + UNUSED(nhop_handle); + hash_entry = switch_l3_search_hash(vrf, ip_addr); + if (!hash_entry) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } +#ifdef SWITCH_PD + status = switch_pd_ip_fib_delete_entry(device, ip_addr, hash_entry->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + status = switch_pd_urpf_delete_entry( + device, handle_to_id(vrf), ip_addr, hash_entry->urpf_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } +#endif + status = switch_l3_delete_hash(vrf, ip_addr); + return status; +} - JLG(temp, switch_vrf_v4_routes, vrf_handle); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - vrf_route_list = (switch_vrf_route_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(vrf_route_list->routes)); - while (node) { - hash_entry = node->data; - switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); - iterator_fn(vrf_handle, ip_addr, hash_entry->nhop_handle); - node = node->next; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_l3_v4_route_entries_get_by_vrf( + switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn) { + switch_l3_hash_t *hash_entry = NULL; + tommy_node *node = NULL; + switch_vrf_route_list_t *vrf_route_list = NULL; + void *temp = NULL; + switch_ip_addr_t ip_addr; + + JLG(temp, switch_vrf_v4_routes, vrf_handle); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(vrf_route_list->routes)); + while (node) { + hash_entry = node->data; + switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + iterator_fn(vrf_handle, ip_addr, hash_entry->nhop_handle); + node = node->next; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_l3_v6_route_entries_get_by_vrf(switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn) -{ - switch_l3_hash_t *hash_entry = NULL; - tommy_node *node = NULL; - switch_vrf_route_list_t *vrf_route_list = NULL; - void *temp = NULL; - switch_ip_addr_t ip_addr; +switch_status_t switch_api_l3_v6_route_entries_get_by_vrf( + switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn) { + switch_l3_hash_t *hash_entry = NULL; + tommy_node *node = NULL; + switch_vrf_route_list_t *vrf_route_list = NULL; + void *temp = NULL; + switch_ip_addr_t ip_addr; + + JLG(temp, switch_vrf_v6_routes, vrf_handle); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(vrf_route_list->routes)); + while (node) { + hash_entry = node->data; + switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + iterator_fn(vrf_handle, ip_addr, hash_entry->nhop_handle); + node = node->next; + } + return SWITCH_STATUS_SUCCESS; +} - JLG(temp, switch_vrf_v6_routes, vrf_handle); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - vrf_route_list = (switch_vrf_route_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(vrf_route_list->routes)); - while (node) { - hash_entry = node->data; - switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); - iterator_fn(vrf_handle, ip_addr, hash_entry->nhop_handle); - node = node->next; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_l3_route_entries_get_by_vrf( + switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + status = switch_api_l3_v4_route_entries_get_by_vrf(vrf_handle, iterator_fn); + status = switch_api_l3_v6_route_entries_get_by_vrf(vrf_handle, iterator_fn); + return status; } -switch_status_t -switch_api_l3_route_entries_get_by_vrf(switch_handle_t vrf_handle, switch_l3_table_iterator_fn iterator_fn) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_l3_route_entries_get( + switch_l3_table_iterator_fn iterator_fn) { + void *temp = NULL; + switch_handle_t vrf_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + JLF(temp, switch_vrf_v4_routes, vrf_handle); + while (temp) { status = switch_api_l3_v4_route_entries_get_by_vrf(vrf_handle, iterator_fn); + JLN(temp, switch_vrf_v4_routes, vrf_handle); + } + vrf_handle = 0; + JLF(temp, switch_vrf_v6_routes, vrf_handle); + while (temp) { status = switch_api_l3_v6_route_entries_get_by_vrf(vrf_handle, iterator_fn); - return status; + JLN(temp, switch_vrf_v6_routes, vrf_handle); + } + return status; } -switch_status_t -switch_api_l3_route_entries_get(switch_l3_table_iterator_fn iterator_fn) -{ - void *temp = NULL; - switch_handle_t vrf_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - JLF(temp, switch_vrf_v4_routes, vrf_handle); - while (temp) { - status = switch_api_l3_v4_route_entries_get_by_vrf(vrf_handle, iterator_fn); - JLN(temp, switch_vrf_v4_routes, vrf_handle); - } - vrf_handle = 0; - JLF(temp, switch_vrf_v6_routes, vrf_handle); - while (temp) { - status = switch_api_l3_v6_route_entries_get_by_vrf(vrf_handle, iterator_fn); - JLN(temp, switch_vrf_v6_routes, vrf_handle); - } - return status; +switch_status_t switch_api_l3_v4_routes_print_by_vrf( + switch_handle_t vrf_handle) { + switch_l3_hash_t *hash_entry = NULL; + tommy_node *node = NULL; + switch_vrf_route_list_t *vrf_route_list = NULL; + void *temp = NULL; + switch_ip_addr_t ip_addr; + + JLG(temp, switch_vrf_v4_routes, vrf_handle); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(vrf_route_list->routes)); + while (node) { + hash_entry = node->data; + switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + printf("\nvrf_handle %x ip %x -> nhop %x", + (unsigned int)vrf_handle, + ip_addr.ip.v4addr, + (unsigned int)hash_entry->nhop_handle); + node = node->next; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_l3_v4_routes_print_by_vrf(switch_handle_t vrf_handle) -{ - switch_l3_hash_t *hash_entry = NULL; - tommy_node *node = NULL; - switch_vrf_route_list_t *vrf_route_list = NULL; - void *temp = NULL; - switch_ip_addr_t ip_addr; - - JLG(temp, switch_vrf_v4_routes, vrf_handle); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - vrf_route_list = (switch_vrf_route_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(vrf_route_list->routes)); - while (node) { - hash_entry = node->data; - switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); - printf("\nvrf_handle %x ip %x -> nhop %x", - (unsigned int) vrf_handle, ip_addr.ip.v4addr, - (unsigned int) hash_entry->nhop_handle); - node = node->next; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_l3_v6_routes_print_by_vrf( + switch_handle_t vrf_handle) { + switch_l3_hash_t *hash_entry = NULL; + tommy_node *node = NULL; + switch_vrf_route_list_t *vrf_route_list = NULL; + void *temp = NULL; + switch_ip_addr_t ip_addr; + char v6_addr[INET6_ADDRSTRLEN]; + + JLG(temp, switch_vrf_v6_routes, vrf_handle); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); + node = tommy_list_head(&(vrf_route_list->routes)); + while (node) { + hash_entry = node->data; + switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); + inet_ntop(AF_INET6, ip_addr.ip.v6addr, v6_addr, INET6_ADDRSTRLEN); + printf("\nvrf_handle %x ip %s -> nhop %x", + (unsigned int)vrf_handle, + v6_addr, + (unsigned int)hash_entry->nhop_handle); + node = node->next; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_l3_v6_routes_print_by_vrf(switch_handle_t vrf_handle) -{ - switch_l3_hash_t *hash_entry = NULL; - tommy_node *node = NULL; - switch_vrf_route_list_t *vrf_route_list = NULL; - void *temp = NULL; - switch_ip_addr_t ip_addr; - char v6_addr[INET6_ADDRSTRLEN]; - - JLG(temp, switch_vrf_v6_routes, vrf_handle); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - vrf_route_list = (switch_vrf_route_list_t *) (*(unsigned long *)temp); - node = tommy_list_head(&(vrf_route_list->routes)); - while (node) { - hash_entry = node->data; - switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); - inet_ntop(AF_INET6, ip_addr.ip.v6addr, v6_addr, INET6_ADDRSTRLEN); - printf("\nvrf_handle %x ip %s -> nhop %x", - (unsigned int) vrf_handle, v6_addr, - (unsigned int) hash_entry->nhop_handle); - node = node->next; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_l3_v4_routes_print_all(void) { + void *temp = NULL; + switch_handle_t vrf_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + JLF(temp, switch_vrf_v4_routes, vrf_handle); + while (temp) { + status = switch_api_l3_v4_routes_print_by_vrf(vrf_handle); + JLN(temp, switch_vrf_v4_routes, vrf_handle); + } + return status; } -switch_status_t -switch_api_l3_v4_routes_print_all(void) -{ - void *temp = NULL; - switch_handle_t vrf_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - JLF(temp, switch_vrf_v4_routes, vrf_handle); - while (temp) { - status = switch_api_l3_v4_routes_print_by_vrf(vrf_handle); - JLN(temp, switch_vrf_v4_routes, vrf_handle); - } - return status; +switch_status_t switch_api_l3_v6_routes_print_all(void) { + switch_handle_t vrf_handle = 0; + void *temp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + JLF(temp, switch_vrf_v6_routes, vrf_handle); + while (temp) { + status = switch_api_l3_v6_routes_print_by_vrf(vrf_handle); + JLN(temp, switch_vrf_v6_routes, vrf_handle); + } + return status; } -switch_status_t -switch_api_l3_v6_routes_print_all(void) -{ - switch_handle_t vrf_handle = 0; - void *temp = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - JLF(temp, switch_vrf_v6_routes, vrf_handle); - while (temp) { - status = switch_api_l3_v6_routes_print_by_vrf(vrf_handle); - JLN(temp, switch_vrf_v6_routes, vrf_handle); - } - return status; +switch_status_t switch_api_l3_routes_print_all(void) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + status = switch_api_l3_v4_routes_print_all(); + status = switch_api_l3_v6_routes_print_all(); + return status; } -switch_status_t -switch_api_l3_routes_print_all(void) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - status = switch_api_l3_v4_routes_print_all(); - status = switch_api_l3_v6_routes_print_all(); - return status; +switch_status_t switch_api_init_default_route_entries( + switch_device_t device, switch_handle_t vrf_handle) { + switch_handle_t drop_nhop_handle; + switch_ip_addr_t ip_addr; + switch_status_t ret; + + drop_nhop_handle = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_NULL_DROP); + + // 127/8, drop + memset(&ip_addr, 0, sizeof(ip_addr)); + ip_addr.type = SWITCH_API_IP_ADDR_V4; + ip_addr.ip.v4addr = 0x7f000000; + ip_addr.prefix_len = 8; + ret = switch_api_l3_route_add(device, vrf_handle, &ip_addr, drop_nhop_handle); + assert(ret == SWITCH_STATUS_SUCCESS); + + // ::1/128, drop + memset(&ip_addr, 0, sizeof(ip_addr)); + ip_addr.type = SWITCH_API_IP_ADDR_V6; + ip_addr.ip.v6addr[15] = 1; + ip_addr.prefix_len = 128; + ret = switch_api_l3_route_add(device, vrf_handle, &ip_addr, drop_nhop_handle); + assert(ret == SWITCH_STATUS_SUCCESS); + + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_init_default_route_entries(switch_device_t device, - switch_handle_t vrf_handle) -{ - switch_handle_t drop_nhop_handle; - switch_ip_addr_t ip_addr; - switch_status_t ret; - - drop_nhop_handle = - switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_NULL_DROP); - - // 127/8, drop - memset(&ip_addr, 0, sizeof(ip_addr)); - ip_addr.type = SWITCH_API_IP_ADDR_V4; - ip_addr.ip.v4addr = 0x7f000000; - ip_addr.prefix_len = 8; - ret = switch_api_l3_route_add(device, vrf_handle, &ip_addr, - drop_nhop_handle); - assert(ret == SWITCH_STATUS_SUCCESS); - - // ::1/128, drop - memset(&ip_addr, 0, sizeof(ip_addr)); - ip_addr.type = SWITCH_API_IP_ADDR_V6; - ip_addr.ip.v6addr[15] = 1; - ip_addr.prefix_len = 128; - ret = switch_api_l3_route_add(device, vrf_handle, &ip_addr, - drop_nhop_handle); - assert(ret == SWITCH_STATUS_SUCCESS); - - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_mtu_create_entry(switch_device_t device, + uint16_t mtu_index, + uint32_t mtu) { + return switch_pd_mtu_table_add_ipv4_check(device, mtu_index, mtu); } #ifdef __cplusplus diff --git a/switchapi/src/switch_l3_int.h b/switchapi/src/switch_l3_int.h index 00e514a..03e0092 100644 --- a/switchapi/src/switch_l3_int.h +++ b/switchapi/src/switch_l3_int.h @@ -24,64 +24,60 @@ limitations under the License. extern "C" { #endif /* __cplusplus */ -#define SWITCH_L3_HASH_TABLE_SIZE (64*1024) +#define SWITCH_L3_HASH_TABLE_SIZE (64 * 1024) #define SWITCH_L3_HASH_KEY_SIZE 24 #define SWITCH_IPV4_PREFIX_LENGTH 32 #define SWITCH_IPV6_PREFIX_LENGTH 128 -#define SWITCH_IP_TYPE_NONE 0 -#define SWITCH_IP_TYPE_IPv4 1 -#define SWITCH_IP_TYPE_IPv6 2 +#define SWITCH_IP_TYPE_NONE 0 +#define SWITCH_IP_TYPE_IPv4 1 +#define SWITCH_IP_TYPE_IPv6 2 typedef struct switch_ip_addr_info_ { - tommy_node node; - bool default_ip; - switch_ip_addr_t ip; - switch_handle_t vrf_handle; + tommy_node node; + bool default_ip; + switch_ip_addr_t ip; + switch_handle_t vrf_handle; } switch_ip_addr_info_t; typedef struct switch_l3_hash_ { - unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; - switch_handle_t nhop_handle; - tommy_hashtable_node node; - tommy_node vrf_route_node; - unsigned int path_count; + unsigned char key[SWITCH_L3_HASH_KEY_SIZE]; + switch_handle_t nhop_handle; + tommy_hashtable_node node; + tommy_node vrf_route_node; + unsigned int path_count; #ifdef SWITCH_PD - p4_pd_entry_hdl_t hw_entry; - p4_pd_entry_hdl_t urpf_entry; + p4_pd_entry_hdl_t hw_entry; + p4_pd_entry_hdl_t urpf_entry; #endif } switch_l3_hash_t; typedef struct switch_urpf_member_info_ { - tommy_node node; - switch_handle_t intf_handle; - p4_pd_entry_hdl_t hw_entry; + tommy_node node; + switch_handle_t intf_handle; + p4_pd_entry_hdl_t hw_entry; } switch_urpf_member_info_t; typedef struct switch_urpg_group_info_ { - tommy_list urpf_member_list; + tommy_list urpf_member_list; } switch_urpf_group_info_t; typedef struct switch_vrf_route_list_ { - tommy_list routes; - uint32_t num_entries; + tommy_list routes; + uint32_t num_entries; } switch_vrf_route_list_t; -#define SWITCH_L3_IP_TYPE(ip_info) \ - ip_info->ip.type +#define SWITCH_L3_IP_TYPE(ip_info) ip_info->ip.type -#define SWITCH_L3_IP_IPV4_ADDRESS(ip_info) \ - ip_info->ip.ip.v4addr +#define SWITCH_L3_IP_IPV4_ADDRESS(ip_info) ip_info->ip.ip.v4addr -#define SWITCH_L3_IP_IPV6_ADDRESS(ip_info) \ - ip_info->ip.ip.v6addr +#define SWITCH_L3_IP_IPV6_ADDRESS(ip_info) ip_info->ip.ip.v6addr switch_status_t switch_l3_init(switch_device_t device); switch_status_t switch_l3_free(switch_device_t device); -switch_status_t -switch_api_init_default_route_entries(switch_device_t device, - switch_handle_t vrf_handle); +switch_status_t switch_api_init_default_route_entries( + switch_device_t device, switch_handle_t vrf_handle); #ifdef __cplusplus } diff --git a/switchapi/src/switch_lag.c b/switchapi/src/switch_lag.c index 12defaf..9e83050 100644 --- a/switchapi/src/switch_lag.c +++ b/switchapi/src/switch_lag.c @@ -32,486 +32,449 @@ static switch_api_id_allocator *lag_select; #define SWITCH_INITIAL_LAG_SIZE 16 -switch_status_t -switch_lag_init(switch_device_t device) -{ - UNUSED(device); - switch_lag_array = NULL; - lag_select = switch_api_id_allocator_new(64 * 1024/ 32, FALSE); - switch_handle_type_init(SWITCH_HANDLE_TYPE_LAG, (1*1024)); - switch_handle_type_init(SWITCH_HANDLE_TYPE_LAG_MEMBER, (1*1024)); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_lag_init(switch_device_t device) { + UNUSED(device); + switch_lag_array = NULL; + lag_select = switch_api_id_allocator_new(64 * 1024 / 32, FALSE); + switch_handle_type_init(SWITCH_HANDLE_TYPE_LAG, (1 * 1024)); + switch_handle_type_init(SWITCH_HANDLE_TYPE_LAG_MEMBER, (1 * 1024)); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_lag_free(switch_device_t device) -{ - UNUSED(device); - switch_handle_type_free(SWITCH_HANDLE_TYPE_LAG); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_lag_free(switch_device_t device) { + UNUSED(device); + switch_handle_type_free(SWITCH_HANDLE_TYPE_LAG); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_lag_handle_create() -{ - switch_handle_t lag_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_LAG, switch_lag_info_t, - switch_lag_array, &info, lag_handle); - return lag_handle; +switch_handle_t switch_lag_handle_create() { + switch_handle_t lag_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_LAG, + switch_lag_info_t, + switch_lag_array, + &info, + lag_handle); + return lag_handle; } -switch_status_t -switch_lag_handle_delete(switch_handle_t lag_handle) -{ - _switch_handle_delete(switch_lag_info_t, switch_lag_array, lag_handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_lag_handle_delete(switch_handle_t lag_handle) { + _switch_handle_delete(switch_lag_info_t, switch_lag_array, lag_handle); + return SWITCH_STATUS_SUCCESS; } -switch_lag_info_t * -switch_api_lag_get_internal(switch_handle_t lag_handle) -{ - switch_lag_info_t *lag_info = NULL; - _switch_handle_get(switch_lag_info_t, switch_lag_array, lag_handle, lag_info); - return lag_info; +switch_lag_info_t *switch_api_lag_get_internal(switch_handle_t lag_handle) { + switch_lag_info_t *lag_info = NULL; + _switch_handle_get(switch_lag_info_t, switch_lag_array, lag_handle, lag_info); + return lag_info; } -switch_handle_t -switch_lag_member_handle_create() -{ - switch_handle_t lag_member_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_LAG_MEMBER, - switch_lag_member_t, - switch_lag_member_array, - &info, - lag_member_handle); - return lag_member_handle; +switch_handle_t switch_lag_member_handle_create() { + switch_handle_t lag_member_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_LAG_MEMBER, + switch_lag_member_t, + switch_lag_member_array, + &info, + lag_member_handle); + return lag_member_handle; } -switch_status_t -switch_lag_member_handle_delete(switch_handle_t lag_member_handle) -{ - _switch_handle_delete(switch_lag_member_t, - switch_lag_member_array, - lag_member_handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_lag_member_handle_delete( + switch_handle_t lag_member_handle) { + _switch_handle_delete( + switch_lag_member_t, switch_lag_member_array, lag_member_handle); + return SWITCH_STATUS_SUCCESS; } -switch_lag_member_t * -switch_api_lag_member_get_internal(switch_handle_t lag_member_handle) -{ - switch_lag_member_t *lag_member = NULL; - _switch_handle_get(switch_lag_member_t, - switch_lag_member_array, - lag_member_handle, - lag_member); - return lag_member; +switch_lag_member_t *switch_api_lag_member_get_internal( + switch_handle_t lag_member_handle) { + switch_lag_member_t *lag_member = NULL; + _switch_handle_get(switch_lag_member_t, + switch_lag_member_array, + lag_member_handle, + lag_member); + return lag_member; } -switch_handle_t -switch_api_lag_create(switch_device_t device) -{ - switch_handle_t lag_handle; - switch_lag_info_t *lag_info = NULL; - - lag_handle = switch_lag_handle_create(); - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - return SWITCH_API_INVALID_HANDLE; - } - - memset(lag_info, 0, sizeof(switch_lag_info_t)); - lag_info->lacp = FALSE; - lag_info->type = SWITCH_API_LAG_SIMPLE; - lag_info->ifindex = SWITCH_LAG_COMPUTE_IFINDEX(lag_handle); - tommy_list_init(&(lag_info->ingress)); - tommy_list_init(&(lag_info->egress)); +switch_handle_t switch_api_lag_create(switch_device_t device) { + switch_handle_t lag_handle; + switch_lag_info_t *lag_info = NULL; + + lag_handle = switch_lag_handle_create(); + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + return SWITCH_API_INVALID_HANDLE; + } + + memset(lag_info, 0, sizeof(switch_lag_info_t)); + lag_info->lacp = FALSE; + lag_info->type = SWITCH_API_LAG_SIMPLE; + lag_info->ifindex = SWITCH_LAG_COMPUTE_IFINDEX(lag_handle); + tommy_list_init(&(lag_info->ingress)); + tommy_list_init(&(lag_info->egress)); #ifdef SWITCH_PD - if(switch_pd_lag_group_create(device, &(lag_info->pd_group_hdl)) != 0) { - // Need to check for error - return SWITCH_API_INVALID_HANDLE; - } - lag_info->device = device; + if (switch_pd_lag_group_create(device, &(lag_info->pd_group_hdl)) != 0) { + // Need to check for error + return SWITCH_API_INVALID_HANDLE; + } + lag_info->device = device; #endif - return lag_handle; + return lag_handle; } -switch_status_t -switch_api_lag_delete(switch_device_t device, switch_handle_t lag_handle) -{ - switch_lag_info_t *lag_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_lag_delete(switch_device_t device, + switch_handle_t lag_handle) { + switch_lag_info_t *lag_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } #ifdef SWITCH_PD - status = switch_pd_lag_group_delete(lag_info->device, lag_info->pd_group_hdl); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + status = switch_pd_lag_group_delete(lag_info->device, lag_info->pd_group_hdl); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } #endif - if (lag_info->egr_bmap) { - switch_api_id_allocator_destroy(lag_info->egr_bmap); - } - switch_lag_handle_delete(lag_handle); - return SWITCH_STATUS_SUCCESS; + if (lag_info->egr_bmap) { + switch_api_id_allocator_destroy(lag_info->egr_bmap); + } + switch_lag_handle_delete(lag_handle); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_lag_member_add(switch_device_t device, switch_handle_t lag_handle, - switch_direction_t direction, switch_port_t port) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_lag_info_t *lag_info = NULL; - switch_lag_member_t *lag_member = NULL; - switch_handle_t lag_member_handle = 0; - switch_port_info_t *port_info = NULL; - - if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - +switch_status_t switch_api_lag_member_add(switch_device_t device, + switch_handle_t lag_handle, + switch_direction_t direction, + switch_port_t port) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_lag_info_t *lag_info = NULL; + switch_lag_member_t *lag_member = NULL; + switch_handle_t lag_member_handle = 0; + switch_port_info_t *port_info = NULL; + + if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (!lag_info->egr_bmap) { + lag_info->egr_bmap = + switch_api_id_allocator_new(SWITCH_INITIAL_LAG_SIZE, FALSE); if (!lag_info->egr_bmap) { - lag_info->egr_bmap = switch_api_id_allocator_new(SWITCH_INITIAL_LAG_SIZE, FALSE); - if (!lag_info->egr_bmap) { - return SWITCH_STATUS_NO_MEMORY; - } - } - - lag_member_handle = switch_lag_member_handle_create(); - lag_member = switch_api_lag_member_get_internal(lag_member_handle); - if (!lag_member) { - return SWITCH_STATUS_NO_MEMORY; + return SWITCH_STATUS_NO_MEMORY; } - - lag_member->index = switch_api_id_allocator_allocate(lag_info->egr_bmap); - lag_member->port = port; - lag_member->lag_member_handle = lag_member_handle; - lag_member->lag_handle = lag_handle; - lag_member->direction = direction; - - switch (direction) { - case SWITCH_API_DIRECTION_BOTH: - case SWITCH_API_DIRECTION_EGRESS: - tommy_list_insert_head(&lag_info->egress, - &(lag_member->egress_node), - lag_member); - port_info = switch_api_port_get_internal(port); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - status = switch_pd_lag_member_add(device, lag_info->pd_group_hdl, - SWITCH_PORT_ID(port_info), - &(lag_member->mbr_hdl)); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - if (lag_info->count == 0) { - status = switch_pd_lag_group_table_add_entry_with_selector(device, - lag_info->ifindex, - lag_info->pd_group_hdl, - &lag_info->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } - lag_info->count++; - // Update lag table in pre - status = switch_multicast_update_lag_port_map(device, lag_handle); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - - port_info = switch_api_port_get_internal(port); - status = switch_pd_egress_port_mapping_table_add_entry( - device, - port, - lag_info->ifindex, - port_info->port_type, - &port_info->eg_port_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("failed to add egress port mapping entry"); - return status; - } - if (direction == SWITCH_API_DIRECTION_EGRESS) - break; - case SWITCH_API_DIRECTION_INGRESS: - tommy_list_insert_head(&lag_info->ingress, - &(lag_member->ingress_node), - lag_member); - // lookup port table - port_info = switch_api_port_get_internal(port); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - status = switch_pd_ingress_port_mapping_table_add_entry(device, port, - lag_info->ifindex, - port_info->port_type, - port_info->hw_entry); - port_info->lag_handle = lag_handle; - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - break; - default: - break; - } - return status; -} - -switch_status_t -switch_api_lag_member_delete(switch_device_t device, switch_handle_t lag_handle, - switch_direction_t direction, switch_port_t port) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_lag_info_t *lag_info = NULL; - switch_lag_member_t *lag_member = NULL; - tommy_node *delete_node = NULL; - switch_port_info_t *port_info = NULL; - - if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - switch (direction) { - case SWITCH_API_DIRECTION_BOTH: - case SWITCH_API_DIRECTION_EGRESS: - delete_node = tommy_list_head(&(lag_info->egress)); - while (delete_node) { - lag_member = delete_node->data; - if (lag_member->port == port) { - break; - } - delete_node = delete_node->next; - } - if (!delete_node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - if(lag_info->count == 1) { - status = switch_pd_lag_group_table_delete_entry(device, lag_info->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } - status = switch_pd_lag_member_delete(device, lag_info->pd_group_hdl, lag_member->mbr_hdl); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - lag_member = tommy_list_remove_existing(&(lag_info->egress), delete_node); - - //Update the lag table in pre - status = switch_multicast_update_lag_port_map(device, lag_handle); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - lag_info->count--; - - port_info = switch_api_port_get_internal(port); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - status = switch_pd_egress_port_mapping_table_add_entry( - device, - port, - port_info->ifindex, - port_info->port_type, - &port_info->eg_port_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("failed to add egress port mapping entry"); - return status; - } - if (direction == SWITCH_API_DIRECTION_EGRESS) - break; - // else fall through - case SWITCH_API_DIRECTION_INGRESS: - delete_node = tommy_list_head(&(lag_info->ingress)); - while (delete_node) { - lag_member = delete_node->data; - if (lag_member->port == port) { - break; - } - delete_node = delete_node->next; - } - if (!delete_node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - lag_member = tommy_list_remove_existing(&(lag_info->ingress), delete_node); - port_info = switch_api_port_get_internal(port); - if (!port_info) { - return SWITCH_STATUS_INVALID_PORT_NUMBER; - } - //part of lag - status = switch_pd_ingress_port_mapping_table_add_entry(device, port, - port_info->ifindex, - port_info->port_type, - port_info->hw_entry); - port_info->lag_handle = 0; - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - switch_free(lag_member); - break; - default: - break; - } - return status; + } + + lag_member_handle = switch_lag_member_handle_create(); + lag_member = switch_api_lag_member_get_internal(lag_member_handle); + if (!lag_member) { + return SWITCH_STATUS_NO_MEMORY; + } + + lag_member->index = switch_api_id_allocator_allocate(lag_info->egr_bmap); + lag_member->port = port; + lag_member->lag_member_handle = lag_member_handle; + lag_member->lag_handle = lag_handle; + lag_member->direction = direction; + + switch (direction) { + case SWITCH_API_DIRECTION_BOTH: + case SWITCH_API_DIRECTION_EGRESS: + tommy_list_insert_head( + &lag_info->egress, &(lag_member->egress_node), lag_member); + port_info = switch_api_port_get_internal(port); + if (!port_info) { + return SWITCH_STATUS_INVALID_PORT_NUMBER; + } + status = switch_pd_lag_member_add(device, + lag_info->pd_group_hdl, + SWITCH_PORT_ID(port_info), + &(lag_member->mbr_hdl)); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + if (lag_info->count == 0) { + status = switch_pd_lag_group_table_add_entry_with_selector( + device, + lag_info->ifindex, + lag_info->pd_group_hdl, + &lag_info->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + } + lag_info->count++; + // Update lag table in pre + status = switch_multicast_update_lag_port_map(device, lag_handle); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + + port_info = switch_api_port_get_internal(port); + status = switch_pd_egress_port_mapping_table_add_entry( + device, + port, + lag_info->ifindex, + port_info->port_type, + port_info->egress_qos_group, + &port_info->eg_port_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to add egress port mapping entry"); + return status; + } + if (direction == SWITCH_API_DIRECTION_EGRESS) break; + case SWITCH_API_DIRECTION_INGRESS: + tommy_list_insert_head( + &lag_info->ingress, &(lag_member->ingress_node), lag_member); + // lookup port table + port_info = switch_api_port_get_internal(port); + if (!port_info) { + return SWITCH_STATUS_INVALID_PORT_NUMBER; + } + status = switch_pd_ingress_port_mapping_table_add_entry( + device, lag_info->ifindex, port_info); + port_info->lag_handle = lag_handle; + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + break; + default: + break; + } + return status; } -switch_handle_t -switch_api_lag_member_create( - switch_device_t device, - switch_handle_t lag_handle, - switch_direction_t direction, - switch_port_t port) -{ - switch_lag_info_t *lag_info = NULL; - tommy_node *node = NULL; - switch_handle_t lag_member_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_lag_member_t *lag_member = NULL; - - if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - status = switch_api_lag_member_add( - device, - lag_handle, - direction, - port); - - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - if (direction == SWITCH_API_DIRECTION_BOTH || - direction == SWITCH_API_DIRECTION_INGRESS) { - node = tommy_list_head(&(lag_info->ingress)); - } else { - node = tommy_list_head(&(lag_info->egress)); - } - - while (node) { - lag_member = node->data; +switch_status_t switch_api_lag_member_delete(switch_device_t device, + switch_handle_t lag_handle, + switch_direction_t direction, + switch_port_t port) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_lag_info_t *lag_info = NULL; + switch_lag_member_t *lag_member = NULL; + tommy_node *delete_node = NULL; + switch_port_info_t *port_info = NULL; + + if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + switch (direction) { + case SWITCH_API_DIRECTION_BOTH: + case SWITCH_API_DIRECTION_EGRESS: + delete_node = tommy_list_head(&(lag_info->egress)); + while (delete_node) { + lag_member = delete_node->data; if (lag_member->port == port) { - break; + break; } - node = node->next; - } - - if (lag_member) { - lag_member_handle = lag_member->lag_member_handle; - } + delete_node = delete_node->next; + } + if (!delete_node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + if (lag_info->count == 1) { + status = + switch_pd_lag_group_table_delete_entry(device, lag_info->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + } + status = switch_pd_lag_member_delete( + device, lag_info->pd_group_hdl, lag_member->mbr_hdl); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + lag_member = tommy_list_remove_existing(&(lag_info->egress), delete_node); - return lag_member_handle; + // Update the lag table in pre + status = switch_multicast_update_lag_port_map(device, lag_handle); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + lag_info->count--; + + port_info = switch_api_port_get_internal(port); + if (!port_info) { + return SWITCH_STATUS_INVALID_PORT_NUMBER; + } + status = switch_pd_egress_port_mapping_table_add_entry( + device, + port, + port_info->ifindex, + port_info->port_type, + port_info->egress_qos_group, + &port_info->eg_port_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to add egress port mapping entry"); + return status; + } + if (direction == SWITCH_API_DIRECTION_EGRESS) break; + // else fall through + case SWITCH_API_DIRECTION_INGRESS: + delete_node = tommy_list_head(&(lag_info->ingress)); + while (delete_node) { + lag_member = delete_node->data; + if (lag_member->port == port) { + break; + } + delete_node = delete_node->next; + } + if (!delete_node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + lag_member = + tommy_list_remove_existing(&(lag_info->ingress), delete_node); + port_info = switch_api_port_get_internal(port); + if (!port_info) { + return SWITCH_STATUS_INVALID_PORT_NUMBER; + } + // part of lag + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + port_info->lag_handle = 0; + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + switch_free(lag_member); + break; + default: + break; + } + return status; } -switch_status_t -switch_api_lag_member_remove( - switch_device_t device, - switch_handle_t lag_member_handle) -{ - switch_lag_member_t *lag_member = NULL; - switch_lag_info_t *lag_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - lag_member = switch_api_lag_member_get_internal(lag_member_handle); - if (!lag_member) { - return SWITCH_STATUS_INVALID_PARAMETER; - } +switch_handle_t switch_api_lag_member_create(switch_device_t device, + switch_handle_t lag_handle, + switch_direction_t direction, + switch_port_t port) { + switch_lag_info_t *lag_info = NULL; + tommy_node *node = NULL; + switch_handle_t lag_member_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_lag_member_t *lag_member = NULL; + + if (!SWITCH_LAG_HANDLE_VALID(lag_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_api_lag_member_add(device, lag_handle, direction, port); + + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + + if (direction == SWITCH_API_DIRECTION_BOTH || + direction == SWITCH_API_DIRECTION_INGRESS) { + node = tommy_list_head(&(lag_info->ingress)); + } else { + node = tommy_list_head(&(lag_info->egress)); + } - lag_info = switch_api_lag_get_internal(lag_member->lag_handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_PARAMETER; + while (node) { + lag_member = node->data; + if (lag_member->port == port) { + break; } + node = node->next; + } - status = switch_api_lag_member_delete( - device, - lag_member->lag_handle, - lag_member->direction, - lag_member->port); - return status; -} + if (lag_member) { + lag_member_handle = lag_member->lag_member_handle; + } -unsigned int -switch_lag_get_count(switch_handle_t lag_handle) -{ - switch_lag_info_t *info = NULL; - _switch_handle_get(switch_lag_info_t, switch_lag_array, lag_handle, info); - return info->count; + return lag_member_handle; } -switch_status_t -switch_api_lag_print_entry(switch_handle_t lag_handle) -{ - switch_lag_info_t *lag_info = NULL; - switch_lag_member_t *lag_member = NULL; - tommy_node *node = NULL; +switch_status_t switch_api_lag_member_remove( + switch_device_t device, switch_handle_t lag_member_handle) { + switch_lag_member_t *lag_member = NULL; + switch_lag_info_t *lag_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + lag_member = switch_api_lag_member_get_internal(lag_member_handle); + if (!lag_member) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + lag_info = switch_api_lag_get_internal(lag_member->lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + status = switch_api_lag_member_delete( + device, lag_member->lag_handle, lag_member->direction, lag_member->port); + return status; +} - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } +unsigned int switch_lag_get_count(switch_handle_t lag_handle) { + switch_lag_info_t *info = NULL; + _switch_handle_get(switch_lag_info_t, switch_lag_array, lag_handle, info); + return info->count; +} - printf("\n\nlag_handle: %x", (unsigned int) lag_handle); - printf("\ningress port list:"); - node = tommy_list_head(&(lag_info->ingress)); - while (node) { - lag_member = node->data; - printf("\n\tport : %d", (int)lag_member->port); - node = node->next; - } - printf("\negress port list:"); - node = tommy_list_head(&(lag_info->egress)); - while (node) { - lag_member = node->data; - printf("\n\tport : %d", (int)lag_member->port); - node = node->next; - } - printf("\n"); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_lag_print_entry(switch_handle_t lag_handle) { + switch_lag_info_t *lag_info = NULL; + switch_lag_member_t *lag_member = NULL; + tommy_node *node = NULL; + + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + printf("\n\nlag_handle: %x", (unsigned int)lag_handle); + printf("\ningress port list:"); + node = tommy_list_head(&(lag_info->ingress)); + while (node) { + lag_member = node->data; + printf("\n\tport : %d", (int)lag_member->port); + node = node->next; + } + printf("\negress port list:"); + node = tommy_list_head(&(lag_info->egress)); + while (node) { + lag_member = node->data; + printf("\n\tport : %d", (int)lag_member->port); + node = node->next; + } + printf("\n"); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_lag_print_all(void) -{ - switch_handle_t lag_handle = 0; - switch_handle_t next_lag_handle = 0; - - switch_handle_get_first(switch_lag_array, lag_handle); - while (lag_handle) { - switch_api_lag_print_entry(lag_handle); - switch_handle_get_next(switch_lag_array, lag_handle, next_lag_handle); - lag_handle = next_lag_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_lag_print_all(void) { + switch_handle_t lag_handle = 0; + switch_handle_t next_lag_handle = 0; + + switch_handle_get_first(switch_lag_array, lag_handle); + while (lag_handle) { + switch_api_lag_print_entry(lag_handle); + switch_handle_get_next(switch_lag_array, lag_handle, next_lag_handle); + lag_handle = next_lag_handle; + } + return SWITCH_STATUS_SUCCESS; } #ifdef SWITCH_LAG_TEST -int lag_main (int argc, char **argv) -{ - return 0; -} +int lag_main(int argc, char **argv) { return 0; } #endif #ifdef __cplusplus diff --git a/switchapi/src/switch_lag_int.h b/switchapi/src/switch_lag_int.h index 5ccc508..074d3aa 100644 --- a/switchapi/src/switch_lag_int.h +++ b/switchapi/src/switch_lag_int.h @@ -17,6 +17,7 @@ limitations under the License. #include "switchapi/switch_id.h" #include "switchapi/switch_handle.h" #include "switchapi/switch_lag.h" +#include "switch_pd_types.h" #ifndef _switch_lag_internal_h_ #define _switch_lag_internal_h_ @@ -24,7 +25,7 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + // LAG #define MAX_LAG_GROUP_SIZE (64) @@ -32,65 +33,64 @@ extern "C" { /** Lag member is one of the ports that can be a member of LAG */ typedef struct switch_lag_member_ { - tommy_node ingress_node; /**< linked list node */ - tommy_node egress_node; /**< linked list node */ - switch_port_t port; /**< physical port */ - uint8_t index; /**< Index relative to base */ - switch_handle_t lag_member_handle; /**< lag member handle */ - switch_handle_t lag_handle; /**< lag member handle */ - switch_direction_t direction; /**< direction */ + tommy_node ingress_node; /**< linked list node */ + tommy_node egress_node; /**< linked list node */ + switch_port_t port; /**< physical port */ + uint8_t index; /**< Index relative to base */ + switch_handle_t lag_member_handle; /**< lag member handle */ + switch_handle_t lag_handle; /**< lag member handle */ + switch_direction_t direction; /**< direction */ #ifdef SWITCH_PD - p4_pd_mbr_hdl_t mbr_hdl; /**< Member handle */ + p4_pd_mbr_hdl_t mbr_hdl; /**< Member handle */ #endif } switch_lag_member_t; - + /** LAG Information */ typedef struct { - switch_lag_type_t type; /**< weighted or otherwise */ - switch_ifindex_t ifindex; /**< LAG Ifindex */ - void *intf_array; - bool lacp; /**< LACP enabled? */ - lacp_key_t key; /**< LACP key */ - tommy_list ingress; /**< Ingress port list */ - tommy_list egress; /**< Egress port list */ - switch_api_id_allocator *egr_bmap; /**< egress bitmap */ - unsigned int count; /**< number of members */ - uint16_t base; /**< Base of lag select table */ - switch_device_t device; /**< device on which lag is set */ + switch_lag_type_t type; /**< weighted or otherwise */ + switch_ifindex_t ifindex; /**< LAG Ifindex */ + void *intf_array; + bool lacp; /**< LACP enabled? */ + lacp_key_t key; /**< LACP key */ + tommy_list ingress; /**< Ingress port list */ + tommy_list egress; /**< Egress port list */ + switch_api_id_allocator *egr_bmap; /**< egress bitmap */ + unsigned int count; /**< number of members */ + uint16_t base; /**< Base of lag select table */ + switch_device_t device; /**< device on which lag is set */ #ifdef SWITCH_PD - p4_pd_entry_hdl_t hw_entry; /**< HW entry */ - p4_pd_grp_hdl_t pd_group_hdl; /**< HW entry */ + p4_pd_entry_hdl_t hw_entry; /**< HW entry */ + p4_pd_grp_hdl_t pd_group_hdl; /**< HW entry */ #endif } switch_lag_info_t; - + /** LAG weighted member information */ typedef struct switch_lag_weighted_member_ { - tommy_node ingress_node; /**< house keeping node */ - tommy_node egress_node; /**< house keeping node */ - switch_lag_member_t port; /**< port member */ - uint16_t weight; /**< weight for port in the group */ - uint8_t index; /**< Index of member */ + tommy_node ingress_node; /**< house keeping node */ + tommy_node egress_node; /**< house keeping node */ + switch_lag_member_t port; /**< port member */ + uint16_t weight; /**< weight for port in the group */ + uint8_t index; /**< Index of member */ #ifdef SWITCH_PD - p4_pd_mbr_hdl_t mbr_hdl; /**< Member handle */ + p4_pd_mbr_hdl_t mbr_hdl; /**< Member handle */ #endif } switch_lag_weighted_member_t; -#define SWITCH_LAG_ID_FROM_IFINDEX(ifindex) \ - (ifindex & \ - (~(SWITCH_IFINDEX_TYPE_LAG << SWITCH_IFINDEX_PORT_WIDTH))) +#define SWITCH_LAG_ID_FROM_IFINDEX(ifindex) \ + (ifindex & (~(SWITCH_IFINDEX_TYPE_LAG << SWITCH_IFINDEX_PORT_WIDTH))) -#define SWITCH_LAG_COMPUTE_IFINDEX(handle) \ - (handle_to_id(handle) | \ - (SWITCH_IFINDEX_TYPE_LAG << SWITCH_IFINDEX_PORT_WIDTH)) +#define SWITCH_LAG_COMPUTE_IFINDEX(handle) \ + (handle_to_id(handle) | \ + (SWITCH_IFINDEX_TYPE_LAG << SWITCH_IFINDEX_PORT_WIDTH)) -#define SWITCH_IS_LAG_IFINDEX(ifindex) \ - ((ifindex >> SWITCH_IFINDEX_PORT_WIDTH) == \ - SWITCH_IFINDEX_TYPE_LAG) +#define SWITCH_IS_LAG_IFINDEX(ifindex) \ + ((ifindex >> SWITCH_IFINDEX_PORT_WIDTH) == SWITCH_IFINDEX_TYPE_LAG) switch_status_t switch_lag_init(switch_device_t device); switch_status_t switch_lag_free(switch_device_t device); switch_lag_info_t *switch_api_lag_get_internal(switch_handle_t lag_handle); -switch_status_t switch_lag_update_prune_mask_table(switch_device_t device, switch_lag_info_t *lag_info); +switch_status_t switch_lag_update_prune_mask_table(switch_device_t device, + switch_lag_info_t *lag_info); #ifdef __cplusplus } diff --git a/switchapi/src/switch_log.c b/switchapi/src/switch_log.c index abc4104..a81ee50 100644 --- a/switchapi/src/switch_log.c +++ b/switchapi/src/switch_log.c @@ -17,53 +17,47 @@ limitations under the License. #include "p4features.h" #include "switch_log_int.h" #include +#include switch_api_log_fn_t *switch_api_client_log_fn = NULL; switch_api_log_level_t switch_api_default_log_level = SWITCH_API_LOG_INFO; -char * switch_print_error(switch_status_t status) -{ - switch (status) { - case SWITCH_STATUS_INVALID_HANDLE: - return "err: invalid handle"; - break; - case SWITCH_STATUS_ITEM_NOT_FOUND: - return "err: entry not found"; - break; - case SWITCH_STATUS_FAILURE: - return "err: general failure"; - break; - default: - return "err: unknown failure"; - break; - } +char *switch_print_error(switch_status_t status) { + switch (status) { + case SWITCH_STATUS_INVALID_HANDLE: + return "err: invalid handle"; + break; + case SWITCH_STATUS_ITEM_NOT_FOUND: + return "err: entry not found"; + break; + case SWITCH_STATUS_FAILURE: + return "err: general failure"; + break; + default: + return "err: unknown failure"; + break; + } } -int -switch_default_logger(switch_api_log_level_t level, char *fmt, ...) -{ - va_list args; +int switch_default_logger(switch_api_log_level_t level, char *fmt, ...) { + va_list args; - if ((switch_api_default_log_level == SWITCH_API_LOG_NONE) || - (level > switch_api_default_log_level)) { - return 0; - } - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); + if ((switch_api_default_log_level == SWITCH_API_LOG_NONE) || + (level > switch_api_default_log_level)) { + return 0; + } + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); - return 1; + return 1; } -void -switch_api_log_function_set(switch_api_log_fn_t *log_fn) -{ - switch_api_client_log_fn = log_fn; +void switch_api_log_function_set(switch_api_log_fn_t *log_fn) { + switch_api_client_log_fn = log_fn; } -void -switch_log_init() -{ - switch_api_default_log_level = SWITCH_API_LOG_INFO; - switch_api_client_log_fn = switch_default_logger; +void switch_log_init() { + switch_api_default_log_level = SWITCH_API_LOG_INFO; + switch_api_client_log_fn = switch_default_logger; } diff --git a/switchapi/src/switch_log.h b/switchapi/src/switch_log.h new file mode 100644 index 0000000..c35620e --- /dev/null +++ b/switchapi/src/switch_log.h @@ -0,0 +1,26 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "p4features.h" +#include + +#define SWITCH_API_ERROR printf +#define SWITCH_API_WARN printf +#define SWITCH_API_INFO printf +#define SWITCH_API_VERBOSE printf +#define SWITCH_API_TRACE printf + +char *switch_print_error(switch_status_t status); diff --git a/switchapi/src/switch_log_int.h b/switchapi/src/switch_log_int.h index 784dd4d..50ed18c 100644 --- a/switchapi/src/switch_log_int.h +++ b/switchapi/src/switch_log_int.h @@ -24,15 +24,26 @@ void switch_log_init(); extern switch_api_log_fn_t *switch_api_client_log_fn; -#define SWITCH_API_ERROR(...) \ - switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_ERROR, __VA_ARGS__); -#define SWITCH_API_WARN(...) \ - switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_WARN, __VA_ARGS__); -#define SWITCH_API_INFO(...) \ - switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_INFO, __VA_ARGS__); +#define SWITCH_API_ERROR(...) \ + if (switch_api_client_log_fn) \ + switch_api_client_log_fn(SWITCH_API_LOG_ERROR, __VA_ARGS__); + +#define SWITCH_API_WARN(...) \ + if (switch_api_client_log_fn) \ + switch_api_client_log_fn(SWITCH_API_LOG_WARN, __VA_ARGS__); + +#define SWITCH_API_INFO(...) \ + if (switch_api_client_log_fn) \ + switch_api_client_log_fn(SWITCH_API_LOG_INFO, __VA_ARGS__); + #define SWITCH_API_VERBOSE(...) \ - switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_VERBOSE, __VA_ARGS__); -#define SWITCH_API_TRACE(...) \ - switch_api_client_log_fn && switch_api_client_log_fn(SWITCH_API_LOG_TRACE, __VA_ARGS__); + if (switch_api_client_log_fn) \ + switch_api_client_log_fn(SWITCH_API_LOG_VERBOSE, __VA_ARGS__); + +#define SWITCH_API_TRACE(...) \ + if (switch_api_client_log_fn) \ + switch_api_client_log_fn(SWITCH_API_LOG_TRACE, __VA_ARGS__); + +char *switch_print_error(switch_status_t status); #endif /*_SWITCH_LOG_INT_H_ */ diff --git a/switchapi/src/switch_lpm.c b/switchapi/src/switch_lpm.c new file mode 100644 index 0000000..c717eaa --- /dev/null +++ b/switchapi/src/switch_lpm.c @@ -0,0 +1,282 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "switchapi/switch_utils.h" +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char byte_t; + +typedef unsigned long value_t; + +typedef struct node_s { + Pvoid_t PJLarray_branches; + Pvoid_t PJLarray_prefixes; + unsigned char branch_num; + unsigned char pref_num; + struct node_s *parent; + byte_t child_id; +} node_t; + +struct switch_lpm_trie_s { + node_t *root; + size_t key_width_bytes; + bool release_memory; + unsigned int num_entries; +}; + +typedef struct switch_lpm_trie_s switch_lpm_trie_t; + +static inline void allocate_node(node_t **node) { + *node = (node_t *)switch_malloc(sizeof(node_t), 1); + memset(*node, 0, sizeof(node_t)); +} + +switch_lpm_trie_t *switch_lpm_trie_create(size_t key_width_bytes, + bool auto_shrink) { + assert(key_width_bytes <= 64); + switch_lpm_trie_t *trie = + (switch_lpm_trie_t *)switch_malloc(sizeof(switch_lpm_trie_t), 1); + trie->key_width_bytes = key_width_bytes; + trie->release_memory = auto_shrink; + allocate_node(&trie->root); + trie->num_entries = 0; + return trie; +} + +unsigned int switch_lpm_trie_size(switch_lpm_trie_t *t) { + if (!t) return 0; + return t->num_entries; +} + +static void destroy_node(node_t *node) { + Word_t index = 0; + Word_t *pnode; + Word_t rc_word; + JLF(pnode, node->PJLarray_branches, index); + while (pnode != NULL) { + destroy_node((node_t *)*pnode); + JLN(pnode, node->PJLarray_branches, index); + } + JLFA(rc_word, node->PJLarray_branches); + JLFA(rc_word, node->PJLarray_prefixes); + switch_free(node); +} + +void switch_lpm_trie_destroy(switch_lpm_trie_t *t) { + destroy_node(t->root); + switch_free(t); +} + +static inline node_t *get_next_node(const node_t *current_node, byte_t byte) { + Word_t *pnode; + JLG(pnode, current_node->PJLarray_branches, (Word_t)byte); + if (!pnode) return NULL; + return (node_t *)*pnode; +} + +static inline void set_next_node(node_t *current_node, + byte_t byte, + node_t *next_node) { + Word_t *pnode; + JLI(pnode, current_node->PJLarray_branches, (Word_t)byte); + *pnode = (Word_t)next_node; +} + +static inline int delete_branch(node_t *current_node, byte_t byte) { + int rc; + JLD(rc, current_node->PJLarray_branches, (Word_t)byte); + return rc; +} + +static inline unsigned short get_prefix_key(unsigned prefix_length, + byte_t byte) { + return prefix_length ? (byte >> (8 - prefix_length)) + (prefix_length << 8) + : 0; +} + +/* returns 1 if was present, 0 otherwise */ +static inline int insert_prefix(node_t *current_node, + unsigned short prefix_key, + const value_t value) { + Word_t *pvalue; + int rc; + JLI(pvalue, current_node->PJLarray_prefixes, (Word_t)prefix_key); + rc = (*pvalue) ? 1 : 0; + *pvalue = (Word_t)value; + return rc; +} + +static inline value_t *get_prefix_ptr(const node_t *current_node, + unsigned short prefix_key) { + Word_t *pvalue; + JLG(pvalue, current_node->PJLarray_prefixes, (Word_t)prefix_key); + return (value_t *)pvalue; +} + +/* returns 1 if was present, 0 otherwise */ +static inline int delete_prefix(node_t *current_node, + unsigned short prefix_key) { + int rc; + JLD(rc, current_node->PJLarray_prefixes, (Word_t)prefix_key); + return rc; +} + +void switch_lpm_trie_insert(switch_lpm_trie_t *trie, + const char *prefix, + int prefix_length, + const value_t value) { + node_t *current_node = trie->root; + byte_t byte; + unsigned short prefix_key; + + while (prefix_length >= 8) { + byte = (byte_t)*prefix; + node_t *node = get_next_node(current_node, byte); + if (!node) { + allocate_node(&node); + node->parent = current_node; + node->child_id = byte; + set_next_node(current_node, byte, node); + current_node->branch_num++; + } + + prefix++; + prefix_length -= 8; + current_node = node; + } + + if (prefix_length == 0) + prefix_key = 0; + else + prefix_key = get_prefix_key((unsigned)prefix_length, (byte_t)*prefix); + + if (!insert_prefix(current_node, prefix_key, value)) current_node->pref_num++; + + trie->num_entries++; +} + +bool switch_lpm_trie_has_prefix(const switch_lpm_trie_t *trie, + const char *prefix, + int prefix_length) { + node_t *current_node = trie->root; + byte_t byte; + unsigned short prefix_key; + + while (prefix_length >= 8) { + byte = (byte_t)*prefix; + node_t *node = get_next_node(current_node, byte); + if (!node) return false; + + prefix++; + prefix_length -= 8; + current_node = node; + } + + if (prefix_length == 0) + prefix_key = 0; + else + prefix_key = get_prefix_key((unsigned)prefix_length, (byte_t)*prefix); + + return (get_prefix_ptr(current_node, prefix_key) != NULL); +} + +bool switch_lpm_trie_lookup(const switch_lpm_trie_t *trie, + const char *key, + value_t *pvalue) { + const node_t *current_node = trie->root; + byte_t byte; + size_t key_width = trie->key_width_bytes; + value_t *pdata = NULL; + unsigned short prefix_key; + unsigned i; + bool found = false; + + while (current_node) { + pdata = get_prefix_ptr(current_node, 0); + if (pdata) { + *pvalue = *pdata; + found = true; + } + if (key_width > 0) { + byte = (byte_t)*key; + for (i = 7; i > 0; i--) { + prefix_key = get_prefix_key((unsigned)i, byte); + pdata = get_prefix_ptr(current_node, prefix_key); + if (pdata) { + *pvalue = *pdata; + found = true; + break; + } + } + + current_node = get_next_node(current_node, byte); + key++; + key_width--; + } else { + break; + } + } + + return found; +} + +bool switch_lpm_trie_delete(switch_lpm_trie_t *trie, + const char *prefix, + int prefix_length) { + node_t *current_node = trie->root; + byte_t byte; + unsigned short prefix_key; + value_t *pdata = NULL; + + while (prefix_length >= 8) { + byte = (byte_t)*prefix; + node_t *node = get_next_node(current_node, byte); + if (!node) return NULL; + + prefix++; + prefix_length -= 8; + current_node = node; + } + + if (prefix_length == 0) + prefix_key = 0; + else + prefix_key = get_prefix_key((unsigned)prefix_length, (byte_t)*prefix); + + pdata = get_prefix_ptr(current_node, prefix_key); + if (!pdata) return false; + + if (trie->release_memory) { + assert(delete_prefix(current_node, prefix_key) == 1); + current_node->pref_num--; + while (current_node->pref_num == 0 && current_node->branch_num == 0) { + node_t *tmp = current_node; + current_node = current_node->parent; + if (!current_node) break; + assert(delete_branch(current_node, tmp->child_id) == 1); + switch_free(tmp); + current_node->branch_num--; + } + } + + trie->num_entries--; + return true; +} diff --git a/switchapi/src/switch_lpm_int.h b/switchapi/src/switch_lpm_int.h new file mode 100644 index 0000000..9630632 --- /dev/null +++ b/switchapi/src/switch_lpm_int.h @@ -0,0 +1,59 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifndef _switch_lpm_int_h_ +#define _switch_lpm_int_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct switch_lpm_trie_s switch_lpm_trie_t; + +typedef unsigned long value_t; + +switch_lpm_trie_t *switch_lpm_trie_create(size_t key_width_bytes, + bool auto_shrink); + +unsigned int switch_lpm_trie_size(switch_lpm_trie_t *t); + +void switch_lpm_trie_destroy(switch_lpm_trie_t *t); + +void switch_lpm_trie_insert(switch_lpm_trie_t *trie, + const char *prefix, + int prefix_length, + const value_t value); + +bool switch_lpm_trie_has_prefix(const switch_lpm_trie_t *trie, + const char *prefix, + int prefix_length); + +bool switch_lpm_trie_lookup(const switch_lpm_trie_t *trie, + const char *key, + value_t *pvalue); + +bool switch_lpm_trie_delete(switch_lpm_trie_t *trie, + const char *prefix, + int prefix_length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/src/switch_mcast.c b/switchapi/src/switch_mcast.c index 17ee257..dabe30e 100644 --- a/switchapi/src/switch_mcast.c +++ b/switchapi/src/switch_mcast.c @@ -43,1155 +43,1113 @@ 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); - switch_rid_allocator = switch_api_id_allocator_new(SWITCH_RID_ALLOCATOR_SIZE, FALSE); - //Reserve the RID 0. - //switch_api_id_allocator_allocate(switch_rid_allocator); - return SWITCH_STATUS_SUCCESS; +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); + switch_rid_allocator = + switch_api_id_allocator_new(SWITCH_RID_ALLOCATOR_SIZE, FALSE); + // Reserve the RID 0. + // switch_api_id_allocator_allocate(switch_rid_allocator); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_mcast_free(switch_device_t device) -{ - switch_handle_type_free(SWITCH_HANDLE_TYPE_MGID); - tommy_hashtable_done(&switch_rid_hash_table); - tommy_hashtable_done(&switch_mcast_group_hash_table); - switch_api_id_allocator_destroy(switch_rid_allocator); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_mcast_free(switch_device_t device) { + switch_handle_type_free(SWITCH_HANDLE_TYPE_MGID); + tommy_hashtable_done(&switch_rid_hash_table); + tommy_hashtable_done(&switch_mcast_group_hash_table); + switch_api_id_allocator_destroy(switch_rid_allocator); + return SWITCH_STATUS_SUCCESS; } -uint16_t -switch_mcast_rid_allocate() -{ - uint16_t rid = 0; - rid = switch_api_id_allocator_allocate(switch_rid_allocator); - return rid; +uint16_t switch_mcast_rid_allocate() { + uint16_t rid = 0; + rid = switch_api_id_allocator_allocate(switch_rid_allocator); + return rid; } -void -switch_mcast_rid_free(uint16_t rid) -{ - switch_api_id_allocator_release(switch_rid_allocator, rid); - return; +void switch_mcast_rid_free(uint16_t rid) { + switch_api_id_allocator_release(switch_rid_allocator, rid); + return; } -static inline void -switch_mcast_rid_hash_key_init(uchar *key, switch_mcast_rid_key_t *rid_key, - uint32_t *len, uint32_t *hash) -{ - *len = 0; - memset(key, 0, SWITCH_MCAST_RID_HASH_KEY_SIZE); +static inline void switch_mcast_rid_hash_key_init( + uchar *key, + switch_mcast_rid_key_t *rid_key, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, SWITCH_MCAST_RID_HASH_KEY_SIZE); - memcpy(key, &(rid_key->mgid_handle), sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); + memcpy(key, &(rid_key->mgid_handle), sizeof(switch_handle_t)); + *len += sizeof(switch_handle_t); - memcpy((key + *len), &(rid_key->bd_handle), sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); + memcpy((key + *len), &(rid_key->bd_handle), sizeof(switch_handle_t)); + *len += sizeof(switch_handle_t); - memcpy((key + *len), &(rid_key->intf_handle), sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); + memcpy((key + *len), &(rid_key->intf_handle), sizeof(switch_handle_t)); + *len += sizeof(switch_handle_t); - *hash = MurmurHash2(key, *len, 0x98761234); + *hash = MurmurHash2(key, *len, 0x98761234); } -static inline int -switch_mcast_rid_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_MCAST_RID_HASH_KEY_SIZE); +static inline int switch_mcast_rid_hash_cmp(const void *key1, + const void *key2) { + return memcmp(key1, key2, SWITCH_MCAST_RID_HASH_KEY_SIZE); } -static switch_mcast_rid_t * -switch_mcast_rid_insert_hash(switch_mcast_rid_key_t *rid_key) -{ - switch_mcast_rid_t *rid_info = NULL; - unsigned char key[SWITCH_MCAST_RID_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_mcast_rid_hash_key_init(key, rid_key, &len, &hash); - rid_info = switch_malloc(sizeof(switch_mcast_rid_t), 1); - if (!rid_info) { - return NULL; - } - memcpy(&rid_info->rid_key, rid_key, sizeof(switch_mcast_rid_key_t)); - tommy_hashtable_insert(&switch_rid_hash_table, - &(rid_info->node), - rid_info, hash); - return rid_info; +switch_mcast_rid_t *switch_mcast_rid_insert_hash( + switch_mcast_rid_key_t *rid_key) { + switch_mcast_rid_t *rid_info = NULL; + unsigned char key[SWITCH_MCAST_RID_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_mcast_rid_hash_key_init(key, rid_key, &len, &hash); + rid_info = switch_malloc(sizeof(switch_mcast_rid_t), 1); + if (!rid_info) { + return NULL; + } + memcpy(&rid_info->rid_key, rid_key, sizeof(switch_mcast_rid_key_t)); + tommy_hashtable_insert( + &switch_rid_hash_table, &(rid_info->node), rid_info, hash); + return rid_info; } -static switch_status_t -switch_mcast_rid_delete_hash(switch_mcast_rid_key_t *rid_key) -{ - switch_mcast_rid_t *rid_info = NULL; - unsigned char key[SWITCH_MCAST_RID_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_mcast_rid_hash_key_init(key, rid_key, &len, &hash); - rid_info = tommy_hashtable_remove(&switch_rid_hash_table, - switch_mcast_rid_hash_cmp, - key, hash); - if (!rid_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - switch_free(rid_info); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_mcast_rid_delete_hash(switch_mcast_rid_key_t *rid_key) { + switch_mcast_rid_t *rid_info = NULL; + unsigned char key[SWITCH_MCAST_RID_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_mcast_rid_hash_key_init(key, rid_key, &len, &hash); + rid_info = tommy_hashtable_remove( + &switch_rid_hash_table, switch_mcast_rid_hash_cmp, key, hash); + if (!rid_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + switch_free(rid_info); + return SWITCH_STATUS_SUCCESS; } -static switch_mcast_rid_t * -switch_mcast_rid_search_hash(switch_mcast_rid_key_t *rid_key, bool *inner_replica) -{ - switch_mcast_rid_t *rid_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_interface_info_t *intf_info = NULL; - unsigned char key[SWITCH_MCAST_RID_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - //TODO: Return appropriate error code during failure - intf_info = switch_api_interface_get(rid_key->intf_handle); - if (!intf_info) { - return NULL; +switch_mcast_rid_t *switch_mcast_rid_search_hash( + switch_mcast_rid_key_t *rid_key, bool *inner_replica) { + switch_mcast_rid_t *rid_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_interface_info_t *intf_info = NULL; + unsigned char key[SWITCH_MCAST_RID_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + // TODO: Return appropriate error code during failure + intf_info = switch_api_interface_get(rid_key->intf_handle); + if (!intf_info) { + return NULL; + } + bd_info = switch_bd_get(rid_key->bd_handle); + if (!bd_info) { + return NULL; + } + + *inner_replica = TRUE; + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + *inner_replica = FALSE; + } + + if (SWITCH_LN_NETWORK_TYPE(bd_info) == + SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC || + SWITCH_LN_NETWORK_TYPE(bd_info) == + SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED) { + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_VLAN_ACCESS) { + rid_key->intf_handle = 0; } - bd_info = switch_bd_get(rid_key->bd_handle); - if (!bd_info) { - return NULL; - } - - *inner_replica = TRUE; - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - *inner_replica = FALSE; - } - - if (SWITCH_LN_NETWORK_TYPE(bd_info) == SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC || - SWITCH_LN_NETWORK_TYPE(bd_info) == SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED) { - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_VLAN_ACCESS) { - rid_key->intf_handle = 0; - } - } else if (SWITCH_LN_NETWORK_TYPE(bd_info) == SWITCH_LOGICAL_NETWORK_TYPE_VLAN) { - rid_key->intf_handle = 0; - } - switch_mcast_rid_hash_key_init(key, rid_key, &len, &hash); - rid_info = tommy_hashtable_search(&switch_rid_hash_table, - switch_mcast_rid_hash_cmp, - key, hash); - return rid_info; + } else if (SWITCH_LN_NETWORK_TYPE(bd_info) == + SWITCH_LOGICAL_NETWORK_TYPE_VLAN) { + rid_key->intf_handle = 0; + } + switch_mcast_rid_hash_key_init(key, rid_key, &len, &hash); + rid_info = tommy_hashtable_search( + &switch_rid_hash_table, switch_mcast_rid_hash_cmp, key, hash); + return rid_info; } -static inline void -switch_mcast_group_hash_key_init(uchar *key, switch_mcast_group_key_t *group_key, - uint32_t *len, uint32_t *hash) -{ - switch_ip_addr_type_t addr_type = 0; - uchar *key_start = key; - - *len = 0; - memset(key, 0, SWITCH_MCAST_GROUP_HASH_KEY_SIZE); - - addr_type = SWITCH_MCAST_GROUP_IP_TYPE(group_key); - memcpy(key, &addr_type, sizeof(switch_ip_addr_type_t)); - key += 1; - *len += 1; - - memcpy(key, &(group_key->sg_entry), 1); - key += 1; - *len += 1; - - if (addr_type == SWITCH_API_IP_ADDR_V4) { - memcpy(key, &(SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key)), 4); - key += 4; - *len += 4; - memcpy(key, &(SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key)), 4); - key += 4; - *len += 4; - } else { - memcpy(key, (SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - key += 16; - *len += 16; - memcpy(key, (SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - key += 16; - *len += 16; - } - - memcpy(key, &(group_key->bd_vrf_handle), sizeof(switch_handle_t)); - key += sizeof(switch_handle_t); - *len += sizeof(switch_handle_t); - - *hash = MurmurHash2(key_start, *len, 0x98761234); +static inline void switch_mcast_group_hash_key_init( + uchar *key, + switch_mcast_group_key_t *group_key, + uint32_t *len, + uint32_t *hash) { + switch_ip_addr_type_t addr_type = 0; + uchar *key_start = key; + + *len = 0; + memset(key, 0, SWITCH_MCAST_GROUP_HASH_KEY_SIZE); + + addr_type = SWITCH_MCAST_GROUP_IP_TYPE(group_key); + memcpy(key, &addr_type, sizeof(switch_ip_addr_type_t)); + key += 1; + *len += 1; + + memcpy(key, &(group_key->sg_entry), 1); + key += 1; + *len += 1; + + if (addr_type == SWITCH_API_IP_ADDR_V4) { + memcpy(key, &(SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key)), 4); + key += 4; + *len += 4; + memcpy(key, &(SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key)), 4); + key += 4; + *len += 4; + } else { + memcpy(key, (SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); + key += 16; + *len += 16; + memcpy(key, (SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); + key += 16; + *len += 16; + } + + memcpy(key, &(group_key->bd_vrf_handle), sizeof(switch_handle_t)); + key += sizeof(switch_handle_t); + *len += sizeof(switch_handle_t); + + *hash = MurmurHash2(key_start, *len, 0x98761234); } -static inline int -switch_mcast_group_hash_cmp(const void *key1, const void *arg) -{ - unsigned char key2[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - switch_mcast_group_info_t *group_info = (void *)arg; +static inline int switch_mcast_group_hash_cmp(const void *key1, + const void *arg) { + unsigned char key2[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + switch_mcast_group_info_t *group_info = (void *)arg; - switch_mcast_group_hash_key_init(key2, &group_info->group_key, &len, &hash); - return memcmp(key1, key2, SWITCH_MCAST_GROUP_HASH_KEY_SIZE); + switch_mcast_group_hash_key_init(key2, &group_info->group_key, &len, &hash); + return memcmp(key1, key2, SWITCH_MCAST_GROUP_HASH_KEY_SIZE); } -static switch_mcast_group_info_t * -switch_mcast_group_insert_hash(switch_mcast_group_key_t *group_key) -{ - switch_mcast_group_info_t *group_info = NULL; - unsigned char key[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_mcast_group_hash_key_init(key, group_key, &len, &hash); - group_info = switch_malloc(sizeof(switch_mcast_group_info_t), 1); - if (!group_info) { - return NULL; - } - memcpy(&group_info->group_key, group_key, sizeof(switch_mcast_group_key_t)); - tommy_hashtable_insert(&switch_mcast_group_hash_table, - &(group_info->node), group_info, hash); - return group_info; +static switch_mcast_group_info_t *switch_mcast_group_insert_hash( + switch_mcast_group_key_t *group_key) { + switch_mcast_group_info_t *group_info = NULL; + unsigned char key[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_mcast_group_hash_key_init(key, group_key, &len, &hash); + group_info = switch_malloc(sizeof(switch_mcast_group_info_t), 1); + if (!group_info) { + return NULL; + } + memcpy(&group_info->group_key, group_key, sizeof(switch_mcast_group_key_t)); + tommy_hashtable_insert( + &switch_mcast_group_hash_table, &(group_info->node), group_info, hash); + return group_info; } -static switch_status_t -switch_mcast_group_delete_hash(switch_mcast_group_key_t *group_key) -{ - switch_mcast_rid_t *group_info = NULL; - unsigned char key[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_mcast_group_hash_key_init(key, group_key, &len, &hash); - group_info = tommy_hashtable_remove(&switch_mcast_group_hash_table, - switch_mcast_group_hash_cmp, - key, hash); - if (!group_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - switch_free(group_info); - return SWITCH_STATUS_SUCCESS; +static switch_status_t switch_mcast_group_delete_hash( + switch_mcast_group_key_t *group_key) { + switch_mcast_rid_t *group_info = NULL; + unsigned char key[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_mcast_group_hash_key_init(key, group_key, &len, &hash); + group_info = tommy_hashtable_remove( + &switch_mcast_group_hash_table, switch_mcast_group_hash_cmp, key, hash); + if (!group_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + switch_free(group_info); + return SWITCH_STATUS_SUCCESS; } -static switch_mcast_group_info_t * -switch_mcast_group_search_hash(switch_mcast_group_key_t *group_key) -{ - switch_mcast_group_info_t *group_info = NULL; - unsigned char key[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_mcast_group_hash_key_init(key, group_key, &len, &hash); - group_info = tommy_hashtable_search(&switch_mcast_group_hash_table, - switch_mcast_group_hash_cmp, - key, hash); - return group_info; +static switch_mcast_group_info_t *switch_mcast_group_search_hash( + switch_mcast_group_key_t *group_key) { + switch_mcast_group_info_t *group_info = NULL; + unsigned char key[SWITCH_MCAST_GROUP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_mcast_group_hash_key_init(key, group_key, &len, &hash); + group_info = tommy_hashtable_search( + &switch_mcast_group_hash_table, switch_mcast_group_hash_cmp, key, hash); + return group_info; } -switch_handle_t -switch_api_mcast_index_allocate(switch_device_t device) -{ - switch_mcast_info_t *mcast_info = NULL; - switch_handle_t mgid_handle; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - - _switch_handle_create(SWITCH_HANDLE_TYPE_MGID, switch_mcast_info_t, - switch_mcast_array, NULL, mgid_handle); - mcast_info = switch_mcast_tree_get(mgid_handle); - if (!mcast_info) { - return 0; - } - status = switch_pd_mcast_mgrp_tree_create(device, - handle_to_id(mgid_handle), - mcast_info); - if (status) { - return 0; - } - tommy_list_init(&mcast_info->node_list); - return mgid_handle; +switch_handle_t switch_api_mcast_index_allocate(switch_device_t device) { + switch_mcast_info_t *mcast_info = NULL; + switch_handle_t mgid_handle; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + _switch_handle_create(SWITCH_HANDLE_TYPE_MGID, + switch_mcast_info_t, + switch_mcast_array, + NULL, + mgid_handle); + mcast_info = switch_mcast_tree_get(mgid_handle); + if (!mcast_info) { + return 0; + } + status = switch_pd_mcast_mgrp_tree_create( + device, handle_to_id(mgid_handle), mcast_info); + if (status) { + return 0; + } + tommy_list_init(&mcast_info->node_list); + return mgid_handle; } -switch_mcast_info_t * -switch_mcast_tree_get(switch_handle_t mgid_handle) -{ - switch_mcast_info_t *mcast_info = NULL; - _switch_handle_get(switch_mcast_info_t, switch_mcast_array, - mgid_handle, mcast_info); - return mcast_info; +switch_mcast_info_t *switch_mcast_tree_get(switch_handle_t mgid_handle) { + switch_mcast_info_t *mcast_info = NULL; + _switch_handle_get( + switch_mcast_info_t, switch_mcast_array, mgid_handle, mcast_info); + return mcast_info; } -switch_status_t -switch_api_mcast_index_delete(switch_device_t device, switch_handle_t mgid_handle) -{ - switch_mcast_info_t *mcast_info = NULL; +switch_status_t switch_api_mcast_index_delete(switch_device_t device, + switch_handle_t mgid_handle) { + switch_mcast_info_t *mcast_info = NULL; - mcast_info = switch_mcast_tree_get(mgid_handle); - if (!mcast_info) { - return 0; - } + mcast_info = switch_mcast_tree_get(mgid_handle); + if (!mcast_info) { + return 0; + } - switch_pd_mcast_mgrp_tree_delete(device, mcast_info); - _switch_handle_delete(switch_mcast_info_t, switch_mcast_array, mgid_handle); - return SWITCH_STATUS_SUCCESS; + switch_pd_mcast_mgrp_tree_delete(device, mcast_info); + _switch_handle_delete(switch_mcast_info_t, switch_mcast_array, mgid_handle); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_multicast_tree_create(switch_device_t device) -{ - return switch_api_mcast_index_allocate(device); +switch_handle_t switch_api_multicast_tree_create(switch_device_t device) { + return switch_api_mcast_index_allocate(device); } -switch_status_t -switch_api_multicast_tree_delete(switch_device_t device, - switch_handle_t mgid_handle) -{ - switch_mcast_info_t *mcast_info = NULL; - switch_mcast_node_t *mcast_node = NULL; - tommy_node *node = NULL; - - mcast_info = switch_mcast_tree_get(mgid_handle); - if (!mcast_info) { - SWITCH_API_ERROR("%s:%d: invalid multicast handle %lx", - __FUNCTION__, __LINE__, mgid_handle); - return SWITCH_STATUS_INVALID_HANDLE; - } - - node = tommy_list_head(&mcast_info->node_list); - while (node) { - mcast_node = node->data; - node = node->next; - switch_pd_mcast_mgid_table_delete_entry(device, - mcast_info->mgrp_hdl, - mcast_node); - switch_pd_mcast_delete_entry(device, mcast_node); - 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); - } - - return switch_api_mcast_index_delete(device, mgid_handle); +switch_status_t switch_api_multicast_tree_delete(switch_device_t device, + switch_handle_t mgid_handle) { + switch_mcast_info_t *mcast_info = NULL; + switch_mcast_node_t *mcast_node = NULL; + tommy_node *node = NULL; + + mcast_info = switch_mcast_tree_get(mgid_handle); + if (!mcast_info) { + SWITCH_API_ERROR("%s:%d: invalid multicast handle %lx", + __FUNCTION__, + __LINE__, + mgid_handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + + node = tommy_list_head(&mcast_info->node_list); + while (node) { + mcast_node = node->data; + node = node->next; + switch_pd_mcast_mgid_table_delete_entry( + device, mcast_info->mgrp_hdl, mcast_node); + switch_pd_mcast_delete_entry(device, mcast_node); + 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); + } + + return switch_api_mcast_index_delete(device, mgid_handle); } -switch_mcast_node_t * -switch_mcast_find_node(switch_mcast_info_t *mcast_info, - switch_mcast_node_type_t node_type, - switch_handle_t rid) -{ - switch_mcast_node_t *mcast_node = NULL; - tommy_node *node = NULL; - - node = tommy_list_head(&mcast_info->node_list); - while(node) { - mcast_node = node->data; - if (node_type == SWITCH_NODE_TYPE_SINGLE) { - if (SWITCH_MCAST_NODE_RID(mcast_node) == rid) { - break; - } - } - node = node->next; +switch_mcast_node_t *switch_mcast_find_node(switch_mcast_info_t *mcast_info, + switch_mcast_node_type_t node_type, + switch_handle_t rid) { + switch_mcast_node_t *mcast_node = NULL; + tommy_node *node = NULL; + + node = tommy_list_head(&mcast_info->node_list); + while (node) { + mcast_node = node->data; + if (node_type == SWITCH_NODE_TYPE_SINGLE) { + if (SWITCH_MCAST_NODE_RID(mcast_node) == rid) { + break; + } } + node = node->next; + } - if (!node) { - mcast_node = NULL; - } + if (!node) { + mcast_node = NULL; + } - return mcast_node; + return mcast_node; } -bool -switch_mcast_node_empty(switch_mcast_node_t *node) -{ - switch_mc_lag_map_t *lag_map = NULL; - switch_mc_port_map_t *port_map = NULL; - int i = 0; +bool switch_mcast_node_empty(switch_mcast_node_t *node) { + switch_mc_lag_map_t *lag_map = NULL; + switch_mc_port_map_t *port_map = NULL; + int i = 0; - lag_map = &(SWITCH_MCAST_NODE_INFO_LAG_MAP(node)); - port_map = &(SWITCH_MCAST_NODE_INFO_PORT_MAP(node)); + lag_map = &(SWITCH_MCAST_NODE_INFO_LAG_MAP(node)); + port_map = &(SWITCH_MCAST_NODE_INFO_PORT_MAP(node)); - for (i = 0; i < SWITCH_PORT_ARRAY_SIZE; i++) { - if ((*port_map)[i]) { - return FALSE; - } + for (i = 0; i < SWITCH_PORT_ARRAY_SIZE; i++) { + if ((*port_map)[i]) { + return FALSE; } - for (i = 0; i < SWITCH_LAG_ARRAY_SIZE; i++) { - if ((*lag_map)[i]) { - return FALSE; - } + } + for (i = 0; i < SWITCH_LAG_ARRAY_SIZE; i++) { + if ((*lag_map)[i]) { + return FALSE; } - return TRUE; + } + return TRUE; } -switch_status_t -switch_mcast_update_port_map(switch_mcast_node_t *node, - switch_handle_t intf_handle, - bool set) -{ - switch_interface_info_t *intf_info = NULL; - switch_interface_info_t *out_intf_info = NULL; - switch_handle_t port_handle; - switch_handle_t out_intf_handle; - switch_port_t port_id = 0; - uint16_t lag_index = 0; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { +switch_status_t switch_mcast_update_port_map(switch_mcast_node_t *node, + switch_handle_t intf_handle, + bool set) { + switch_interface_info_t *intf_info = NULL; + switch_interface_info_t *out_intf_info = NULL; + switch_handle_t port_handle; + switch_handle_t out_intf_handle; + switch_port_t port_id = 0; + uint16_t lag_index = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + port_handle = SWITCH_INTF_PORT_HANDLE(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: + if (SWITCH_HANDLE_IS_LAG(port_handle)) { + lag_index = SWITCH_INTF_L2_LAG_INDEX(intf_info); + } else { + port_id = SWITCH_INTF_L2_PORT(intf_info); + } + break; + case SWITCH_API_INTERFACE_L3: + case SWITCH_API_INTERFACE_L3_VLAN: + case SWITCH_API_INTERFACE_L3_PORT_VLAN: + if (SWITCH_HANDLE_IS_LAG(port_handle)) { + lag_index = SWITCH_INTF_L3_LAG_INDEX(intf_info); + } else { + port_id = SWITCH_INTF_L3_PORT(intf_info); + } + break; + case SWITCH_API_INTERFACE_TUNNEL: + out_intf_handle = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); + out_intf_info = switch_api_interface_get(out_intf_handle); + if (!out_intf_info) { return SWITCH_STATUS_INVALID_INTERFACE; - } - - port_handle = SWITCH_INTF_PORT_HANDLE(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: - if (SWITCH_HANDLE_IS_LAG(port_handle)) { - lag_index = SWITCH_INTF_L2_LAG_INDEX(intf_info); - } else { - port_id = SWITCH_INTF_L2_PORT(intf_info); - } - break; - case SWITCH_API_INTERFACE_L3: - case SWITCH_API_INTERFACE_L3_VLAN: - case SWITCH_API_INTERFACE_L3_PORT_VLAN: - if (SWITCH_HANDLE_IS_LAG(port_handle)) { - lag_index = SWITCH_INTF_L3_LAG_INDEX(intf_info); - } else { - port_id = SWITCH_INTF_L3_PORT(intf_info); - } - break; - case SWITCH_API_INTERFACE_TUNNEL: - out_intf_handle = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); - out_intf_info = switch_api_interface_get(out_intf_handle); - if (!out_intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - if (SWITCH_HANDLE_IS_LAG(out_intf_handle)) { - lag_index = SWITCH_INTF_L3_LAG_INDEX(out_intf_info); - } else { - port_id = SWITCH_INTF_L3_PORT(out_intf_info); - } - break; - default: - return SWITCH_STATUS_FAILURE; - } - if (set) { - if (lag_index) { - SWITCH_MC_LAG_MAP_SET_(SWITCH_MCAST_NODE_INFO_LAG_MAP(node), - lag_index); - } else { - SWITCH_MC_PORT_MAP_SET_(SWITCH_MCAST_NODE_INFO_PORT_MAP(node), - port_id); - } + } + if (SWITCH_HANDLE_IS_LAG(out_intf_handle)) { + lag_index = SWITCH_INTF_L3_LAG_INDEX(out_intf_info); + } else { + port_id = SWITCH_INTF_L3_PORT(out_intf_info); + } + break; + default: + return SWITCH_STATUS_FAILURE; + } + if (set) { + if (lag_index) { + SWITCH_MC_LAG_MAP_SET_(SWITCH_MCAST_NODE_INFO_LAG_MAP(node), lag_index); } else { - if (lag_index) { - SWITCH_MC_LAG_MAP_CLEAR_(SWITCH_MCAST_NODE_INFO_LAG_MAP(node), - lag_index); - } else { - SWITCH_MC_PORT_MAP_CLEAR_(SWITCH_MCAST_NODE_INFO_PORT_MAP(node), - port_id); - } + SWITCH_MC_PORT_MAP_SET_(SWITCH_MCAST_NODE_INFO_PORT_MAP(node), port_id); } - return SWITCH_STATUS_SUCCESS; -} - -static void -switch_mcast_update_mcast_info(switch_mcast_info_t *mcast_info, - uint16_t mbr_count, - switch_vlan_interface_t *mbrs, bool add) -{ - int i = 0, j = 0; - - for (i = 0; i < mbr_count; i++) { - switch_vlan_interface_t *mbr = &mbrs[i]; - int found = -1; - for (j = 0; j < mcast_info->mbr_count; j++) { - if (memcmp(&(mcast_info->mbrs[j]), mbr, - sizeof(switch_vlan_interface_t)) == 0) { - found = j; - break; - } - } - - // (add and entry is already present) or (delete and entry is not found) - if ((add && (found != -1)) || (!add && (found == -1))) { - continue; - } - - if (add) { - if (mcast_info->mbr_count_max == mcast_info->mbr_count) { - mcast_info->mbrs = switch_realloc(mcast_info->mbrs, - (sizeof(switch_vlan_interface_t) * - (mcast_info->mbr_count_max + 16))); - if (!mcast_info->mbrs) { - return; - } - mcast_info->mbr_count_max += 16; - } - mcast_info->mbrs[mcast_info->mbr_count] = *mbr; - mcast_info->mbr_count++; - } else { - mcast_info->mbrs[found] = mcast_info->mbrs[mcast_info->mbr_count-1]; - mcast_info->mbr_count--; - } + } else { + if (lag_index) { + SWITCH_MC_LAG_MAP_CLEAR_(SWITCH_MCAST_NODE_INFO_LAG_MAP(node), lag_index); + } else { + SWITCH_MC_PORT_MAP_CLEAR_(SWITCH_MCAST_NODE_INFO_PORT_MAP(node), port_id); } + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_mcast_rid_get(switch_handle_t bd_handle, - switch_handle_t intf_handle, - switch_rid_t *rid) -{ - switch_bd_info_t *bd_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_ln_member_t *ln_member = NULL; - - *rid = 0; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; +static void switch_mcast_update_mcast_info(switch_mcast_info_t *mcast_info, + uint16_t mbr_count, + switch_vlan_interface_t *mbrs, + bool add) { + int i = 0, j = 0; + + for (i = 0; i < mbr_count; i++) { + switch_vlan_interface_t *mbr = &mbrs[i]; + int found = -1; + for (j = 0; j < mcast_info->mbr_count; j++) { + if (memcmp(&(mcast_info->mbrs[j]), + mbr, + sizeof(switch_vlan_interface_t)) == 0) { + found = j; + break; + } } - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; + // (add and entry is already present) or (delete and entry is not found) + if ((add && (found != -1)) || (!add && (found == -1))) { + continue; } - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL || - SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_PORT_VLAN) { - ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); - if (!ln_member) { - return SWITCH_STATUS_FAILURE; + if (add) { + if (mcast_info->mbr_count_max == mcast_info->mbr_count) { + mcast_info->mbrs = switch_realloc(mcast_info->mbrs, + (sizeof(switch_vlan_interface_t) * + (mcast_info->mbr_count_max + 16))); + if (!mcast_info->mbrs) { + return; } - *rid = ln_member->rid; + mcast_info->mbr_count_max += 16; + } + mcast_info->mbrs[mcast_info->mbr_count] = *mbr; + mcast_info->mbr_count++; } else { - *rid = bd_info->rid; + mcast_info->mbrs[found] = mcast_info->mbrs[mcast_info->mbr_count - 1]; + mcast_info->mbr_count--; } - return SWITCH_STATUS_SUCCESS; + } } -switch_status_t -switch_api_multicast_member_add(switch_device_t device, - switch_handle_t mgid_handle, - uint16_t mbr_count, - switch_vlan_interface_t *mbrs) -{ - switch_mcast_info_t *mcast_info = NULL; - switch_mcast_node_t *mcast_node = NULL; - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - 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_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) { - SWITCH_API_ERROR("%s:%d: invalid multicast handle %lx", - __FUNCTION__, __LINE__, mgid_handle); - return SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_mcast_rid_get(switch_handle_t bd_handle, + switch_handle_t intf_handle, + switch_rid_t *rid) { + switch_bd_info_t *bd_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_ln_member_t *ln_member = NULL; + + *rid = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL || + SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L2_PORT_VLAN) { + ln_member = + switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!ln_member) { + return SWITCH_STATUS_FAILURE; } - - for (index = 0; index < mbr_count; index++) { - - bd_handle = mbrs[index].vlan_handle; - if (bd_handle) { - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - SWITCH_API_ERROR("%s:%d: invalid bd handle %lx", - __FUNCTION__, __LINE__, bd_handle); - continue; - } - } - - 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_interface_handle_get( - handle, - bd_handle, - &intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: invalid interface %lx", - __FUNCTION__, __LINE__, - mbrs[index].intf_handle); - continue; - } - } - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info || - (SWITCH_INTF_TYPE(intf_info)== SWITCH_API_INTERFACE_L3_VLAN)) { - SWITCH_API_ERROR("%s:%d: invalid interface %lx", - __FUNCTION__, __LINE__, bd_handle); - continue; - } - if (!bd_handle) { - bd_handle = intf_info->bd_handle; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - } - - status = switch_mcast_rid_get(bd_handle, intf_handle, &rid); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: cannot find valid rid for bd %lx", - __FUNCTION__, __LINE__, bd_handle); - continue; - } - - 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); - if (!mcast_node) { - mcast_node = switch_malloc(sizeof(switch_mcast_node_t), 1); - if (!mcast_node) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(mcast_node, 0, sizeof(switch_mcast_node_t)); - SWITCH_MCAST_NODE_RID(mcast_node) = rid; - new_node = TRUE; - tommy_list_insert_head(&mcast_info->node_list, - &(mcast_node->node), mcast_node); - } - - status = switch_mcast_update_port_map(mcast_node, intf_handle, TRUE); - - // Create a L1 Node - 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); - } else { - status = switch_pd_mcast_update_entry(device, mcast_node); - } - } - - switch_mcast_update_mcast_info(mcast_info, mbr_count, mbrs, true); - return status; + *rid = ln_member->rid; + } else { + *rid = bd_info->rid; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_multicast_member_delete(switch_device_t device, - switch_handle_t mgid_handle, - uint16_t mbr_count, - switch_vlan_interface_t *mbrs) -{ - switch_mcast_info_t *mcast_info = NULL; - switch_mcast_node_t *mcast_node = NULL; - 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) { - return SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_api_multicast_member_add(switch_device_t device, + switch_handle_t mgid_handle, + uint16_t mbr_count, + switch_vlan_interface_t *mbrs) { + switch_mcast_info_t *mcast_info = NULL; + switch_mcast_node_t *mcast_node = NULL; + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + 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_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) { + SWITCH_API_ERROR("%s:%d: invalid multicast handle %lx", + __FUNCTION__, + __LINE__, + mgid_handle); + return SWITCH_STATUS_INVALID_HANDLE; + } + + for (index = 0; index < mbr_count; index++) { + bd_handle = mbrs[index].vlan_handle; + if (bd_handle) { + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR( + "%s:%d: invalid bd handle %lx", __FUNCTION__, __LINE__, bd_handle); + continue; + } } - for (index = 0; index < mbr_count; index++) { - - bd_handle = mbrs[index].vlan_handle; - if (bd_handle) { - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - SWITCH_API_ERROR("%s:%d: invalid bd handle %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_INVALID_VLAN_ID; - } - } - - 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_interface_handle_get( - handle, - bd_handle, - &intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: invalid interface %lx", - __FUNCTION__, __LINE__, - mbrs[index].intf_handle); - return SWITCH_STATUS_INVALID_INTERFACE; - } - } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - if (!bd_handle) { - bd_handle = intf_info->bd_handle; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - } - - status = switch_mcast_rid_get(bd_handle, intf_handle, &rid); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: cannot find valid rid for bd %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_INVALID_INTERFACE; - } - - - mcast_node = switch_mcast_find_node(mcast_info, - SWITCH_NODE_TYPE_SINGLE, - rid); - if (!mcast_node) { - // Found rid but not l1 node. - // This should never happen. - 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); - if (delete_mcast_node) { - status = switch_pd_mcast_mgid_table_delete_entry( - device, mcast_info->mgrp_hdl, mcast_node); - status = switch_pd_mcast_delete_entry(device, mcast_node); - mcast_node = tommy_list_remove_existing(&mcast_info->node_list, - &(mcast_node->node)); - switch_free(mcast_node); - } + 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_interface_handle_get(handle, bd_handle, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: invalid interface %lx", + __FUNCTION__, + __LINE__, + mbrs[index].intf_handle); + continue; + } } - switch_mcast_update_mcast_info(mcast_info, mbr_count, mbrs, false); - return status; -} + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info || + (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_VLAN)) { + SWITCH_API_ERROR( + "%s:%d: invalid interface %lx", __FUNCTION__, __LINE__, bd_handle); + continue; + } + if (!bd_handle) { + bd_handle = intf_info->bd_handle; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + } -switch_status_t -switch_api_multicast_member_get(switch_device_t device, - switch_handle_t mgid_handle, - uint16_t *mbr_count, - switch_vlan_interface_t **mbrs) -{ - switch_mcast_info_t *mcast_info = NULL; - - mcast_info = switch_mcast_tree_get(mgid_handle); - if (!mcast_info) { - return SWITCH_STATUS_INVALID_HANDLE; + status = switch_mcast_rid_get(bd_handle, intf_handle, &rid); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: cannot find valid rid for bd %lx", + __FUNCTION__, + __LINE__, + bd_handle); + continue; } - *mbr_count = mcast_info->mbr_count; - *mbrs = NULL; - if (*mbr_count) { - *mbrs = switch_malloc(sizeof(switch_vlan_interface_t), *mbr_count); - memcpy(*mbrs, mcast_info->mbrs, - sizeof(switch_vlan_interface_t) * (*mbr_count)); + 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); } - return SWITCH_STATUS_SUCCESS; -} -static switch_status_t -switch_mcast_get_rpf_group(switch_mcast_mode_t mc_mode, - switch_handle_t *rpf_bd_list, uint16_t rpf_bd_count, - uint16_t *rpf_group) -{ - if ((mc_mode == SWITCH_API_MCAST_IPMC_NONE) || - ((mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) && (rpf_bd_count != 1)) || - ((mc_mode == SWITCH_API_MCAST_IPMC_PIM_BIDIR) && (!rpf_bd_count))) { - return SWITCH_STATUS_INVALID_PARAMETER; + 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); + if (!mcast_node) { + mcast_node = switch_malloc(sizeof(switch_mcast_node_t), 1); + if (!mcast_node) { + return SWITCH_STATUS_NO_MEMORY; + } + memset(mcast_node, 0, sizeof(switch_mcast_node_t)); + SWITCH_MCAST_NODE_RID(mcast_node) = rid; + new_node = TRUE; + tommy_list_insert_head( + &mcast_info->node_list, &(mcast_node->node), mcast_node); } - if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_BIDIR) { - if (rpf_bd_count != 1) { - return SWITCH_STATUS_INVALID_PARAMETER; - } - *rpf_group = rpf_bd_list[0]; - return SWITCH_STATUS_SUCCESS; + status = switch_mcast_update_port_map(mcast_node, intf_handle, TRUE); + + // Create a L1 Node + 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); + } else { + status = switch_pd_mcast_update_entry(device, mcast_node); } + } - switch_handle_t rpf_handle = 0; - switch_handle_type_t rpf_handle_type = 0; + switch_mcast_update_mcast_info(mcast_info, mbr_count, mbrs, true); + return status; +} - rpf_handle = rpf_bd_list[0]; - rpf_handle_type = switch_handle_get_type(rpf_handle); - if ((rpf_handle_type != SWITCH_HANDLE_TYPE_BD) && - (rpf_handle_type != SWITCH_HANDLE_TYPE_INTERFACE)) { - return SWITCH_STATUS_INVALID_PARAMETER; +switch_status_t switch_api_multicast_member_delete( + switch_device_t device, + switch_handle_t mgid_handle, + uint16_t mbr_count, + switch_vlan_interface_t *mbrs) { + switch_mcast_info_t *mcast_info = NULL; + switch_mcast_node_t *mcast_node = NULL; + 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) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + for (index = 0; index < mbr_count; index++) { + bd_handle = mbrs[index].vlan_handle; + if (bd_handle) { + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR( + "%s:%d: invalid bd handle %lx", __FUNCTION__, __LINE__, bd_handle); + return SWITCH_STATUS_INVALID_VLAN_ID; + } } - if (rpf_handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { - switch_interface_info_t *intf_info = NULL; - intf_info = switch_api_interface_get(rpf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: invalid interface handle %lx", - __FUNCTION__, __LINE__, rpf_handle); - return SWITCH_STATUS_INVALID_INTERFACE; - } - rpf_handle = intf_info->bd_handle; + 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_interface_handle_get(handle, bd_handle, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: invalid interface %lx", + __FUNCTION__, + __LINE__, + mbrs[index].intf_handle); + return SWITCH_STATUS_INVALID_INTERFACE; + } + } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; } - switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(rpf_handle); - if (!bd_info) { - SWITCH_API_ERROR("%s:%d: invalid rpf handle %lx", - __FUNCTION__, __LINE__, rpf_bd_list[0]); + if (!bd_handle) { + bd_handle = intf_info->bd_handle; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { return SWITCH_STATUS_INVALID_VLAN_ID; + } } - *rpf_group = handle_to_id(rpf_handle); - - return SWITCH_STATUS_SUCCESS; -} -switch_status_t -switch_api_multicast_mroute_add(switch_device_t device, - switch_handle_t mgid_handle, - switch_handle_t vrf_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip, - switch_mcast_mode_t mc_mode, - switch_handle_t *rpf_bd_list, - uint16_t rpf_bd_count) -{ - switch_mcast_group_info_t *group_info = NULL; - switch_mcast_group_key_t *group_key = NULL; - switch_vrf_info_t *vrf_info = NULL; - switch_mcast_group_key_t group_key_temp; - switch_status_t status = SWITCH_STATUS_SUCCESS; - bool core_entry = false; - uint16_t rpf_group = 0; - - status = switch_mcast_get_rpf_group(mc_mode, rpf_bd_list, rpf_bd_count, - &rpf_group); + status = switch_mcast_rid_get(bd_handle, intf_handle, &rid); if (status != SWITCH_STATUS_SUCCESS) { - return status; + SWITCH_API_ERROR("%s:%d: cannot find valid rid for bd %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_INVALID_INTERFACE; } - group_key = &group_key_temp; - memset(group_key, 0, sizeof(switch_mcast_group_key_t)); - memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); - memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); - group_key->bd_vrf_handle = vrf_handle; - group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + mcast_node = + switch_mcast_find_node(mcast_info, SWITCH_NODE_TYPE_SINGLE, rid); + if (!mcast_node) { + // Found rid but not l1 node. + // This should never happen. + return SWITCH_STATUS_ITEM_NOT_FOUND; + } - group_info = switch_mcast_group_search_hash(group_key); - if (!group_info) { - group_info = switch_mcast_group_insert_hash(group_key); - if (!group_info) { - return SWITCH_STATUS_NO_MEMORY; - } + 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; } - vrf_info = switch_vrf_get(vrf_handle); - if (!vrf_info) { - return SWITCH_STATUS_INVALID_HANDLE; + 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); } - if (SWITCH_VRF_IS_CORE(vrf_info)) { - core_entry = TRUE; + + status = switch_mcast_update_port_map(mcast_node, intf_handle, FALSE); + delete_mcast_node = switch_mcast_node_empty(mcast_node); + if (delete_mcast_node) { + status = switch_pd_mcast_mgid_table_delete_entry( + device, mcast_info->mgrp_hdl, mcast_node); + status = switch_pd_mcast_delete_entry(device, mcast_node); + mcast_node = tommy_list_remove_existing(&mcast_info->node_list, + &(mcast_node->node)); + switch_free(mcast_node); } + } - group_info->mgid_handle = mgid_handle; - status = switch_pd_mcast_table_add_entry(device, - handle_to_id(mgid_handle), - mc_mode, group_info, - core_entry, TRUE, rpf_group); - return status; + switch_mcast_update_mcast_info(mcast_info, mbr_count, mbrs, false); + return status; } -switch_status_t -switch_api_multicast_mroute_delete(switch_device_t device, - switch_handle_t vrf_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip) -{ - switch_mcast_group_info_t *group_info = NULL; - switch_mcast_group_key_t *group_key = NULL; - switch_vrf_info_t *vrf_info = NULL; - switch_mcast_group_key_t group_key_temp; - switch_status_t status = SWITCH_STATUS_SUCCESS; - bool core_entry = FALSE; - - group_key = &group_key_temp; - memset(group_key, 0, sizeof(switch_mcast_group_key_t)); - memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); - memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); - group_key->bd_vrf_handle = vrf_handle; - group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; - - group_info = switch_mcast_group_search_hash(group_key); - if (!group_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } +switch_status_t switch_api_multicast_member_get( + switch_device_t device, + switch_handle_t mgid_handle, + uint16_t *mbr_count, + switch_vlan_interface_t **mbrs) { + switch_mcast_info_t *mcast_info = NULL; + + mcast_info = switch_mcast_tree_get(mgid_handle); + if (!mcast_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + *mbr_count = mcast_info->mbr_count; + *mbrs = NULL; + if (*mbr_count) { + *mbrs = switch_malloc(sizeof(switch_vlan_interface_t), *mbr_count); + memcpy(*mbrs, + mcast_info->mbrs, + sizeof(switch_vlan_interface_t) * (*mbr_count)); + } + return SWITCH_STATUS_SUCCESS; +} - vrf_info = switch_vrf_get(vrf_handle); - if (!vrf_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if (SWITCH_VRF_IS_CORE(vrf_info)) { - core_entry = TRUE; +static switch_status_t switch_mcast_get_rpf_group(switch_mcast_mode_t mc_mode, + switch_handle_t *rpf_bd_list, + uint16_t rpf_bd_count, + uint16_t *rpf_group) { + if ((mc_mode == SWITCH_API_MCAST_IPMC_NONE) || + ((mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) && (rpf_bd_count != 1)) || + ((mc_mode == SWITCH_API_MCAST_IPMC_PIM_BIDIR) && (!rpf_bd_count))) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_BIDIR) { + if (rpf_bd_count != 1) { + return SWITCH_STATUS_INVALID_PARAMETER; } + *rpf_group = rpf_bd_list[0]; + return SWITCH_STATUS_SUCCESS; + } - status = switch_pd_mcast_table_delete_entry(device, group_info, - core_entry, TRUE); + switch_handle_t rpf_handle = 0; + switch_handle_type_t rpf_handle_type = 0; - switch_mcast_group_delete_hash(group_key); - return status; + rpf_handle = rpf_bd_list[0]; + rpf_handle_type = switch_handle_get_type(rpf_handle); + if ((rpf_handle_type != SWITCH_HANDLE_TYPE_BD) && + (rpf_handle_type != SWITCH_HANDLE_TYPE_INTERFACE)) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + if (rpf_handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { + switch_interface_info_t *intf_info = NULL; + intf_info = switch_api_interface_get(rpf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d: invalid interface handle %lx", + __FUNCTION__, + __LINE__, + rpf_handle); + return SWITCH_STATUS_INVALID_INTERFACE; + } + rpf_handle = intf_info->bd_handle; + } + + switch_bd_info_t *bd_info = NULL; + bd_info = switch_bd_get(rpf_handle); + if (!bd_info) { + SWITCH_API_ERROR("%s:%d: invalid rpf handle %lx", + __FUNCTION__, + __LINE__, + rpf_bd_list[0]); + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *rpf_group = handle_to_id(rpf_handle); + + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_multicast_mroute_tree_get(switch_device_t device, - switch_handle_t vrf_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip, - switch_handle_t *mgid_handle) -{ - switch_mcast_group_info_t *group_info = NULL; - switch_mcast_group_key_t *group_key = NULL; - switch_mcast_group_key_t group_key_temp; - - group_key = &group_key_temp; - memset(group_key, 0, sizeof(switch_mcast_group_key_t)); - memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); - memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); - group_key->bd_vrf_handle = vrf_handle; - group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; - - group_info = switch_mcast_group_search_hash(group_key); +switch_status_t switch_api_multicast_mroute_add(switch_device_t device, + switch_handle_t mgid_handle, + switch_handle_t vrf_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip, + switch_mcast_mode_t mc_mode, + switch_handle_t *rpf_bd_list, + uint16_t rpf_bd_count) { + switch_mcast_group_info_t *group_info = NULL; + switch_mcast_group_key_t *group_key = NULL; + switch_vrf_info_t *vrf_info = NULL; + switch_mcast_group_key_t group_key_temp; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool core_entry = false; + uint16_t rpf_group = 0; + + status = switch_mcast_get_rpf_group( + mc_mode, rpf_bd_list, rpf_bd_count, &rpf_group); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + + group_key = &group_key_temp; + memset(group_key, 0, sizeof(switch_mcast_group_key_t)); + memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); + memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); + group_key->bd_vrf_handle = vrf_handle; + group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + + group_info = switch_mcast_group_search_hash(group_key); + if (!group_info) { + group_info = switch_mcast_group_insert_hash(group_key); if (!group_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + return SWITCH_STATUS_NO_MEMORY; } + } + + vrf_info = switch_vrf_get(vrf_handle); + if (!vrf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if (SWITCH_VRF_IS_CORE(vrf_info)) { + core_entry = TRUE; + } + + group_info->mgid_handle = mgid_handle; + status = switch_pd_mcast_table_add_entry(device, + handle_to_id(mgid_handle), + mc_mode, + group_info, + core_entry, + TRUE, + rpf_group); + return status; +} - *mgid_handle = group_info->mgid_handle; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_multicast_mroute_delete( + switch_device_t device, + switch_handle_t vrf_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip) { + switch_mcast_group_info_t *group_info = NULL; + switch_mcast_group_key_t *group_key = NULL; + switch_vrf_info_t *vrf_info = NULL; + switch_mcast_group_key_t group_key_temp; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool core_entry = FALSE; + + group_key = &group_key_temp; + memset(group_key, 0, sizeof(switch_mcast_group_key_t)); + memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); + memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); + group_key->bd_vrf_handle = vrf_handle; + group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + + group_info = switch_mcast_group_search_hash(group_key); + if (!group_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + vrf_info = switch_vrf_get(vrf_handle); + if (!vrf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if (SWITCH_VRF_IS_CORE(vrf_info)) { + core_entry = TRUE; + } + + status = + switch_pd_mcast_table_delete_entry(device, group_info, core_entry, TRUE); + + switch_mcast_group_delete_hash(group_key); + return status; +} + +switch_status_t switch_api_multicast_mroute_tree_get( + switch_device_t device, + switch_handle_t vrf_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip, + switch_handle_t *mgid_handle) { + switch_mcast_group_info_t *group_info = NULL; + switch_mcast_group_key_t *group_key = NULL; + switch_mcast_group_key_t group_key_temp; + + group_key = &group_key_temp; + memset(group_key, 0, sizeof(switch_mcast_group_key_t)); + memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); + memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); + group_key->bd_vrf_handle = vrf_handle; + group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + + group_info = switch_mcast_group_search_hash(group_key); + if (!group_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + *mgid_handle = group_info->mgid_handle; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_multicast_l2route_add(switch_device_t device, - switch_handle_t mgid_handle, - switch_handle_t bd_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip) -{ - switch_mcast_group_info_t *group_info = NULL; - switch_mcast_group_key_t *group_key = NULL; - switch_bd_info_t *bd_info = NULL; - switch_mcast_group_key_t group_key_temp; - switch_status_t status = SWITCH_STATUS_SUCCESS; - bool core_entry = FALSE; - switch_mcast_mode_t mc_mode = SWITCH_API_MCAST_IPMC_NONE; - - group_key = &group_key_temp; - memset(group_key, 0, sizeof(switch_mcast_group_key_t)); - memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); - memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); - group_key->bd_vrf_handle = bd_handle; - group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; - - group_info = switch_mcast_group_search_hash(group_key); +switch_status_t switch_api_multicast_l2route_add( + switch_device_t device, + switch_handle_t mgid_handle, + switch_handle_t bd_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip) { + switch_mcast_group_info_t *group_info = NULL; + switch_mcast_group_key_t *group_key = NULL; + switch_bd_info_t *bd_info = NULL; + switch_mcast_group_key_t group_key_temp; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool core_entry = FALSE; + switch_mcast_mode_t mc_mode = SWITCH_API_MCAST_IPMC_NONE; + + group_key = &group_key_temp; + memset(group_key, 0, sizeof(switch_mcast_group_key_t)); + memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); + memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); + group_key->bd_vrf_handle = bd_handle; + group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + + group_info = switch_mcast_group_search_hash(group_key); + if (!group_info) { + group_info = switch_mcast_group_insert_hash(group_key); if (!group_info) { - group_info = switch_mcast_group_insert_hash(group_key); - if (!group_info) { - return SWITCH_STATUS_NO_MEMORY; - } + return SWITCH_STATUS_NO_MEMORY; } + } - if (SWITCH_HANDLE_IS_BD(bd_handle)) { - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if (SWITCH_BD_IS_CORE(bd_info)) { - core_entry = TRUE; - } + if (SWITCH_HANDLE_IS_BD(bd_handle)) { + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; } - - group_info->mgid_handle = mgid_handle; - status = switch_pd_mcast_table_add_entry(device, - handle_to_id(mgid_handle), - mc_mode, group_info, - core_entry, FALSE, 0); - return status; + if (SWITCH_BD_IS_CORE(bd_info)) { + core_entry = TRUE; + } + } + + group_info->mgid_handle = mgid_handle; + status = switch_pd_mcast_table_add_entry(device, + handle_to_id(mgid_handle), + mc_mode, + group_info, + core_entry, + FALSE, + 0); + return status; } -switch_status_t -switch_api_multicast_l2route_delete(switch_device_t device, - switch_handle_t bd_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip) -{ - switch_mcast_group_info_t *group_info = NULL; - switch_mcast_group_key_t *group_key = NULL; - switch_bd_info_t *bd_info = NULL; - switch_mcast_group_key_t group_key_temp; - switch_status_t status = SWITCH_STATUS_SUCCESS; - bool core_entry = FALSE; - - group_key = &group_key_temp; - memset(group_key, 0, sizeof(switch_mcast_group_key_t)); - memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); - memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); - group_key->bd_vrf_handle = bd_handle; - group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; - - group_info = switch_mcast_group_search_hash(group_key); - if (!group_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; +switch_status_t switch_api_multicast_l2route_delete( + switch_device_t device, + switch_handle_t bd_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip) { + switch_mcast_group_info_t *group_info = NULL; + switch_mcast_group_key_t *group_key = NULL; + switch_bd_info_t *bd_info = NULL; + switch_mcast_group_key_t group_key_temp; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool core_entry = FALSE; + + group_key = &group_key_temp; + memset(group_key, 0, sizeof(switch_mcast_group_key_t)); + memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); + memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); + group_key->bd_vrf_handle = bd_handle; + group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + + group_info = switch_mcast_group_search_hash(group_key); + if (!group_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + if (SWITCH_HANDLE_IS_BD(bd_handle)) { + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; } - - if (SWITCH_HANDLE_IS_BD(bd_handle)) { - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if (SWITCH_BD_IS_CORE(bd_info)) { - core_entry = TRUE; - } + if (SWITCH_BD_IS_CORE(bd_info)) { + core_entry = TRUE; } + } - status = switch_pd_mcast_table_delete_entry(device, - group_info, - core_entry, FALSE); + status = + switch_pd_mcast_table_delete_entry(device, group_info, core_entry, FALSE); - switch_mcast_group_delete_hash(group_key); - return status; + switch_mcast_group_delete_hash(group_key); + return status; } -switch_status_t -switch_api_multicast_l2route_tree_get(switch_device_t device, - switch_handle_t bd_handle, - const switch_ip_addr_t *src_ip, - const switch_ip_addr_t *grp_ip, - switch_handle_t *mgid_handle) -{ - switch_mcast_group_info_t *group_info = NULL; - switch_mcast_group_key_t *group_key = NULL; - switch_mcast_group_key_t group_key_temp; - - group_key = &group_key_temp; - memset(group_key, 0, sizeof(switch_mcast_group_key_t)); - memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); - memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); - group_key->bd_vrf_handle = bd_handle; - group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; - - group_info = switch_mcast_group_search_hash(group_key); - if (!group_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - *mgid_handle = group_info->mgid_handle; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_multicast_l2route_tree_get( + switch_device_t device, + switch_handle_t bd_handle, + const switch_ip_addr_t *src_ip, + const switch_ip_addr_t *grp_ip, + switch_handle_t *mgid_handle) { + switch_mcast_group_info_t *group_info = NULL; + switch_mcast_group_key_t *group_key = NULL; + switch_mcast_group_key_t group_key_temp; + + group_key = &group_key_temp; + memset(group_key, 0, sizeof(switch_mcast_group_key_t)); + memcpy(&group_key->src_ip, src_ip, sizeof(switch_ip_addr_t)); + memcpy(&group_key->grp_ip, grp_ip, sizeof(switch_ip_addr_t)); + group_key->bd_vrf_handle = bd_handle; + group_key->sg_entry = (group_key->src_ip.prefix_len == 0) ? false : true; + + group_info = switch_mcast_group_search_hash(group_key); + if (!group_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + *mgid_handle = group_info->mgid_handle; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_multicast_update_lag_port_map(switch_device_t device, switch_handle_t lag_handle) -{ - switch_lag_info_t *lag_info = NULL; - switch_lag_member_t *lag_member = NULL; - tommy_node *node = NULL; - switch_mc_port_map_t port_map; - switch_port_t port_id = 0; - uint16_t lag_index = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - lag_info = switch_api_lag_get_internal(lag_handle); - if (!lag_info) { - SWITCH_API_ERROR("%s:%d: invalid lag handle", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_HANDLE; - } - memset(port_map, 0, sizeof(switch_mc_port_map_t)); - lag_index = handle_to_id(lag_handle); - node = tommy_list_head(&(lag_info->egress)); - while (node) { - lag_member = node->data; - port_id = lag_member->port; - SWITCH_MC_PORT_MAP_SET_(port_map, port_id); - node = node->next; - } - status = switch_pd_mcast_lag_port_map_update(device, lag_index, port_map); - return status; +switch_status_t switch_multicast_update_lag_port_map( + switch_device_t device, switch_handle_t lag_handle) { + switch_lag_info_t *lag_info = NULL; + switch_lag_member_t *lag_member = NULL; + tommy_node *node = NULL; + switch_mc_port_map_t port_map; + switch_port_t port_id = 0; + uint16_t lag_index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + lag_info = switch_api_lag_get_internal(lag_handle); + if (!lag_info) { + SWITCH_API_ERROR("%s:%d: invalid lag handle", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_HANDLE; + } + memset(port_map, 0, sizeof(switch_mc_port_map_t)); + lag_index = handle_to_id(lag_handle); + node = tommy_list_head(&(lag_info->egress)); + while (node) { + lag_member = node->data; + port_id = lag_member->port; + SWITCH_MC_PORT_MAP_SET_(port_map, port_id); + node = node->next; + } + status = switch_pd_mcast_lag_port_map_update(device, lag_index, port_map); + return status; } #ifdef __cplusplus diff --git a/switchapi/src/switch_mcast_int.h b/switchapi/src/switch_mcast_int.h index 2788f89..6228e7a 100644 --- a/switchapi/src/switch_mcast_int.h +++ b/switchapi/src/switch_mcast_int.h @@ -26,161 +26,147 @@ limitations under the License. extern "C" { #endif /* __cplusplus */ - -#define SWITCH_MCAST_RID_HASH_KEY_SIZE 24 +#define SWITCH_MCAST_RID_HASH_KEY_SIZE 24 #define SWITCH_MCAST_GROUP_HASH_KEY_SIZE 64 typedef uint16_t switch_rid_t; typedef uint32_t mc_mgrp_hdl_t; -#define SWITCH_PORT_ARRAY_SIZE ((SWITCH_API_MAX_PORTS + 7)/8) +#define SWITCH_PORT_ARRAY_SIZE ((SWITCH_API_MAX_PORTS + 7) / 8) typedef uint8_t switch_mc_port_map_t[SWITCH_PORT_ARRAY_SIZE]; -#define SWITCH_LAG_ARRAY_SIZE ((SWITCH_API_MAX_LAG + 7)/8) +#define SWITCH_LAG_ARRAY_SIZE ((SWITCH_API_MAX_LAG + 7) / 8) typedef uint8_t switch_mc_lag_map_t[SWITCH_LAG_ARRAY_SIZE]; -#define SWITCH_MC_PORT_MAP_CLEAR_(pm, port) \ - do { \ - int _port_p = (port); \ - switch_mc_port_map_t *_port_pm = &(pm); \ - if (_port_p >= SWITCH_API_MAX_PORTS) break; \ - size_t _port_i = (_port_p)/8; \ - int _port_j = (_port_p) % 8; \ - (*_port_pm)[_port_i] &= ~(1 << _port_j); \ +#define SWITCH_MC_PORT_MAP_CLEAR_(pm, port) \ + do { \ + int _port_p = (port); \ + switch_mc_port_map_t *_port_pm = &(pm); \ + if (_port_p >= SWITCH_API_MAX_PORTS) break; \ + size_t _port_i = (_port_p) / 8; \ + int _port_j = (_port_p) % 8; \ + (*_port_pm)[_port_i] &= ~(1 << _port_j); \ } while (0); -#define SWITCH_MC_PORT_MAP_SET_(pm, port) \ - do { \ - int _port_p = (port); \ - switch_mc_port_map_t *_port_pm = &(pm); \ - if (_port_p >= SWITCH_API_MAX_PORTS) break; \ - size_t _port_i = (_port_p)/8; \ - int _port_j = (_port_p) % 8; \ - (*_port_pm)[_port_i] |= (1 << _port_j); \ +#define SWITCH_MC_PORT_MAP_SET_(pm, port) \ + do { \ + int _port_p = (port); \ + switch_mc_port_map_t *_port_pm = &(pm); \ + if (_port_p >= SWITCH_API_MAX_PORTS) break; \ + size_t _port_i = (_port_p) / 8; \ + int _port_j = (_port_p) % 8; \ + (*_port_pm)[_port_i] |= (1 << _port_j); \ } while (0); -#define SWITCH_MC_LAG_MAP_CLEAR_(pm, lag) \ - do { \ - int _lag_p = (lag); \ - switch_mc_lag_map_t *_lag_pm = &(pm); \ - if (_lag_p >= SWITCH_API_MAX_LAG) break; \ - size_t _lag_i = (_lag_p)/8; \ - int _lag_j = (_lag_p)%8; \ - (*_lag_pm)[_lag_i] &= ~(1 << _lag_j); \ +#define SWITCH_MC_LAG_MAP_CLEAR_(pm, lag) \ + do { \ + int _lag_p = (lag); \ + switch_mc_lag_map_t *_lag_pm = &(pm); \ + if (_lag_p >= SWITCH_API_MAX_LAG) break; \ + size_t _lag_i = (_lag_p) / 8; \ + int _lag_j = (_lag_p) % 8; \ + (*_lag_pm)[_lag_i] &= ~(1 << _lag_j); \ } while (0); -#define SWITCH_MC_LAG_MAP_SET_(pm, lag) \ - do { \ - int _lag_p = (lag); \ - switch_mc_lag_map_t *_lag_pm = &(pm); \ - if (_lag_p >= SWITCH_API_MAX_LAG) break; \ - size_t _lag_i = (_lag_p)/8; \ - int _lag_j = (_lag_p)%8; \ - (*_lag_pm)[_lag_i] |= (1 << _lag_j); \ +#define SWITCH_MC_LAG_MAP_SET_(pm, lag) \ + do { \ + int _lag_p = (lag); \ + switch_mc_lag_map_t *_lag_pm = &(pm); \ + if (_lag_p >= SWITCH_API_MAX_LAG) break; \ + size_t _lag_i = (_lag_p) / 8; \ + int _lag_j = (_lag_p) % 8; \ + (*_lag_pm)[_lag_i] |= (1 << _lag_j); \ } while (0); typedef enum switch_mcast_node_type_ { - SWITCH_NODE_TYPE_SINGLE = 1, + SWITCH_NODE_TYPE_SINGLE = 1, } switch_mcast_node_type_t; typedef struct switch_mcast_node_info_ { - switch_rid_t rid; - switch_mc_port_map_t port_map; - switch_mc_lag_map_t lag_map; - p4_pd_entry_hdl_t hw_entry; - p4_pd_entry_hdl_t rid_hw_entry; + switch_rid_t rid; + switch_mc_port_map_t port_map; + switch_mc_lag_map_t lag_map; + p4_pd_entry_hdl_t hw_entry; + 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; + 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; - union { - switch_mcast_node_info_t node_info; - } u; + tommy_node node; + switch_mcast_node_type_t node_type; + union { + switch_mcast_node_info_t node_info; + } u; } switch_mcast_node_t; typedef struct switch_mcast_info_ { - p4_pd_entry_hdl_t mgrp_hdl; - tommy_list node_list; - uint16_t mbr_count_max; - uint16_t mbr_count; - switch_vlan_interface_t *mbrs; + p4_pd_entry_hdl_t mgrp_hdl; + tommy_list node_list; + uint16_t mbr_count_max; + uint16_t mbr_count; + switch_vlan_interface_t *mbrs; } switch_mcast_info_t; typedef struct switch_mcast_rid_key_ { - switch_handle_t mgid_handle; - switch_handle_t bd_handle; - switch_handle_t intf_handle; + switch_handle_t mgid_handle; + switch_handle_t bd_handle; + switch_handle_t intf_handle; } switch_mcast_rid_key_t; typedef struct switch_mcast_rid_ { - switch_mcast_rid_key_t rid_key; - uint16_t rid; - tommy_hashtable_node node; + switch_mcast_rid_key_t rid_key; + uint16_t rid; + tommy_hashtable_node node; } switch_mcast_rid_t; typedef struct switch_mcast_group_key_ { - switch_handle_t bd_vrf_handle; - switch_ip_addr_t src_ip; - switch_ip_addr_t grp_ip; - bool sg_entry; + switch_handle_t bd_vrf_handle; + switch_ip_addr_t src_ip; + switch_ip_addr_t grp_ip; + bool sg_entry; } switch_mcast_group_key_t; typedef struct switch_mcast_group_info_ { - switch_mcast_group_key_t group_key; - tommy_hashtable_node node; - switch_handle_t mgid_handle; - p4_pd_entry_hdl_t outer_hw_entry; - p4_pd_entry_hdl_t inner_hw_entry; + switch_mcast_group_key_t group_key; + tommy_hashtable_node node; + switch_handle_t mgid_handle; + p4_pd_entry_hdl_t outer_hw_entry; + p4_pd_entry_hdl_t inner_hw_entry; } switch_mcast_group_info_t; typedef enum switch_mcast_key_type_ { - SWITCH_MCAST_KEY_TYPE_BD, - SWITCH_MCAST_KEY_TYPE_VRF + SWITCH_MCAST_KEY_TYPE_BD, + SWITCH_MCAST_KEY_TYPE_VRF } switch_mcast_key_type_t; -#define SWITCH_MCAST_NODE_RID(node) \ - node->u.node_info.rid +#define SWITCH_MCAST_NODE_RID(node) node->u.node_info.rid -#define SWITCH_MCAST_NODE_RID_HW_ENTRY(node) \ - node->u.node_info.rid_hw_entry +#define SWITCH_MCAST_NODE_RID_HW_ENTRY(node) node->u.node_info.rid_hw_entry -#define SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key) \ - group_key->src_ip.ip.v4addr +#define SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key) group_key->src_ip.ip.v4addr -#define SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key) \ - group_key->src_ip.ip.v6addr +#define SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key) group_key->src_ip.ip.v6addr -#define SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key) \ - group_key->grp_ip.ip.v4addr +#define SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key) group_key->grp_ip.ip.v4addr -#define SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key) \ - group_key->grp_ip.ip.v6addr +#define SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key) group_key->grp_ip.ip.v6addr -#define SWITCH_MCAST_GROUP_IP_TYPE(group_key) \ - group_key->grp_ip.type +#define SWITCH_MCAST_GROUP_IP_TYPE(group_key) group_key->grp_ip.type -#define SWITCH_MCAST_NODE_INFO_HW_ENTRY(node) \ - node->u.node_info.hw_entry +#define SWITCH_MCAST_NODE_INFO_HW_ENTRY(node) node->u.node_info.hw_entry -#define SWITCH_MCAST_NODE_INFO_PORT_MAP(node) \ - node->u.node_info.port_map +#define SWITCH_MCAST_NODE_INFO_PORT_MAP(node) node->u.node_info.port_map -#define SWITCH_MCAST_NODE_INFO_LAG_MAP(node) \ - node->u.node_info.lag_map +#define SWITCH_MCAST_NODE_INFO_LAG_MAP(node) node->u.node_info.lag_map -#define SWITCH_MCAST_ECMP_INFO_HW_ENTRY(node) \ - node->u.ecmp_info.hw_entry +#define SWITCH_MCAST_ECMP_INFO_HW_ENTRY(node) node->u.ecmp_info.hw_entry -#define SWITCH_MCAST_ECMP_INFO_NODE_LIST(node) \ - node->u.ecmp_info.node_list +#define SWITCH_MCAST_ECMP_INFO_NODE_LIST(node) node->u.ecmp_info.node_list -#define SWITCH_MCAST_ECMP_INFO_HDL(node) \ - node->u.ecmp_info.handle +#define SWITCH_MCAST_ECMP_INFO_HDL(node) node->u.ecmp_info.handle /* MCAST Internal API's */ switch_status_t switch_mcast_init(switch_device_t device); @@ -188,9 +174,11 @@ switch_status_t switch_mcast_free(switch_device_t device); uint16_t switch_mcast_rid_allocate(); void switch_mcast_rid_free(uint16_t rid); switch_handle_t switch_api_mcast_index_allocate(switch_device_t device); -switch_status_t switch_api_mcast_index_delete(switch_device_t device, switch_handle_t mgid_handle); -switch_mcast_info_t * switch_mcast_tree_get(switch_handle_t mgid_handle); -switch_status_t switch_multicast_update_lag_port_map(switch_device_t device, switch_handle_t lag_handle); +switch_status_t switch_api_mcast_index_delete(switch_device_t device, + switch_handle_t mgid_handle); +switch_mcast_info_t *switch_mcast_tree_get(switch_handle_t mgid_handle); +switch_status_t switch_multicast_update_lag_port_map( + switch_device_t device, switch_handle_t lag_handle); #ifdef __cplusplus } diff --git a/switchapi/src/switch_meter.c b/switchapi/src/switch_meter.c index 29366e8..3b51f75 100644 --- a/switchapi/src/switch_meter.c +++ b/switchapi/src/switch_meter.c @@ -22,196 +22,172 @@ limitations under the License. static void *switch_meter_array = NULL; -switch_status_t -switch_meter_init(switch_device_t device) -{ - switch_meter_array = NULL; - switch_handle_type_init(SWITCH_HANDLE_TYPE_METER, (1024)); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_meter_init(switch_device_t device) { + switch_meter_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_METER, (1024)); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_meter_create() -{ - switch_handle_t meter_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_METER, - switch_meter_info_t, - switch_meter_array, - NULL, meter_handle); - return meter_handle; +switch_handle_t switch_meter_create() { + switch_handle_t meter_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_METER, + switch_meter_info_t, + switch_meter_array, + NULL, + meter_handle); + return meter_handle; } -switch_meter_info_t * -switch_meter_info_get(switch_handle_t meter_handle) -{ - switch_meter_info_t *meter_info = NULL; - _switch_handle_get(switch_meter_info_t, switch_meter_array, meter_handle, meter_info); - return meter_info; +switch_meter_info_t *switch_meter_info_get(switch_handle_t meter_handle) { + switch_meter_info_t *meter_info = NULL; + _switch_handle_get( + switch_meter_info_t, switch_meter_array, meter_handle, meter_info); + return meter_info; } -switch_status_t -switch_meter_delete(switch_handle_t meter_handle) -{ - _switch_handle_delete(switch_meter_info_t, - switch_meter_array, - meter_handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_meter_delete(switch_handle_t meter_handle) { + _switch_handle_delete(switch_meter_info_t, switch_meter_array, meter_handle); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_meter_create( - switch_device_t device, - switch_api_meter_t *api_meter_info) -{ - switch_meter_info_t *meter_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t meter_handle = 0; - - meter_handle = switch_meter_create(); - meter_info = switch_meter_info_get(meter_handle); - if (!meter_info) { - return SWITCH_API_INVALID_HANDLE; - } - - memcpy(&meter_info->api_meter_info, api_meter_info, sizeof(switch_api_meter_t)); - - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - meter_info->stats_info = switch_malloc(sizeof(switch_meter_stats_info_t), 1); - if (!meter_info->stats_info) { - return SWITCH_API_INVALID_HANDLE; - } - - memset(meter_info->stats_info, 0, sizeof(switch_meter_stats_info_t)); - - if (api_meter_info->meter_mode == SWITCH_METER_MODE_STORM_CONTROL) { - meter_info->api_meter_info.pbs = meter_info->api_meter_info.cbs; - meter_info->api_meter_info.pir = meter_info->api_meter_info.cir; - meter_info->api_meter_info.action[SWITCH_METER_COLOR_YELLOW] = - meter_info->api_meter_info.action[SWITCH_METER_COLOR_GREEN]; - status = switch_pd_storm_control_meter_add_entry( - device, - handle_to_id(meter_handle), - meter_info); - } else { - status = switch_pd_meter_index_table_add_entry( - device, - handle_to_id(meter_handle), - meter_info, - &meter_info->meter_idx_pd_hdl); - } - - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - status = switch_pd_meter_action_table_add_entry( - device, - handle_to_id(meter_handle), - meter_info, - meter_info->action_pd_hdl); - - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - return meter_handle; +switch_handle_t switch_api_meter_create(switch_device_t device, + switch_api_meter_t *api_meter_info) { + switch_meter_info_t *meter_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t meter_handle = 0; + + meter_handle = switch_meter_create(); + meter_info = switch_meter_info_get(meter_handle); + if (!meter_info) { + return SWITCH_API_INVALID_HANDLE; + } + + memcpy( + &meter_info->api_meter_info, api_meter_info, sizeof(switch_api_meter_t)); + + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + + meter_info->stats_info = switch_malloc(sizeof(switch_meter_stats_info_t), 1); + if (!meter_info->stats_info) { + return SWITCH_API_INVALID_HANDLE; + } + + memset(meter_info->stats_info, 0, sizeof(switch_meter_stats_info_t)); + + if (api_meter_info->meter_mode == SWITCH_METER_MODE_STORM_CONTROL) { + meter_info->api_meter_info.pbs = meter_info->api_meter_info.cbs; + meter_info->api_meter_info.pir = meter_info->api_meter_info.cir; + meter_info->api_meter_info.action[SWITCH_COLOR_YELLOW] = + meter_info->api_meter_info.action[SWITCH_COLOR_GREEN]; + status = switch_pd_storm_control_meter_add_entry( + device, handle_to_id(meter_handle), meter_info); + } else { + status = + switch_pd_meter_index_table_add_entry(device, + handle_to_id(meter_handle), + meter_info, + &meter_info->meter_idx_pd_hdl); + } + + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_pd_meter_action_table_add_entry(device, + handle_to_id(meter_handle), + meter_info, + meter_info->action_pd_hdl); + + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + + return meter_handle; } -switch_status_t -switch_api_meter_update( - switch_device_t device, - switch_handle_t meter_handle, - switch_api_meter_t *api_meter_info) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_meter_info_t *meter_info = NULL; - - meter_info = switch_meter_info_get(meter_handle); - if (!meter_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - memcpy(&meter_info->api_meter_info, api_meter_info, sizeof(switch_api_meter_t)); - - if (api_meter_info->meter_mode == SWITCH_METER_MODE_STORM_CONTROL) { - meter_info->api_meter_info.pbs = meter_info->api_meter_info.cbs; - meter_info->api_meter_info.pir = meter_info->api_meter_info.cir; - meter_info->api_meter_info.action[SWITCH_METER_COLOR_YELLOW] = - meter_info->api_meter_info.action[SWITCH_METER_COLOR_GREEN]; - status = switch_pd_storm_control_meter_add_entry( - device, - handle_to_id(meter_handle), - meter_info); - } else { - status = switch_pd_meter_index_table_update_entry( - device, - handle_to_id(meter_handle), - meter_info, - meter_info->meter_idx_pd_hdl); - } - - status = switch_pd_meter_action_table_update_entry( - device, - handle_to_id(meter_handle), - meter_info, - meter_info->action_pd_hdl); - - return status; +switch_status_t switch_api_meter_update(switch_device_t device, + switch_handle_t meter_handle, + switch_api_meter_t *api_meter_info) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_meter_info_t *meter_info = NULL; + + meter_info = switch_meter_info_get(meter_handle); + if (!meter_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + memcpy( + &meter_info->api_meter_info, api_meter_info, sizeof(switch_api_meter_t)); + + if (api_meter_info->meter_mode == SWITCH_METER_MODE_STORM_CONTROL) { + meter_info->api_meter_info.pbs = meter_info->api_meter_info.cbs; + meter_info->api_meter_info.pir = meter_info->api_meter_info.cir; + meter_info->api_meter_info.action[SWITCH_COLOR_YELLOW] = + meter_info->api_meter_info.action[SWITCH_COLOR_GREEN]; + status = switch_pd_storm_control_meter_add_entry( + device, handle_to_id(meter_handle), meter_info); + } else { + status = + switch_pd_meter_index_table_update_entry(device, + handle_to_id(meter_handle), + meter_info, + meter_info->meter_idx_pd_hdl); + } + + status = switch_pd_meter_action_table_update_entry(device, + handle_to_id(meter_handle), + meter_info, + meter_info->action_pd_hdl); + + return status; } -switch_status_t -switch_api_meter_delete( - switch_device_t device, - switch_handle_t meter_handle) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_meter_info_t *meter_info = NULL; - - meter_info = switch_meter_info_get(meter_handle); - if (!meter_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - if (meter_info->api_meter_info.meter_mode != SWITCH_METER_MODE_STORM_CONTROL) { - status = switch_pd_meter_index_table_delete_entry( - device, - meter_info->meter_idx_pd_hdl); - } - - status = switch_pd_meter_action_table_delete_entry( - device, - meter_info->action_pd_hdl); - - switch_free(meter_info->stats_info); - switch_meter_delete(meter_handle); - return status; +switch_status_t switch_api_meter_delete(switch_device_t device, + switch_handle_t meter_handle) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_meter_info_t *meter_info = NULL; + + meter_info = switch_meter_info_get(meter_handle); + if (!meter_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + if (meter_info->api_meter_info.meter_mode != + SWITCH_METER_MODE_STORM_CONTROL) { + status = switch_pd_meter_index_table_delete_entry( + device, meter_info->meter_idx_pd_hdl); + } + + status = switch_pd_meter_action_table_delete_entry(device, + meter_info->action_pd_hdl); + + switch_free(meter_info->stats_info); + switch_meter_delete(meter_handle); + return status; } -switch_status_t -switch_api_meter_stats_get(switch_device_t device, - switch_handle_t meter_handle, - uint8_t count, - switch_meter_stats_t *counter_ids, - switch_counter_t *counters) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_meter_info_t *meter_info = NULL; - switch_meter_stats_info_t *stats_info = NULL; - int index = 0; - switch_bd_stats_id_t counter_id = 0; - - meter_info = switch_meter_info_get(meter_handle); - if (!meter_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - stats_info = meter_info->stats_info; - status = switch_pd_meter_stats_get(device, meter_info); - for (index = 0; index < count; index++) { - counter_id = counter_ids[index]; - counters[index] = stats_info->counters[counter_id]; - } - return status; +switch_status_t switch_api_meter_stats_get(switch_device_t device, + switch_handle_t meter_handle, + uint8_t count, + switch_meter_stats_t *counter_ids, + switch_counter_t *counters) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_meter_info_t *meter_info = NULL; + switch_meter_stats_info_t *stats_info = NULL; + int index = 0; + switch_meter_stats_t counter_id = 0; + + meter_info = switch_meter_info_get(meter_handle); + if (!meter_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + stats_info = meter_info->stats_info; + status = switch_pd_meter_stats_get(device, meter_info); + for (index = 0; index < count; index++) { + counter_id = counter_ids[index]; + counters[index] = stats_info->counters[counter_id]; + } + return status; } diff --git a/switchapi/src/switch_meter_int.h b/switchapi/src/switch_meter_int.h index 8e1c21f..a8d37a1 100644 --- a/switchapi/src/switch_meter_int.h +++ b/switchapi/src/switch_meter_int.h @@ -18,24 +18,28 @@ limitations under the License. #define _SWITCH_METER_INT_H_ #include +#include "switch_pd_types.h" typedef uint32_t switch_meter_idx_t; typedef struct switch_meter_stats_info_ { - uint16_t stats_idx[SWITCH_METER_STATS_MAX]; - switch_counter_t counters[SWITCH_METER_STATS_MAX]; + uint16_t stats_idx[SWITCH_METER_STATS_MAX]; + switch_counter_t counters[SWITCH_METER_STATS_MAX]; } switch_meter_stats_info_t; typedef struct switch_meter_info_ { - switch_api_meter_t api_meter_info; - switch_meter_stats_info_t *stats_info; - p4_pd_entry_hdl_t meter_idx_pd_hdl; - p4_pd_entry_hdl_t action_pd_hdl[SWITCH_METER_COLOR_MAX]; + switch_api_meter_t api_meter_info; + switch_meter_stats_info_t *stats_info; + p4_pd_entry_hdl_t meter_idx_pd_hdl; + p4_pd_entry_hdl_t action_pd_hdl[SWITCH_COLOR_MAX]; } switch_meter_info_t; -switch_status_t -switch_meter_init(switch_device_t device); +switch_status_t switch_meter_init(switch_device_t device); + +switch_meter_info_t *switch_meter_info_get(switch_handle_t meter_handle); + +switch_handle_t switch_meter_create(); + +switch_status_t switch_meter_delete(switch_handle_t meter_handle); -switch_meter_info_t * -switch_meter_info_get(switch_handle_t meter_handle); #endif /* _SWITCH_METER_INT_H_ */ diff --git a/switchapi/src/switch_mirror.c b/switchapi/src/switch_mirror.c index bc4e28f..1793c71 100644 --- a/switchapi/src/switch_mirror.c +++ b/switchapi/src/switch_mirror.c @@ -28,317 +28,320 @@ static switch_api_id_allocator *session_id_allocator; switch_handle_t switch_mirror_set_and_create(unsigned int id); -switch_status_t -switch_mirror_init(switch_device_t device) -{ - switch_mirror_array = NULL; - switch_handle_type_init(SWITCH_HANDLE_TYPE_MIRROR, - SWITCH_MAX_MIRROR_SESSIONS); - session_id_allocator = switch_api_id_allocator_new( - SWITCH_MAX_MIRROR_SESSIONS/32, - FALSE); - - // negative mirroring action - switch_pd_neg_mirror_add_entry(device); - // keep this id allocated so it is not given to anyone else - switch_mirror_set_and_create(SWITCH_NEGATIVE_MIRROR_SESSION_ID); - switch_api_id_allocator_set(session_id_allocator, - SWITCH_NEGATIVE_MIRROR_SESSION_ID); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_mirror_init(switch_device_t device) { + switch_mirror_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_MIRROR, + SWITCH_MAX_MIRROR_SESSIONS); + session_id_allocator = + switch_api_id_allocator_new(SWITCH_MAX_MIRROR_SESSIONS / 32, FALSE); + + // keep this id allocated so it is not given to anyone else + switch_mirror_set_and_create(SWITCH_NEGATIVE_MIRROR_SESSION_ID); + switch_api_id_allocator_set(session_id_allocator, + SWITCH_NEGATIVE_MIRROR_SESSION_ID); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_mirror_create() -{ - switch_handle_t mirror_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_MIRROR, - switch_mirror_info_t, - switch_mirror_array, - NULL, mirror_handle); - return mirror_handle; +switch_handle_t switch_mirror_create() { + switch_handle_t mirror_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_MIRROR, + switch_mirror_info_t, + switch_mirror_array, + NULL, + mirror_handle); + return mirror_handle; } -switch_handle_t -switch_mirror_set_and_create(unsigned int id) -{ - switch_handle_t mirror_handle; - _switch_handle_set_and_create(SWITCH_HANDLE_TYPE_MIRROR, - switch_mirror_info_t, - switch_mirror_array, - NULL, id, mirror_handle); - return mirror_handle; +switch_handle_t switch_mirror_set_and_create(unsigned int id) { + switch_handle_t mirror_handle; + _switch_handle_set_and_create(SWITCH_HANDLE_TYPE_MIRROR, + switch_mirror_info_t, + switch_mirror_array, + NULL, + id, + mirror_handle); + return mirror_handle; } -switch_mirror_info_t * -switch_mirror_info_get(switch_handle_t mirror_handle) -{ - switch_mirror_info_t *mirror_info = NULL; - _switch_handle_get(switch_mirror_info_t, switch_mirror_array, mirror_handle, mirror_info); - return mirror_info; +switch_mirror_info_t *switch_mirror_info_get(switch_handle_t mirror_handle) { + switch_mirror_info_t *mirror_info = NULL; + _switch_handle_get( + switch_mirror_info_t, switch_mirror_array, mirror_handle, mirror_info); + return mirror_info; } -switch_status_t -switch_mirror_delete(switch_handle_t mirror_handle) -{ - _switch_handle_delete(switch_mirror_info_t, - switch_mirror_array, - mirror_handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_mirror_delete(switch_handle_t mirror_handle) { + _switch_handle_delete( + switch_mirror_info_t, switch_mirror_array, mirror_handle); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_mirror_session_create(switch_device_t device, - switch_api_mirror_info_t *api_mirror_info) -{ - switch_mirror_info_t *mirror_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t mirror_handle = 0; - switch_handle_t intf_handle = 0; - switch_api_interface_info_t api_intf_info; - switch_handle_t tunnel_intf_handle = 0; - switch_tunnel_info_t *tunnel_info = NULL; - switch_handle_t inner_neigh_handle = 0; - switch_handle_t outer_neigh_handle = 0; - switch_api_neighbor_t api_neighbor; - switch_nhop_key_t nhop_key; - switch_handle_t nhop_handle = 0; - switch_handle_t vlan_handle = 0; - switch_vlan_port_t vlan_port; - switch_ip_encap_t *ip_encap = NULL; - - if (api_mirror_info->session_id) { - mirror_handle = switch_mirror_set_and_create(api_mirror_info->session_id); - } else { - mirror_handle = switch_mirror_create(); - api_mirror_info->session_id = handle_to_id(mirror_handle); - } - mirror_info = switch_mirror_info_get(mirror_handle); - if (!mirror_info) { - return SWITCH_API_INVALID_HANDLE; - } - - memset(mirror_info, 0, sizeof(switch_mirror_info_t)); - - api_mirror_info->enable = TRUE; - memcpy(&mirror_info->api_mirror_info, api_mirror_info, sizeof(switch_api_mirror_info_t)); - switch_api_id_allocator_set(session_id_allocator, - api_mirror_info->session_id); - - switch (api_mirror_info->session_type) { - case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: - status = switch_pd_mirror_session_update(device, mirror_handle, mirror_info); - break; - case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: - case SWITCH_MIRROR_SESSION_TYPE_COALESCE: - break; - default: - break; - } - - if (SWITCH_NHOP_HANDLE_VALID(api_mirror_info->nhop_handle)) { - status = switch_pd_mirror_table_entry_add(device, - mirror_handle, - mirror_info); - } else if (api_mirror_info->tunnel_create || api_mirror_info->vlan_create) { - switch (api_mirror_info->mirror_type) { - case SWITCH_MIRROR_TYPE_LOCAL: - break; - case SWITCH_MIRROR_TYPE_REMOTE: - vlan_handle = switch_api_vlan_create(device, - api_mirror_info->vlan_id); - memset(&api_intf_info, 0, sizeof(switch_api_interface_info_t)); - api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_TRUNK; - api_intf_info.u.port_lag_handle = api_mirror_info->egress_port; - intf_handle = switch_api_interface_create(device, &api_intf_info); - if (intf_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_TRACE("%s:%d: failed to create encap interface\n", - __FUNCTION__, __LINE__); - return SWITCH_API_INVALID_HANDLE; - } - vlan_port.tagging_mode = 0; - vlan_port.handle = intf_handle; - status = switch_api_vlan_ports_add(device, vlan_handle, - 1, &vlan_port); - mirror_info->vlan_handle = vlan_handle; - mirror_info->intf_handle = intf_handle; - break; - case SWITCH_MIRROR_TYPE_ENHANCED_REMOTE: - //Create the encap interface - memset(&api_intf_info, 0, sizeof(switch_api_interface_info_t)); - api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_ACCESS; - api_intf_info.u.port_lag_handle = api_mirror_info->egress_port; - intf_handle = switch_api_interface_create(device, &api_intf_info); - if (intf_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_TRACE("%s:%d: failed to create encap interface\n", - __FUNCTION__, __LINE__); - return SWITCH_API_INVALID_HANDLE; - } - - tunnel_info = &api_mirror_info->tunnel_info; - tunnel_info->u.ip_encap.vrf_handle = switch_api_default_vrf_internal(); - tunnel_info->encap_mode = SWITCH_API_TUNNEL_ENCAP_MODE_IP; - tunnel_info->out_if = intf_handle; - tunnel_intf_handle = switch_api_tunnel_interface_create(device, 0, - tunnel_info); - if (intf_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_TRACE("failed to create tunnel interface %s:%d\n", - __FUNCTION__, __LINE__); - return SWITCH_API_INVALID_HANDLE; - } - - memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); - nhop_key.intf_handle = tunnel_intf_handle; - nhop_handle = switch_api_nhop_create(device, &nhop_key); - if (nhop_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_TRACE("%s:%d: failed to create nhop for tunnel interface\n", - __FUNCTION__, __LINE__); - return SWITCH_API_INVALID_HANDLE; - } - - ip_encap = &tunnel_info->u.ip_encap; - memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); - api_neighbor.vrf_handle = switch_api_default_vrf_internal(); - api_neighbor.interface = tunnel_intf_handle; - api_neighbor.nhop_handle = nhop_handle; - api_neighbor.rw_type = SWITCH_API_NEIGHBOR_RW_TYPE_L2; - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { - api_neighbor.neigh_type = SWITCH_API_NEIGHBOR_IPV4_TUNNEL; - } else { - api_neighbor.neigh_type = SWITCH_API_NEIGHBOR_IPV4_TUNNEL; - } - inner_neigh_handle = switch_api_neighbor_entry_add(device, &api_neighbor); - if (inner_neigh_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_TRACE("%s:%d: failed to create inner neighbor for tunnel interface\n", - __FUNCTION__, __LINE__); - return SWITCH_API_INVALID_HANDLE; - } - - memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); - api_neighbor.vrf_handle = switch_api_default_vrf_internal(); - api_neighbor.interface = tunnel_intf_handle; - memcpy(&api_neighbor.mac_addr, &api_mirror_info->dst_mac, - sizeof(switch_mac_addr_t)); - outer_neigh_handle = switch_api_neighbor_entry_add(device, &api_neighbor); - if (outer_neigh_handle == SWITCH_API_INVALID_HANDLE) { - SWITCH_API_TRACE("%s:%d failed to create inner neighbor for tunnel interface\n", - __FUNCTION__, __LINE__); - return SWITCH_API_INVALID_HANDLE; - } - - mirror_info->intf_handle = intf_handle; - mirror_info->tunnel_intf_handle = tunnel_intf_handle; - mirror_info->inner_neigh_handle = inner_neigh_handle; - mirror_info->outer_neigh_handle = outer_neigh_handle; - mirror_info->api_mirror_info.nhop_handle = nhop_handle; - - status = switch_pd_mirror_table_entry_add(device, - mirror_handle, - mirror_info); - break; - default: - return SWITCH_API_INVALID_HANDLE; - } - } +switch_handle_t switch_api_mirror_session_create( + switch_device_t device, switch_api_mirror_info_t *api_mirror_info) { + switch_mirror_info_t *mirror_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t mirror_handle = 0; + switch_handle_t intf_handle = 0; + switch_api_interface_info_t api_intf_info; + switch_handle_t tunnel_intf_handle = 0; + switch_tunnel_info_t *tunnel_info = NULL; + switch_handle_t inner_neigh_handle = 0; + switch_handle_t outer_neigh_handle = 0; + switch_api_neighbor_t api_neighbor; + switch_nhop_key_t nhop_key; + switch_handle_t nhop_handle = 0; + switch_handle_t vlan_handle = 0; + switch_vlan_port_t vlan_port; + switch_ip_encap_t *ip_encap = NULL; + + if (api_mirror_info->session_id) { + mirror_handle = switch_mirror_set_and_create(api_mirror_info->session_id); + } else { + mirror_handle = switch_mirror_create(); + api_mirror_info->session_id = handle_to_id(mirror_handle); + } + mirror_info = switch_mirror_info_get(mirror_handle); + if (!mirror_info) { + return SWITCH_API_INVALID_HANDLE; + } + + memset(mirror_info, 0, sizeof(switch_mirror_info_t)); + + api_mirror_info->enable = TRUE; + memcpy(&mirror_info->api_mirror_info, + api_mirror_info, + sizeof(switch_api_mirror_info_t)); + switch_api_id_allocator_set(session_id_allocator, + api_mirror_info->session_id); + + switch (api_mirror_info->session_type) { + case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: + status = + switch_pd_mirror_session_update(device, mirror_handle, mirror_info); + break; + case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: + case SWITCH_MIRROR_SESSION_TYPE_COALESCE: + break; + default: + break; + } + + if (SWITCH_NHOP_HANDLE_VALID(api_mirror_info->nhop_handle)) { + status = + switch_pd_mirror_table_entry_add(device, mirror_handle, mirror_info); + } else if (api_mirror_info->tunnel_create || api_mirror_info->vlan_create) { + switch (api_mirror_info->mirror_type) { + case SWITCH_MIRROR_TYPE_LOCAL: + break; + case SWITCH_MIRROR_TYPE_REMOTE: + vlan_handle = switch_api_vlan_create(device, api_mirror_info->vlan_id); + memset(&api_intf_info, 0, sizeof(switch_api_interface_info_t)); + api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_TRUNK; + api_intf_info.u.port_lag_handle = api_mirror_info->egress_port; + intf_handle = switch_api_interface_create(device, &api_intf_info); + if (intf_handle == SWITCH_API_INVALID_HANDLE) { + SWITCH_API_TRACE("%s:%d: failed to create encap interface\n", + __FUNCTION__, + __LINE__); + goto error_return; + } + vlan_port.tagging_mode = 0; + vlan_port.handle = intf_handle; + status = switch_api_vlan_ports_add(device, vlan_handle, 1, &vlan_port); + mirror_info->vlan_handle = vlan_handle; + mirror_info->intf_handle = intf_handle; + break; + case SWITCH_MIRROR_TYPE_ENHANCED_REMOTE: + // Create the encap interface + memset(&api_intf_info, 0, sizeof(switch_api_interface_info_t)); + api_intf_info.type = SWITCH_API_INTERFACE_L2_VLAN_ACCESS; + api_intf_info.u.port_lag_handle = api_mirror_info->egress_port; + intf_handle = switch_api_interface_create(device, &api_intf_info); + if (intf_handle == SWITCH_API_INVALID_HANDLE) { + SWITCH_API_TRACE("%s:%d: failed to create encap interface\n", + __FUNCTION__, + __LINE__); + goto error_return; + } - if (status != SWITCH_STATUS_SUCCESS) { - switch_api_id_allocator_release(session_id_allocator, - api_mirror_info->session_id); - switch_mirror_delete(mirror_handle); - return SWITCH_API_INVALID_HANDLE; - } - return mirror_handle; -} + tunnel_info = &api_mirror_info->tunnel_info; + tunnel_info->u.ip_encap.vrf_handle = switch_api_default_vrf_internal(); + tunnel_info->encap_mode = SWITCH_API_TUNNEL_ENCAP_MODE_IP; + tunnel_info->out_if = intf_handle; + tunnel_intf_handle = + switch_api_tunnel_interface_create(device, 0, tunnel_info); + if (intf_handle == SWITCH_API_INVALID_HANDLE) { + SWITCH_API_TRACE("failed to create tunnel interface %s:%d\n", + __FUNCTION__, + __LINE__); + goto error_return; + } -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) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_mirror_info_t *mirror_info = NULL; - switch_api_mirror_info_t *tmp_api_mirror_info = NULL; - - mirror_info = switch_mirror_info_get(mirror_handle); - if (!mirror_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } + memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); + nhop_key.intf_handle = tunnel_intf_handle; + nhop_handle = switch_api_nhop_create(device, &nhop_key); + if (nhop_handle == SWITCH_API_INVALID_HANDLE) { + SWITCH_API_TRACE( + "%s:%d: failed to create nhop for tunnel interface\n", + __FUNCTION__, + __LINE__); + goto error_return; + } - tmp_api_mirror_info = &mirror_info->api_mirror_info; - memcpy(&mirror_info->api_mirror_info, api_mirror_info, sizeof(switch_api_mirror_info_t)); - switch (api_mirror_info->session_type) { - case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: - status = switch_pd_mirror_session_update(device, mirror_handle, mirror_info); - break; - case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: - case SWITCH_MIRROR_SESSION_TYPE_COALESCE: - break; - default: - break; - } - if (!SWITCH_NHOP_HANDLE_VALID(tmp_api_mirror_info->nhop_handle) && - SWITCH_NHOP_HANDLE_VALID(api_mirror_info->nhop_handle)) { - status = switch_pd_mirror_table_entry_add(device, - mirror_handle, - mirror_info); - } - return status; -} + ip_encap = &tunnel_info->u.ip_encap; + memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); + api_neighbor.vrf_handle = switch_api_default_vrf_internal(); + api_neighbor.interface = tunnel_intf_handle; + api_neighbor.nhop_handle = nhop_handle; + api_neighbor.rw_type = SWITCH_API_NEIGHBOR_RW_TYPE_L2; + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + api_neighbor.neigh_type = SWITCH_API_NEIGHBOR_IPV4_TUNNEL; + } else { + api_neighbor.neigh_type = SWITCH_API_NEIGHBOR_IPV4_TUNNEL; + } + inner_neigh_handle = + switch_api_neighbor_entry_add(device, &api_neighbor); + if (inner_neigh_handle == SWITCH_API_INVALID_HANDLE) { + SWITCH_API_TRACE( + "%s:%d: failed to create inner neighbor for tunnel interface\n", + __FUNCTION__, + __LINE__); + goto error_return; + } -switch_status_t -switch_api_mirror_session_delete(switch_device_t device, switch_handle_t mirror_handle) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_mirror_info_t *mirror_info = NULL; - switch_api_mirror_info_t *api_mirror_info = NULL; - switch_vlan_port_t vlan_port; - - mirror_info = switch_mirror_info_get(mirror_handle); - if (!mirror_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } + memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); + api_neighbor.vrf_handle = switch_api_default_vrf_internal(); + api_neighbor.interface = tunnel_intf_handle; + memcpy(&api_neighbor.mac_addr, + &api_mirror_info->dst_mac, + sizeof(switch_mac_addr_t)); + outer_neigh_handle = + switch_api_neighbor_entry_add(device, &api_neighbor); + if (outer_neigh_handle == SWITCH_API_INVALID_HANDLE) { + SWITCH_API_TRACE( + "%s:%d failed to create inner neighbor for tunnel interface\n", + __FUNCTION__, + __LINE__); + goto error_return; + } - api_mirror_info = &mirror_info->api_mirror_info; - switch (api_mirror_info->session_type) { - case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: - status = switch_pd_mirror_session_delete(device, mirror_handle); - break; - case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: - case SWITCH_MIRROR_SESSION_TYPE_COALESCE: - break; - default: - break; - } + mirror_info->intf_handle = intf_handle; + mirror_info->tunnel_intf_handle = tunnel_intf_handle; + mirror_info->inner_neigh_handle = inner_neigh_handle; + mirror_info->outer_neigh_handle = outer_neigh_handle; + mirror_info->api_mirror_info.nhop_handle = nhop_handle; - if (api_mirror_info->tunnel_create || api_mirror_info->vlan_create) { - switch (api_mirror_info->mirror_type) { - case SWITCH_MIRROR_TYPE_LOCAL: - break; - case SWITCH_MIRROR_TYPE_REMOTE: - vlan_port.tagging_mode = 0; - vlan_port.handle = mirror_info->intf_handle; - status = switch_api_vlan_ports_remove(device, - mirror_info->vlan_handle, - 1, &vlan_port); - status = switch_api_interface_delete(device, mirror_info->intf_handle); - status = switch_api_vlan_delete(device, mirror_info->vlan_handle); - break; - case SWITCH_MIRROR_TYPE_ENHANCED_REMOTE: - status = switch_api_neighbor_entry_remove(device, mirror_info->outer_neigh_handle); - status = switch_api_neighbor_entry_remove(device, mirror_info->inner_neigh_handle); - status = switch_api_nhop_delete(device, mirror_info->api_mirror_info.nhop_handle); - status = switch_api_tunnel_interface_delete(device, mirror_info->tunnel_intf_handle); - status = switch_api_interface_delete(device, mirror_info->intf_handle); - status = switch_pd_mirror_table_entry_delete(device, mirror_info); - break; - default: - return SWITCH_STATUS_FAILURE; - } - } else if (SWITCH_NHOP_HANDLE_VALID(api_mirror_info->nhop_handle)) { - status = switch_pd_mirror_table_entry_delete(device, mirror_info); + status = switch_pd_mirror_table_entry_add( + device, mirror_handle, mirror_info); + break; + default: + return SWITCH_API_INVALID_HANDLE; } + } +error_return: + if (status != SWITCH_STATUS_SUCCESS) { switch_api_id_allocator_release(session_id_allocator, api_mirror_info->session_id); switch_mirror_delete(mirror_handle); - return status; + return SWITCH_API_INVALID_HANDLE; + } + return mirror_handle; +} + +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) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_mirror_info_t *mirror_info = NULL; + switch_api_mirror_info_t *tmp_api_mirror_info = NULL; + + mirror_info = switch_mirror_info_get(mirror_handle); + if (!mirror_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + tmp_api_mirror_info = &mirror_info->api_mirror_info; + memcpy(&mirror_info->api_mirror_info, + api_mirror_info, + sizeof(switch_api_mirror_info_t)); + switch (api_mirror_info->session_type) { + case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: + status = + switch_pd_mirror_session_update(device, mirror_handle, mirror_info); + break; + case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: + case SWITCH_MIRROR_SESSION_TYPE_COALESCE: + break; + default: + break; + } + if (!SWITCH_NHOP_HANDLE_VALID(tmp_api_mirror_info->nhop_handle) && + SWITCH_NHOP_HANDLE_VALID(api_mirror_info->nhop_handle)) { + status = + switch_pd_mirror_table_entry_add(device, mirror_handle, mirror_info); + } + return status; +} + +switch_status_t switch_api_mirror_session_delete( + switch_device_t device, switch_handle_t mirror_handle) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_mirror_info_t *mirror_info = NULL; + switch_api_mirror_info_t *api_mirror_info = NULL; + switch_vlan_port_t vlan_port; + + mirror_info = switch_mirror_info_get(mirror_handle); + if (!mirror_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + api_mirror_info = &mirror_info->api_mirror_info; + switch (api_mirror_info->session_type) { + case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: + status = switch_pd_mirror_session_delete(device, mirror_handle); + break; + case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: + case SWITCH_MIRROR_SESSION_TYPE_COALESCE: + break; + default: + break; + } + + if (api_mirror_info->tunnel_create || api_mirror_info->vlan_create) { + switch (api_mirror_info->mirror_type) { + case SWITCH_MIRROR_TYPE_LOCAL: + break; + case SWITCH_MIRROR_TYPE_REMOTE: + vlan_port.tagging_mode = 0; + vlan_port.handle = mirror_info->intf_handle; + status = switch_api_vlan_ports_remove( + device, mirror_info->vlan_handle, 1, &vlan_port); + status = switch_api_interface_delete(device, mirror_info->intf_handle); + status = switch_api_vlan_delete(device, mirror_info->vlan_handle); + break; + case SWITCH_MIRROR_TYPE_ENHANCED_REMOTE: + status = switch_api_neighbor_entry_remove( + device, mirror_info->outer_neigh_handle); + status = switch_api_neighbor_entry_remove( + device, mirror_info->inner_neigh_handle); + status = switch_api_nhop_delete( + device, mirror_info->api_mirror_info.nhop_handle); + status = switch_api_tunnel_interface_delete( + device, mirror_info->tunnel_intf_handle); + status = switch_api_interface_delete(device, mirror_info->intf_handle); + status = switch_pd_mirror_table_entry_delete(device, mirror_info); + break; + default: + return SWITCH_STATUS_FAILURE; + } + } else if (SWITCH_NHOP_HANDLE_VALID(api_mirror_info->nhop_handle)) { + status = switch_pd_mirror_table_entry_delete(device, mirror_info); + } + + switch_api_id_allocator_release(session_id_allocator, + api_mirror_info->session_id); + switch_mirror_delete(mirror_handle); + return status; } diff --git a/switchapi/src/switch_mirror_int.h b/switchapi/src/switch_mirror_int.h index 17d0f49..98e249e 100644 --- a/switchapi/src/switch_mirror_int.h +++ b/switchapi/src/switch_mirror_int.h @@ -14,25 +14,27 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "switch_pd_types.h" + #ifndef _SWITCH_MIRROR_INT_H_ #define _SWITCH_MIRROR_INT_H_ +#include "switchapi/switch_mirror.h" + typedef struct switch_mirror_info_ { - switch_api_mirror_info_t api_mirror_info; - uint32_t max_pkt_len; - switch_handle_t intf_handle; - switch_handle_t vlan_handle; - switch_handle_t tunnel_intf_handle; - switch_handle_t inner_neigh_handle; - switch_handle_t outer_neigh_handle; - uint32_t pkt_hdr; - uint8_t hdr_len; - p4_pd_entry_hdl_t pd_hdl; + switch_api_mirror_info_t api_mirror_info; + uint32_t max_pkt_len; + switch_handle_t intf_handle; + switch_handle_t vlan_handle; + switch_handle_t tunnel_intf_handle; + switch_handle_t inner_neigh_handle; + switch_handle_t outer_neigh_handle; + uint32_t pkt_hdr; + uint8_t hdr_len; + p4_pd_entry_hdl_t pd_hdl; } switch_mirror_info_t; -switch_status_t -switch_mirror_init(switch_device_t device); +switch_status_t switch_mirror_init(switch_device_t device); -switch_mirror_info_t * -switch_mirror_info_get(switch_handle_t mirror_handle); +switch_mirror_info_t *switch_mirror_info_get(switch_handle_t mirror_handle); #endif /* _SWITCH_MIRROR_INT_H_ */ diff --git a/switchapi/src/switch_nat.c b/switchapi/src/switch_nat.c new file mode 100644 index 0000000..f4480dc --- /dev/null +++ b/switchapi/src/switch_nat.c @@ -0,0 +1,199 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_nat.h" +#include "switchapi/switch_status.h" +#include "switchapi/switch_interface.h" +#include "switchapi/switch_utils.h" +#include "switch_nhop_int.h" +#include "switch_pd.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static tommy_hashtable switch_nat_hash_table; +static switch_api_id_allocator *nat_rw_alloc; + +#define SWITCH_NAT_HASH_TABLE_SIZE 1024 +#define SWITCH_NAT_REWRITE_TABLE_SIZE (16 * 1024) + +switch_status_t switch_nat_init(switch_device_t device) { + UNUSED(device); + tommy_hashtable_init(&switch_nat_hash_table, SWITCH_NAT_HASH_TABLE_SIZE); + nat_rw_alloc = switch_api_id_allocator_new( + SWITCH_NAT_REWRITE_TABLE_SIZE / sizeof(uint32_t), false); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_nat_free(switch_device_t device) { + UNUSED(device); + tommy_hashtable_done(&switch_nat_hash_table); + return SWITCH_STATUS_SUCCESS; +} + +static inline void switch_nat_hash_key_init(uchar *key, + switch_api_nat_info_t *api_nat_info, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, SWITCH_NAT_HASH_KEY_SIZE); + memcpy(key, &api_nat_info->vrf_handle, sizeof(switch_handle_t)); + *len += sizeof(switch_handle_t); + + if (SWITCH_NAT_TYPE_IS_VALID_SRC(api_nat_info)) { + memcpy(&key[*len], &(SWITCH_NAT_SRC_IP(api_nat_info)), 4); + } + *len += 4; + + if (SWITCH_NAT_TYPE_IS_VALID_SRC_PORT(api_nat_info)) { + memcpy(&key[*len], &api_nat_info->src_port, 2); + } + *len += 2; + + if (SWITCH_NAT_TYPE_IS_VALID_DST(api_nat_info)) { + memcpy(&key[*len], &(SWITCH_NAT_DST_IP(api_nat_info)), 4); + } + *len += 4; + + if (SWITCH_NAT_TYPE_IS_VALID_DST_PORT(api_nat_info)) { + memcpy(&key[*len], &api_nat_info->dst_port, 2); + } + *len += 2; + + if (SWITCH_NAT_TYPE_IS_VALID_SRC_PORT(api_nat_info) || + SWITCH_NAT_TYPE_IS_VALID_DST_PORT(api_nat_info)) { + memcpy(&key[*len], &api_nat_info->protocol, 2); + } + *len += 2; + + memcpy(&key[*len], &api_nat_info->nat_rw_type, 1); + *len += 1; + + *hash = MurmurHash2(key, *len, 0x98761234); +} + +static inline int switch_nat_hash_cmp(const void *key1, const void *key2) { + return memcmp(key1, key2, SWITCH_NAT_HASH_KEY_SIZE); +} + +static switch_nat_info_t *switch_nat_insert_hash( + switch_api_nat_info_t *api_nat_info) { + switch_nat_info_t *nat_info = NULL; + unsigned char key[SWITCH_NAT_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_nat_hash_key_init(key, api_nat_info, &len, &hash); + nat_info = switch_malloc(sizeof(switch_nat_info_t), 1); + if (!nat_info) { + return NULL; + } + memcpy(&nat_info->api_nat_info, api_nat_info, sizeof(switch_api_nat_info_t)); + memcpy(nat_info->key, key, SWITCH_NAT_HASH_KEY_SIZE); + tommy_hashtable_insert( + &switch_nat_hash_table, &(nat_info->node), nat_info, hash); + return nat_info; +} + +static switch_status_t switch_nat_delete_hash( + switch_api_nat_info_t *api_nat_info) { + switch_nat_info_t *nat_info = NULL; + unsigned char key[SWITCH_NAT_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_nat_hash_key_init(key, api_nat_info, &len, &hash); + nat_info = tommy_hashtable_remove( + &switch_nat_hash_table, switch_nat_hash_cmp, key, hash); + if (!nat_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + switch_free(nat_info); + return SWITCH_STATUS_SUCCESS; +} + +static switch_nat_info_t *switch_nat_search_hash( + switch_api_nat_info_t *api_nat_info) { + switch_nat_info_t *nat_info = NULL; + unsigned char key[SWITCH_NAT_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_nat_hash_key_init(key, api_nat_info, &len, &hash); + nat_info = tommy_hashtable_search( + &switch_nat_hash_table, switch_nat_hash_cmp, key, hash); + return nat_info; +} + +switch_status_t switch_api_nat_add(switch_device_t device, + switch_api_nat_info_t *api_nat_info) { + switch_interface_info_t *intf_info = NULL; + switch_nat_info_t *nat_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + bool add = true; + + nat_info = switch_nat_search_hash(api_nat_info); + if (nat_info) { + add = false; + } else { + nat_info = switch_nat_insert_hash(api_nat_info); + if (!nat_info) { + return SWITCH_STATUS_NO_MEMORY; + } + nat_info->nat_rw_index = switch_api_id_allocator_allocate(nat_rw_alloc); + } + +#ifdef SWITCH_PD + if (add) { + status = switch_pd_nat_table_add_entry( + device, intf_info, nat_info, &nat_info->hw_entry); + status = switch_pd_nat_rewrite_table_add_entry( + device, nat_info, &nat_info->rw_hw_entry); + } else { + } +#endif + + return status; +} + +switch_status_t switch_api_nat_delete(switch_device_t device, + switch_api_nat_info_t *api_nat_info) { + switch_nat_info_t *nat_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + nat_info = switch_nat_search_hash(api_nat_info); + if (!nat_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + switch_api_id_allocator_release(nat_rw_alloc, nat_info->nat_rw_index); + +#ifdef SWITCH_PD + status = + switch_pd_nat_table_delete_entry(device, nat_info, nat_info->hw_entry); + status = + switch_pd_nat_rewrite_table_delete_entry(device, nat_info->rw_hw_entry); +#endif + + status = switch_nat_delete_hash(api_nat_info); + return status; +} + +#ifdef __cplusplus +} +#endif diff --git a/switchapi/src/switch_nat_int.h b/switchapi/src/switch_nat_int.h new file mode 100644 index 0000000..b4c30f6 --- /dev/null +++ b/switchapi/src/switch_nat_int.h @@ -0,0 +1,90 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// +// switch_nat_int.h +// switch_api +// +// Created on 7/28/14. +// Copyright (c) 2014 bn. All rights reserved. +// + +#ifndef _switch_nat_int_h_ +#define _switch_nat_int_h_ + +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_nat.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SWITCH_NAT_HASH_KEY_SIZE 24 + +typedef struct switch_nat_info_ { + unsigned char key[SWITCH_NAT_HASH_KEY_SIZE]; + switch_api_nat_info_t api_nat_info; + tommy_hashtable_node node; +#ifdef SWITCH_PD + uint32_t nat_rw_index; + p4_pd_entry_hdl_t hw_entry; + p4_pd_entry_hdl_t rw_hw_entry; +#endif +} switch_nat_info_t; + +#define SWITCH_NAT_SRC_IP(info) info->src_ip.ip.v4addr + +#define SWITCH_NAT_DST_IP(info) info->dst_ip.ip.v4addr + +#define SWITCH_NAT_TYPE_IS_VALID_SRC(info) \ + ((info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_UDP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_UDP)) + +#define SWITCH_NAT_TYPE_IS_VALID_SRC_PORT(info) \ + ((info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_UDP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_UDP)) + +#define SWITCH_NAT_TYPE_IS_VALID_DST(info) \ + ((info->nat_rw_type == SWITCH_NAT_RW_TYPE_DST) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_DST_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_DST_UDP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_UDP)) + +#define SWITCH_NAT_TYPE_IS_VALID_DST_PORT(info) \ + ((info->nat_rw_type == SWITCH_NAT_RW_TYPE_DST_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_DST_UDP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_TCP) || \ + (info->nat_rw_type == SWITCH_NAT_RW_TYPE_SRC_DST_UDP)) + +#define SWITCH_NAT_RW_SRC_IP(info) info->rw_src_ip.ip.v4addr + +#define SWITCH_NAT_RW_DST_IP(info) info->rw_dst_ip.ip.v4addr + +switch_status_t switch_nat_init(switch_device_t device); +switch_status_t switch_nat_free(switch_device_t device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/src/switch_neighbor.c b/switchapi/src/switch_neighbor.c index 122312a..ec06d18 100644 --- a/switchapi/src/switch_neighbor.c +++ b/switchapi/src/switch_neighbor.c @@ -33,497 +33,531 @@ limitations under the License. extern "C" { #endif /* __cplusplus */ -static void *switch_neighbor_array=NULL; +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) -{ - UNUSED(device); - switch_neighbor_array = NULL; - tommy_hashtable_init(&switch_dmac_rewrite_table, SWITCH_DMAC_REWRITE_HASH_TABLE_SIZE); - tommy_hashtable_init(&switch_neighbor_dmac_table, SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE); - dmac_rewrite_index_allocator = switch_api_id_allocator_new(SWITCH_DMAC_REWRITE_HASH_TABLE_SIZE, FALSE); - return switch_handle_type_init(SWITCH_HANDLE_TYPE_ARP, (64*1024)); +switch_status_t switch_neighbor_init(switch_device_t device) { + UNUSED(device); + switch_neighbor_array = NULL; + tommy_hashtable_init(&switch_dmac_rewrite_table, + SWITCH_DMAC_REWRITE_HASH_TABLE_SIZE); + tommy_hashtable_init(&switch_neighbor_dmac_table, + SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE); + dmac_rewrite_index_allocator = + switch_api_id_allocator_new(SWITCH_DMAC_REWRITE_HASH_TABLE_SIZE, FALSE); + return switch_handle_type_init(SWITCH_HANDLE_TYPE_ARP, (64 * 1024)); } -switch_status_t -switch_neighbor_free(switch_device_t device) -{ - UNUSED(device); - switch_handle_type_free(SWITCH_HANDLE_TYPE_ARP); - tommy_hashtable_done(&switch_dmac_rewrite_table); - tommy_hashtable_done(&switch_neighbor_dmac_table); - switch_api_id_allocator_destroy(dmac_rewrite_index_allocator); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_neighbor_free(switch_device_t device) { + UNUSED(device); + switch_handle_type_free(SWITCH_HANDLE_TYPE_ARP); + tommy_hashtable_done(&switch_dmac_rewrite_table); + tommy_hashtable_done(&switch_neighbor_dmac_table); + switch_api_id_allocator_destroy(dmac_rewrite_index_allocator); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_neighbor_info_create() -{ - switch_handle_t handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_ARP, switch_neighbor_info_t, switch_neighbor_array, NULL, handle); - return handle; +switch_handle_t switch_neighbor_info_create() { + switch_handle_t handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_ARP, + switch_neighbor_info_t, + switch_neighbor_array, + NULL, + handle); + return handle; } -switch_neighbor_info_t * -switch_neighbor_info_get(switch_handle_t handle) -{ - switch_neighbor_info_t *neighbor_info = NULL; - _switch_handle_get(switch_neighbor_info_t, switch_neighbor_array, handle, neighbor_info); - return neighbor_info; +switch_neighbor_info_t *switch_neighbor_info_get(switch_handle_t handle) { + switch_neighbor_info_t *neighbor_info = NULL; + _switch_handle_get( + switch_neighbor_info_t, switch_neighbor_array, handle, neighbor_info); + return neighbor_info; } -void -switch_neighbor_info_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_neighbor_info_t, switch_neighbor_array, handle); +void switch_neighbor_info_delete(switch_handle_t handle) { + _switch_handle_delete(switch_neighbor_info_t, switch_neighbor_array, handle); } -static void -switch_dmac_rewrite_hash_key_init(uchar *key, switch_mac_addr_t *mac, - uint32_t *len, uint32_t *hash) -{ - *len=0; - memset(key, 0, SWITCH_DMAC_REWRITE_HASH_KEY_SIZE); - memcpy(key, mac, sizeof(switch_mac_addr_t)); - *len = sizeof(switch_mac_addr_t); - *hash = MurmurHash2(key, *len, 0x98761234); +static void switch_dmac_rewrite_hash_key_init(uchar *key, + switch_mac_addr_t *mac, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, SWITCH_DMAC_REWRITE_HASH_KEY_SIZE); + memcpy(key, mac, sizeof(switch_mac_addr_t)); + *len = sizeof(switch_mac_addr_t); + *hash = MurmurHash2(key, *len, 0x98761234); } -static inline int -switch_dmac_rewrite_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_DMAC_REWRITE_HASH_KEY_SIZE); +static inline int switch_dmac_rewrite_hash_cmp(const void *key1, + const void *key2) { + return memcmp(key1, key2, SWITCH_DMAC_REWRITE_HASH_KEY_SIZE); } -static switch_dmac_rewrite_t * -switch_dmac_rewrite_search_hash(switch_mac_addr_t *mac) -{ - unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - switch_dmac_rewrite_t *dmac_rewrite = NULL; - - switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); - dmac_rewrite = tommy_hashtable_search(&switch_dmac_rewrite_table, switch_dmac_rewrite_hash_cmp, key, hash); - return dmac_rewrite; -} - -static uint16_t -switch_dmac_rewrite_insert_hash(switch_device_t device, switch_mac_addr_t *mac) -{ - unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - uint16_t mac_index = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_dmac_rewrite_t *dmac_rewrite = NULL; - - dmac_rewrite = switch_dmac_rewrite_search_hash(mac); - if (dmac_rewrite) { - mac_index = dmac_rewrite->index; - dmac_rewrite->ref_count++; - } else { - switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); - dmac_rewrite = switch_malloc(sizeof(switch_dmac_rewrite_t), 1); - if (!dmac_rewrite) { - return mac_index; - } - mac_index = switch_api_id_allocator_allocate(dmac_rewrite_index_allocator); - memcpy(&dmac_rewrite->mac, mac, sizeof(switch_mac_addr_t)); - dmac_rewrite->index = mac_index; - dmac_rewrite->ref_count = 1; - status = switch_pd_tunnel_dmac_rewrite_table_add_entry(device, mac_index, mac, &dmac_rewrite->rewrite_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add tunnel dmac entry!", __FUNCTION__, __LINE__); - return mac_index; - } - tommy_hashtable_insert(&switch_dmac_rewrite_table, &(dmac_rewrite->node), dmac_rewrite, hash); - } - return mac_index; +static switch_dmac_rewrite_t *switch_dmac_rewrite_search_hash( + switch_mac_addr_t *mac) { + unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + switch_dmac_rewrite_t *dmac_rewrite = NULL; + + switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); + dmac_rewrite = tommy_hashtable_search( + &switch_dmac_rewrite_table, switch_dmac_rewrite_hash_cmp, key, hash); + return dmac_rewrite; } -static switch_status_t -switch_dmac_rewrite_delete_hash(switch_device_t device, switch_mac_addr_t *mac) -{ - switch_dmac_rewrite_t *dmac_rewrite = NULL; - unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - dmac_rewrite = switch_dmac_rewrite_search_hash(mac); +static uint16_t switch_dmac_rewrite_insert_hash(switch_device_t device, + switch_mac_addr_t *mac) { + unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + uint16_t mac_index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_dmac_rewrite_t *dmac_rewrite = NULL; + + dmac_rewrite = switch_dmac_rewrite_search_hash(mac); + if (dmac_rewrite) { + mac_index = dmac_rewrite->index; + dmac_rewrite->ref_count++; + } else { + switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); + dmac_rewrite = switch_malloc(sizeof(switch_dmac_rewrite_t), 1); if (!dmac_rewrite) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + return mac_index; } - dmac_rewrite->ref_count--; - if (dmac_rewrite->ref_count == 0) { - switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); - dmac_rewrite = tommy_hashtable_remove(&switch_dmac_rewrite_table, switch_dmac_rewrite_hash_cmp, key, hash); - status = switch_pd_tunnel_dmac_rewrite_table_delete_entry(device, dmac_rewrite->rewrite_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d unabl to delete tunnel dmac entry!", __FUNCTION__, __LINE__); - return status; - } - switch_api_id_allocator_release(dmac_rewrite_index_allocator, dmac_rewrite->index); - switch_free(dmac_rewrite); + mac_index = switch_api_id_allocator_allocate(dmac_rewrite_index_allocator); + memcpy(&dmac_rewrite->mac, mac, sizeof(switch_mac_addr_t)); + dmac_rewrite->index = mac_index; + dmac_rewrite->ref_count = 1; + status = switch_pd_tunnel_dmac_rewrite_table_add_entry( + device, mac_index, mac, &dmac_rewrite->rewrite_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to add tunnel dmac entry!", __FUNCTION__, __LINE__); + return mac_index; } - return status; + tommy_hashtable_insert( + &switch_dmac_rewrite_table, &(dmac_rewrite->node), dmac_rewrite, hash); + } + return mac_index; } -static void -switch_neighbor_dmac_hash_key_init(uchar *key, switch_handle_t bd_handle, - switch_mac_addr_t *mac, - uint32_t *len, uint32_t *hash) -{ - *len=0; - memset(key, 0, SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE); - memcpy(key, &bd_handle, sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); - memcpy(key + *len, mac, sizeof(switch_mac_addr_t)); - *len += sizeof(switch_mac_addr_t); - *hash = MurmurHash2(key, *len, 0x98761234); +static switch_status_t switch_dmac_rewrite_delete_hash(switch_device_t device, + switch_mac_addr_t *mac) { + switch_dmac_rewrite_t *dmac_rewrite = NULL; + unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + dmac_rewrite = switch_dmac_rewrite_search_hash(mac); + if (!dmac_rewrite) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + dmac_rewrite->ref_count--; + if (dmac_rewrite->ref_count == 0) { + switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); + dmac_rewrite = tommy_hashtable_remove( + &switch_dmac_rewrite_table, switch_dmac_rewrite_hash_cmp, key, hash); + status = switch_pd_tunnel_dmac_rewrite_table_delete_entry( + device, dmac_rewrite->rewrite_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d unabl to delete tunnel dmac entry!", __FUNCTION__, __LINE__); + return status; + } + switch_api_id_allocator_release(dmac_rewrite_index_allocator, + dmac_rewrite->index); + switch_free(dmac_rewrite); + } + return status; } -static inline int -switch_neighbor_dmac_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_DMAC_REWRITE_HASH_KEY_SIZE); +static void switch_neighbor_dmac_hash_key_init(uchar *key, + switch_handle_t bd_handle, + switch_mac_addr_t *mac, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE); + memcpy(key, &bd_handle, sizeof(switch_handle_t)); + *len += sizeof(switch_handle_t); + memcpy(key + *len, mac, sizeof(switch_mac_addr_t)); + *len += sizeof(switch_mac_addr_t); + *hash = MurmurHash2(key, *len, 0x98761234); } -switch_neighbor_dmac_t * -switch_neighbor_dmac_search_hash(switch_handle_t bd_handle, switch_mac_addr_t *mac) -{ - unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - switch_neighbor_dmac_t *neighbor_dmac = NULL; - - switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash); - neighbor_dmac = tommy_hashtable_search(&switch_neighbor_dmac_table, - switch_neighbor_dmac_hash_cmp, - key, hash); - return neighbor_dmac; +static inline int switch_neighbor_dmac_hash_cmp(const void *key1, + const void *key2) { + return memcmp(key1, key2, SWITCH_DMAC_REWRITE_HASH_KEY_SIZE); } -static switch_status_t -switch_neighbor_dmac_insert_hash(switch_device_t device, switch_handle_t bd_handle, - switch_mac_addr_t *mac, switch_handle_t neighbor_handle) -{ - unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - uint16_t mac_index = 0; - switch_neighbor_dmac_t *neighbor_dmac = NULL; - - switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash); - neighbor_dmac = switch_malloc(sizeof(switch_neighbor_dmac_t), 1); - if (!neighbor_dmac) { - return mac_index; - } - memcpy(&neighbor_dmac->mac, mac, sizeof(switch_mac_addr_t)); - neighbor_dmac->handle = bd_handle; - neighbor_dmac->neighbor_handle = neighbor_handle; - tommy_hashtable_insert(&switch_neighbor_dmac_table, &(neighbor_dmac->node), neighbor_dmac, hash); - return SWITCH_STATUS_SUCCESS; +switch_neighbor_dmac_t *switch_neighbor_dmac_search_hash( + switch_handle_t bd_handle, switch_mac_addr_t *mac) { + unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + switch_neighbor_dmac_t *neighbor_dmac = NULL; + + switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash); + neighbor_dmac = tommy_hashtable_search( + &switch_neighbor_dmac_table, switch_neighbor_dmac_hash_cmp, key, hash); + return neighbor_dmac; } -static switch_status_t -switch_neighbor_dmac_delete_hash(switch_device_t device, switch_handle_t bd_handle, - switch_mac_addr_t *mac) -{ - switch_neighbor_dmac_t *neighbor_dmac = NULL; - unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; - unsigned int len = 0; - uint32_t hash = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - neighbor_dmac = switch_neighbor_dmac_search_hash(bd_handle, mac); - if (!neighbor_dmac) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - 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; +static switch_status_t switch_neighbor_dmac_insert_hash( + switch_device_t device, + switch_handle_t bd_handle, + switch_mac_addr_t *mac, + switch_handle_t neighbor_handle) { + unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + uint16_t mac_index = 0; + switch_neighbor_dmac_t *neighbor_dmac = NULL; + + switch_neighbor_dmac_hash_key_init(key, bd_handle, mac, &len, &hash); + neighbor_dmac = switch_malloc(sizeof(switch_neighbor_dmac_t), 1); + if (!neighbor_dmac) { + return mac_index; + } + memcpy(&neighbor_dmac->mac, mac, sizeof(switch_mac_addr_t)); + neighbor_dmac->handle = bd_handle; + neighbor_dmac->neighbor_handle = neighbor_handle; + tommy_hashtable_insert( + &switch_neighbor_dmac_table, &(neighbor_dmac->node), neighbor_dmac, hash); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_neighbor_entry_add_rewrite(switch_device_t device, - switch_handle_t neighbor_handle, - switch_neighbor_info_t *neighbor_info) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint16_t nhop_index = 0; - switch_api_neighbor_t *neighbor = NULL; - switch_interface_info_t *intf_info = NULL; - switch_tunnel_info_t *tunnel_info = NULL; - uint16_t tunnel_index = 0; - switch_encap_type_t encap_type = 0; - uint16_t bd = 0; - - neighbor = &neighbor_info->neighbor; - nhop_index = handle_to_id(neighbor->nhop_handle); - - intf_info = switch_api_interface_get(neighbor->interface); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - if (intf_info->ln_bd_handle) { - bd = handle_to_id(intf_info->ln_bd_handle); - } else { - bd = handle_to_id(intf_info->bd_handle); - } - if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN || - neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN || - neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN || - neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN || - neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN || - neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN) { - tunnel_index = handle_to_id(neighbor->interface); - status = switch_pd_rewrite_table_mpls_rewrite_add_entry( - device, bd, - nhop_index, tunnel_index, - neighbor->neigh_type, neighbor->mac_addr, - neighbor->mpls_label, neighbor->header_count, - &neighbor_info->rewrite_entry); - } else if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - tunnel_index = handle_to_id(neighbor->interface); - tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); - if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { - encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); - status = switch_pd_rewrite_table_tunnel_rewrite_add_entry( - device, bd, - nhop_index, - neighbor->mac_addr, - neighbor->neigh_type, neighbor->rw_type, - tunnel_index, encap_type, - &neighbor_info->rewrite_entry); - } - } else { - status = switch_pd_rewrite_table_unicast_rewrite_add_entry( - device, bd, nhop_index, neighbor->mac_addr, - neighbor->rw_type, &neighbor_info->rewrite_entry); - } - switch_neighbor_dmac_insert_hash(device, intf_info->bd_handle, - &neighbor->mac_addr, neighbor_handle); - - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: Unable to add unicast rewrite entry!.", __FUNCTION__, __LINE__); - } - return status; +static switch_status_t switch_neighbor_dmac_delete_hash( + switch_device_t device, switch_handle_t bd_handle, switch_mac_addr_t *mac) { + switch_neighbor_dmac_t *neighbor_dmac = NULL; + unsigned char key[SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + neighbor_dmac = switch_neighbor_dmac_search_hash(bd_handle, mac); + if (!neighbor_dmac) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + 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; } -switch_status_t -switch_api_neighbor_entry_add_tunnel_rewrite(switch_device_t device, - switch_neighbor_info_t *neighbor_info) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_neighbor_t *neighbor = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint16_t smac_index = 1; - uint16_t dmac_index = 0; - uint16_t sip_index = 0; - uint16_t dip_index = 0; - switch_handle_t vrf_handle = 0; - switch_ip_encap_t *ip_encap = NULL; - switch_mpls_encap_t *mpls_encap = NULL; - switch_tunnel_info_t *tunnel_info = NULL; - switch_ip_addr_t *src_ip = NULL; - switch_ip_addr_t *dst_ip = NULL; - - neighbor = &neighbor_info->neighbor; - intf_info = switch_api_interface_get(neighbor->interface); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: invalid interface for tunnel rewrite!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - +switch_status_t switch_api_neighbor_entry_add_rewrite( + switch_device_t device, + switch_handle_t neighbor_handle, + switch_neighbor_info_t *neighbor_info) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint16_t nhop_index = 0; + switch_api_neighbor_t *neighbor = NULL; + switch_interface_info_t *intf_info = NULL; + switch_tunnel_info_t *tunnel_info = NULL; + uint16_t tunnel_index = 0; + switch_encap_type_t encap_type = 0; + uint16_t bd = 0; + + neighbor = &neighbor_info->neighbor; + nhop_index = handle_to_id(neighbor->nhop_handle); + + intf_info = switch_api_interface_get(neighbor->interface); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + if (intf_info->ln_bd_handle) { + bd = handle_to_id(intf_info->ln_bd_handle); + } else { + bd = handle_to_id(intf_info->bd_handle); + } + if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN || + neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN || + neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN || + neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN || + neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN || + neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN) { + tunnel_index = handle_to_id(neighbor->interface); + status = switch_pd_rewrite_table_mpls_rewrite_add_entry( + device, + bd, + nhop_index, + tunnel_index, + neighbor->neigh_type, + neighbor->mac_addr, + neighbor->mpls_label, + neighbor->header_count, + &neighbor_info->rewrite_entry); + } else if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + tunnel_index = handle_to_id(neighbor->interface); tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); - dmac_index = switch_dmac_rewrite_insert_hash(device, &neighbor->mac_addr); - if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { - ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); - vrf_handle = ip_encap->vrf_handle; - - src_ip = &ip_encap->src_ip; - sip_index = switch_tunnel_src_vtep_index_get(vrf_handle, src_ip); - - dst_ip = &ip_encap->dst_ip; - dip_index = switch_tunnel_dst_vtep_index_get(vrf_handle, dst_ip); - - status = switch_pd_tunnel_rewrite_table_add_entry(device, handle_to_id(neighbor->interface), - sip_index, dip_index, - smac_index, dmac_index, - &neighbor_info->rewrite_entry); - } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { - mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); - status = switch_pd_tunnel_rewrite_table_mpls_add_entry(device, - handle_to_id(neighbor->interface), smac_index, dmac_index, - mpls_encap, &neighbor_info->rewrite_entry); + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + status = switch_pd_rewrite_table_tunnel_rewrite_add_entry( + device, + bd, + nhop_index, + neighbor->mac_addr, + neighbor->neigh_type, + neighbor->rw_type, + tunnel_index, + encap_type, + &neighbor_info->rewrite_entry); } - - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d unable to add tunnel rewrite entry", __FUNCTION__, __LINE__); - return status; - } - - return status; + } else { + status = switch_pd_rewrite_table_unicast_rewrite_add_entry( + device, + bd, + nhop_index, + neighbor->mac_addr, + neighbor->rw_type, + &neighbor_info->rewrite_entry); + } + switch_neighbor_dmac_insert_hash( + device, intf_info->bd_handle, &neighbor->mac_addr, neighbor_handle); + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: Unable to add unicast rewrite entry!.", __FUNCTION__, __LINE__); + } + return status; } -switch_handle_t -switch_api_neighbor_entry_add(switch_device_t device, switch_api_neighbor_t *neighbor) -{ - switch_neighbor_info_t *neighbor_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_handle_t handle = SWITCH_API_INVALID_HANDLE; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_nhop_info_t *nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_handle_t nhop_handle = 0; +switch_status_t switch_api_neighbor_entry_add_tunnel_rewrite( + switch_device_t device, switch_neighbor_info_t *neighbor_info) { + switch_interface_info_t *intf_info = NULL; + switch_api_neighbor_t *neighbor = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint16_t smac_index = 1; + uint16_t dmac_index = 0; + uint16_t sip_index = 0; + uint16_t dip_index = 0; + switch_handle_t vrf_handle = 0; + switch_ip_encap_t *ip_encap = NULL; + switch_mpls_encap_t *mpls_encap = NULL; + switch_tunnel_info_t *tunnel_info = NULL; + switch_ip_addr_t *src_ip = NULL; + switch_ip_addr_t *dst_ip = NULL; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + + neighbor = &neighbor_info->neighbor; + intf_info = switch_api_interface_get(neighbor->interface); + if (!intf_info) { + SWITCH_API_ERROR( + "%s:%d: invalid interface for tunnel rewrite!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); + dmac_index = switch_dmac_rewrite_insert_hash(device, &neighbor->mac_addr); + + if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { + ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); + vrf_handle = ip_encap->vrf_handle; + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + + src_ip = &ip_encap->src_ip; + sip_index = + switch_tunnel_src_vtep_index_get(vrf_handle, encap_type, src_ip); + + dst_ip = &ip_encap->dst_ip; + dip_index = + switch_tunnel_dst_vtep_index_get(vrf_handle, encap_type, dst_ip); + + status = switch_pd_tunnel_rewrite_table_add_entry( + device, + handle_to_id(neighbor->interface), + sip_index, + dip_index, + smac_index, + dmac_index, + &neighbor_info->rewrite_entry); + } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { + mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); + status = switch_pd_tunnel_rewrite_table_mpls_add_entry( + device, + handle_to_id(neighbor->interface), + smac_index, + dmac_index, + mpls_encap, + &neighbor_info->rewrite_entry); + } + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d unable to add tunnel rewrite entry", __FUNCTION__, __LINE__); + return status; + } - intf_info = switch_api_interface_get(neighbor->interface); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: invalid interface for rewrite!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } + return status; +} - handle = switch_neighbor_info_create(); - neighbor_info = switch_neighbor_info_get(handle); - memcpy(&neighbor_info->neighbor, neighbor, sizeof(switch_api_neighbor_t)); +switch_handle_t switch_api_neighbor_entry_add(switch_device_t device, + switch_api_neighbor_t *neighbor) { + switch_neighbor_info_t *neighbor_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_handle_t handle = SWITCH_API_INVALID_HANDLE; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_handle_t nhop_handle = 0; + + intf_info = switch_api_interface_get(neighbor->interface); + if (!intf_info) { + SWITCH_API_ERROR( + "%s:%d: invalid interface for rewrite!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + handle = switch_neighbor_info_create(); + neighbor_info = switch_neighbor_info_get(handle); + memcpy(&neighbor_info->neighbor, neighbor, sizeof(switch_api_neighbor_t)); #ifdef SWITCH_PD - nhop_handle = neighbor->nhop_handle; - if (neighbor->nhop_handle == SWITCH_API_INVALID_HANDLE) { - // check for neighbor type - if(neighbor->neigh_type == SWITCH_API_NEIGHBOR_NONE && neighbor->rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L3) { - switch_nhop_key_t nhop_key; - // allocate nhop and set neighbor handle - memset(&nhop_key, 0, sizeof(nhop_key)); - nhop_key.ip_addr = neighbor->ip_addr; - nhop_key.intf_handle = neighbor->interface; - nhop_key.ip_addr_valid = 1; - nhop_handle = switch_api_nhop_create(device, &nhop_key); - } + nhop_handle = neighbor->nhop_handle; + if (neighbor->nhop_handle == SWITCH_API_INVALID_HANDLE) { + // check for neighbor type + if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_NONE && + neighbor->rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L3) { + switch_nhop_key_t nhop_key; + // allocate nhop and set neighbor handle + memset(&nhop_key, 0, sizeof(nhop_key)); + nhop_key.ip_addr = neighbor->ip_addr; + nhop_key.intf_handle = neighbor->interface; + nhop_key.ip_addr_valid = 1; + nhop_handle = switch_api_nhop_create(device, &nhop_key); } - if (nhop_handle != SWITCH_API_INVALID_HANDLE && nhop_handle) { - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_API_INVALID_HANDLE; - } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - spath_info->neighbor_handle = handle; - neighbor_info->neighbor.nhop_handle = nhop_handle; - status = switch_api_nhop_update(device, nhop_handle); - status = switch_api_neighbor_entry_add_rewrite(device, handle, neighbor_info); - } else { - status = switch_api_neighbor_entry_add_tunnel_rewrite(device, neighbor_info); + } + if (nhop_handle != SWITCH_API_INVALID_HANDLE && nhop_handle) { + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_API_INVALID_HANDLE; } + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + spath_info->neighbor_handle = handle; + neighbor_info->neighbor.nhop_handle = nhop_handle; + status = switch_api_nhop_update(device, nhop_handle); + status = + switch_api_neighbor_entry_add_rewrite(device, handle, neighbor_info); + } else { + status = + switch_api_neighbor_entry_add_tunnel_rewrite(device, neighbor_info); + } #endif + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: failed to create neighbor entry!", __FUNCTION__, __LINE__); + } + neighbor->nhop_handle = nhop_handle; + return handle; +} + +switch_status_t switch_api_neighbor_entry_remove( + switch_device_t device, switch_handle_t neighbor_handle) { + switch_neighbor_info_t *neighbor_info = NULL; + switch_api_neighbor_t *neighbor = NULL; + switch_nhop_info_t *nhop_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_NEIGHBOR_HANDLE_VALID(neighbor_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + neighbor_info = switch_neighbor_info_get(neighbor_handle); + if (!neighbor_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } +#ifdef SWITCH_PD + if (neighbor_info->neighbor.nhop_handle) { + status = switch_pd_rewrite_table_delete_entry(device, + neighbor_info->rewrite_entry); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: failed to create neighbor entry!", __FUNCTION__, __LINE__); + return status; } - return handle; -} - -switch_status_t -switch_api_neighbor_entry_remove(switch_device_t device, switch_handle_t neighbor_handle) -{ - switch_neighbor_info_t *neighbor_info = NULL; - switch_api_neighbor_t *neighbor = NULL; - switch_nhop_info_t *nhop_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_NEIGHBOR_HANDLE_VALID(neighbor_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; + neighbor = &neighbor_info->neighbor; + intf_info = switch_api_interface_get(neighbor->interface); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; } - - neighbor_info = switch_neighbor_info_get(neighbor_handle); - if (!neighbor_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + switch_neighbor_dmac_delete_hash( + device, intf_info->bd_handle, &neighbor->mac_addr); + } else { + status = switch_dmac_rewrite_delete_hash(device, + &neighbor_info->neighbor.mac_addr); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } -#ifdef SWITCH_PD - if (neighbor_info->neighbor.nhop_handle) { - status = switch_pd_rewrite_table_delete_entry(device, neighbor_info->rewrite_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - neighbor = &neighbor_info->neighbor; - intf_info = switch_api_interface_get(neighbor->interface); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch_neighbor_dmac_delete_hash(device, intf_info->bd_handle, &neighbor->mac_addr); - } else { - status = switch_dmac_rewrite_delete_hash(device, &neighbor_info->neighbor.mac_addr); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - status = switch_pd_tunnel_rewrite_table_delete_entry(device, neighbor_info->rewrite_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } + status = switch_pd_tunnel_rewrite_table_delete_entry( + device, neighbor_info->rewrite_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } + } #endif - switch_neighbor_info_delete(neighbor_handle); - nhop_info = switch_nhop_get(neighbor_info->neighbor.nhop_handle); - if (nhop_info) { - nhop_info->u.spath.neighbor_handle = 0; - status = switch_api_nhop_update(device, neighbor_info->neighbor.nhop_handle); - if (nhop_info->valid == 0) { - switch_api_nhop_delete(device, neighbor_info->neighbor.nhop_handle); - } + switch_neighbor_info_delete(neighbor_handle); + nhop_info = switch_nhop_get(neighbor_info->neighbor.nhop_handle); + if (nhop_info) { + nhop_info->u.spath.neighbor_handle = 0; + status = + switch_api_nhop_update(device, neighbor_info->neighbor.nhop_handle); + if (nhop_info->valid == 0) { + switch_api_nhop_delete(device, neighbor_info->neighbor.nhop_handle); } - return status; + } + return status; } -switch_status_t -switch_api_neighbor_print_entry(switch_handle_t neighbor_handle) -{ - switch_neighbor_info_t *neighbor_info = NULL; - switch_api_neighbor_t *neighbor = NULL; - switch_mac_addr_t *mac = NULL; - - neighbor_info = switch_neighbor_info_get(neighbor_handle); - if (!neighbor_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - neighbor = &neighbor_info->neighbor; - printf("\n\nneighbor_handle: %x:", (unsigned int) neighbor_handle); - printf("\n\ttype: %x", neighbor->neigh_type); - printf("\n\tvrf_handle :%x nhop_handle %x interface_handle %x", - (unsigned int) neighbor->vrf_handle, - (unsigned int) neighbor->nhop_handle, - (unsigned int) neighbor->interface); - mac = &neighbor->mac_addr; - printf("\n\trewrite mac %02x:%02x:%02x:%02x:%02x:%02x", - mac->mac_addr[0], mac->mac_addr[1], mac->mac_addr[2], - mac->mac_addr[3], mac->mac_addr[4], mac->mac_addr[5]); - printf("\n"); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_neighbor_print_entry( + switch_handle_t neighbor_handle) { + switch_neighbor_info_t *neighbor_info = NULL; + switch_api_neighbor_t *neighbor = NULL; + switch_mac_addr_t *mac = NULL; + + neighbor_info = switch_neighbor_info_get(neighbor_handle); + if (!neighbor_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + neighbor = &neighbor_info->neighbor; + printf("\n\nneighbor_handle: %x:", (unsigned int)neighbor_handle); + printf("\n\ttype: %x", neighbor->neigh_type); + printf("\n\tvrf_handle :%x nhop_handle %x interface_handle %x", + (unsigned int)neighbor->vrf_handle, + (unsigned int)neighbor->nhop_handle, + (unsigned int)neighbor->interface); + mac = &neighbor->mac_addr; + printf("\n\trewrite mac %02x:%02x:%02x:%02x:%02x:%02x", + mac->mac_addr[0], + mac->mac_addr[1], + mac->mac_addr[2], + mac->mac_addr[3], + mac->mac_addr[4], + mac->mac_addr[5]); + printf("\n"); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_neighbor_print_all(void) -{ - switch_handle_t neighbor_handle = 0; - switch_handle_t next_neighbor_handle = 0; - - switch_handle_get_first(switch_neighbor_array, neighbor_handle); - while (neighbor_handle) { - switch_api_neighbor_print_entry(neighbor_handle); - switch_handle_get_next(switch_neighbor_array, neighbor_handle, next_neighbor_handle); - neighbor_handle = next_neighbor_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_neighbor_print_all(void) { + switch_handle_t neighbor_handle = 0; + switch_handle_t next_neighbor_handle = 0; + + switch_handle_get_first(switch_neighbor_array, neighbor_handle); + while (neighbor_handle) { + switch_api_neighbor_print_entry(neighbor_handle); + switch_handle_get_next( + switch_neighbor_array, neighbor_handle, next_neighbor_handle); + neighbor_handle = next_neighbor_handle; + } + return SWITCH_STATUS_SUCCESS; } - + #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_neighbor_int.h b/switchapi/src/switch_neighbor_int.h index bf2bbf0..562dd1f 100644 --- a/switchapi/src/switch_neighbor_int.h +++ b/switchapi/src/switch_neighbor_int.h @@ -17,6 +17,7 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" #include "switchapi/switch_neighbor.h" +#include "switch_pd_types.h" #ifdef __cplusplus extern "C" { @@ -26,42 +27,42 @@ extern "C" { #define SWITCH_DMAC_REWRITE_HASH_KEY_SIZE 6 typedef struct switch_neighbor_ { - switch_api_neighbor_t neighbor; + switch_api_neighbor_t neighbor; #ifdef SWITCH_PD - p4_pd_entry_hdl_t rewrite_entry; /**< hold the HW Entry */ + p4_pd_entry_hdl_t rewrite_entry; /**< hold the HW Entry */ #endif } switch_neighbor_info_t; typedef struct switch_dmac_rewrite_ { - switch_mac_addr_t mac; - tommy_hashtable_node node; - uint16_t index; - uint16_t ref_count; + switch_mac_addr_t mac; + tommy_hashtable_node node; + uint16_t index; + uint16_t ref_count; #ifdef SWITCH_PD - p4_pd_entry_hdl_t rewrite_entry; + p4_pd_entry_hdl_t rewrite_entry; #endif } switch_dmac_rewrite_t; #define SWITCH_NEIGHBOR_DMAC_HASH_KEY_SIZE 14 typedef struct switch_neighbor_dmac_ { - switch_handle_t handle; - switch_mac_addr_t mac; - tommy_hashtable_node node; - switch_handle_t neighbor_handle; + switch_handle_t handle; + switch_mac_addr_t mac; + tommy_hashtable_node node; + switch_handle_t neighbor_handle; } switch_neighbor_dmac_t; switch_status_t switch_neighbor_init(switch_device_t device); switch_status_t switch_neighbor_free(switch_device_t device); -switch_status_t -switch_api_neighbor_entry_add_unicast_rewrite(switch_device_t device, switch_neighbor_info_t *neighbor_info); -switch_status_t -switch_api_neighbor_entry_add_tunnel_rewrite(switch_device_t device, switch_neighbor_info_t *neighbor_info); - -switch_neighbor_info_t * switch_neighbor_info_get(switch_handle_t handle); +switch_status_t switch_api_neighbor_entry_add_unicast_rewrite( + switch_device_t device, switch_neighbor_info_t *neighbor_info); +switch_status_t switch_api_neighbor_entry_add_tunnel_rewrite( + switch_device_t device, switch_neighbor_info_t *neighbor_info); -switch_neighbor_dmac_t * -switch_neighbor_dmac_search_hash(switch_handle_t bd_handle, switch_mac_addr_t *mac); +switch_neighbor_info_t *switch_neighbor_info_get(switch_handle_t handle); + +switch_neighbor_dmac_t *switch_neighbor_dmac_search_hash( + switch_handle_t bd_handle, switch_mac_addr_t *mac); #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_nhop.c b/switchapi/src/switch_nhop.c index efae147..1d73f1f 100644 --- a/switchapi/src/switch_nhop.c +++ b/switchapi/src/switch_nhop.c @@ -36,801 +36,830 @@ static void *switch_nhop_array; static switch_api_id_allocator *ecmp_select; static tommy_hashtable switch_nhop_hash_table; -switch_status_t -switch_nhop_init(switch_device_t device) -{ - switch_nhop_array = NULL; - ecmp_select = switch_api_id_allocator_new(64 * 1024/ 32, FALSE); - switch_handle_type_init(SWITCH_HANDLE_TYPE_NHOP, (16*1024)); - tommy_hashtable_init(&switch_nhop_hash_table, SWITCH_NHOP_HASH_TABLE_SIZE); - switch_nhop_create(); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_nhop_init(switch_device_t device) { + switch_nhop_array = NULL; + ecmp_select = switch_api_id_allocator_new(64 * 1024 / 32, FALSE); + switch_handle_type_init(SWITCH_HANDLE_TYPE_NHOP, (16 * 1024)); + tommy_hashtable_init(&switch_nhop_hash_table, SWITCH_NHOP_HASH_TABLE_SIZE); + switch_nhop_create(); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_nhop_free(switch_device_t device) -{ - switch_handle_type_free(SWITCH_HANDLE_TYPE_NHOP); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_nhop_free(switch_device_t device) { + switch_handle_type_free(SWITCH_HANDLE_TYPE_NHOP); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_nhop_create() -{ - switch_handle_t nhop_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_NHOP, switch_nhop_info_t, switch_nhop_array, NULL, nhop_handle); - return nhop_handle; +switch_handle_t switch_nhop_create() { + switch_handle_t nhop_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_NHOP, + switch_nhop_info_t, + switch_nhop_array, + NULL, + nhop_handle); + return nhop_handle; } -switch_nhop_info_t * -switch_nhop_get(switch_handle_t nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; - _switch_handle_get(switch_nhop_info_t, switch_nhop_array, nhop_handle, nhop_info); - return nhop_info; +switch_nhop_info_t *switch_nhop_get(switch_handle_t nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; + _switch_handle_get( + switch_nhop_info_t, switch_nhop_array, nhop_handle, nhop_info); + return nhop_info; } -switch_status_t -switch_nhop_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_nhop_info_t, switch_nhop_array, handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_nhop_delete(switch_handle_t handle) { + _switch_handle_delete(switch_nhop_info_t, switch_nhop_array, handle); + return SWITCH_STATUS_SUCCESS; } -static inline void -switch_nhop_hash_key_init(uchar *key, switch_nhop_key_t *nhop_key, - uint32_t *len, uint32_t *hash) -{ - *len=0; - memset(key, 0, SWITCH_NHOP_HASH_KEY_SIZE); - memcpy(key, (uchar *) &nhop_key->intf_handle, sizeof(switch_handle_t)); - *len += sizeof(switch_handle_t); - key[*len] = nhop_key->ip_addr.type; - *len += 4; - if(nhop_key->ip_addr.type == SWITCH_API_IP_ADDR_V4) { - *(unsigned int *)(&key[*len]) = nhop_key->ip_addr.ip.v4addr; - *len += 16; - } - else { - memcpy(&key[*len], nhop_key->ip_addr.ip.v6addr, 16); - *len += 16; - } - key[*len] = nhop_key->ip_addr.prefix_len; - *len += 4; - *hash = MurmurHash2(key, *len, 0x98761234); +switch_status_t switch_api_nhop_set(switch_device_t device, + switch_handle_t handle, + switch_nhop_key_t *nhop_key) { + switch_nhop_info_t *info = switch_nhop_get(handle); + switch (info->type) { + case SWITCH_NHOP_INDEX_TYPE_ONE_PATH: + // need to check each field in key diff? + memcpy(&info->u.spath.nhop_key, nhop_key, sizeof(switch_nhop_key_t)); + break; + case SWITCH_NHOP_INDEX_TYPE_ECMP: + case SWITCH_NHOP_INDEX_TYPE_NONE: + return SWITCH_STATUS_NOT_SUPPORTED; + } + + return switch_api_nhop_update(device, handle); } -static inline int -switch_nhop_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_NHOP_HASH_KEY_SIZE); +switch_status_t switch_api_nhop_get(switch_device_t device, + switch_handle_t handle, + switch_nhop_key_t **nhop_key) { + switch_nhop_info_t *info = switch_nhop_get(handle); + switch (info->type) { + case SWITCH_NHOP_INDEX_TYPE_ONE_PATH: + *nhop_key = &info->u.spath.nhop_key; + break; + case SWITCH_NHOP_INDEX_TYPE_ECMP: + case SWITCH_NHOP_INDEX_TYPE_NONE: + return SWITCH_STATUS_NOT_SUPPORTED; + } + + return SWITCH_STATUS_SUCCESS; } -static switch_status_t -switch_nhop_insert_hash(switch_spath_info_t *spath_info, - switch_nhop_key_t *nhop_key, - switch_handle_t nhop_handle) -{ - switch_nhop_key_t *temp_nhop_key = NULL; - unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - temp_nhop_key = &spath_info->nhop_key; - memset(temp_nhop_key, 0, sizeof(switch_nhop_key_t)); - memcpy(temp_nhop_key, nhop_key, sizeof(switch_nhop_key_t)); - spath_info->nhop_handle = nhop_handle; - switch_nhop_hash_key_init(key, temp_nhop_key, &len, &hash); - tommy_hashtable_insert(&switch_nhop_hash_table, - &(spath_info->node), - spath_info, hash); - return SWITCH_STATUS_SUCCESS; +static inline void switch_nhop_hash_key_init(uchar *key, + switch_nhop_key_t *nhop_key, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, SWITCH_NHOP_HASH_KEY_SIZE); + memcpy(key, (uchar *)&nhop_key->intf_handle, sizeof(switch_handle_t)); + *len += sizeof(switch_handle_t); + key[*len] = nhop_key->ip_addr.type; + *len += 4; + if (nhop_key->ip_addr.type == SWITCH_API_IP_ADDR_V4) { + *(unsigned int *)(&key[*len]) = nhop_key->ip_addr.ip.v4addr; + *len += 16; + } else { + memcpy(&key[*len], nhop_key->ip_addr.ip.v6addr, 16); + *len += 16; + } + key[*len] = nhop_key->ip_addr.prefix_len; + *len += 4; + *hash = MurmurHash2(key, *len, 0x98761234); } -static switch_status_t -switch_nhop_delete_hash(switch_spath_info_t *spath_info) -{ - switch_nhop_key_t *temp_nhop_key = NULL; - unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - temp_nhop_key = &spath_info->nhop_key; - if (!temp_nhop_key->ip_addr_valid) { - return SWITCH_STATUS_SUCCESS; - } - switch_nhop_hash_key_init(key, temp_nhop_key, &len, &hash); - spath_info = tommy_hashtable_remove(&switch_nhop_hash_table, - switch_nhop_hash_cmp, - key, hash); - if (!spath_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - return SWITCH_STATUS_SUCCESS; +static inline int switch_nhop_hash_cmp(const void *key1, const void *key2) { + return memcmp(key1, key2, SWITCH_NHOP_HASH_KEY_SIZE); } -switch_handle_t -switch_api_nhop_handle_get(switch_nhop_key_t *nhop_key) -{ - switch_spath_info_t *spath_info = NULL; - unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; - uint32_t len = 0; - uint32_t hash = 0; - - switch_nhop_hash_key_init(key, nhop_key, &len, &hash); - spath_info = tommy_hashtable_search(&switch_nhop_hash_table, - switch_nhop_hash_cmp, - key, hash); - if (!spath_info) { - return SWITCH_API_INVALID_HANDLE; - } - return spath_info->nhop_handle; +static switch_status_t switch_nhop_insert_hash(switch_spath_info_t *spath_info, + switch_nhop_key_t *nhop_key, + switch_handle_t nhop_handle) { + switch_nhop_key_t *temp_nhop_key = NULL; + unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + temp_nhop_key = &spath_info->nhop_key; + memset(temp_nhop_key, 0, sizeof(switch_nhop_key_t)); + memcpy(temp_nhop_key, nhop_key, sizeof(switch_nhop_key_t)); + spath_info->nhop_handle = nhop_handle; + switch_nhop_hash_key_init(key, temp_nhop_key, &len, &hash); + tommy_hashtable_insert( + &switch_nhop_hash_table, &(spath_info->node), spath_info, hash); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_neighbor_handle_get(switch_handle_t nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; +static switch_status_t switch_nhop_delete_hash( + switch_spath_info_t *spath_info) { + switch_nhop_key_t *temp_nhop_key = NULL; + unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_API_INVALID_HANDLE; - } + temp_nhop_key = &spath_info->nhop_key; + if (!temp_nhop_key->ip_addr_valid) { + return SWITCH_STATUS_SUCCESS; + } + switch_nhop_hash_key_init(key, temp_nhop_key, &len, &hash); + spath_info = tommy_hashtable_remove( + &switch_nhop_hash_table, switch_nhop_hash_cmp, key, hash); + if (!spath_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + return SWITCH_STATUS_SUCCESS; +} - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_API_INVALID_HANDLE; - } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - return spath_info->neighbor_handle; +switch_handle_t switch_api_nhop_handle_get(switch_nhop_key_t *nhop_key) { + switch_spath_info_t *spath_info = NULL; + unsigned char key[SWITCH_NHOP_HASH_KEY_SIZE]; + uint32_t len = 0; + uint32_t hash = 0; + + switch_nhop_hash_key_init(key, nhop_key, &len, &hash); + spath_info = tommy_hashtable_search( + &switch_nhop_hash_table, switch_nhop_hash_cmp, key, hash); + if (!spath_info) { + return SWITCH_API_INVALID_HANDLE; + } + return spath_info->nhop_handle; } -switch_status_t -switch_nhop_ifindex_get(switch_handle_t nhop_handle, - switch_ifindex_t *ifindex, - bool *flood, - uint32_t *mc_index) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_neighbor_info_t *neighbor_info = NULL; - switch_api_neighbor_t *neighbor = NULL; - switch_api_mac_entry_t mac_entry; - switch_mac_info_t *mac_info = NULL; - switch_handle_t neighbor_handle; - switch_bd_info_t *bd_info = NULL; - switch_port_info_t *tmp_port_info = NULL; - switch_lag_info_t *tmp_lag_info = NULL; - switch_interface_info_t *tmp_intf_info = NULL; - switch_api_mac_entry_t *tmp_mac_entry = NULL; - switch_handle_type_t handle_type = 0; - switch_handle_t encap_if; - switch_spath_info_t *spath_info = NULL; +switch_handle_t switch_api_neighbor_handle_get(switch_handle_t nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_API_INVALID_HANDLE; + } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_API_INVALID_HANDLE; + } + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + return spath_info->neighbor_handle; +} + +switch_status_t switch_nhop_ifindex_get(switch_handle_t nhop_handle, + switch_ifindex_t *ifindex, + bool *flood, + uint32_t *mc_index) { + switch_nhop_info_t *nhop_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_neighbor_info_t *neighbor_info = NULL; + switch_api_neighbor_t *neighbor = NULL; + switch_api_mac_entry_t mac_entry; + switch_mac_info_t *mac_info = NULL; + switch_handle_t neighbor_handle; + switch_bd_info_t *bd_info = NULL; + switch_port_info_t *tmp_port_info = NULL; + switch_lag_info_t *tmp_lag_info = NULL; + switch_interface_info_t *tmp_intf_info = NULL; + switch_api_mac_entry_t *tmp_mac_entry = NULL; + switch_handle_type_t handle_type = 0; + switch_handle_t encap_if; + switch_spath_info_t *spath_info = NULL; + + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + *ifindex = intf_info->ifindex; + *flood = FALSE; + *mc_index = 0; + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + encap_if = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); + intf_info = switch_api_interface_get(encap_if); if (!intf_info) { - return SWITCH_STATUS_INVALID_HANDLE; + return SWITCH_STATUS_INVALID_HANDLE; } - *ifindex = intf_info->ifindex; - *flood = FALSE; - *mc_index = 0; - - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - encap_if = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); - intf_info = switch_api_interface_get(encap_if); - if (!intf_info) { - return SWITCH_STATUS_INVALID_HANDLE; + SWITCH_API_TRACE("%s:%d ifindex for tunnel interface: %x", + __FUNCTION__, + __LINE__, + *ifindex); + } + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_VLAN) { + neighbor_handle = spath_info->neighbor_handle; + if (neighbor_handle == SWITCH_API_INVALID_HANDLE || neighbor_handle == 0) { + *ifindex = switch_api_cpu_glean_ifindex(); + } else { + neighbor_info = switch_neighbor_info_get(neighbor_handle); + if (!neighbor_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + neighbor = &neighbor_info->neighbor; + memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t)); + mac_entry.vlan_handle = intf_info->bd_handle; + memcpy(&mac_entry.mac, &neighbor->mac_addr, ETH_LEN); + mac_info = switch_mac_table_entry_find(&mac_entry); + if (!mac_info) { + bd_info = switch_bd_get(intf_info->bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; } - *ifindex = intf_info->ifindex; - SWITCH_API_TRACE("%s:%d ifindex for tunnel interface: %x", - __FUNCTION__, __LINE__, *ifindex); - } - - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_VLAN) { - neighbor_handle = spath_info->neighbor_handle; - if (neighbor_handle == SWITCH_API_INVALID_HANDLE || - neighbor_handle == 0) { - *ifindex = switch_api_cpu_glean_ifindex(); - } else { - neighbor_info = switch_neighbor_info_get(neighbor_handle); - if (!neighbor_info) { - return SWITCH_STATUS_INVALID_HANDLE; + *mc_index = handle_to_id(bd_info->uuc_mc_index); + *flood = TRUE; + } else { + tmp_mac_entry = &mac_info->mac_entry; + handle_type = switch_handle_get_type(tmp_mac_entry->handle); + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + tmp_port_info = switch_api_port_get_internal(tmp_mac_entry->handle); + if (!tmp_port_info) { + return SWITCH_STATUS_INVALID_HANDLE; } - neighbor = &neighbor_info->neighbor; - memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t)); - mac_entry.vlan_handle = intf_info->bd_handle; - memcpy(&mac_entry.mac, &neighbor->mac_addr, ETH_LEN); - mac_info = switch_mac_table_entry_find(&mac_entry); - if (!mac_info) { - bd_info = switch_bd_get(intf_info->bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - *mc_index = handle_to_id(bd_info->uuc_mc_index); - *flood = TRUE; - } else { - tmp_mac_entry = &mac_info->mac_entry; - handle_type = switch_handle_get_type(tmp_mac_entry->handle); - switch (handle_type) { - case SWITCH_HANDLE_TYPE_PORT: - tmp_port_info = switch_api_port_get_internal(tmp_mac_entry->handle); - if (!tmp_port_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - *ifindex = tmp_port_info->ifindex; - break; - case SWITCH_HANDLE_TYPE_LAG: - tmp_lag_info = switch_api_lag_get_internal(tmp_mac_entry->handle); - if (!tmp_lag_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - *ifindex = tmp_lag_info->ifindex; - break; - case SWITCH_HANDLE_TYPE_INTERFACE: - tmp_intf_info = switch_api_interface_get(tmp_mac_entry->handle); - if (!tmp_intf_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - *ifindex = tmp_intf_info->ifindex; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; - } + *ifindex = tmp_port_info->ifindex; + break; + case SWITCH_HANDLE_TYPE_LAG: + tmp_lag_info = switch_api_lag_get_internal(tmp_mac_entry->handle); + if (!tmp_lag_info) { + return SWITCH_STATUS_INVALID_HANDLE; } + *ifindex = tmp_lag_info->ifindex; + break; + case SWITCH_HANDLE_TYPE_INTERFACE: + tmp_intf_info = switch_api_interface_get(tmp_mac_entry->handle); + if (!tmp_intf_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + *ifindex = tmp_intf_info->ifindex; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; } + } } - return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_api_nhop_create(switch_device_t device, switch_nhop_key_t *nhop_key) -{ - switch_handle_t nhop_handle; - switch_nhop_info_t *nhop_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_ifindex_t ifindex = 0; - bool flood = FALSE; - uint32_t mc_index = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_INTERFACE_HANDLE_VALID(nhop_key->intf_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - intf_info = switch_api_interface_get(nhop_key->intf_handle); - if (!intf_info) { - return SWITCH_API_INVALID_HANDLE; - } - - if((nhop_handle = switch_api_nhop_handle_get(nhop_key)) == SWITCH_API_INVALID_HANDLE) { - nhop_handle = switch_nhop_create(); - } else { - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_API_INVALID_HANDLE; - } - return nhop_handle; - } +switch_handle_t switch_api_nhop_create(switch_device_t device, + switch_nhop_key_t *nhop_key) { + switch_handle_t nhop_handle; + switch_nhop_info_t *nhop_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_ifindex_t ifindex = 0; + bool flood = FALSE; + uint32_t mc_index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_INTERFACE_HANDLE_VALID(nhop_key->intf_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + intf_info = switch_api_interface_get(nhop_key->intf_handle); + if (!intf_info) { + return SWITCH_API_INVALID_HANDLE; + } + + if ((nhop_handle = switch_api_nhop_handle_get(nhop_key)) == + SWITCH_API_INVALID_HANDLE) { + nhop_handle = switch_nhop_create(); + } else { nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { - return SWITCH_API_INVALID_HANDLE; - } - nhop_info->type = SWITCH_NHOP_INDEX_TYPE_ONE_PATH; - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - spath_info->nhop_key.intf_handle = nhop_key->intf_handle; - intf_info->nhop_handle = nhop_handle; - nhop_info->valid = 1; - - status = switch_nhop_ifindex_get(nhop_handle, &ifindex, &flood, &mc_index); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; + return SWITCH_API_INVALID_HANDLE; } + return nhop_handle; + } + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_API_INVALID_HANDLE; + } + nhop_info->type = SWITCH_NHOP_INDEX_TYPE_ONE_PATH; + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + spath_info->nhop_key.intf_handle = nhop_key->intf_handle; + intf_info->nhop_handle = nhop_handle; + nhop_info->valid = 1; + + status = switch_nhop_ifindex_get(nhop_handle, &ifindex, &flood, &mc_index); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } #ifdef SWITCH_PD - bool tunnel = (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL); - status = switch_pd_nexthop_table_add_entry(device, - handle_to_id(nhop_handle), - handle_to_id(intf_info->bd_handle), - ifindex, flood, mc_index, tunnel, - &spath_info->hw_entry); + bool tunnel = (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL); + status = switch_pd_nexthop_table_add_entry(device, + handle_to_id(nhop_handle), + handle_to_id(intf_info->bd_handle), + ifindex, + flood, + mc_index, + tunnel, + &spath_info->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + + if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { + status = + switch_pd_urpf_bd_table_add_entry(device, + handle_to_id(nhop_handle), + handle_to_id(intf_info->bd_handle), + &spath_info->urpf_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { - status = switch_pd_urpf_bd_table_add_entry(device, handle_to_id(nhop_handle), - handle_to_id(intf_info->bd_handle), - &spath_info->urpf_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } + return SWITCH_API_INVALID_HANDLE; } + } #endif - if (nhop_key->ip_addr_valid) { - switch_nhop_insert_hash(spath_info, nhop_key, nhop_handle); - } - return nhop_handle; + if (nhop_key->ip_addr_valid) { + switch_nhop_insert_hash(spath_info, nhop_key, nhop_handle); + } + return nhop_handle; } -switch_status_t -switch_api_nhop_update(switch_device_t device, switch_handle_t nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_ifindex_t ifindex = 0; - bool flood = FALSE; - uint32_t mc_index = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_nhop_update(switch_device_t device, + switch_handle_t nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_ifindex_t ifindex = 0; + bool flood = FALSE; + uint32_t mc_index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_nhop_ifindex_get(nhop_handle, &ifindex, &flood, &mc_index); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +#ifdef SWITCH_PD + bool tunnel = (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL); + status = + switch_pd_nexthop_table_update_entry(device, + handle_to_id(nhop_handle), + handle_to_id(intf_info->bd_handle), + ifindex, + flood, + mc_index, + tunnel, + &spath_info->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } +#endif + return SWITCH_STATUS_SUCCESS; +} - status = switch_nhop_ifindex_get(nhop_handle, &ifindex, &flood, &mc_index); +switch_status_t switch_api_nhop_delete(switch_device_t device, + switch_handle_t nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (nhop_info->ref_count) { + return SWITCH_STATUS_RESOURCE_IN_USE; + } + + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + nhop_info->valid = 0; + if (nhop_info->u.spath.neighbor_handle == 0) { +#ifdef SWITCH_PD + status = switch_pd_nexthop_table_delete_entry(device, spath_info->hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_INVALID_HANDLE; + return status; } - - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; + if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { + status = switch_pd_urpf_bd_table_delete_entry(device, + spath_info->urpf_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } } +#endif + switch_nhop_delete_hash(spath_info); + switch_nhop_delete(nhop_handle); + } + return SWITCH_STATUS_SUCCESS; +} -#ifdef SWITCH_PD - bool tunnel = (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL); - status = switch_pd_nexthop_table_update_entry(device, - handle_to_id(nhop_handle), - handle_to_id(intf_info->bd_handle), - ifindex, flood, mc_index, tunnel, - &spath_info->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } +switch_handle_t switch_api_ecmp_create(switch_device_t device) { + switch_handle_t nhop_handle; + switch_nhop_info_t *nhop_info = NULL; + switch_ecmp_info_t *ecmp_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + nhop_handle = switch_nhop_create(); + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_API_INVALID_HANDLE; + } + nhop_info->type = SWITCH_NHOP_INDEX_TYPE_ECMP; + ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); + memset(ecmp_info, 0, sizeof(switch_ecmp_info_t)); + ecmp_info->hw_entry = SWITCH_HW_INVALID_HANDLE; + ecmp_info->count = 0; + tommy_list_init(&(ecmp_info->members)); +#ifdef SWITCH_PD + status = switch_pd_ecmp_group_create(device, &(ecmp_info->pd_group_hdl)); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } #endif - return SWITCH_STATUS_SUCCESS; + + return nhop_handle; } -switch_status_t -switch_api_nhop_delete(switch_device_t device, switch_handle_t nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_handle_t switch_api_ecmp_create_with_members( + switch_device_t device, + uint32_t member_count, + switch_handle_t *nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_ecmp_info_t *ecmp_info = NULL; + switch_ecmp_member_t *ecmp_member = NULL; + switch_handle_t ecmp_handle; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t index = 0; + + ecmp_handle = switch_api_ecmp_create(device); + nhop_info = switch_nhop_get(ecmp_handle); + if (!nhop_info) { + return SWITCH_API_INVALID_HANDLE; + } + + ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); + tommy_list_init(&ecmp_info->members); - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +#ifdef SWITCH_PD + status = switch_pd_ecmp_group_create(device, &(ecmp_info->pd_group_hdl)); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } +#endif - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_HANDLE; + for (index = 0; index < member_count; index++) { + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle[index])) { + return SWITCH_STATUS_INVALID_HANDLE; } - if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { - return SWITCH_STATUS_INVALID_HANDLE; + ecmp_member = switch_malloc(sizeof(switch_ecmp_member_t), 1); + if (!ecmp_member) { + // TODO: Cleanup memory + return SWITCH_API_INVALID_HANDLE; } + ecmp_member->nhop_handle = nhop_handle[index]; + ecmp_member->mbr_hdl = 0; - if (nhop_info->ref_count) { - return SWITCH_STATUS_RESOURCE_IN_USE; + nhop_info = switch_nhop_get(ecmp_member->nhop_handle); + if (!nhop_info) { + return SWITCH_API_INVALID_HANDLE; } spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; + return SWITCH_API_INVALID_HANDLE; } - nhop_info->valid = 0; - if(nhop_info->u.spath.neighbor_handle == 0) { -#ifdef SWITCH_PD - status = switch_pd_nexthop_table_delete_entry(device, spath_info->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { - status = switch_pd_urpf_bd_table_delete_entry(device, spath_info->urpf_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } -#endif - switch_nhop_delete_hash(spath_info); - switch_nhop_delete(nhop_handle); - } - return SWITCH_STATUS_SUCCESS; -} - -switch_handle_t -switch_api_ecmp_create(switch_device_t device) -{ - switch_handle_t nhop_handle; - switch_nhop_info_t *nhop_info = NULL; - switch_ecmp_info_t *ecmp_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - nhop_handle = switch_nhop_create(); - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_API_INVALID_HANDLE; - } - nhop_info->type = SWITCH_NHOP_INDEX_TYPE_ECMP; - ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); - memset(ecmp_info, 0, sizeof(switch_ecmp_info_t)); - ecmp_info->hw_entry = SWITCH_HW_INVALID_HANDLE; - ecmp_info->count = 0; - tommy_list_init(&(ecmp_info->members)); + nhop_info->ref_count++; #ifdef SWITCH_PD - status = switch_pd_ecmp_group_create(device, &(ecmp_info->pd_group_hdl)); + status = switch_pd_ecmp_member_add(device, + ecmp_info->pd_group_hdl, + handle_to_id(ecmp_member->nhop_handle), + intf_info, + &(ecmp_member->mbr_hdl)); if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; + return SWITCH_API_INVALID_HANDLE; } -#endif - - return nhop_handle; -} -switch_handle_t -switch_api_ecmp_create_with_members(switch_device_t device, - uint32_t member_count, - switch_handle_t *nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_ecmp_info_t *ecmp_info = NULL; - switch_ecmp_member_t *ecmp_member = NULL; - switch_handle_t ecmp_handle; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint32_t index = 0; - - ecmp_handle = switch_api_ecmp_create(device); - nhop_info = switch_nhop_get(ecmp_handle); - if (!nhop_info) { + if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { + status = + switch_pd_urpf_bd_table_add_entry(device, + handle_to_id(ecmp_handle), + handle_to_id(intf_info->bd_handle), + &(ecmp_member->urpf_hw_entry)); + if (status != SWITCH_STATUS_SUCCESS) { return SWITCH_API_INVALID_HANDLE; + } } - - ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); - tommy_list_init(&ecmp_info->members); +#endif + tommy_list_insert_head( + &ecmp_info->members, &(ecmp_member->node), ecmp_member); + } #ifdef SWITCH_PD - status = switch_pd_ecmp_group_create(device, &(ecmp_info->pd_group_hdl)); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } + status = switch_pd_ecmp_group_table_add_entry_with_selector( + device, + handle_to_id(ecmp_handle), + ecmp_info->pd_group_hdl, + &(ecmp_info->hw_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } #endif + ecmp_info->count = member_count; + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + return ecmp_handle; +} - for (index = 0; index < member_count; index++) { - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle[index])) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - ecmp_member = switch_malloc(sizeof(switch_ecmp_member_t), 1); - if (!ecmp_member) { - // TODO: Cleanup memory - return SWITCH_API_INVALID_HANDLE; - } - ecmp_member->nhop_handle = nhop_handle[index]; - ecmp_member->mbr_hdl = 0; - +switch_status_t switch_api_ecmp_delete(switch_device_t device, + switch_handle_t handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_ecmp_info_t *ecmp_info = NULL; + tommy_node *node = NULL; + switch_ecmp_member_t *ecmp_member = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_NHOP_HANDLE_VALID(handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + nhop_info = switch_nhop_get(handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; + } + if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { + ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); + if (ecmp_info->count > 0) { + node = tommy_list_head(&(ecmp_info->members)); + while (node) { + ecmp_member = (switch_ecmp_member_t *)node->data; nhop_info = switch_nhop_get(ecmp_member->nhop_handle); if (!nhop_info) { - return SWITCH_API_INVALID_HANDLE; - } - - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); - if (!intf_info) { - return SWITCH_API_INVALID_HANDLE; + return SWITCH_STATUS_INVALID_NHOP; } - nhop_info->ref_count++; - -#ifdef SWITCH_PD - status = switch_pd_ecmp_member_add(device, ecmp_info->pd_group_hdl, - handle_to_id(ecmp_member->nhop_handle), intf_info, - &(ecmp_member->mbr_hdl)); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { - status = switch_pd_urpf_bd_table_add_entry(device, handle_to_id(ecmp_handle), - handle_to_id(intf_info->bd_handle), - &(ecmp_member->urpf_hw_entry)); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - } -#endif - tommy_list_insert_head(&ecmp_info->members, &(ecmp_member->node), ecmp_member); + nhop_info->ref_count--; + node = node->next; + } } - #ifdef SWITCH_PD - status = switch_pd_ecmp_group_table_add_entry_with_selector(device, handle_to_id(ecmp_handle), - ecmp_info->pd_group_hdl, &(ecmp_info->hw_entry)); + status = switch_pd_ecmp_group_delete(device, ecmp_info->pd_group_hdl); if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; + return status; } #endif - ecmp_info->count = member_count; - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - return ecmp_handle; + } + return switch_nhop_delete(handle); } -switch_status_t -switch_api_ecmp_delete(switch_device_t device, switch_handle_t handle) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_ecmp_info_t *ecmp_info = NULL; - tommy_node *node = NULL; - switch_ecmp_member_t *ecmp_member = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_NHOP_HANDLE_VALID(handle)) { - return SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_api_ecmp_member_add(switch_device_t device, + switch_handle_t ecmp_handle, + uint16_t nhop_count, + switch_handle_t *nhop_handle_list) { + switch_nhop_info_t *e_nhop_info = NULL; + switch_nhop_info_t *nhop_info = NULL; + switch_ecmp_info_t *ecmp_info = NULL; + switch_ecmp_member_t *ecmp_member = NULL; + switch_interface_info_t *intf_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_handle_t nhop_handle; + switch_status_t status = SWITCH_STATUS_SUCCESS; + int count = 0; + + if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + e_nhop_info = switch_nhop_get(ecmp_handle); + if (!e_nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; + } + ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info)); + + for (count = 0; count < nhop_count; count++) { + nhop_handle = nhop_handle_list[count]; + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; } - - nhop_info = switch_nhop_get(handle); + nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; + return SWITCH_STATUS_INVALID_NHOP; } - if (nhop_info->type != SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { - ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); - if (ecmp_info->count > 0) { - node = tommy_list_head(&(ecmp_info->members)); - while (node) { - ecmp_member = (switch_ecmp_member_t *) node->data; - nhop_info = switch_nhop_get(ecmp_member->nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; - } - nhop_info->ref_count--; - node = node->next; - } - } -#ifdef SWITCH_PD - status = switch_pd_ecmp_group_delete(device, ecmp_info->pd_group_hdl); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } -#endif - } - return switch_nhop_delete(handle); -} + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); -switch_status_t -switch_api_ecmp_member_add(switch_device_t device, switch_handle_t ecmp_handle, - uint16_t nhop_count, switch_handle_t *nhop_handle_list) -{ - switch_nhop_info_t *e_nhop_info = NULL; - switch_nhop_info_t *nhop_info = NULL; - switch_ecmp_info_t *ecmp_info = NULL; - switch_ecmp_member_t *ecmp_member = NULL; - switch_interface_info_t *intf_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_handle_t nhop_handle; - switch_status_t status = SWITCH_STATUS_SUCCESS; - int count = 0; - - if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; + ecmp_member = switch_malloc(sizeof(switch_ecmp_member_t), 1); + if (!ecmp_member) { + return SWITCH_STATUS_NO_MEMORY; } - - e_nhop_info = switch_nhop_get(ecmp_handle); - if (!e_nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; + ecmp_member->nhop_handle = nhop_handle; + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; } - ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info)); - - for (count = 0; count < nhop_count; count++) { - nhop_handle = nhop_handle_list[count]; - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; - } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - - ecmp_member = switch_malloc(sizeof(switch_ecmp_member_t), 1); - if (!ecmp_member) { - return SWITCH_STATUS_NO_MEMORY; - } - ecmp_member->nhop_handle = nhop_handle; - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - nhop_info->ref_count++; + nhop_info->ref_count++; #ifdef SWITCH_PD - status = switch_pd_ecmp_member_add(device, ecmp_info->pd_group_hdl, - handle_to_id(ecmp_member->nhop_handle), intf_info, - &(ecmp_member->mbr_hdl)); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - if (ecmp_info->count == 0) { - status = switch_pd_ecmp_group_table_add_entry_with_selector(device, - handle_to_id(ecmp_handle), - ecmp_info->pd_group_hdl, - &(ecmp_info->hw_entry)); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } - if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { - status = switch_pd_urpf_bd_table_add_entry(device, handle_to_id(ecmp_handle), - handle_to_id(intf_info->bd_handle), - &(ecmp_member->urpf_hw_entry)); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } -#endif - ecmp_info->count++; - tommy_list_insert_head(&ecmp_info->members, &(ecmp_member->node), ecmp_member); + status = switch_pd_ecmp_member_add(device, + ecmp_info->pd_group_hdl, + handle_to_id(ecmp_member->nhop_handle), + intf_info, + &(ecmp_member->mbr_hdl)); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + if (ecmp_info->count == 0) { + status = switch_pd_ecmp_group_table_add_entry_with_selector( + device, + handle_to_id(ecmp_handle), + ecmp_info->pd_group_hdl, + &(ecmp_info->hw_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + } + if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { + status = + switch_pd_urpf_bd_table_add_entry(device, + handle_to_id(ecmp_handle), + handle_to_id(intf_info->bd_handle), + &(ecmp_member->urpf_hw_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } } - return status; +#endif + ecmp_info->count++; + tommy_list_insert_head( + &ecmp_info->members, &(ecmp_member->node), ecmp_member); + } + return status; } -switch_status_t -switch_api_ecmp_member_delete(switch_device_t device, switch_handle_t ecmp_handle, - uint16_t nhop_count, switch_handle_t *nhop_handle_list) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_nhop_info_t *e_nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_ecmp_info_t *ecmp_info = NULL; - switch_ecmp_member_t *ecmp_member = NULL; - tommy_node *node = NULL; - switch_handle_t nhop_handle; - switch_status_t status = SWITCH_STATUS_SUCCESS; - int count = 0; - - if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_api_ecmp_member_delete( + switch_device_t device, + switch_handle_t ecmp_handle, + uint16_t nhop_count, + switch_handle_t *nhop_handle_list) { + switch_nhop_info_t *nhop_info = NULL; + switch_nhop_info_t *e_nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_ecmp_info_t *ecmp_info = NULL; + switch_ecmp_member_t *ecmp_member = NULL; + tommy_node *node = NULL; + switch_handle_t nhop_handle; + switch_status_t status = SWITCH_STATUS_SUCCESS; + int count = 0; + + if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + e_nhop_info = switch_nhop_get(ecmp_handle); + if (!e_nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; + } + for (count = 0; count < nhop_count; count++) { + nhop_handle = nhop_handle_list[count]; + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; } - - e_nhop_info = switch_nhop_get(ecmp_handle); - if (!e_nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; + } + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info)); + node = tommy_list_head(&(ecmp_info->members)); + while (node) { + ecmp_member = (switch_ecmp_member_t *)node->data; + if (ecmp_member->nhop_handle == nhop_handle) { + break; + } + node = node->next; } - for (count = 0; count < nhop_count; count++) { - nhop_handle = nhop_handle_list[count]; - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; - } - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info)); - node = tommy_list_head(&(ecmp_info->members)); - while (node) { - ecmp_member = (switch_ecmp_member_t *) node->data; - if (ecmp_member->nhop_handle == nhop_handle) { - break; - } - node = node->next; - } - if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + if (!node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - nhop_info->ref_count--; + nhop_info->ref_count--; #if SWITCH_PD - if (ecmp_info->count == 1) { - status = switch_pd_ecmp_group_table_delete_entry(device, ecmp_info->hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } - status = switch_pd_ecmp_member_delete(device, ecmp_info->pd_group_hdl, - ecmp_member->mbr_hdl); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { - status = switch_pd_urpf_bd_table_delete_entry(device, ecmp_member->urpf_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - } -#endif - ecmp_info->count--; - ecmp_member = tommy_list_remove_existing(&(ecmp_info->members), node); - switch_free(ecmp_member); + if (ecmp_info->count == 1) { + status = + switch_pd_ecmp_group_table_delete_entry(device, ecmp_info->hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + } + status = switch_pd_ecmp_member_delete( + device, ecmp_info->pd_group_hdl, ecmp_member->mbr_hdl); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { + status = switch_pd_urpf_bd_table_delete_entry(device, + ecmp_member->urpf_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } } - return status; +#endif + ecmp_info->count--; + ecmp_member = tommy_list_remove_existing(&(ecmp_info->members), node); + switch_free(ecmp_member); + } + return status; } -switch_nhop_index_type_t -switch_api_nhop_type_get(switch_handle_t nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; +switch_nhop_index_type_t switch_api_nhop_type_get(switch_handle_t nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; - if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { - return SWITCH_NHOP_INDEX_TYPE_NONE; - } + if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { + return SWITCH_NHOP_INDEX_TYPE_NONE; + } - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_NHOP_INDEX_TYPE_NONE; - } - return nhop_info->type; + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_NHOP_INDEX_TYPE_NONE; + } + return nhop_info->type; } -switch_status_t -switch_api_nhop_print_entry(switch_handle_t nhop_handle) -{ - switch_nhop_info_t *nhop_info = NULL; - switch_spath_info_t *spath_info = NULL; - switch_ecmp_info_t *ecmp_info = NULL; - switch_ecmp_member_t *ecmp_member = NULL; - tommy_node *node = NULL; +switch_status_t switch_api_nhop_print_entry(switch_handle_t nhop_handle) { + switch_nhop_info_t *nhop_info = NULL; + switch_spath_info_t *spath_info = NULL; + switch_ecmp_info_t *ecmp_info = NULL; + switch_ecmp_member_t *ecmp_member = NULL; + tommy_node *node = NULL; - nhop_info = switch_nhop_get(nhop_handle); - if (!nhop_info) { - return SWITCH_STATUS_INVALID_NHOP; - } + nhop_info = switch_nhop_get(nhop_handle); + if (!nhop_info) { + return SWITCH_STATUS_INVALID_NHOP; + } - printf("\n\nnhop_handle %x", (unsigned int) nhop_handle); - if (nhop_info->type == SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { - spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); - printf("\ntype : single path"); - printf("\nintf_handle %x", (unsigned int) spath_info->nhop_key.intf_handle); - } else { - ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); - printf("\ntype : ecmp path"); - printf("\nnumber of ecmp path %d", ecmp_info->count); - node = tommy_list_head(&(ecmp_info->members)); - while (node) { - ecmp_member = node->data; - printf("\n\tecmp_member_nhop %x", (unsigned int) ecmp_member->nhop_handle); - node = node->next; - } - } - return SWITCH_STATUS_SUCCESS; + printf("\n\nnhop_handle %x", (unsigned int)nhop_handle); + if (nhop_info->type == SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { + spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); + printf("\ntype : single path"); + printf("\nintf_handle %x", (unsigned int)spath_info->nhop_key.intf_handle); + } else { + ecmp_info = &(SWITCH_NHOP_ECMP_INFO(nhop_info)); + printf("\ntype : ecmp path"); + printf("\nnumber of ecmp path %d", ecmp_info->count); + node = tommy_list_head(&(ecmp_info->members)); + while (node) { + ecmp_member = node->data; + printf("\n\tecmp_member_nhop %x", (unsigned int)ecmp_member->nhop_handle); + node = node->next; + } + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_nhop_print_all(void) -{ - switch_handle_t nhop_handle = 0; - switch_handle_t next_nhop_handle = 0; - - switch_handle_get_first(switch_nhop_array, nhop_handle); - while (nhop_handle) { - switch_api_nhop_print_entry(nhop_handle); - switch_handle_get_next(switch_nhop_array, nhop_handle, next_nhop_handle); - nhop_handle = next_nhop_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_nhop_print_all(void) { + switch_handle_t nhop_handle = 0; + switch_handle_t next_nhop_handle = 0; + + switch_handle_get_first(switch_nhop_array, nhop_handle); + while (nhop_handle) { + switch_api_nhop_print_entry(nhop_handle); + switch_handle_get_next(switch_nhop_array, nhop_handle, next_nhop_handle); + nhop_handle = next_nhop_handle; + } + return SWITCH_STATUS_SUCCESS; } diff --git a/switchapi/src/switch_nhop_int.h b/switchapi/src/switch_nhop_int.h index aa82791..e976774 100644 --- a/switchapi/src/switch_nhop_int.h +++ b/switchapi/src/switch_nhop_int.h @@ -17,74 +17,68 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" #include "switchapi/switch_nhop.h" +#include "switch_pd_types.h" -#define MAX_ECMP_GROUP_SIZE (64) +#define MAX_ECMP_GROUP_SIZE (64) #define SWITCH_NHOP_HASH_TABLE_SIZE 4096 -#define SWITCH_NHOP_HASH_KEY_SIZE 32 +#define SWITCH_NHOP_HASH_KEY_SIZE 32 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -typedef struct switch_ecmp_member_ -{ - tommy_node node; - switch_handle_t nhop_handle; +typedef struct switch_ecmp_member_ { + tommy_node node; + switch_handle_t nhop_handle; #ifdef SWITCH_PD - p4_pd_entry_hdl_t urpf_hw_entry; - p4_pd_mbr_hdl_t mbr_hdl; + p4_pd_entry_hdl_t urpf_hw_entry; + p4_pd_mbr_hdl_t mbr_hdl; #endif } switch_ecmp_member_t; -typedef struct switch_ecmp_info_ -{ - unsigned int count; - tommy_list members; +typedef struct switch_ecmp_info_ { + unsigned int count; + tommy_list members; #ifdef SWITCH_PD - p4_pd_entry_hdl_t hw_entry; - p4_pd_grp_hdl_t pd_group_hdl; + p4_pd_entry_hdl_t hw_entry; + p4_pd_grp_hdl_t pd_group_hdl; #endif } switch_ecmp_info_t; -typedef struct switch_spath_info_ -{ - switch_nhop_key_t nhop_key; - tommy_node node; - switch_handle_t nhop_handle; - switch_handle_t neighbor_handle; +typedef struct switch_spath_info_ { + switch_nhop_key_t nhop_key; + tommy_node node; + switch_handle_t nhop_handle; + switch_handle_t neighbor_handle; #ifdef SWITCH_PD - p4_pd_entry_hdl_t hw_entry; - p4_pd_entry_hdl_t urpf_hw_entry; + p4_pd_entry_hdl_t hw_entry; + p4_pd_entry_hdl_t urpf_hw_entry; #endif } switch_spath_info_t; -typedef struct switch_nhop_info_ -{ - unsigned int ref_count; - bool valid; - switch_nhop_index_type_t type; - union { - switch_spath_info_t spath; - switch_ecmp_info_t ecmp; - } u; +typedef struct switch_nhop_info_ { + unsigned int ref_count; + bool valid; + switch_nhop_index_type_t type; + union { + switch_spath_info_t spath; + switch_ecmp_info_t ecmp; + } u; } switch_nhop_info_t; -#define SWITCH_NHOP_ECMP_INFO(nhop) \ - nhop->u.ecmp +#define SWITCH_NHOP_ECMP_INFO(nhop) nhop->u.ecmp -#define SWITCH_NHOP_SPATH_INFO(nhop) \ - nhop->u.spath +#define SWITCH_NHOP_SPATH_INFO(nhop) nhop->u.spath -#define SWITCH_NHOP_TYPE_IS_ECMP(nhop) \ - nhop->type == SWITCH_NHOP_INDEX_TYPE_ECMP +#define SWITCH_NHOP_TYPE_IS_ECMP(nhop) nhop->type == SWITCH_NHOP_INDEX_TYPE_ECMP switch_status_t switch_nhop_init(switch_device_t device); switch_status_t switch_nhop_free(switch_device_t device); switch_nhop_info_t *switch_nhop_get(); switch_handle_t switch_nhop_create(); -switch_status_t -switch_api_nhop_update(switch_device_t device, switch_handle_t nhop_handle); +switch_status_t switch_api_nhop_update(switch_device_t device, + switch_handle_t nhop_handle); #ifdef __cplusplus } diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index 64f7fa5..3c5498d 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -50,1027 +50,1090 @@ 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_filter_list); - tommy_list_init(&packet_tx_filter_list); - return status; +switch_status_t switch_packet_init(switch_device_t device) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + tommy_list_init(&packet_rx_filter_list); + tommy_list_init(&packet_tx_filter_list); + return status; } -switch_status_t -switch_packet_done( - switch_device_t device) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - 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; - int sockflags = 0; +static void switch_packet_create_pipe() { + int ret = 0; + int sockflags = 0; - // create a pipe to wake up the main thread from select - ret = pipe(pipe_fd); - assert(ret == 0); + // create a pipe to wake up the main thread from select + ret = pipe(pipe_fd); + assert(ret == 0); - // set fd to be non-blocking - sockflags = fcntl(pipe_fd[0], F_GETFL, 0); - if (fcntl(pipe_fd[0], F_SETFL, sockflags | O_NONBLOCK) < 0) { - perror("f_setfl on cpu interface failed"); - exit(1); - } + // set fd to be non-blocking + sockflags = fcntl(pipe_fd[0], F_GETFL, 0); + if (fcntl(pipe_fd[0], F_SETFL, sockflags | O_NONBLOCK) < 0) { + perror("f_setfl on cpu interface failed"); + exit(1); + } } -static void -switch_packet_read_from_pipe() { - int ret = 0; - char buf[1]; +static void switch_packet_read_from_pipe() { + int ret = 0; + char buf[1]; - ret = read(pipe_fd[0], buf, 1); - assert(ret == 1); - assert(buf[0] = 'A'); + ret = read(pipe_fd[0], buf, 1); + assert(ret == 1); + assert(buf[0] = 'A'); } -static void -switch_packet_write_to_pipe() { - int ret = 0; - char buf[1]; +static void switch_packet_write_to_pipe() { + int ret = 0; + char buf[1]; - buf[0] = 'A'; - ret = write(pipe_fd[1], buf, 1); - assert(ret == 1); + buf[0] = 'A'; + ret = write(pipe_fd[1], buf, 1); + assert(ret == 1); } -void -switch_packet_tx_to_hw(switch_packet_header_t *packet_header, char *packet, int packet_size) -{ - static char out_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; - struct sockaddr_ll addr; - switch_cpu_header_t *cpu_header = NULL; - switch_fabric_header_t *fabric_header = NULL; - int current_offset = 0; - - fabric_header = &packet_header->fabric_header; - cpu_header = &packet_header->cpu_header; - memset(&addr, 0, sizeof(addr)); - addr.sll_ifindex = cpu_ifindex; - - fabric_header->ether_type = htons(fabric_header->ether_type); - fabric_header->dst_port_or_group = htons(fabric_header->dst_port_or_group); - - 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); - current_offset += SWITCH_PACKET_HEADER_OFFSET; - - memcpy((out_packet + current_offset), packet_header, sizeof(switch_packet_header_t)); - current_offset += sizeof(switch_packet_header_t); - - memcpy((out_packet + current_offset), packet + SWITCH_PACKET_HEADER_OFFSET, - (packet_size - SWITCH_PACKET_HEADER_OFFSET)); - packet_size = packet_size + sizeof(switch_packet_header_t); - - if (sendto(cpu_sock_fd, out_packet, packet_size, 0, - (struct sockaddr *)&addr, sizeof(addr)) < 0) { - perror("packet send failed"); - } -// SWITCH_API_TRACE("Sent packet to hw port %d\n", -// packet_header->fabric_header.dst_port_or_group); +void switch_packet_tx_to_hw(switch_packet_header_t *packet_header, + char *packet, + int packet_size) { + static char out_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + struct sockaddr_ll addr; + switch_cpu_header_t *cpu_header = NULL; + switch_fabric_header_t *fabric_header = NULL; + int current_offset = 0; + + fabric_header = &packet_header->fabric_header; + cpu_header = &packet_header->cpu_header; + memset(&addr, 0, sizeof(addr)); + addr.sll_ifindex = cpu_ifindex; + + fabric_header->ether_type = htons(fabric_header->ether_type); + fabric_header->dst_port_or_group = htons(fabric_header->dst_port_or_group); + cpu_header->reason_code = htons(cpu_header->reason_code); + + memcpy(out_packet, packet, SWITCH_PACKET_HEADER_OFFSET); + current_offset += SWITCH_PACKET_HEADER_OFFSET; + + memcpy((out_packet + current_offset), + packet_header, + sizeof(switch_packet_header_t)); + current_offset += sizeof(switch_packet_header_t); + + memcpy((out_packet + current_offset), + packet + SWITCH_PACKET_HEADER_OFFSET, + (packet_size - SWITCH_PACKET_HEADER_OFFSET)); + packet_size = packet_size + sizeof(switch_packet_header_t); + + if (sendto(cpu_sock_fd, + out_packet, + packet_size, + 0, + (struct sockaddr *)&addr, + sizeof(addr)) < 0) { + perror("packet send failed"); + } + // SWITCH_API_TRACE("Sent packet to hw port %d\n", + // packet_header->fabric_header.dst_port_or_group); } -static void -switch_packet_rx_from_hw() -{ - int packet_size = 0; - switch_packet_header_t *packet_header = NULL; - static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; - static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - // read packet from cpu port - while((packet_size = read(cpu_sock_fd, in_packet, sizeof(in_packet))) > 0) { - uint16_t ethType = *(uint16_t *)(in_packet + 12); - if(ntohs(ethType) != 0x9000) - continue; - packet_header = (switch_packet_header_t *) - (in_packet + SWITCH_PACKET_HEADER_OFFSET); - packet_size = packet_size - sizeof(switch_packet_header_t); - memcpy(packet, in_packet, SWITCH_PACKET_HEADER_OFFSET); - memcpy(packet + SWITCH_PACKET_HEADER_OFFSET, - in_packet + SWITCH_PACKET_HEADER_OFFSET + - sizeof(switch_packet_header_t), - packet_size - SWITCH_PACKET_HEADER_OFFSET); - packet_header->cpu_header.reason_code = - ntohs(packet_header->cpu_header.reason_code); - if(packet_header->cpu_header.reason_code == SWITCH_HOSTIF_REASON_CODE_NULL_DROP) - continue; - packet_header->cpu_header.ingress_port = - ntohs(packet_header->cpu_header.ingress_port); - packet_header->cpu_header.ingress_ifindex = - ntohs(packet_header->cpu_header.ingress_ifindex); - packet_header->cpu_header.ingress_bd = - ntohs(packet_header->cpu_header.ingress_bd); - status = switch_api_hostif_rx_packet_from_hw(packet_header, packet, packet_size); - if (status != SWITCH_STATUS_SUCCESS) { - return; - } - } +static void switch_packet_extract_optional_header( + switch_packet_header_t *packet_header, + switch_opt_header_t **opt_header, + uint16_t *opt_length) { + *opt_length = 0; + if (packet_header->cpu_header.reason_code == + SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE) { + *opt_header = + (switch_opt_header_t *)(packet_header + sizeof(switch_packet_header_t)); + (*opt_header)->sflow_header.sflow_session_id = + ntohs((*opt_header)->sflow_header.sflow_session_id); + (*opt_header)->sflow_header.sflow_egress_ifindex = + ntohs((*opt_header)->sflow_header.sflow_egress_ifindex); + *opt_length = sizeof(switch_sflow_header_t); + } } -void -switch_packet_rx_to_host( - switch_packet_header_t *packet_header, - char *packet, - int packet_size) -{ - switch_cpu_header_t *cpu_header = NULL; - switch_packet_rx_info_t *rx_info = NULL; - 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; - - 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); +static void switch_packet_rx_from_hw() { + int packet_size = 0; + switch_packet_header_t *packet_header = NULL; + switch_opt_header_t *opt_header = NULL; + static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint16_t opt_length = 0; + + // read packet from cpu port + while ((packet_size = read(cpu_sock_fd, in_packet, sizeof(in_packet))) > 0) { + uint16_t ethType = *(uint16_t *)(in_packet + 12); + if (ntohs(ethType) != 0x9000) continue; + packet_header = + (switch_packet_header_t *)(in_packet + SWITCH_PACKET_HEADER_OFFSET); + memcpy(packet, in_packet, SWITCH_PACKET_HEADER_OFFSET); + packet_header->cpu_header.reason_code = + ntohs(packet_header->cpu_header.reason_code); + if (packet_header->cpu_header.reason_code == + SWITCH_HOSTIF_REASON_CODE_NULL_DROP) + continue; + + switch_packet_extract_optional_header( + packet_header, &opt_header, &opt_length); + packet_size = packet_size - sizeof(switch_packet_header_t) - opt_length; + memcpy(packet + SWITCH_PACKET_HEADER_OFFSET, + in_packet + SWITCH_PACKET_HEADER_OFFSET + + sizeof(switch_packet_header_t) + opt_length, + packet_size - SWITCH_PACKET_HEADER_OFFSET); + + packet_header->cpu_header.ingress_port = + ntohs(packet_header->cpu_header.ingress_port); + packet_header->cpu_header.ingress_ifindex = + ntohs(packet_header->cpu_header.ingress_ifindex); + packet_header->cpu_header.ingress_bd = + ntohs(packet_header->cpu_header.ingress_bd); + status = switch_api_hostif_rx_packet_from_hw( + packet_header, opt_header, packet, packet_size); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("failed to find fd. dropping packet"); - return; + return; } + } +} - SWITCH_API_INFO("Rx packet reason_code 0x%x - send to fd %d, action %d\n", - rx_entry.reason_code, rx_info->intf_fd, rx_info->vlan_action); - if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) { - 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); - 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) { - 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) { - 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); - } +void switch_packet_rx_transform(switch_packet_header_t *packet_header, + char *transformed_packet, + char *packet, + int *packet_size) { + switch_cpu_header_t *cpu_header = NULL; + switch_packet_rx_info_t *rx_info = NULL; + switch_ethernet_header_t *eth_header = NULL; + switch_vlan_header_t *vlan_header = NULL; + switch_packet_rx_entry_t rx_entry; + 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 filter. packet not transformed"); + memcpy(transformed_packet, packet, *packet_size); + return; + } + + if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) { + 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(transformed_packet, packet, offset); + vlan_header = (switch_vlan_header_t *)(transformed_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); + memcpy(transformed_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); + memcpy(transformed_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; + } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_REMOVE) { + eth_header = (switch_ethernet_header_t *)packet; + if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { + offset = 2 * ETH_LEN; + memcpy(transformed_packet, packet, offset); + memcpy(transformed_packet, packet + offset, *packet_size - offset); + *packet_size -= sizeof(switch_vlan_header_t); + } else { + memcpy(transformed_packet, packet, *packet_size); + } + } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_SWAP) { + 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 *)(transformed_packet + offset); + vlan_header->vid = htons(rx_info->vlan_id); + } else { + memcpy(transformed_packet, packet, *packet_size); } + } else { + memcpy(transformed_packet, packet, *packet_size); + } +} + +void switch_packet_rx_to_host(switch_packet_header_t *packet_header, + char *packet, + int packet_size) { + switch_cpu_header_t *cpu_header = NULL; + switch_packet_rx_info_t *rx_info = NULL; + static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + switch_packet_rx_entry_t rx_entry; + int intf_fd = 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; + } + + SWITCH_API_INFO("Rx packet reason_code 0x%x - send to fd %d, action %d\n", + rx_entry.reason_code, + rx_info->intf_fd, + rx_info->vlan_action); + + switch_packet_rx_transform(packet_header, 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; + } + return; } -void -switch_packet_tx_from_host(int intf_fd) -{ - switch_hostif_info_t *hostif_info = NULL; - 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 ((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); - if (!hostif_info) { - perror("invalid hostif fd"); - return; - } - 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->bypass_flags == SWITCH_BYPASS_ALL) { - cpu_header->tx_bypass = TRUE; - 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 = 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; - - 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); - } +void switch_packet_tx_bd_transform(char *in_packet, + int in_packet_size, + char *out_packet, + int *out_packet_size, + switch_packet_tx_info_t *tx_info) { + 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; + uint16_t ether_type = 0; + uint16_t offset = 0; + uint16_t vlan_offset = 0; + + /* + * 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; + + 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(out_packet, in_packet, 2 * ETH_LEN); + memcpy(out_packet + 2 * ETH_LEN + vlan_offset, + in_packet + 2 * ETH_LEN, + (in_packet_size - 2 * ETH_LEN)); + *out_packet_size = in_packet_size; + *out_packet_size += vlan_offset; + + vlan_header = (switch_vlan_header_t *)(out_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 *)(out_packet + offset); + vlan_header->vid = ntohs(vlan_id2); + vlan_header->tpid = ntohs(SWITCH_ETHERTYPE_DOT1Q); + vlan_header->dei = 0; + vlan_header->pcp = 0; + } } -static void -switch_packet_cpu_interface_create() -{ - struct ifreq ifr; - struct sockaddr_ll addr; - int sockflags = 0; - - // initialize raw socket - if ((cpu_sock_fd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) { - perror("failed to open raw socket"); - exit(1); - } +void switch_packet_tx_switched(switch_packet_header_t *packet_header, + char *in_packet, + int in_packet_size) { + int packet_size = 0; + static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; + switch_ethernet_header_t *eth_header = NULL; + switch_vlan_header_t *vlan_header = NULL; + switch_vlan_t vlan_id1 = 0; + switch_packet_tx_entry_t tx_entry; + switch_packet_tx_info_t *tx_info = NULL; + switch_status_t status; + + 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.fd_valid = false; + 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"); + return; + } - // initialize cpu port - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, cpu_intf_name, IFNAMSIZ); - if (ioctl(cpu_sock_fd, SIOCGIFINDEX, (void *)&ifr) < 0) { - perror("failed to get ifindex of cpu interface"); - exit(1); - } + memset(packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE); + switch_packet_tx_bd_transform( + in_packet, in_packet_size, packet, &packet_size, tx_info); + switch_packet_tx_to_hw(packet_header, packet, packet_size); +} - // bind to cpu port - cpu_ifindex = ifr.ifr_ifindex; - memset(&addr, 0, sizeof(addr)); - addr.sll_family = AF_PACKET; - addr.sll_ifindex = cpu_ifindex; - addr.sll_protocol = htons(ETH_P_ALL); - if (bind(cpu_sock_fd, (struct sockaddr *)&addr, - sizeof(struct sockaddr_ll)) < 0) { - perror("bind to cpu interface failed"); - exit(1); +void switch_packet_tx_from_host(int intf_fd) { + switch_hostif_info_t *hostif_info = NULL; + 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_ethernet_header_t *eth_header = NULL; + switch_vlan_header_t *vlan_header = NULL; + switch_vlan_t vlan_id1 = 0; + switch_packet_tx_entry_t tx_entry; + switch_packet_tx_info_t *tx_info = NULL; + switch_device_t device = 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 ((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); + if (!hostif_info) { + perror("invalid hostif fd"); + return; } - - // set cpu port to be non-blocking - sockflags = fcntl(cpu_sock_fd, F_GETFL, 0); - if (fcntl(cpu_sock_fd, F_SETFL, sockflags | O_NONBLOCK) < 0) { - perror("f_setfl on cpu interface failed"); - exit(1); + 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); } -} -switch_status_t -switch_packet_hostif_create(switch_device_t device, switch_hostif_info_t *hostif_info) -{ - int intf_fd = 0; - struct ifreq ifr; - int sock_flags = 0; - char *intf_name = NULL; - void *temp = NULL; - switch_api_capability_t api_switch_info; - switch_mac_addr_t mac; - - switch_api_capability_get(device, &api_switch_info); - - if ((intf_fd = open("/dev/net/tun", O_RDWR)) < 0) { - return SWITCH_STATUS_FAILURE; + 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(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - intf_name = hostif_info->hostif.intf_name; - strncpy(ifr.ifr_name, intf_name, IFNAMSIZ); - if ((ioctl(intf_fd, TUNSETIFF, (void *)&ifr)) < 0) { - perror("tunsetiff failed"); - close(intf_fd); - return SWITCH_STATUS_FAILURE; - } + memset(&packet_header, 0x0, sizeof(packet_header)); + cpu_header = &packet_header.cpu_header; + fabric_header = &packet_header.fabric_header; - // set connection to be non-blocking - sock_flags = fcntl(intf_fd, F_GETFL, 0); - if ((fcntl(intf_fd, F_SETFL, sock_flags | O_NONBLOCK)) < 0) { - perror("f_setfl failed"); - close(intf_fd); - return SWITCH_STATUS_FAILURE; + if (tx_info->bypass_flags == SWITCH_BYPASS_ALL) { + cpu_header->tx_bypass = TRUE; + 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 = tx_info->bypass_flags; + switch_packet_tx_bd_transform( + in_packet, in_packet_size, packet, &packet_size, tx_info); } + 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; - memset(&mac, 0, sizeof(switch_mac_addr_t)); - if (memcmp(&api_switch_info.switch_mac, &mac, ETH_LEN) != 0) { - // set the mac address - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, intf_name, IFNAMSIZ); - ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; - memcpy(ifr.ifr_addr.sa_data, &api_switch_info.switch_mac, ETH_LEN); - if ((ioctl(intf_fd, SIOCSIFHWADDR, (void *)&ifr)) < 0) { - perror("ioctl failed"); - close(intf_fd); - return SWITCH_STATUS_FAILURE; - } - } - // bring the interface up + switch_packet_tx_to_hw(&packet_header, packet, packet_size); + } +} + +static void switch_packet_cpu_interface_create() { + struct ifreq ifr; + struct sockaddr_ll addr; + int sockflags = 0; + + // initialize raw socket + if ((cpu_sock_fd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0) { + perror("failed to open raw socket"); + exit(1); + } + + // initialize cpu port + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, cpu_intf_name, IFNAMSIZ); + if (ioctl(cpu_sock_fd, SIOCGIFINDEX, (void *)&ifr) < 0) { + perror("failed to get ifindex of cpu interface"); + exit(1); + } + + // bind to cpu port + cpu_ifindex = ifr.ifr_ifindex; + memset(&addr, 0, sizeof(addr)); + addr.sll_family = AF_PACKET; + addr.sll_ifindex = cpu_ifindex; + addr.sll_protocol = htons(ETH_P_ALL); + if (bind(cpu_sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_ll)) < + 0) { + perror("bind to cpu interface failed"); + exit(1); + } + + // set cpu port to be non-blocking + sockflags = fcntl(cpu_sock_fd, F_GETFL, 0); + if (fcntl(cpu_sock_fd, F_SETFL, sockflags | O_NONBLOCK) < 0) { + perror("f_setfl on cpu interface failed"); + exit(1); + } +} + +switch_status_t switch_packet_hostif_create(switch_device_t device, + switch_hostif_info_t *hostif_info) { + int intf_fd = 0; + struct ifreq ifr; + int sock_flags = 0; + char *intf_name = NULL; + void *temp = NULL; + switch_api_capability_t api_switch_info; + switch_mac_addr_t mac; + + switch_api_capability_get(device, &api_switch_info); + + if ((intf_fd = open("/dev/net/tun", O_RDWR)) < 0) { + return SWITCH_STATUS_FAILURE; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + intf_name = hostif_info->hostif.intf_name; + strncpy(ifr.ifr_name, intf_name, IFNAMSIZ); + if ((ioctl(intf_fd, TUNSETIFF, (void *)&ifr)) < 0) { + perror("tunsetiff failed"); + close(intf_fd); + return SWITCH_STATUS_FAILURE; + } + + // set connection to be non-blocking + sock_flags = fcntl(intf_fd, F_GETFL, 0); + if ((fcntl(intf_fd, F_SETFL, sock_flags | O_NONBLOCK)) < 0) { + perror("f_setfl failed"); + close(intf_fd); + return SWITCH_STATUS_FAILURE; + } + + memset(&mac, 0, sizeof(switch_mac_addr_t)); + if (memcmp(&api_switch_info.switch_mac, &mac, ETH_LEN) != 0) { + // set the mac address memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, intf_name, IFNAMSIZ); - if ((ioctl(cpu_sock_fd, SIOCGIFFLAGS, (void *)&ifr)) < 0) { - perror("ioctl get failed"); - // close(intf_fd); - // return SWITCH_STATUS_FAILURE; + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_addr.sa_data, &api_switch_info.switch_mac, ETH_LEN); + if ((ioctl(intf_fd, SIOCSIFHWADDR, (void *)&ifr)) < 0) { + perror("ioctl failed"); + close(intf_fd); + return SWITCH_STATUS_FAILURE; } - else { - ifr.ifr_flags |= IFF_UP; - if ((ioctl(cpu_sock_fd, SIOCSIFFLAGS, (void *)&ifr)) < 0) { - perror("ioctl set failed"); - // close(intf_fd); - // return SWITCH_STATUS_FAILURE; - } + } + // bring the interface up + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, intf_name, IFNAMSIZ); + if ((ioctl(cpu_sock_fd, SIOCGIFFLAGS, (void *)&ifr)) < 0) { + perror("ioctl get failed"); + // close(intf_fd); + // return SWITCH_STATUS_FAILURE; + } else { + ifr.ifr_flags |= IFF_UP; + if ((ioctl(cpu_sock_fd, SIOCSIFFLAGS, (void *)&ifr)) < 0) { + perror("ioctl set failed"); + // close(intf_fd); + // return SWITCH_STATUS_FAILURE; } + } - hostif_info->intf_fd = intf_fd; - JLG(temp, switch_intf_fd_array, intf_fd); - if (!temp) { - JLI(temp, switch_intf_fd_array, intf_fd); - *(unsigned long *)temp = (unsigned long) (hostif_info); - } + hostif_info->intf_fd = intf_fd; + JLG(temp, switch_intf_fd_array, intf_fd); + if (!temp) { + JLI(temp, switch_intf_fd_array, intf_fd); + *(unsigned long *)temp = (unsigned long)(hostif_info); + } - switch_packet_write_to_pipe(); + switch_packet_write_to_pipe(); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_packet_hostif_delete(switch_device_t device, switch_hostif_info_t *hostif_info) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - void *temp = NULL; +switch_status_t switch_packet_hostif_delete(switch_device_t device, + switch_hostif_info_t *hostif_info) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + void *temp = NULL; - JLG(temp, switch_intf_fd_array, hostif_info->intf_fd); - if (!temp) { - return SWITCH_STATUS_FAILURE; - } - JLD(status, switch_intf_fd_array, hostif_info->intf_fd); + JLG(temp, switch_intf_fd_array, hostif_info->intf_fd); + if (!temp) { + return SWITCH_STATUS_FAILURE; + } + JLD(status, switch_intf_fd_array, hostif_info->intf_fd); - switch_packet_write_to_pipe(); + switch_packet_write_to_pipe(); - return status; + return status; } -static int -switch_packet_select_fd_get(fd_set *read_fds) -{ - switch_hostif_info_t *hostif_info = NULL; - void *temp = NULL; - int nfds; - Word_t index = 0; - - nfds = (cpu_sock_fd > pipe_fd[0]) ? cpu_sock_fd : pipe_fd[0]; - - JLF(temp, switch_intf_fd_array, index); - while (temp) { - hostif_info = - (switch_hostif_info_t *) (*(unsigned long *) temp); - FD_SET(hostif_info->intf_fd, read_fds); - if (hostif_info->intf_fd > nfds) { - nfds = hostif_info->intf_fd; - } - JLN(temp, switch_intf_fd_array, index); +static int switch_packet_select_fd_get(fd_set *read_fds) { + switch_hostif_info_t *hostif_info = NULL; + void *temp = NULL; + int nfds; + Word_t index = 0; + + nfds = (cpu_sock_fd > pipe_fd[0]) ? cpu_sock_fd : pipe_fd[0]; + + JLF(temp, switch_intf_fd_array, index); + while (temp) { + hostif_info = (switch_hostif_info_t *)(*(unsigned long *)temp); + FD_SET(hostif_info->intf_fd, read_fds); + if (hostif_info->intf_fd > nfds) { + nfds = hostif_info->intf_fd; } - return nfds + 1; + JLN(temp, switch_intf_fd_array, index); + } + return nfds + 1; } -static void -switch_packet_tx_from_hosts(fd_set read_fds) -{ - switch_hostif_info_t *hostif_info = NULL; - void *temp = NULL; - Word_t index = 0; - - JLF(temp, switch_intf_fd_array, index); - while (temp) { - hostif_info = - (switch_hostif_info_t *) (*(unsigned long *) temp); - if (FD_ISSET(hostif_info->intf_fd, &read_fds)) { - switch_packet_tx_from_host(hostif_info->intf_fd); - } - JLN(temp, switch_intf_fd_array, index); +static void switch_packet_tx_from_hosts(fd_set read_fds) { + switch_hostif_info_t *hostif_info = NULL; + void *temp = NULL; + Word_t index = 0; + + JLF(temp, switch_intf_fd_array, index); + while (temp) { + hostif_info = (switch_hostif_info_t *)(*(unsigned long *)temp); + if (FD_ISSET(hostif_info->intf_fd, &read_fds)) { + switch_packet_tx_from_host(hostif_info->intf_fd); } + JLN(temp, switch_intf_fd_array, index); + } } -static void * -switch_packet_driver_thread(void *args) -{ - fd_set read_fds; - int nfds = -1; - int ret = 0; - - switch_packet_cpu_interface_create(); - assert(cpu_sock_fd != -1); - - switch_packet_create_pipe(); - - while (TRUE) { - FD_ZERO(&read_fds); - FD_SET(cpu_sock_fd, &read_fds); - FD_SET(pipe_fd[0], &read_fds); - nfds = switch_packet_select_fd_get(&read_fds); - ret = select(nfds, &read_fds, NULL, NULL, NULL); - if (ret == -1) { - perror("select called failed"); - return NULL; - } else if (ret) { - if (FD_ISSET(cpu_sock_fd, &read_fds)) { - switch_packet_rx_from_hw(); - } else if (FD_ISSET(pipe_fd[0], &read_fds)) { - switch_packet_read_from_pipe(); - } else { - switch_packet_tx_from_hosts(read_fds); - } - } +static void *switch_packet_driver_thread(void *args) { + fd_set read_fds; + int nfds = -1; + int ret = 0; + + switch_packet_cpu_interface_create(); + assert(cpu_sock_fd != -1); + + switch_packet_create_pipe(); + + while (TRUE) { + FD_ZERO(&read_fds); + FD_SET(cpu_sock_fd, &read_fds); + FD_SET(pipe_fd[0], &read_fds); + nfds = switch_packet_select_fd_get(&read_fds); + ret = select(nfds, &read_fds, NULL, NULL, NULL); + if (ret == -1) { + perror("select called failed"); + return NULL; + } else if (ret) { + if (FD_ISSET(cpu_sock_fd, &read_fds)) { + switch_packet_rx_from_hw(); + } else if (FD_ISSET(pipe_fd[0], &read_fds)) { + switch_packet_read_from_pipe(); + } else { + switch_packet_tx_from_hosts(read_fds); + } } + } } -int start_switch_api_packet_driver() -{ - pthread_create(&packet_driver_thread, NULL, - switch_packet_driver_thread, NULL); - return SWITCH_STATUS_SUCCESS; +int start_switch_api_packet_driver() { + pthread_create( + &packet_driver_thread, NULL, switch_packet_driver_thread, NULL); + return SWITCH_STATUS_SUCCESS; } -static bool -switch_packet_tx_filter_match(switch_packet_tx_entry_t *tx_entry1, - switch_packet_tx_entry_t *tx_entry2) -{ - // entry1 is the one stored in the filter list - // entry2 represents incoming packet, therefore all the valid - // bits and masks are used from entry1 - if ((!tx_entry1->fd_valid || (tx_entry1->intf_fd == tx_entry2->intf_fd)) && - (!tx_entry1->vlan_valid || (tx_entry1->vlan_id == tx_entry2->vlan_id))){ - // priority is not be compared so matching entry can be found - return TRUE; - } - return FALSE; +static bool switch_packet_tx_filter_match(switch_packet_tx_entry_t *tx_entry1, + switch_packet_tx_entry_t *tx_entry2) { + /* + * entry1 is the one stored in the filter list + * entry2 represents incoming packet, therefore all the valid + * bits and masks are used from entry1 + */ + if ((!tx_entry1->fd_valid || (tx_entry1->intf_fd == tx_entry2->intf_fd)) && + (!tx_entry1->vlan_valid || (tx_entry1->vlan_id == tx_entry2->vlan_id))) { + return TRUE; + } + return FALSE; } -int32_t -switch_packet_tx_filter_priority_compare( - const void *key1, - const void *key2) -{ - switch_packet_tx_entry_t *tx_entry1 = NULL; - switch_packet_tx_entry_t *tx_entry2 = NULL; +int32_t switch_packet_tx_filter_priority_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; - } + if (!key1 || !key2) { + return 0; + } - tx_entry1 = (switch_packet_tx_entry_t *) key1; - tx_entry2 = (switch_packet_tx_entry_t *) key2; + tx_entry1 = (switch_packet_tx_entry_t *)key1; + tx_entry2 = (switch_packet_tx_entry_t *)key2; - return (int32_t)tx_entry1->priority - (int32_t)tx_entry2->priority; + return (int32_t)tx_entry1->priority - (int32_t)tx_entry2->priority; } -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; - - if (!tx_key || !tx_action) { - SWITCH_API_ERROR("filter tx create failed. invalid params"); - return SWITCH_STATUS_INVALID_PARAMETER; - } - +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; + + if (!tx_key || !tx_action) { + SWITCH_API_ERROR("filter tx create failed. invalid params"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + if (tx_key->handle_valid) { hostif_info = switch_hostif_get(tx_key->hostif_handle); if (!hostif_info) { - SWITCH_API_ERROR("invalid hostif handle"); - return SWITCH_STATUS_INVALID_HANDLE; + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; } + } - memset(&tx_entry, 0x0, sizeof(tx_entry)); + memset(&tx_entry, 0x0, sizeof(tx_entry)); + if (tx_key->handle_valid) { 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_entry.priority = tx_key->priority; - - 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; + } + 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_entry.priority = tx_key->priority; + + 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->bypass_flags != SWITCH_BYPASS_ALL) { + 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; } - if (tx_action->bypass_flags != SWITCH_BYPASS_ALL) { - 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; - } + 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->bypass_flags = tx_action->bypass_flags; - tx_info->port = handle_to_id(tx_action->port_handle); - - SWITCH_API_INFO("net_filter_tx_create: hostif 0x%x, vlan_id = %d, fd 0x%x, bypass 0x%x\n", - tx_key->hostif_handle, tx_key->vlan_valid ? tx_key->vlan_id : 0xFFF, - tx_entry.intf_fd, tx_info->bypass_flags); - - 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; + } + + memcpy(&tx_info->tx_entry, &tx_entry, sizeof(tx_entry)); + tx_info->bd = handle_to_id(bd_handle); + tx_info->bypass_flags = tx_action->bypass_flags; + tx_info->port = handle_to_id(tx_action->port_handle); + + SWITCH_API_INFO( + "net_filter_tx_create: hostif 0x%lx, vlan_id = %d, fd 0x%x, bypass " + "0x%x\n", + tx_key->hostif_handle, + tx_key->vlan_valid ? tx_key->vlan_id : 0xFFF, + tx_entry.intf_fd, + tx_info->bypass_flags); + + 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; } -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; - tommy_node *node = NULL; - switch_hostif_info_t *hostif_info = NULL; - 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; - } - - memset(&tx_entry, 0x0, sizeof(tx_entry)); - if (tx_key->handle_valid) { - hostif_info = switch_hostif_get(tx_key->hostif_handle); - if (!hostif_info) { - SWITCH_API_ERROR("invalid hostif handle"); - return SWITCH_STATUS_INVALID_HANDLE; - } - tx_entry.intf_fd = hostif_info->intf_fd; +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; + tommy_node *node = NULL; + switch_hostif_info_t *hostif_info = NULL; + 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; + } + + memset(&tx_entry, 0x0, sizeof(tx_entry)); + if (tx_key->handle_valid) { + hostif_info = switch_hostif_get(tx_key->hostif_handle); + if (!hostif_info) { + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; } + tx_entry.intf_fd = hostif_info->intf_fd; + } - if (tx_key->vlan_valid) { - tx_entry.vlan_id = tx_key->vlan_id; - } + if (tx_key->vlan_valid) { + tx_entry.vlan_id = tx_key->vlan_id; + } - 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; + 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; - if (switch_packet_tx_filter_match(tmp_tx_entry, &tx_entry)) { - node_found = TRUE; - break; - } - node = node->next; + if (switch_packet_tx_filter_match(tmp_tx_entry, &tx_entry)) { + 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; - } + 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_filter_list, node); - switch_free(tmp_tx_info); - return status; + tommy_list_remove_existing(&packet_tx_filter_list, node); + switch_free(tmp_tx_info); + return status; } -int32_t -switch_packet_rx_filter_priority_compare( - const void *key1, - const void *key2) -{ - switch_packet_rx_entry_t *rx_entry1 = NULL; - switch_packet_rx_entry_t *rx_entry2 = NULL; +int32_t switch_packet_rx_filter_priority_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; - } + if (!key1 || !key2) { + return 0; + } - rx_entry1 = (switch_packet_rx_entry_t *) key1; - rx_entry2 = (switch_packet_rx_entry_t *) key2; + rx_entry1 = (switch_packet_rx_entry_t *)key1; + rx_entry2 = (switch_packet_rx_entry_t *)key2; - return (int32_t)rx_entry1->priority - (int32_t)rx_entry2->priority; + return (int32_t)rx_entry1->priority - (int32_t)rx_entry2->priority; } -static bool -switch_packet_rx_filter_match(switch_packet_rx_entry_t *rx_entry1, - switch_packet_rx_entry_t *rx_entry2) -{ - // entry1 is the one stored in the filter list - // entry2 represents incoming packet, therefore all the valid - // bits and masks are used from entry1 - if ((!rx_entry1->port_valid || rx_entry1->port == rx_entry2->port) && - (!rx_entry1->ifindex_valid || rx_entry1->ifindex == rx_entry2->ifindex) && - (!rx_entry1->bd_valid || rx_entry1->bd == rx_entry2->bd) && - (!rx_entry1->reason_code_valid || - (rx_entry1->reason_code & rx_entry1->reason_code_mask) == - (rx_entry2->reason_code & rx_entry1->reason_code_mask))) { - // priority is not be compared so matching entry can be found - // use reason_code mask from entry1 - return TRUE; - } - return FALSE; - +static bool switch_packet_rx_filter_match(switch_packet_rx_entry_t *rx_entry1, + switch_packet_rx_entry_t *rx_entry2) { + // entry1 is the one stored in the filter list + // entry2 represents incoming packet, therefore all the valid + // bits and masks are used from entry1 + if ((!rx_entry1->port_valid || rx_entry1->port == rx_entry2->port) && + (!rx_entry1->ifindex_valid || rx_entry1->ifindex == rx_entry2->ifindex) && + (!rx_entry1->bd_valid || rx_entry1->bd == rx_entry2->bd) && + (!rx_entry1->reason_code_valid || + (rx_entry1->reason_code & rx_entry1->reason_code_mask) == + (rx_entry2->reason_code & rx_entry1->reason_code_mask))) { + // priority is not be compared so matching entry can be found + // use reason_code mask from entry1 + return TRUE; + } + return FALSE; } -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; - - if (!rx_key || !rx_action) { - SWITCH_API_ERROR("filter rx create failed. invalid params"); - return SWITCH_STATUS_INVALID_PARAMETER; +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; + + 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) { + 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; } - - 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; + 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; } - 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; + 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; + } + if (rx_action->hostif_handle) { 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_valid = rx_key->port_valid; - rx_entry.port = handle_to_id(rx_key->port_handle); - rx_entry.reason_code_valid = rx_key->reason_code_valid; - rx_entry.reason_code = rx_key->reason_code; - rx_entry.reason_code_mask = rx_key->reason_code_mask; - 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; + SWITCH_API_ERROR("invalid hostif handle"); + return SWITCH_STATUS_INVALID_HANDLE; } - - 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_entry.bd = handle_to_id(bd_handle); + rx_entry.ifindex = ifindex; + rx_entry.port_valid = rx_key->port_valid; + rx_entry.port = handle_to_id(rx_key->port_handle); + rx_entry.reason_code_valid = rx_key->reason_code_valid; + rx_entry.reason_code = rx_key->reason_code; + rx_entry.reason_code_mask = rx_key->reason_code_mask; + 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; + if (hostif_info) { rx_info->intf_fd = hostif_info->intf_fd; - - SWITCH_API_INFO("net_filter_rx_create: port 0x%x, port_lag_hdl = 0x%x, " - "if_bd_hdl 0x%x, rcode 0x%x, rcode_mask 0x%x " - "vlan_id %d, fd %d, action %d\n", - rx_key->port_valid ? rx_key->port_handle : 0, - rx_key->port_lag_valid ? rx_key->port_lag_handle : 0, - rx_key->handle_valid ? rx_key->handle : 0, - rx_key->reason_code_valid ? rx_key->reason_code : 0, - rx_key->reason_code_mask, - rx_info->vlan_id, rx_info->vlan_action, rx_info->intf_fd); - /* - * 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_filter_priority_compare); - return status; + } + + SWITCH_API_INFO( + "net_filter_rx_create: port 0x%lx, port_lag_hdl = 0x%lx, " + "if_bd_hdl 0x%lx, rcode 0x%x, rcode_mask 0x%x " + "vlan_id %d, fd %d, action %d\n", + rx_key->port_valid ? rx_key->port_handle : 0, + rx_key->port_lag_valid ? rx_key->port_lag_handle : 0, + rx_key->handle_valid ? rx_key->handle : 0, + rx_key->reason_code_valid ? rx_key->reason_code : 0, + rx_key->reason_code_mask, + rx_info->vlan_id, + rx_info->vlan_action, + rx_info->intf_fd); + /* + * 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_filter_priority_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_entry_t rx_entry; - switch_packet_rx_info_t *tmp_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; - - if (!rx_key) { - SWITCH_API_ERROR("filter rx delete failed. invalid params"); - return SWITCH_STATUS_INVALID_PARAMETER; +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_entry_t rx_entry; + switch_packet_rx_info_t *tmp_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; + tommy_node *node = NULL; + 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; + } + + memset(&rx_entry, 0, sizeof(switch_packet_rx_entry_t)); + + if (rx_key->port_lag_valid && rx_key->port_lag_handle) { + 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; + } + rx_entry.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; + } + rx_entry.ifindex = port_info->ifindex; } - - memset(&rx_entry, 0, sizeof(switch_packet_rx_entry_t)); - - if (rx_key->port_lag_valid && rx_key->port_lag_handle) { - 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; - } - rx_entry.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; - } - rx_entry.ifindex = port_info->ifindex; - } + } + + 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; } - - 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 = handle_to_id(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 = handle_to_id(bd_handle); + } - if (rx_entry.port_valid) { - rx_entry.port == handle_to_id(rx_key->port_handle); - } - rx_entry.bd_valid = rx_key->handle_valid; - rx_entry.reason_code = rx_key->reason_code; - - 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; - if (switch_packet_rx_filter_match(tmp_rx_entry, &rx_entry)) { - node_found = TRUE; - break; - } - node = node->next; + if (rx_entry.port_valid) { + rx_entry.port = handle_to_id(rx_key->port_handle); + } + rx_entry.bd_valid = rx_key->handle_valid; + rx_entry.reason_code = rx_key->reason_code; + + 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; + if (switch_packet_rx_filter_match(tmp_rx_entry, &rx_entry)) { + 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; - } + 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_filter_list, node); + tommy_list_remove_existing(&packet_rx_filter_list, node); - switch_free(tmp_rx_info); - return status; + switch_free(tmp_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_filter_list); - while (node) { - tmp_rx_info = (switch_packet_rx_info_t *) node->data; - tmp_rx_entry = &tmp_rx_info->rx_entry; - - if (switch_packet_rx_filter_match(tmp_rx_entry, rx_entry)) { - *rx_info = tmp_rx_info; - status = SWITCH_STATUS_SUCCESS; - break; - } - node = node->next; +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_filter_list); + while (node) { + tmp_rx_info = (switch_packet_rx_info_t *)node->data; + tmp_rx_entry = &tmp_rx_info->rx_entry; + + if (switch_packet_rx_filter_match(tmp_rx_entry, rx_entry)) { + *rx_info = tmp_rx_info; + status = SWITCH_STATUS_SUCCESS; + break; } + node = node->next; + } - return status; + 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_filter_list); - while (node) { - tmp_tx_info = (switch_packet_tx_info_t *) node->data; - tmp_tx_entry = &tmp_tx_info->tx_entry; - if (switch_packet_tx_filter_match(tmp_tx_entry, tx_entry)) { - *tx_info = tmp_tx_info; - status = SWITCH_STATUS_SUCCESS; - break; - } - node = node->next; +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_filter_list); + while (node) { + tmp_tx_info = (switch_packet_tx_info_t *)node->data; + tmp_tx_entry = &tmp_tx_info->tx_entry; + if (switch_packet_tx_filter_match(tmp_tx_entry, tx_entry)) { + *tx_info = tmp_tx_info; + status = SWITCH_STATUS_SUCCESS; + break; } + node = node->next; + } - return status; + return status; } diff --git a/switchapi/src/switch_packet_int.h b/switchapi/src/switch_packet_int.h index 4db4c21..25e61f3 100644 --- a/switchapi/src/switch_packet_int.h +++ b/switchapi/src/switch_packet_int.h @@ -31,84 +31,80 @@ extern "C" { #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; - uint32_t reason_code_mask; - bool reason_code_valid; - uint32_t priority; + 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; + uint32_t reason_code_mask; + 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_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; + 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; - switch_tx_bypass_flags_t bypass_flags; - switch_port_t port; + switch_packet_tx_entry_t tx_entry; + tommy_node node; + uint16_t bd; + switch_tx_bypass_flags_t bypass_flags; + 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; + 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; + 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 -switch_packet_hostif_create(switch_device_t device, switch_hostif_info_t *hostif_info); -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); +void switch_packet_tx_switched(switch_packet_header_t *packet_header, + char *packet, + int packet_size); +void switch_packet_tx_to_hw(switch_packet_header_t *packet_header, + char *packet, + int packet_size); +switch_status_t switch_packet_hostif_create(switch_device_t device, + switch_hostif_info_t *hostif_info); +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 4fe4008..68a0fce 100644 --- a/switchapi/src/switch_pd.c +++ b/switchapi/src/switch_pd.c @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "assert.h" #include "p4features.h" #include "switch_pd.h" #include "switch_log_int.h" @@ -26,6094 +27,5898 @@ limitations under the License. #include "switch_sflow_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; p4_pd_sess_hdl_t g_mc_sess_hdl = 0; -p4_pd_status_t -switch_pd_client_init(switch_device_t device) -{ +p4_pd_status_t switch_pd_client_init(switch_device_t device) { #ifndef P4_MULTICAST_DISABLE - p4_pd_status_t sts = 0; - sts = p4_pd_mc_create_session(&g_mc_sess_hdl); - if (sts) return sts; + p4_pd_status_t status = 0; + status = p4_pd_mc_create_session(&g_mc_sess_hdl); + if (status) return status; #endif - return p4_pd_client_init(&g_sess_hdl, SWITCH_MAX_TXN_SZ); -} - -p4_pd_status_t -switch_pd_dmac_table_add_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - uint16_t nhop_index, - uint16_t mgid_index, - uint32_t aging_time, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + return p4_pd_client_init(&g_sess_hdl); +} + +p4_pd_status_t switch_pd_dmac_table_add_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + uint16_t nhop_index, + uint16_t mgid_index, + uint32_t aging_time, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - p4_pd_dc_dmac_match_spec_t match_spec; - p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_dmac_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_dmac_match_spec_t)); + memset(&match_spec, 0, sizeof(p4_pd_dc_dmac_match_spec_t)); - match_spec.ingress_metadata_bd = handle_to_id(mac_entry->vlan_handle); - memcpy(match_spec.l2_metadata_lkp_mac_da, &mac_entry->mac, ETH_LEN); + match_spec.ingress_metadata_bd = handle_to_id(mac_entry->vlan_handle); + memcpy(match_spec.l2_metadata_lkp_mac_da, &mac_entry->mac, ETH_LEN); - if (mac_entry->mac_action == SWITCH_MAC_ACTION_FORWARD) { - if (mgid_index) { - p4_pd_dc_dmac_multicast_hit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_dmac_multicast_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - status = p4_pd_dc_dmac_table_add_with_dmac_multicast_hit(g_sess_hdl, + if (mac_entry->mac_action == SWITCH_MAC_ACTION_FORWARD) { + if (mgid_index) { + p4_pd_dc_dmac_multicast_hit_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_dmac_multicast_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + status = p4_pd_dc_dmac_table_add_with_dmac_multicast_hit(g_sess_hdl, p4_pd_device, &match_spec, &action_spec, aging_time, entry_hdl); - } else { - 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: - { - p4_pd_dc_dmac_hit_action_spec_t hit_action_spec; - memset(&hit_action_spec, 0, sizeof(p4_pd_dc_dmac_hit_action_spec_t)); - hit_action_spec.action_ifindex = intf_info->ifindex; - status = p4_pd_dc_dmac_table_add_with_dmac_hit(g_sess_hdl, - p4_pd_device, - &match_spec, - &hit_action_spec, - aging_time, - entry_hdl); - } - break; - case SWITCH_API_INTERFACE_TUNNEL: - { - p4_pd_dc_dmac_redirect_nexthop_action_spec_t nhop_action_spec; - memset(&nhop_action_spec, 0, sizeof(p4_pd_dc_dmac_redirect_nexthop_action_spec_t)); - nhop_action_spec.action_nexthop_index = nhop_index; - status = p4_pd_dc_dmac_table_add_with_dmac_redirect_nexthop(g_sess_hdl, - p4_pd_device, - &match_spec, - &nhop_action_spec, - aging_time, - entry_hdl); - } - break; - default: - status = SWITCH_STATUS_INVALID_INTERFACE; - break; - } - } } else { - status = p4_pd_dc_dmac_table_add_with_dmac_drop(g_sess_hdl, - p4_pd_device, - &match_spec, - aging_time, - entry_hdl); - + 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: { + p4_pd_dc_dmac_hit_action_spec_t hit_action_spec; + memset(&hit_action_spec, 0, sizeof(p4_pd_dc_dmac_hit_action_spec_t)); + hit_action_spec.action_ifindex = intf_info->ifindex; + status = p4_pd_dc_dmac_table_add_with_dmac_hit(g_sess_hdl, + p4_pd_device, + &match_spec, + &hit_action_spec, + aging_time, + entry_hdl); + } break; + case SWITCH_API_INTERFACE_TUNNEL: { + p4_pd_dc_dmac_redirect_nexthop_action_spec_t nhop_action_spec; + memset(&nhop_action_spec, + 0, + sizeof(p4_pd_dc_dmac_redirect_nexthop_action_spec_t)); + nhop_action_spec.action_nexthop_index = nhop_index; + status = p4_pd_dc_dmac_table_add_with_dmac_redirect_nexthop( + g_sess_hdl, + p4_pd_device, + &match_spec, + &nhop_action_spec, + aging_time, + entry_hdl); + } break; + default: + status = SWITCH_STATUS_INVALID_INTERFACE; + break; + } } + } else { + status = p4_pd_dc_dmac_table_add_with_dmac_drop( + g_sess_hdl, p4_pd_device, &match_spec, aging_time, entry_hdl); + } #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_dmac_table_update_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - uint16_t nhop_index, - uint16_t mgid_index, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - UNUSED(mac_entry); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_dmac_table_update_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + uint16_t nhop_index, + uint16_t mgid_index, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + UNUSED(mac_entry); #ifndef P4_L2_DISABLE - if (mgid_index) { - p4_pd_dc_dmac_multicast_hit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_dmac_multicast_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - status = p4_pd_dc_dmac_table_modify_with_dmac_multicast_hit(g_sess_hdl, - device, - entry_hdl, - &action_spec); - } else { - switch(SWITCH_INTF_TYPE(intf_info)) { - case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: - case SWITCH_API_INTERFACE_L2_VLAN_TRUNK: - { - p4_pd_dc_dmac_hit_action_spec_t hit_action_spec; - memset(&hit_action_spec, 0, sizeof(p4_pd_dc_dmac_hit_action_spec_t)); - hit_action_spec.action_ifindex = intf_info->ifindex; - status = p4_pd_dc_dmac_table_modify_with_dmac_hit(g_sess_hdl, - device, - entry_hdl, - &hit_action_spec); - } - break; - case SWITCH_API_INTERFACE_TUNNEL: - { - p4_pd_dc_dmac_redirect_nexthop_action_spec_t nhop_action_spec; - memset(&nhop_action_spec, 0, sizeof(p4_pd_dc_dmac_redirect_nexthop_action_spec_t)); - nhop_action_spec.action_nexthop_index = nhop_index; - status = p4_pd_dc_dmac_table_modify_with_dmac_redirect_nexthop(g_sess_hdl, - device, - entry_hdl, - &nhop_action_spec); - } - break; - default: - status = SWITCH_STATUS_INVALID_INTERFACE; - } + if (mgid_index) { + p4_pd_dc_dmac_multicast_hit_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_dmac_multicast_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + status = p4_pd_dc_dmac_table_modify_with_dmac_multicast_hit( + g_sess_hdl, device, entry_hdl, &action_spec); + } else { + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + case SWITCH_API_INTERFACE_L2_VLAN_TRUNK: { + p4_pd_dc_dmac_hit_action_spec_t hit_action_spec; + memset(&hit_action_spec, 0, sizeof(p4_pd_dc_dmac_hit_action_spec_t)); + hit_action_spec.action_ifindex = intf_info->ifindex; + status = p4_pd_dc_dmac_table_modify_with_dmac_hit( + g_sess_hdl, device, entry_hdl, &hit_action_spec); + } break; + case SWITCH_API_INTERFACE_TUNNEL: { + p4_pd_dc_dmac_redirect_nexthop_action_spec_t nhop_action_spec; + memset(&nhop_action_spec, + 0, + sizeof(p4_pd_dc_dmac_redirect_nexthop_action_spec_t)); + nhop_action_spec.action_nexthop_index = nhop_index; + status = p4_pd_dc_dmac_table_modify_with_dmac_redirect_nexthop( + g_sess_hdl, device, entry_hdl, &nhop_action_spec); + } break; + default: + status = SWITCH_STATUS_INVALID_INTERFACE; } + } #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_dmac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_dmac_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - status = p4_pd_dc_dmac_table_delete(g_sess_hdl, device, - entry_hdl); + status = p4_pd_dc_dmac_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_smac_table_add_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_smac_table_add_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - p4_pd_dc_smac_match_spec_t match_spec; - p4_pd_dc_smac_hit_action_spec_t action_spec; - p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_smac_match_spec_t match_spec; + p4_pd_dc_smac_hit_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_smac_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_smac_hit_action_spec_t)); + memset(&match_spec, 0, sizeof(p4_pd_dc_smac_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_smac_hit_action_spec_t)); - match_spec.ingress_metadata_bd = handle_to_id(mac_entry->vlan_handle); - memcpy(match_spec.l2_metadata_lkp_mac_sa, &mac_entry->mac, ETH_LEN); + match_spec.ingress_metadata_bd = handle_to_id(mac_entry->vlan_handle); + memcpy(match_spec.l2_metadata_lkp_mac_sa, &mac_entry->mac, ETH_LEN); - action_spec.action_ifindex = intf_info->ifindex; + action_spec.action_ifindex = intf_info->ifindex; - status = p4_pd_dc_smac_table_add_with_smac_hit(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); + status = p4_pd_dc_smac_table_add_with_smac_hit( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_smac_table_update_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_smac_table_update_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - p4_pd_dc_smac_hit_action_spec_t action_spec; + p4_pd_dc_smac_hit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_smac_hit_action_spec_t)); - action_spec.action_ifindex = intf_info->ifindex; + memset(&action_spec, 0, sizeof(p4_pd_dc_smac_hit_action_spec_t)); + action_spec.action_ifindex = intf_info->ifindex; - status = p4_pd_dc_smac_table_modify_with_smac_hit(g_sess_hdl, - device, - entry_hdl, - &action_spec); + status = p4_pd_dc_smac_table_modify_with_smac_hit( + g_sess_hdl, device, entry_hdl, &action_spec); #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_smac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_smac_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - status = p4_pd_dc_smac_table_delete(g_sess_hdl, device, - entry_hdl); + status = p4_pd_dc_smac_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_mac_table_set_learning_timeout(switch_device_t device, uint32_t timeout) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_mac_table_set_learning_timeout(switch_device_t device, + uint32_t timeout) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - p4_pd_dc_set_learning_timeout(g_sess_hdl, device, timeout); + p4_pd_dc_set_learning_timeout(g_sess_hdl, device, timeout); #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_nexthop_table_add_entry(switch_device_t device, - uint16_t nhop_index, - uint16_t bd, - switch_ifindex_t ifindex, - bool flood, - uint32_t mc_index, - bool tunnel, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_dc_nexthop_match_spec_t match_spec; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_nexthop_match_spec_t)); - match_spec.l3_metadata_nexthop_index = nhop_index; - - - if (flood) { - p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_uuc_mc_index= mc_index; - status = p4_pd_dc_nexthop_table_add_with_set_nexthop_details_for_post_routed_flood( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } else { - p4_pd_dc_set_nexthop_details_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_nexthop_details_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_ifindex = ifindex; - action_spec.action_tunnel = tunnel; - status = p4_pd_dc_nexthop_table_add_with_set_nexthop_details(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_nexthop_table_update_entry(switch_device_t device, - uint16_t nhop_index, - uint16_t bd, - switch_ifindex_t ifindex, - bool flood, - uint32_t mc_index, - bool tunnel, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - - UNUSED(nhop_index); - - if (flood) { - p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_uuc_mc_index = mc_index; - status = p4_pd_dc_nexthop_table_modify_with_set_nexthop_details_for_post_routed_flood( - g_sess_hdl, - device, - *entry_hdl, - &action_spec); - } else { - p4_pd_dc_set_nexthop_details_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_nexthop_details_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_ifindex = ifindex; - action_spec.action_tunnel = tunnel; - status = p4_pd_dc_nexthop_table_modify_with_set_nexthop_details(g_sess_hdl, - device, - *entry_hdl, - &action_spec); - } - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ecmp_group_create(switch_device_t device, - p4_pd_grp_hdl_t *pd_group_hdl) -{ - switch_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - status = p4_pd_dc_ecmp_action_profile_create_group(g_sess_hdl, - p4_pd_device, - MAX_ECMP_GROUP_SIZE, - pd_group_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ecmp_group_delete(switch_device_t device, - p4_pd_grp_hdl_t pd_group_hdl) -{ - switch_status_t status = 0; - status = p4_pd_dc_ecmp_action_profile_del_group(g_sess_hdl, device, - pd_group_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_ecmp_member_add(switch_device_t device, - p4_pd_grp_hdl_t pd_group_hdl, - uint16_t nhop_index, - switch_interface_info_t *intf_info, - p4_pd_mbr_hdl_t *mbr_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t pd_device; - p4_pd_dc_set_ecmp_nexthop_details_action_spec_t action_spec; - - pd_device.device_id = device; - pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_ecmp_nexthop_details_action_spec_t)); - - action_spec.action_ifindex = intf_info->ifindex; - action_spec.action_bd = handle_to_id(intf_info->bd_handle); - action_spec.action_nhop_index = nhop_index; - action_spec.action_tunnel = - (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL); - +p4_pd_status_t switch_pd_nexthop_table_add_entry(switch_device_t device, + uint16_t nhop_index, + uint16_t bd, + switch_ifindex_t ifindex, + bool flood, + uint32_t mc_index, + bool tunnel, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_dc_nexthop_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_nexthop_match_spec_t)); + match_spec.l3_metadata_nexthop_index = nhop_index; + + if (flood) { + p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t + action_spec; + memset( + &action_spec, + 0, + sizeof( + p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_uuc_mc_index = mc_index; status = - p4_pd_dc_ecmp_action_profile_add_member_with_set_ecmp_nexthop_details( - g_sess_hdl, - pd_device, &action_spec, mbr_hdl); - - status = p4_pd_dc_ecmp_action_profile_add_member_to_group(g_sess_hdl, - device, pd_group_hdl, *mbr_hdl); - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ecmp_group_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_ecmp_group_table_delete(g_sess_hdl, - device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ecmp_member_delete(switch_device_t device, - p4_pd_grp_hdl_t pd_group_hdl, - p4_pd_mbr_hdl_t mbr_hdl) -{ - p4_pd_dc_ecmp_action_profile_del_member_from_group(g_sess_hdl, - device, pd_group_hdl, - mbr_hdl); - - p4_pd_dc_ecmp_action_profile_del_member(g_sess_hdl, device, mbr_hdl); - p4_pd_complete_operations(g_sess_hdl); - return 0; -} - -p4_pd_status_t -switch_pd_ecmp_group_table_add_entry_with_selector(switch_device_t device, - uint16_t ecmp_index, - p4_pd_grp_hdl_t grp_hdl, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dc_ecmp_group_match_spec_t match_spec; - p4_pd_dev_target_t pd_device; - - pd_device.device_id = device; - pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ecmp_group_match_spec_t)); - match_spec.l3_metadata_nexthop_index = ecmp_index; - status = p4_pd_dc_ecmp_group_add_entry_with_selector(g_sess_hdl, pd_device, - &match_spec, grp_hdl, entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -p4_pd_ecmp_group_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_ecmp_group_table_delete(g_sess_hdl, - device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_nexthop_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status; - - status = p4_pd_dc_nexthop_table_delete(g_sess_hdl, device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_dc_nexthop_table_add_with_set_nexthop_details_for_post_routed_flood( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } else { + p4_pd_dc_set_nexthop_details_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_nexthop_details_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_ifindex = ifindex; + action_spec.action_tunnel = tunnel; + status = p4_pd_dc_nexthop_table_add_with_set_nexthop_details( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_nexthop_table_update_entry( + switch_device_t device, + uint16_t nhop_index, + uint16_t bd, + switch_ifindex_t ifindex, + bool flood, + uint32_t mc_index, + bool tunnel, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + + UNUSED(nhop_index); + + if (flood) { + p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t + action_spec; + memset( + &action_spec, + 0, + sizeof( + p4_pd_dc_set_nexthop_details_for_post_routed_flood_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_uuc_mc_index = mc_index; + status = + p4_pd_dc_nexthop_table_modify_with_set_nexthop_details_for_post_routed_flood( + g_sess_hdl, device, *entry_hdl, &action_spec); + } else { + p4_pd_dc_set_nexthop_details_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_nexthop_details_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_ifindex = ifindex; + action_spec.action_tunnel = tunnel; + status = p4_pd_dc_nexthop_table_modify_with_set_nexthop_details( + g_sess_hdl, device, *entry_hdl, &action_spec); + } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ecmp_group_create(switch_device_t device, + p4_pd_grp_hdl_t *pd_group_hdl) { + switch_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_ecmp_action_profile_create_group( + g_sess_hdl, p4_pd_device, MAX_ECMP_GROUP_SIZE, pd_group_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_ip_fib_add_entry(switch_device_t device, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, bool ecmp, - switch_handle_t nexthop, p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_ecmp_group_delete(switch_device_t device, + p4_pd_grp_hdl_t pd_group_hdl) { + switch_status_t status = 0; + status = + p4_pd_dc_ecmp_action_profile_del_group(g_sess_hdl, device, pd_group_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ecmp_member_add(switch_device_t device, + p4_pd_grp_hdl_t pd_group_hdl, + uint16_t nhop_index, + switch_interface_info_t *intf_info, + p4_pd_mbr_hdl_t *mbr_hdl) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t pd_device; + p4_pd_dc_set_ecmp_nexthop_details_action_spec_t action_spec; + + pd_device.device_id = device; + pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset( + &action_spec, 0, sizeof(p4_pd_dc_set_ecmp_nexthop_details_action_spec_t)); + + action_spec.action_ifindex = intf_info->ifindex; + action_spec.action_bd = handle_to_id(intf_info->bd_handle); + action_spec.action_nhop_index = nhop_index; + action_spec.action_tunnel = + (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL); + + status = + p4_pd_dc_ecmp_action_profile_add_member_with_set_ecmp_nexthop_details( + g_sess_hdl, pd_device, &action_spec, mbr_hdl); + + status = p4_pd_dc_ecmp_action_profile_add_member_to_group( + g_sess_hdl, device, pd_group_hdl, *mbr_hdl); + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ecmp_group_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + status = p4_pd_dc_ecmp_group_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ecmp_member_delete(switch_device_t device, + p4_pd_grp_hdl_t pd_group_hdl, + p4_pd_mbr_hdl_t mbr_hdl) { + p4_pd_dc_ecmp_action_profile_del_member_from_group( + g_sess_hdl, device, pd_group_hdl, mbr_hdl); + + p4_pd_dc_ecmp_action_profile_del_member(g_sess_hdl, device, mbr_hdl); + p4_pd_complete_operations(g_sess_hdl); + return 0; +} + +p4_pd_status_t switch_pd_ecmp_group_table_add_entry_with_selector( + switch_device_t device, + uint16_t ecmp_index, + p4_pd_grp_hdl_t grp_hdl, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dc_ecmp_group_match_spec_t match_spec; + p4_pd_dev_target_t pd_device; + + pd_device.device_id = device; + pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_ecmp_group_match_spec_t)); + match_spec.l3_metadata_nexthop_index = ecmp_index; + status = p4_pd_dc_ecmp_group_add_entry_with_selector( + g_sess_hdl, pd_device, &match_spec, grp_hdl, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t p4_pd_ecmp_group_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + status = p4_pd_dc_ecmp_group_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_nexthop_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status; + + status = p4_pd_dc_nexthop_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ip_fib_add_entry(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + bool ecmp, + switch_handle_t nexthop, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_L3_DISABLE - p4_pd_dev_target_t p4_pd_device; - bool host_entry = FALSE; + p4_pd_dev_target_t p4_pd_device; + bool host_entry = FALSE; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - host_entry = ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; - if (ecmp) { - if (host_entry) { - p4_pd_dc_ipv4_fib_match_spec_t v4_match_spec; - p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; - - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - - v4_match_spec.l3_metadata_vrf = vrf; - v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; - v4_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv4_fib_table_add_with_fib_hit_ecmp(g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } else { - p4_pd_dc_ipv4_fib_lpm_match_spec_t v4_match_spec; - p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; - - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_lpm_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - v4_match_spec.l3_metadata_vrf = vrf; - v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; - v4_match_spec.ipv4_metadata_lkp_ipv4_da_prefix_length = - ip_addr->prefix_len; - v4_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv4_fib_lpm_table_add_with_fib_hit_ecmp(g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } - } else { - if (host_entry) { - p4_pd_dc_ipv4_fib_match_spec_t v4_match_spec; - p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; - - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - - v4_match_spec.l3_metadata_vrf = vrf; - v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; - v4_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv4_fib_table_add_with_fib_hit_nexthop(g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } else { - p4_pd_dc_ipv4_fib_lpm_match_spec_t v4_match_spec; - p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; - - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_lpm_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - - v4_match_spec.l3_metadata_vrf = vrf; - v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; - v4_match_spec.ipv4_metadata_lkp_ipv4_da_prefix_length = - ip_addr->prefix_len; - v4_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv4_fib_lpm_table_add_with_fib_hit_nexthop(g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } - } -#endif /* P4_IPV4_DISABLE */ + host_entry = + ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; + if (ecmp) { + if (host_entry) { + p4_pd_dc_ipv4_fib_match_spec_t v4_match_spec; + p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; + + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_match_spec_t)); + memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + + v4_match_spec.l3_metadata_vrf = vrf; + v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; + v4_action_spec.action_ecmp_index = nexthop; + status = p4_pd_dc_ipv4_fib_table_add_with_fib_hit_ecmp(g_sess_hdl, + p4_pd_device, + &v4_match_spec, + &v4_action_spec, + entry_hdl); + } else { + p4_pd_dc_ipv4_fib_lpm_match_spec_t v4_match_spec; + p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; + + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_lpm_match_spec_t)); + memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + v4_match_spec.l3_metadata_vrf = vrf; + v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; + v4_match_spec.ipv4_metadata_lkp_ipv4_da_prefix_length = + ip_addr->prefix_len; + v4_action_spec.action_ecmp_index = nexthop; + status = + p4_pd_dc_ipv4_fib_lpm_table_add_with_fib_hit_ecmp(g_sess_hdl, + p4_pd_device, + &v4_match_spec, + &v4_action_spec, + entry_hdl); + } } else { + if (host_entry) { + p4_pd_dc_ipv4_fib_match_spec_t v4_match_spec; + p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; + + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_match_spec_t)); + memset( + &v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + + v4_match_spec.l3_metadata_vrf = vrf; + v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; + v4_action_spec.action_nexthop_index = nexthop; + status = + p4_pd_dc_ipv4_fib_table_add_with_fib_hit_nexthop(g_sess_hdl, + p4_pd_device, + &v4_match_spec, + &v4_action_spec, + entry_hdl); + } else { + p4_pd_dc_ipv4_fib_lpm_match_spec_t v4_match_spec; + p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; + + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_fib_lpm_match_spec_t)); + memset( + &v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + + v4_match_spec.l3_metadata_vrf = vrf; + v4_match_spec.ipv4_metadata_lkp_ipv4_da = ip_addr->ip.v4addr; + v4_match_spec.ipv4_metadata_lkp_ipv4_da_prefix_length = + ip_addr->prefix_len; + v4_action_spec.action_nexthop_index = nexthop; + status = p4_pd_dc_ipv4_fib_lpm_table_add_with_fib_hit_nexthop( + g_sess_hdl, + p4_pd_device, + &v4_match_spec, + &v4_action_spec, + entry_hdl); + } + } +#endif /* P4_IPV4_DISABLE */ + } else { #ifndef P4_IPV6_DISABLE - host_entry = ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; - if (ecmp) { - if (host_entry) { - p4_pd_dc_ipv6_fib_match_spec_t v6_match_spec; - p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; - - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - - v6_match_spec.l3_metadata_vrf = vrf; - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_da, - ip_addr->ip.v6addr, 16); - v6_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv6_fib_table_add_with_fib_hit_ecmp(g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); - } else { - p4_pd_dc_ipv6_fib_lpm_match_spec_t v6_match_spec; - p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; - - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_lpm_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - - v6_match_spec.l3_metadata_vrf = vrf; - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_da, - ip_addr->ip.v6addr, 16); - v6_match_spec.ipv6_metadata_lkp_ipv6_da_prefix_length = - ip_addr->prefix_len; - v6_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv6_fib_lpm_table_add_with_fib_hit_ecmp(g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); - } - } else { - if (host_entry) { - p4_pd_dc_ipv6_fib_match_spec_t v6_match_spec; - p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; - - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - - v6_match_spec.l3_metadata_vrf = vrf; - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_da, - ip_addr->ip.v6addr, 16); - v6_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv6_fib_table_add_with_fib_hit_nexthop(g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); - } else { - p4_pd_dc_ipv6_fib_lpm_match_spec_t v6_match_spec; - p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; - - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_lpm_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - - v6_match_spec.l3_metadata_vrf = vrf; - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_da, - ip_addr->ip.v6addr, 16); - v6_match_spec.ipv6_metadata_lkp_ipv6_da_prefix_length = - ip_addr->prefix_len; - v6_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv6_fib_lpm_table_add_with_fib_hit_nexthop(g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); - } - } -#endif /* P4_IPV6_DISABLE */ + host_entry = + ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; + if (ecmp) { + if (host_entry) { + p4_pd_dc_ipv6_fib_match_spec_t v6_match_spec; + p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; + + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_match_spec_t)); + memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + + v6_match_spec.l3_metadata_vrf = vrf; + memcpy( + &v6_match_spec.ipv6_metadata_lkp_ipv6_da, ip_addr->ip.v6addr, 16); + v6_action_spec.action_ecmp_index = nexthop; + status = p4_pd_dc_ipv6_fib_table_add_with_fib_hit_ecmp(g_sess_hdl, + p4_pd_device, + &v6_match_spec, + &v6_action_spec, + entry_hdl); + } else { + p4_pd_dc_ipv6_fib_lpm_match_spec_t v6_match_spec; + p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; + + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_lpm_match_spec_t)); + memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + + v6_match_spec.l3_metadata_vrf = vrf; + memcpy( + &v6_match_spec.ipv6_metadata_lkp_ipv6_da, ip_addr->ip.v6addr, 16); + v6_match_spec.ipv6_metadata_lkp_ipv6_da_prefix_length = + ip_addr->prefix_len; + v6_action_spec.action_ecmp_index = nexthop; + status = + p4_pd_dc_ipv6_fib_lpm_table_add_with_fib_hit_ecmp(g_sess_hdl, + p4_pd_device, + &v6_match_spec, + &v6_action_spec, + entry_hdl); + } + } else { + if (host_entry) { + p4_pd_dc_ipv6_fib_match_spec_t v6_match_spec; + p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; + + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_match_spec_t)); + memset( + &v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + + v6_match_spec.l3_metadata_vrf = vrf; + memcpy( + &v6_match_spec.ipv6_metadata_lkp_ipv6_da, ip_addr->ip.v6addr, 16); + v6_action_spec.action_nexthop_index = nexthop; + status = + p4_pd_dc_ipv6_fib_table_add_with_fib_hit_nexthop(g_sess_hdl, + p4_pd_device, + &v6_match_spec, + &v6_action_spec, + entry_hdl); + } else { + p4_pd_dc_ipv6_fib_lpm_match_spec_t v6_match_spec; + p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; + + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_fib_lpm_match_spec_t)); + memset( + &v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + + v6_match_spec.l3_metadata_vrf = vrf; + memcpy( + &v6_match_spec.ipv6_metadata_lkp_ipv6_da, ip_addr->ip.v6addr, 16); + v6_match_spec.ipv6_metadata_lkp_ipv6_da_prefix_length = + ip_addr->prefix_len; + v6_action_spec.action_nexthop_index = nexthop; + status = p4_pd_dc_ipv6_fib_lpm_table_add_with_fib_hit_nexthop( + g_sess_hdl, + p4_pd_device, + &v6_match_spec, + &v6_action_spec, + entry_hdl); + } } +#endif /* P4_IPV6_DISABLE */ + } #endif /* L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ip_fib_update_entry(switch_device_t device, switch_handle_t vrf, - switch_ip_addr_t *ip_addr, bool ecmp, - switch_handle_t nexthop, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - UNUSED(vrf); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ip_fib_update_entry(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + bool ecmp, + switch_handle_t nexthop, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + UNUSED(vrf); #ifndef P4_L3_DISABLE - bool host_entry = FALSE; + bool host_entry = FALSE; - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - host_entry = ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; - if (ecmp) { - if (host_entry) { - p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - v4_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv4_fib_table_modify_with_fib_hit_ecmp(g_sess_hdl, - device, - entry_hdl, - &v4_action_spec); - } else { - p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - v4_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv4_fib_lpm_table_modify_with_fib_hit_ecmp(g_sess_hdl, - device, - entry_hdl, - &v4_action_spec); - } - } else { - if (host_entry) { - p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - v4_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv4_fib_table_modify_with_fib_hit_nexthop(g_sess_hdl, - device, - entry_hdl, - &v4_action_spec); - } else { - p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - v4_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv4_fib_lpm_table_modify_with_fib_hit_nexthop(g_sess_hdl, - device, - entry_hdl, - &v4_action_spec); - } - } -#endif /* P4_IPV4_DISABLE */ + host_entry = + ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; + if (ecmp) { + if (host_entry) { + p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; + memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + v4_action_spec.action_ecmp_index = nexthop; + status = p4_pd_dc_ipv4_fib_table_modify_with_fib_hit_ecmp( + g_sess_hdl, device, entry_hdl, &v4_action_spec); + } else { + p4_pd_dc_fib_hit_ecmp_action_spec_t v4_action_spec; + memset(&v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + v4_action_spec.action_ecmp_index = nexthop; + status = p4_pd_dc_ipv4_fib_lpm_table_modify_with_fib_hit_ecmp( + g_sess_hdl, device, entry_hdl, &v4_action_spec); + } } else { + if (host_entry) { + p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; + memset( + &v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + v4_action_spec.action_nexthop_index = nexthop; + status = p4_pd_dc_ipv4_fib_table_modify_with_fib_hit_nexthop( + g_sess_hdl, device, entry_hdl, &v4_action_spec); + } else { + p4_pd_dc_fib_hit_nexthop_action_spec_t v4_action_spec; + memset( + &v4_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + v4_action_spec.action_nexthop_index = nexthop; + status = p4_pd_dc_ipv4_fib_lpm_table_modify_with_fib_hit_nexthop( + g_sess_hdl, device, entry_hdl, &v4_action_spec); + } + } +#endif /* P4_IPV4_DISABLE */ + } else { #ifndef P4_IPV6_DISABLE - host_entry = ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; - if (ecmp) { - if (host_entry) { - p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - v6_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv6_fib_table_modify_with_fib_hit_ecmp(g_sess_hdl, - device, - entry_hdl, - &v6_action_spec); - } else { - p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); - v6_action_spec.action_ecmp_index = nexthop; - status = p4_pd_dc_ipv6_fib_lpm_table_modify_with_fib_hit_ecmp(g_sess_hdl, - device, - entry_hdl, - &v6_action_spec); - } - } else { - if (host_entry) { - p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - v6_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv6_fib_table_modify_with_fib_hit_nexthop(g_sess_hdl, - device, - entry_hdl, - &v6_action_spec); - } else { - p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); - v6_action_spec.action_nexthop_index = nexthop; - status = p4_pd_dc_ipv6_fib_lpm_table_modify_with_fib_hit_nexthop(g_sess_hdl, - device, - entry_hdl, - &v6_action_spec); - } - } -#endif /* P4_IPV6_DISABLE */ + host_entry = + ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; + if (ecmp) { + if (host_entry) { + p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; + memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + v6_action_spec.action_ecmp_index = nexthop; + status = p4_pd_dc_ipv6_fib_table_modify_with_fib_hit_ecmp( + g_sess_hdl, device, entry_hdl, &v6_action_spec); + } else { + p4_pd_dc_fib_hit_ecmp_action_spec_t v6_action_spec; + memset(&v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_ecmp_action_spec_t)); + v6_action_spec.action_ecmp_index = nexthop; + status = p4_pd_dc_ipv6_fib_lpm_table_modify_with_fib_hit_ecmp( + g_sess_hdl, device, entry_hdl, &v6_action_spec); + } + } else { + if (host_entry) { + p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; + memset( + &v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + v6_action_spec.action_nexthop_index = nexthop; + status = p4_pd_dc_ipv6_fib_table_modify_with_fib_hit_nexthop( + g_sess_hdl, device, entry_hdl, &v6_action_spec); + } else { + p4_pd_dc_fib_hit_nexthop_action_spec_t v6_action_spec; + memset( + &v6_action_spec, 0, sizeof(p4_pd_dc_fib_hit_nexthop_action_spec_t)); + v6_action_spec.action_nexthop_index = nexthop; + status = p4_pd_dc_ipv6_fib_lpm_table_modify_with_fib_hit_nexthop( + g_sess_hdl, device, entry_hdl, &v6_action_spec); + } } +#endif /* P4_IPV6_DISABLE */ + } #endif /* P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_ip_fib_delete_entry(switch_device_t device, - switch_ip_addr_t *ip_addr, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_ip_fib_delete_entry(switch_device_t device, + switch_ip_addr_t *ip_addr, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef L3_DISABLE - bool host_entry = FALSE; + bool host_entry = FALSE; - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { #ifndef IPV4_DISABLE - host_entry = ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; - if (host_entry) { - status = p4_pd_dc_ipv4_fib_table_delete(g_sess_hdl, - device, - entry_hdl); - } else { - status = p4_pd_dc_ipv4_fib_lpm_table_delete(g_sess_hdl, - device, - entry_hdl); - } -#endif /* IPV4_DISABLE */ + host_entry = + ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH ? TRUE : FALSE; + if (host_entry) { + status = p4_pd_dc_ipv4_fib_table_delete(g_sess_hdl, device, entry_hdl); } else { + status = + p4_pd_dc_ipv4_fib_lpm_table_delete(g_sess_hdl, device, entry_hdl); + } +#endif /* IPV4_DISABLE */ + } else { #ifndef P4_IPV6_DISABLE - host_entry = ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; - if (host_entry) { - status = p4_pd_dc_ipv6_fib_table_delete(g_sess_hdl, - device, - entry_hdl); - } else { - status = p4_pd_dc_ipv6_fib_lpm_table_delete(g_sess_hdl, - device, - entry_hdl); - } -#endif /* P4_IPV6_DISABLE */ + host_entry = + ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH ? TRUE : FALSE; + if (host_entry) { + status = p4_pd_dc_ipv6_fib_table_delete(g_sess_hdl, device, entry_hdl); + } else { + status = + p4_pd_dc_ipv6_fib_lpm_table_delete(g_sess_hdl, device, entry_hdl); } +#endif /* P4_IPV6_DISABLE */ + } #endif /* L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_inner_rmac_table_add_entry(switch_device_t device, - switch_handle_t rmac_group, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_rmac_match_spec_t match_spec; +p4_pd_status_t switch_pd_inner_rmac_table_add_entry( + switch_device_t device, + switch_handle_t rmac_group, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_rmac_match_spec_t match_spec; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - 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); + 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); - status = p4_pd_dc_rmac_table_add_with_rmac_hit(g_sess_hdl, - p4_pd_device, - &match_spec, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_rmac_table_add_with_rmac_hit( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_inner_rmac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_inner_rmac_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; - status = p4_pd_dc_rmac_table_delete(g_sess_hdl, - device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_rmac_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_outer_rmac_table_add_entry(switch_device_t device, - switch_handle_t rmac_group, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_outer_rmac_table_add_entry( + switch_device_t device, + switch_handle_t rmac_group, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_outer_rmac_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_outer_rmac_match_spec_t match_spec; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_rmac_match_spec_t)); - match_spec.l3_metadata_rmac_group = rmac_group; - memcpy(match_spec.ethernet_dstAddr, mac, ETH_LEN); + memset(&match_spec, 0, sizeof(p4_pd_dc_rmac_match_spec_t)); + match_spec.l3_metadata_rmac_group = rmac_group; + 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, - &match_spec, - entry_hdl); + p4_pd_dc_outer_rmac_table_add_with_outer_rmac_hit( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_outer_rmac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_outer_rmac_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - status = p4_pd_dc_outer_rmac_table_delete(g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_outer_rmac_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_src_vtep_table_add_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - switch_ifindex_t ifindex, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_src_vtep_table_add_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + switch_ifindex_t ifindex, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) - p4_pd_dev_target_t p4_pd_device; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - p4_pd_dc_ipv4_src_vtep_match_spec_t v4_match_spec; - p4_pd_dc_src_vtep_hit_action_spec_t v4_action_spec; + p4_pd_dc_ipv4_src_vtep_match_spec_t v4_match_spec; + p4_pd_dc_src_vtep_hit_action_spec_t v4_action_spec; - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_src_vtep_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_src_vtep_hit_action_spec_t)); + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_ipv4_src_vtep_match_spec_t)); + 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_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; + v4_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); + 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( - g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); + status = p4_pd_dc_ipv4_src_vtep_table_add_with_src_vtep_hit( + g_sess_hdl, p4_pd_device, &v4_match_spec, &v4_action_spec, entry_hdl); #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - p4_pd_dc_ipv6_src_vtep_match_spec_t v6_match_spec; - p4_pd_dc_src_vtep_hit_action_spec_t v6_action_spec; + p4_pd_dc_ipv6_src_vtep_match_spec_t v6_match_spec; + p4_pd_dc_src_vtep_hit_action_spec_t v6_action_spec; - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_src_vtep_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_src_vtep_hit_action_spec_t)); + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_ipv6_src_vtep_match_spec_t)); + 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_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; + v6_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); + 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( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); + status = p4_pd_dc_ipv6_src_vtep_table_add_with_src_vtep_hit( + g_sess_hdl, p4_pd_device, &v6_match_spec, &v6_action_spec, entry_hdl); #endif /* P4_IPV6_DISABLE */ - } + } #endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_src_vtep_table_delete_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_src_vtep_table_delete_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ipv4_src_vtep_table_delete(g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_ipv4_src_vtep_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_ipv6_src_vtep_table_delete(g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_ipv6_src_vtep_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV6_DISABLE */ - } + } #endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_dest_vtep_table_add_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_dest_vtep_table_add_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) - p4_pd_dev_target_t p4_pd_device; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - if (SWITCH_IP_ENCAP_DST_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + if (SWITCH_IP_ENCAP_DST_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - 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_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( - g_sess_hdl, - p4_pd_device, - &v4_match_spec, - entry_hdl); + 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_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( + g_sess_hdl, p4_pd_device, &v4_match_spec, entry_hdl); #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - 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_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); - status = p4_pd_dc_ipv6_dest_vtep_table_add_with_set_tunnel_termination_flag( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - entry_hdl); + 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_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); + status = p4_pd_dc_ipv6_dest_vtep_table_add_with_set_tunnel_termination_flag( + g_sess_hdl, p4_pd_device, &v6_match_spec, entry_hdl); #endif /* P4_IPV6_DISABLE */ - } + } #endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_dest_vtep_table_delete_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_dest_vtep_table_delete_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ipv4_dest_vtep_table_delete(g_sess_hdl, - device, - entry_hdl); + status = + p4_pd_dc_ipv4_dest_vtep_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_ipv6_dest_vtep_table_delete(g_sess_hdl, - device, - entry_hdl); + status = + p4_pd_dc_ipv6_dest_vtep_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV6_DISABLE */ - } + } #endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_tunnel_smac_rewrite_table_add_entry(switch_device_t device, - uint16_t smac_index, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_smac_rewrite_table_add_entry( + switch_device_t device, + uint16_t smac_index, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_tunnel_smac_rewrite_match_spec_t match_spec; + p4_pd_dc_rewrite_tunnel_smac_action_spec_t action_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_smac_rewrite_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_smac_action_spec_t)); + + match_spec.tunnel_metadata_tunnel_smac_index = smac_index; + memcpy(action_spec.action_smac, mac->mac_addr, ETH_LEN); + + status = p4_pd_dc_tunnel_smac_rewrite_table_add_with_rewrite_tunnel_smac( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_smac_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + status = + p4_pd_dc_tunnel_smac_rewrite_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_dmac_rewrite_table_add_entry( + switch_device_t device, + uint16_t dmac_index, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_tunnel_dmac_rewrite_match_spec_t match_spec; + p4_pd_dc_rewrite_tunnel_dmac_action_spec_t action_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_dmac_rewrite_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_dmac_action_spec_t)); + + match_spec.tunnel_metadata_tunnel_dmac_index = dmac_index; + memcpy(action_spec.action_dmac, mac->mac_addr, ETH_LEN); + + status = p4_pd_dc_tunnel_dmac_rewrite_table_add_with_rewrite_tunnel_dmac( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_dmac_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + status = + p4_pd_dc_tunnel_dmac_rewrite_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_rewrite_table_add_entry( + switch_device_t device, + uint16_t tunnel_index, + uint16_t sip_index, + uint16_t dip_index, + uint16_t smac_index, + uint16_t dmac_index, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_tunnel_rewrite_match_spec_t match_spec; + p4_pd_dc_set_tunnel_rewrite_details_action_spec_t action_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_rewrite_match_spec_t)); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_tunnel_rewrite_details_action_spec_t)); + + match_spec.tunnel_metadata_tunnel_index = tunnel_index; + action_spec.action_smac_idx = smac_index; + action_spec.action_dmac_idx = dmac_index; + action_spec.action_sip_index = sip_index; + action_spec.action_dip_index = dip_index; + + status = p4_pd_dc_tunnel_rewrite_table_add_with_set_tunnel_rewrite_details( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + status = p4_pd_dc_tunnel_rewrite_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_table_add_entry(switch_device_t device, + switch_encap_type_t encap_type, + uint16_t tunnel_vni, + switch_rid_t ingress_rid, + switch_bd_info_t *bd_info, + switch_ip_encap_t *ip_encap, + switch_handle_t bd_handle, + p4_pd_entry_hdl_t entry_hdl[]) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_tunnel_smac_rewrite_match_spec_t match_spec; - p4_pd_dc_rewrite_tunnel_smac_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; + uint16_t ingress_tunnel_type = 0; + switch_logical_network_t *ln_info = NULL; + int entry = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + switch (encap_type) { + case SWITCH_API_ENCAP_TYPE_VXLAN: + ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_VXLAN; + break; + case SWITCH_API_ENCAP_TYPE_GENEVE: + ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GENEVE; + break; + case SWITCH_API_ENCAP_TYPE_NVGRE: + ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NVGRE; + break; + case SWITCH_API_ENCAP_TYPE_GRE: + 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; + } + + ln_info = &bd_info->ln_info; + p4_pd_dc_tunnel_match_spec_t match_spec; + + if ((ingress_tunnel_type == SWITCH_INGRESS_TUNNEL_TYPE_VXLAN) || + (ingress_tunnel_type == SWITCH_INGRESS_TUNNEL_TYPE_GENEVE) || + (ingress_tunnel_type == SWITCH_INGRESS_TUNNEL_TYPE_NVGRE)) { + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); + match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; + match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; + match_spec.inner_ipv6_valid = FALSE; + match_spec.inner_ipv4_valid = FALSE; + + p4_pd_dc_terminate_tunnel_inner_non_ip_action_spec_t non_ip_action_spec; + memset(&non_ip_action_spec, + 0, + sizeof(p4_pd_dc_terminate_tunnel_inner_non_ip_action_spec_t)); + non_ip_action_spec.action_bd = bd_handle; + non_ip_action_spec.action_bd_label = handle_to_id(ln_info->bd_label); + non_ip_action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); + + status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_non_ip( + g_sess_hdl, + p4_pd_device, + &match_spec, + &non_ip_action_spec, + &entry_hdl[entry++]); - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +#ifndef P4_IPV4_DISABLE + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); + match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; + match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; + match_spec.inner_ipv4_valid = TRUE; + match_spec.inner_ipv6_valid = FALSE; + + p4_pd_dc_terminate_tunnel_inner_ethernet_ipv4_action_spec_t v4_action_spec; + memset(&v4_action_spec, + 0, + sizeof(p4_pd_dc_terminate_tunnel_inner_ethernet_ipv4_action_spec_t)); + v4_action_spec.action_bd = bd_handle; + v4_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); + v4_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); + v4_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); + v4_action_spec.action_bd_label = handle_to_id(ln_info->bd_label); + v4_action_spec.action_ipv4_unicast_enabled = + SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + v4_action_spec.action_ipv4_multicast_enabled = + SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + v4_action_spec.action_igmp_snooping_enabled = + SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); + v4_action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; + v4_action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_smac_rewrite_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_smac_action_spec_t)); + status = + p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ethernet_ipv4( + g_sess_hdl, + p4_pd_device, + &match_spec, + &v4_action_spec, + &entry_hdl[entry++]); +#endif /* P4_IPV4_DISABLE */ - match_spec.tunnel_metadata_tunnel_smac_index = smac_index; - memcpy(action_spec.action_smac, mac->mac_addr, ETH_LEN); +#ifndef P4_IPV6_DISABLE + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); + match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; + match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; + match_spec.inner_ipv6_valid = TRUE; + match_spec.inner_ipv4_valid = FALSE; + + p4_pd_dc_terminate_tunnel_inner_ethernet_ipv6_action_spec_t v6_action_spec; + memset(&v6_action_spec, + 0, + sizeof(p4_pd_dc_terminate_tunnel_inner_ethernet_ipv6_action_spec_t)); + v6_action_spec.action_bd = bd_handle; + v6_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); + v6_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); + v6_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); + v6_action_spec.action_bd_label = handle_to_id(ln_info->bd_label); + v6_action_spec.action_ipv6_unicast_enabled = + SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + v6_action_spec.action_ipv6_multicast_enabled = + SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + v6_action_spec.action_mld_snooping_enabled = + SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); + v6_action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; + v6_action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); - status = p4_pd_dc_tunnel_smac_rewrite_table_add_with_rewrite_tunnel_smac(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} + status = + p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ethernet_ipv6( + g_sess_hdl, + p4_pd_device, + &match_spec, + &v6_action_spec, + &entry_hdl[entry++]); +#endif /* P4_IPV6_DISABLE */ + } else { +#ifndef P4_IPV4_DISABLE + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); + match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; + match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; + match_spec.inner_ipv4_valid = TRUE; + match_spec.inner_ipv6_valid = FALSE; + + p4_pd_dc_terminate_tunnel_inner_ipv4_action_spec_t v4_action_spec; + memset(&v4_action_spec, + 0, + sizeof(p4_pd_dc_terminate_tunnel_inner_ipv4_action_spec_t)); + v4_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); + v4_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); + v4_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); + v4_action_spec.action_ipv4_unicast_enabled = + SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + v4_action_spec.action_ipv4_multicast_enabled = + SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + v4_action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; -p4_pd_status_t -switch_pd_tunnel_smac_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - status = p4_pd_dc_tunnel_smac_rewrite_table_delete(g_sess_hdl, - device, - entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_tunnel_dmac_rewrite_table_add_entry(switch_device_t device, - uint16_t dmac_index, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_tunnel_dmac_rewrite_match_spec_t match_spec; - p4_pd_dc_rewrite_tunnel_dmac_action_spec_t action_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ipv4( + g_sess_hdl, + p4_pd_device, + &match_spec, + &v4_action_spec, + &entry_hdl[entry++]); +#endif /* P4_IPV4_DISABLE */ - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_dmac_rewrite_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_dmac_action_spec_t)); +#ifndef P4_IPV6_DISABLE + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); + match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; + match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; + match_spec.inner_ipv6_valid = TRUE; + match_spec.inner_ipv4_valid = FALSE; + + p4_pd_dc_terminate_tunnel_inner_ipv6_action_spec_t v6_action_spec; + memset(&v6_action_spec, + 0, + sizeof(p4_pd_dc_terminate_tunnel_inner_ipv6_action_spec_t)); + v6_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); + v6_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); + v6_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); + v6_action_spec.action_ipv6_unicast_enabled = + SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + v6_action_spec.action_ipv6_multicast_enabled = + SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + v6_action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; - match_spec.tunnel_metadata_tunnel_dmac_index = dmac_index; - memcpy(action_spec.action_dmac, mac->mac_addr, ETH_LEN); + status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ipv6( + g_sess_hdl, + p4_pd_device, + &match_spec, + &v6_action_spec, + &entry_hdl[entry++]); +#endif /* P4_IPV6_DISABLE */ + } - status = p4_pd_dc_tunnel_dmac_rewrite_table_add_with_rewrite_tunnel_dmac(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_dmac_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_tunnel_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl[]) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - status = p4_pd_dc_tunnel_dmac_rewrite_table_delete(g_sess_hdl, - device, - entry_hdl); + int entry = 0; + for (entry = 0; entry < 3; entry++) { + if (entry_hdl[entry]) { + status = + p4_pd_dc_tunnel_table_delete(g_sess_hdl, device, entry_hdl[entry]); + } + } + p4_pd_complete_operations(g_sess_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + return status; } -p4_pd_status_t -switch_pd_tunnel_rewrite_table_add_entry(switch_device_t device, uint16_t tunnel_index, - uint16_t sip_index, uint16_t dip_index, - uint16_t smac_index, uint16_t dmac_index, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_egress_vni_table_add_entry( + switch_device_t device, + switch_handle_t egress_bd, + uint16_t tunnel_vni, + uint8_t tunnel_type, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_tunnel_rewrite_match_spec_t match_spec; - p4_pd_dc_set_tunnel_rewrite_details_action_spec_t action_spec; + p4_pd_dc_egress_vni_match_spec_t match_spec; + p4_pd_dc_set_egress_tunnel_vni_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_rewrite_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_set_tunnel_rewrite_details_action_spec_t)); + memset(&match_spec, 0, sizeof(p4_pd_dc_egress_vni_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_set_egress_tunnel_vni_action_spec_t)); - match_spec.tunnel_metadata_tunnel_index = tunnel_index; - action_spec.action_smac_idx = smac_index; - action_spec.action_dmac_idx = dmac_index; - action_spec.action_sip_index = sip_index; - action_spec.action_dip_index = dip_index; - - status = p4_pd_dc_tunnel_rewrite_table_add_with_set_tunnel_rewrite_details( - g_sess_hdl, p4_pd_device, &match_spec, - &action_spec, entry_hdl); + match_spec.egress_metadata_bd = egress_bd; + match_spec.tunnel_metadata_egress_tunnel_type = tunnel_type; + action_spec.action_vnid = tunnel_vni; + status = p4_pd_dc_egress_vni_table_add_with_set_egress_tunnel_vni( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_rewrite_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_egress_vni_table_delete_entry( + switch_device_t device_id, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - status = p4_pd_dc_tunnel_rewrite_table_delete(g_sess_hdl, - device, - entry_hdl); + + status = p4_pd_dc_egress_vni_table_delete(g_sess_hdl, device_id, entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_table_add_entry(switch_device_t device, - switch_encap_type_t encap_type, - uint16_t tunnel_vni, - switch_rid_t ingress_rid, - switch_bd_info_t *bd_info, - switch_ip_encap_t *ip_encap, - switch_handle_t bd_handle, - p4_pd_entry_hdl_t entry_hdl[]) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_tunnel_decap_tables_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; + #ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - uint16_t ingress_tunnel_type = 0; - switch_logical_network_t *ln_info = NULL; - int entry = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - switch(encap_type) { - case SWITCH_API_ENCAP_TYPE_VXLAN: - ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_VXLAN; - break; - case SWITCH_API_ENCAP_TYPE_GENEVE: - ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GENEVE; - break; - case SWITCH_API_ENCAP_TYPE_NVGRE: - ingress_tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NVGRE; - break; - case SWITCH_API_ENCAP_TYPE_GRE: - 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; - } + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_tunnel_decap_process_inner_match_spec_t i_match_spec; + p4_pd_dc_tunnel_decap_process_outer_match_spec_t o_match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + /* inner tcp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); + i_match_spec.inner_tcp_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_tcp( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* inner udp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); + i_match_spec.inner_udp_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_udp( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* inner icmp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); + i_match_spec.inner_icmp_valid = TRUE; + status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_icmp( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* inner uknown */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); + status = + p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_unknown( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* vxlan, 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_VXLAN; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_vxlan_inner_ipv4( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - ln_info = &bd_info->ln_info; - p4_pd_dc_tunnel_match_spec_t match_spec; +#ifndef P4_IPV6_DISABLE + /* vxlan, 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_VXLAN; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_vxlan_inner_ipv6( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ - if ((ingress_tunnel_type == SWITCH_INGRESS_TUNNEL_TYPE_VXLAN) || - (ingress_tunnel_type == SWITCH_INGRESS_TUNNEL_TYPE_GENEVE) || - (ingress_tunnel_type == SWITCH_INGRESS_TUNNEL_TYPE_NVGRE)) { + /* vxlan, 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_VXLAN; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_vxlan_inner_non_ip( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* geneve, 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_GENEVE; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_genv_inner_ipv4( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); - match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; - match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; - match_spec.inner_ipv6_valid = FALSE; - match_spec.inner_ipv4_valid = FALSE; +#ifndef P4_IPV6_DISABLE + /* geneve, 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_GENEVE; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_genv_inner_ipv6( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ - p4_pd_dc_terminate_tunnel_inner_non_ip_action_spec_t non_ip_action_spec; - memset(&non_ip_action_spec, 0, - sizeof(p4_pd_dc_terminate_tunnel_inner_non_ip_action_spec_t)); - non_ip_action_spec.action_bd = bd_handle; - non_ip_action_spec.action_bd_label = handle_to_id(ln_info->bd_label); - non_ip_action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); + /* geneve, 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_GENEVE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_genv_inner_non_ip( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_non_ip( - g_sess_hdl, - p4_pd_device, - &match_spec, - &non_ip_action_spec, - &entry_hdl[entry++]); +#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; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_nvgre_inner_ipv4( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); -#ifndef P4_IPV4_DISABLE - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); - match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; - match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; - match_spec.inner_ipv4_valid = TRUE; - match_spec.inner_ipv6_valid = FALSE; - - p4_pd_dc_terminate_tunnel_inner_ethernet_ipv4_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, - sizeof(p4_pd_dc_terminate_tunnel_inner_ethernet_ipv4_action_spec_t)); - v4_action_spec.action_bd = bd_handle; - v4_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); - v4_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); - v4_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); - v4_action_spec.action_bd_label = handle_to_id(ln_info->bd_label); - v4_action_spec.action_ipv4_unicast_enabled = SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - v4_action_spec.action_ipv4_multicast_enabled = SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - v4_action_spec.action_igmp_snooping_enabled = SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); - v4_action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; - v4_action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); - - status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ethernet_ipv4( - g_sess_hdl, - p4_pd_device, - &match_spec, - &v4_action_spec, - &entry_hdl[entry++]); -#endif /* P4_IPV4_DISABLE */ +#ifndef P4_IPV6_DISABLE + /* nvgre, 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_NVGRE; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_nvgre_inner_ipv6( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ + + /* nvgre, 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_NVGRE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_nvgre_inner_non_ip( + g_sess_hdl, 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 - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); - match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; - match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; - match_spec.inner_ipv6_valid = TRUE; - match_spec.inner_ipv4_valid = FALSE; - - p4_pd_dc_terminate_tunnel_inner_ethernet_ipv6_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, - sizeof(p4_pd_dc_terminate_tunnel_inner_ethernet_ipv6_action_spec_t)); - v6_action_spec.action_bd = bd_handle; - v6_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); - v6_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); - v6_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); - v6_action_spec.action_bd_label = handle_to_id(ln_info->bd_label); - v6_action_spec.action_ipv6_unicast_enabled = SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - v6_action_spec.action_ipv6_multicast_enabled = SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - v6_action_spec.action_mld_snooping_enabled = SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); - v6_action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; - v6_action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); - - status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ethernet_ipv6( - g_sess_hdl, - p4_pd_device, - &match_spec, - &v6_action_spec, - &entry_hdl[entry++]); + /* 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 */ - } else { -#ifndef P4_IPV4_DISABLE - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); - match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; - match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; - match_spec.inner_ipv4_valid = TRUE; - match_spec.inner_ipv6_valid = FALSE; - - p4_pd_dc_terminate_tunnel_inner_ipv4_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, - sizeof(p4_pd_dc_terminate_tunnel_inner_ipv4_action_spec_t)); - v4_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); - v4_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); - v4_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); - v4_action_spec.action_ipv4_unicast_enabled = SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - v4_action_spec.action_ipv4_multicast_enabled = SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - v4_action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; - - status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ipv4( - g_sess_hdl, - p4_pd_device, - &match_spec, - &v4_action_spec, - &entry_hdl[entry++]); -#endif /* P4_IPV4_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 - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_match_spec_t)); - match_spec.tunnel_metadata_tunnel_vni = tunnel_vni; - match_spec.tunnel_metadata_ingress_tunnel_type = ingress_tunnel_type; - match_spec.inner_ipv6_valid = TRUE; - match_spec.inner_ipv4_valid = FALSE; - - p4_pd_dc_terminate_tunnel_inner_ipv6_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, - sizeof(p4_pd_dc_terminate_tunnel_inner_ipv6_action_spec_t)); - v6_action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); - v6_action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); - v6_action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); - v6_action_spec.action_ipv6_unicast_enabled = SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - v6_action_spec.action_ipv6_multicast_enabled = SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - v6_action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; - - status = p4_pd_dc_tunnel_table_add_with_terminate_tunnel_inner_ipv6( - g_sess_hdl, - p4_pd_device, - &match_spec, - &v6_action_spec, - &entry_hdl[entry++]); + /* 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 */ - } -#endif /* P4_TUNNEL_DISABLE */ +#ifndef P4_MPLS_DISABLE + /* mpls, inner_ipv4, pop 1 */ + 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_MPLS_L3VPN_NUM_LABELS_1; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv4_pop1( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, inner_ipv4, pop 2 */ + 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_MPLS_L3VPN_NUM_LABELS_2; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv4_pop2( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, inner_ipv4, pop 3 */ + 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_MPLS_L3VPN_NUM_LABELS_3; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv4_pop3( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} +#ifndef P4_IPV6_DISABLE + /* mpls, inner_ipv6, pop 1 */ + 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_MPLS_L3VPN_NUM_LABELS_1; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv6_pop1( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, inner_ipv6, pop 2 */ + 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_MPLS_L3VPN_NUM_LABELS_2; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv6_pop2( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, inner_ipv6, pop 3 */ + 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_MPLS_L3VPN_NUM_LABELS_3; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv6_pop3( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ -p4_pd_status_t -switch_pd_tunnel_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl[]) -{ - p4_pd_status_t status = 0; - int entry = 0; -#ifndef P4_TUNNEL_DISABLE - for (entry = 0; entry < 3; entry++) { - if (entry_hdl[entry]) { - status = p4_pd_dc_tunnel_table_delete(g_sess_hdl, - device, entry_hdl[entry]); - } - } + /* mpls, ethernet, inner_ipv4, pop 1 */ + 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_MPLS_L2VPN_NUM_LABELS_1; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv4_pop1( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, inner_ipv4, pop 2 */ + 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_MPLS_L2VPN_NUM_LABELS_2; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv4_pop2( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, inner_ipv4, pop 3 */ + 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_MPLS_L2VPN_NUM_LABELS_3; + o_match_spec.inner_ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv4_pop3( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + +#ifndef P4_IPV6_DISABLE + /* mpls, ethernet, inner_ipv6, pop 1 */ + 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_MPLS_L2VPN_NUM_LABELS_1; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv6_pop1( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, inner_ipv6, pop 2 */ + 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_MPLS_L2VPN_NUM_LABELS_2; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv6_pop2( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, inner_ipv6, pop 3 */ + 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_MPLS_L2VPN_NUM_LABELS_3; + o_match_spec.inner_ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv6_pop3( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ + + /* mpls, ethernet, non_ip, pop 1 */ + 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_MPLS_L2VPN_NUM_LABELS_1; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_non_ip_pop1( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, inner_ipv6, pop 2 */ + 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_MPLS_L2VPN_NUM_LABELS_2; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_non_ip_pop2( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, inner_ipv6, pop 3 */ + 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_MPLS_L2VPN_NUM_LABELS_3; + status = + p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_non_ip_pop3( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif /* P4_MPLS_DISABLE */ #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} -p4_pd_status_t -switch_pd_egress_vni_table_add_entry(switch_device_t device, - switch_handle_t egress_bd, - uint16_t tunnel_vni, - uint8_t tunnel_type, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_encap_tables_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; + +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_tunnel_encap_process_outer_match_spec_t o_match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + p4_pd_dc_tunnel_encap_process_inner_match_spec_t i_match_spec; + + /* ipv4, tcp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv4_valid = TRUE; + i_match_spec.tcp_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_tcp_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv4, udp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv4_valid = TRUE; + i_match_spec.udp_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_udp_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv4, icmp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv4_valid = TRUE; + i_match_spec.icmp_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_icmp_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv4, uknown */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv4_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_unknown_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv6, tcp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv6_valid = TRUE; + i_match_spec.tcp_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_tcp_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv6, udp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv6_valid = TRUE; + i_match_spec.udp_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_udp_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv6, icmp */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv6_valid = TRUE; + i_match_spec.icmp_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_icmp_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* ipv6, uknown */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + i_match_spec.ipv6_valid = TRUE; + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_unknown_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); + + /* non ip */ + memset(&i_match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); + status = + p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_non_ip_rewrite( + g_sess_hdl, p4_pd_device, &i_match_spec, &entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE */ + #ifndef P4_TUNNEL_DISABLE - p4_pd_dc_egress_vni_match_spec_t match_spec; - p4_pd_dc_set_egress_tunnel_vni_action_spec_t action_spec; - p4_pd_dev_target_t p4_pd_device; + /* default entry */ + status = p4_pd_dc_tunnel_encap_process_outer_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + /* ipv4 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_IPV4_VXLAN; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_vxlan_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_VXLAN; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_vxlan_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +#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; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_vxlan_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_VXLAN; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_vxlan_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif - memset(&match_spec, 0, sizeof(p4_pd_dc_egress_vni_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_set_egress_tunnel_vni_action_spec_t)); + /* ipv4 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_IPV4_GENEVE; + o_match_spec.multicast_metadata_replica = false; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_genv_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_GENEVE; + o_match_spec.multicast_metadata_replica = true; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_genv_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - match_spec.egress_metadata_bd = egress_bd; - match_spec.tunnel_metadata_egress_tunnel_type = tunnel_type; - action_spec.action_vnid = tunnel_vni; +#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; + o_match_spec.multicast_metadata_replica = false; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_genv_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_GENEVE; + o_match_spec.multicast_metadata_replica = true; + status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_genv_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif - status = p4_pd_dc_egress_vni_table_add_with_set_egress_tunnel_vni(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} +#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; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_nvgre_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_NVGRE; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_nvgre_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); -p4_pd_status_t -switch_pd_egress_vni_table_delete_entry(switch_device_t device_id, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE +#ifndef TUNNEL_OVER_IPV6_DISABLE + /* ipv6 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_IPV6_NVGRE; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_nvgre_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_NVGRE; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_nvgre_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); +#endif +#endif - status = p4_pd_dc_egress_vni_table_delete(g_sess_hdl, - device_id, - entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} + /* 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); -p4_pd_status_t -switch_pd_tunnel_decap_tables_init_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +#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 -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_tunnel_decap_process_inner_match_spec_t i_match_spec; - p4_pd_dc_tunnel_decap_process_outer_match_spec_t o_match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - /* inner tcp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); - i_match_spec.inner_tcp_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_tcp( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + /* 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); - /* inner udp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); - i_match_spec.inner_udp_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_udp( - g_sess_hdl, - p4_pd_device, - &i_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 - /* inner icmp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); - i_match_spec.inner_icmp_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_icmp( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); +#ifndef P4_MPLS_DISABLE + /* mpls, ethernet, push 1 */ + 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_MPLS_L2VPN; + o_match_spec.tunnel_metadata_egress_header_count = 1; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push1_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_MPLS_L2VPN; + o_match_spec.tunnel_metadata_egress_header_count = 1; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push1_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, push 2 */ + 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_MPLS_L2VPN; + o_match_spec.tunnel_metadata_egress_header_count = 2; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push2_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_MPLS_L2VPN; + o_match_spec.tunnel_metadata_egress_header_count = 2; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push2_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ethernet, push 3 */ + 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_MPLS_L2VPN; + o_match_spec.tunnel_metadata_egress_header_count = 3; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push3_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_MPLS_L2VPN; + o_match_spec.tunnel_metadata_egress_header_count = 3; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push3_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ip, push 1 */ + 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_MPLS_L3VPN; + o_match_spec.tunnel_metadata_egress_header_count = 1; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push1_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_MPLS_L3VPN; + o_match_spec.tunnel_metadata_egress_header_count = 1; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push1_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ip, push 2 */ + 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_MPLS_L3VPN; + o_match_spec.tunnel_metadata_egress_header_count = 2; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push2_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_MPLS_L3VPN; + o_match_spec.tunnel_metadata_egress_header_count = 2; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push2_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); + + /* mpls, ip, push 3 */ + 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_MPLS_L3VPN; + o_match_spec.tunnel_metadata_egress_header_count = 3; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push3_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_MPLS_L3VPN; + o_match_spec.tunnel_metadata_egress_header_count = 3; + o_match_spec.multicast_metadata_replica = true; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push3_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - /* inner uknown */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_decap_process_inner_match_spec_t)); - status = p4_pd_dc_tunnel_decap_process_inner_table_add_with_decap_inner_unknown( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); +#endif /* P4_MPLS_DISABLE */ +#endif /* P4_TUNNEL_DISABLE */ +#ifndef P4_MIRROR_DISABLE + /* ipv4 erspan */ + 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_ERSPAN_T3; + o_match_spec.multicast_metadata_replica = false; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_erspan_t3_rewrite( + g_sess_hdl, p4_pd_device, &o_match_spec, &entry_hdl); - /* vxlan, 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_VXLAN; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_vxlan_inner_ipv4( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +#endif /* P4_MIRROR_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_rewrite_table_fabric_add_entry( + switch_device_t device, + switch_tunnel_type_egress_t tunnel_type, + uint16_t tunnel_index, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + p4_pd_dc_tunnel_encap_process_outer_match_spec_t match_spec; + p4_pd_dc_fabric_rewrite_action_spec_t action_spec; + switch (tunnel_type) { + case SWITCH_EGRESS_TUNNEL_TYPE_CPU: + memset(&match_spec, + 0, + sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_fabric_rewrite_action_spec_t)); + match_spec.tunnel_metadata_egress_tunnel_type = + SWITCH_EGRESS_TUNNEL_TYPE_CPU; + match_spec.tunnel_metadata_egress_header_count = 0; + match_spec.multicast_metadata_replica = false; + action_spec.action_tunnel_index = tunnel_index; + status = + p4_pd_dc_tunnel_encap_process_outer_table_add_with_fabric_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + break; + default: + break; + } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_rewrite_cpu_add_entry( + switch_device_t device, + uint16_t tunnel_index, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + p4_pd_dc_tunnel_rewrite_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_rewrite_match_spec_t)); + match_spec.tunnel_metadata_tunnel_index = tunnel_index; + status = p4_pd_dc_tunnel_rewrite_table_add_with_cpu_rx_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_src_rewrite_table_add_entry( + switch_device_t device, + uint16_t tunnel_src_index, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + p4_pd_dc_tunnel_src_rewrite_match_spec_t v4_match_spec; + p4_pd_dc_rewrite_tunnel_ipv4_src_action_spec_t v4_action_spec; + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_tunnel_src_rewrite_match_spec_t)); + memset(&v4_action_spec, + 0, + sizeof(p4_pd_dc_rewrite_tunnel_ipv4_src_action_spec_t)); + v4_match_spec.tunnel_metadata_tunnel_src_index = tunnel_src_index; + v4_action_spec.action_ip = SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap); + status = p4_pd_dc_tunnel_src_rewrite_table_add_with_rewrite_tunnel_ipv4_src( + g_sess_hdl, p4_pd_device, &v4_match_spec, &v4_action_spec, entry_hdl); + } else { #ifndef P4_IPV6_DISABLE - /* vxlan, 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_VXLAN; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_vxlan_inner_ipv6( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + p4_pd_dc_tunnel_src_rewrite_match_spec_t v6_match_spec; + p4_pd_dc_rewrite_tunnel_ipv6_src_action_spec_t v6_action_spec; + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_tunnel_src_rewrite_match_spec_t)); + memset(&v6_action_spec, + 0, + sizeof(p4_pd_dc_rewrite_tunnel_ipv6_src_action_spec_t)); + v6_match_spec.tunnel_metadata_tunnel_src_index = tunnel_src_index; + memcpy( + &v6_action_spec.action_ip, SWITCH_IP_ENCAP_IPV6_SRC_IP(ip_encap), 16); + status = p4_pd_dc_tunnel_src_rewrite_table_add_with_rewrite_tunnel_ipv6_src( + g_sess_hdl, p4_pd_device, &v6_match_spec, &v6_action_spec, entry_hdl); #endif /* P4_IPV6_DISABLE */ - - /* vxlan, 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_VXLAN; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_vxlan_inner_non_ip( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); - - /* geneve, 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_GENEVE; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_genv_inner_ipv4( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); - + } +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_src_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + status = + p4_pd_dc_tunnel_src_rewrite_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_dst_rewrite_table_add_entry( + switch_device_t device, + uint16_t tunnel_dst_index, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + if (SWITCH_IP_ENCAP_DST_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + p4_pd_dc_tunnel_dst_rewrite_match_spec_t v4_match_spec; + p4_pd_dc_rewrite_tunnel_ipv4_dst_action_spec_t v4_action_spec; + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_tunnel_dst_rewrite_match_spec_t)); + memset(&v4_action_spec, + 0, + sizeof(p4_pd_dc_rewrite_tunnel_ipv4_dst_action_spec_t)); + v4_match_spec.tunnel_metadata_tunnel_dst_index = tunnel_dst_index; + v4_action_spec.action_ip = SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap); + status = p4_pd_dc_tunnel_dst_rewrite_table_add_with_rewrite_tunnel_ipv4_dst( + g_sess_hdl, p4_pd_device, &v4_match_spec, &v4_action_spec, entry_hdl); + } else { #ifndef P4_IPV6_DISABLE - /* geneve, 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_GENEVE; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_genv_inner_ipv6( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + p4_pd_dc_tunnel_dst_rewrite_match_spec_t v6_match_spec; + p4_pd_dc_rewrite_tunnel_ipv6_dst_action_spec_t v6_action_spec; + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_tunnel_dst_rewrite_match_spec_t)); + memset(&v6_action_spec, + 0, + sizeof(p4_pd_dc_rewrite_tunnel_ipv6_dst_action_spec_t)); + v6_match_spec.tunnel_metadata_tunnel_dst_index = tunnel_dst_index; + memcpy( + &v6_action_spec.action_ip, SWITCH_IP_ENCAP_IPV6_DST_IP(ip_encap), 16); + status = p4_pd_dc_tunnel_dst_rewrite_table_add_with_rewrite_tunnel_ipv6_dst( + g_sess_hdl, p4_pd_device, &v6_match_spec, &v6_action_spec, entry_hdl); #endif /* P4_IPV6_DISABLE */ + } +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_dst_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + status = + p4_pd_dc_tunnel_dst_rewrite_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +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_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + switch_logical_network_t *ln_info = NULL; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + ln_info = &bd_info->ln_info; + p4_pd_dc_set_bd_properties_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_bd_properties_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); + action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); + action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); + action_spec.action_bd_label = handle_to_id(ln_info->bd_label); + action_spec.action_ipv4_unicast_enabled = + SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + action_spec.action_ipv6_unicast_enabled = + SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info); + action_spec.action_ipv4_multicast_enabled = + SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + action_spec.action_ipv6_multicast_enabled = + SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info); + action_spec.action_igmp_snooping_enabled = + SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); + action_spec.action_mld_snooping_enabled = + SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); + action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; + action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; + action_spec.action_stp_group = handle_to_id(bd_info->stp_handle); + action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); + action_spec.action_learning_enabled = SWITCH_LN_LEARN_ENABLED(bd_info); + + if (SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info)) { + action_spec.action_ipv4_mcast_key_type = 1; + action_spec.action_ipv4_mcast_key = handle_to_id(ln_info->vrf_handle); + } else { + action_spec.action_ipv4_mcast_key_type = 0; + action_spec.action_ipv4_mcast_key = bd; + } + + if (SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info)) { + action_spec.action_ipv6_mcast_key_type = 1; + action_spec.action_ipv6_mcast_key = handle_to_id(ln_info->vrf_handle); + } else { + action_spec.action_ipv6_mcast_key_type = 0; + action_spec.action_ipv6_mcast_key = bd; + } + + status = p4_pd_dc_bd_action_profile_add_member_with_set_bd_properties( + g_sess_hdl, p4_pd_device, &action_spec, &(bd_info->bd_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("bd member add failed"); + return status; + } - /* geneve, 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_GENEVE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_genv_inner_non_ip( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +#ifndef P4_MULTICAST_DISABLE + /* Unknown unicast flood */ + p4_pd_dc_bd_flood_match_spec_t flood_match_spec; + p4_pd_dc_set_bd_flood_mc_index_action_spec_t flood_action_spec; + memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); + memset(&flood_action_spec, + 0, + sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); + flood_match_spec.ingress_metadata_bd = bd; + 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); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("bd flood uuc add failed"); + p4_pd_dc_bd_action_profile_del_member( + g_sess_hdl, device, bd_info->bd_entry); + return status; + } + + /* Unknown multicast flood */ + memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); + memset(&flood_action_spec, + 0, + sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); + flood_match_spec.ingress_metadata_bd = bd; + 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); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("bd flood uuc add failed"); + p4_pd_dc_bd_action_profile_del_member( + g_sess_hdl, device, bd_info->bd_entry); -#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; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_nvgre_inner_ipv4( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +#ifndef P4_MULTICAST_DISABLE + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->uuc_entry); +#endif + return status; + } + + /* Unknown broadcast flood */ + memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); + memset(&flood_action_spec, + 0, + sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); + flood_match_spec.ingress_metadata_bd = bd; + 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); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("bd flood uuc add failed"); + p4_pd_dc_bd_action_profile_del_member( + g_sess_hdl, device, bd_info->bd_entry); -#ifndef P4_IPV6_DISABLE - /* nvgre, 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_NVGRE; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_nvgre_inner_ipv6( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif /* P4_IPV6_DISABLE */ +#ifndef P4_MULTICAST_DISABLE + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->uuc_entry); + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->umc_entry); +#endif - /* nvgre, 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_NVGRE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_nvgre_inner_non_ip( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + return status; + } #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); + 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)); + if (status != SWITCH_STATUS_SUCCESS) { + p4_pd_dc_bd_action_profile_del_member( + g_sess_hdl, device, bd_info->bd_entry); -#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 */ +#ifndef P4_MULTICAST_DISABLE + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->uuc_entry); + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->umc_entry); + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->bcast_entry); +#endif + } - /* 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); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* 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); +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_status_t status = 0; + switch_logical_network_t *ln_info = NULL; + + ln_info = &bd_info->ln_info; + + p4_pd_dc_set_bd_properties_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_bd_properties_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); + action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); + action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); + action_spec.action_bd_label = handle_to_id(ln_info->bd_label); + action_spec.action_ipv4_unicast_enabled = + SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + action_spec.action_ipv6_unicast_enabled = + SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info); + action_spec.action_ipv4_multicast_enabled = + SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + action_spec.action_ipv6_multicast_enabled = + SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info); + action_spec.action_igmp_snooping_enabled = + SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); + action_spec.action_mld_snooping_enabled = + SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); + action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; + action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; + action_spec.action_stp_group = handle_to_id(bd_info->stp_handle); + action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); + action_spec.action_learning_enabled = SWITCH_LN_LEARN_ENABLED(bd_info); + + if (SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info)) { + action_spec.action_ipv4_mcast_key_type = 1; + action_spec.action_ipv4_mcast_key = handle_to_id(ln_info->vrf_handle); + } else { + action_spec.action_ipv4_mcast_key_type = 0; + action_spec.action_ipv4_mcast_key = bd; + } + + if (SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info)) { + action_spec.action_ipv6_mcast_key_type = 1; + action_spec.action_ipv6_mcast_key = handle_to_id(ln_info->vrf_handle); + } else { + action_spec.action_ipv6_mcast_key_type = 0; + action_spec.action_ipv6_mcast_key = bd; + } + + status = p4_pd_dc_bd_action_profile_modify_member_with_set_bd_properties( + g_sess_hdl, device, bd_info->bd_entry, &action_spec); -#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_MULTICAST_DISABLE + /* Unknown unicast flood */ + p4_pd_dc_set_bd_flood_mc_index_action_spec_t flood_action_spec; + 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->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); + + /* 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); + + /* 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); +#endif -#ifndef P4_MPLS_DISABLE - /* mpls, inner_ipv4, pop 1 */ - 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_MPLS_L3VPN_NUM_LABELS_1; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv4_pop1( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* mpls, inner_ipv4, pop 2 */ - 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_MPLS_L3VPN_NUM_LABELS_2; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv4_pop2( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +p4_pd_status_t switch_pd_bd_table_delete_entry(switch_device_t device, + switch_bd_info_t *bd_info) { + p4_pd_status_t status = 0; - /* mpls, inner_ipv4, pop 3 */ - 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_MPLS_L3VPN_NUM_LABELS_3; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv4_pop3( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_port_vlan_mapping_table_delete( + g_sess_hdl, device, bd_info->cpu_entry); -#ifndef P4_IPV6_DISABLE - /* mpls, inner_ipv6, pop 1 */ - 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_MPLS_L3VPN_NUM_LABELS_1; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv6_pop1( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_bd_action_profile_del_member( + g_sess_hdl, device, bd_info->bd_entry); - /* mpls, inner_ipv6, pop 2 */ - 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_MPLS_L3VPN_NUM_LABELS_2; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv6_pop2( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +#ifndef P4_MULTICAST_DISABLE + status = + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->uuc_entry); + status = + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->umc_entry); + status = + p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, bd_info->bcast_entry); +#endif - /* mpls, inner_ipv6, pop 3 */ - 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_MPLS_L3VPN_NUM_LABELS_3; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ipv6_pop3( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif /* P4_IPV6_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* mpls, ethernet, inner_ipv4, pop 1 */ - 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_MPLS_L2VPN_NUM_LABELS_1; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv4_pop1( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +p4_pd_status_t switch_pd_egress_bd_map_table_add_entry( + switch_device_t device, + switch_handle_t bd_handle, + switch_bd_info_t *bd_info) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_egress_bd_map_match_spec_t match_spec; + p4_pd_dc_set_egress_bd_properties_action_spec_t action_spec; - /* mpls, ethernet, inner_ipv4, pop 2 */ - 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_MPLS_L2VPN_NUM_LABELS_2; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv4_pop2( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - /* mpls, ethernet, inner_ipv4, pop 3 */ - 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_MPLS_L2VPN_NUM_LABELS_3; - o_match_spec.inner_ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv4_pop3( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + match_spec.egress_metadata_bd = handle_to_id(bd_handle); + action_spec.action_smac_idx = bd_info->smac_index; + action_spec.action_nat_mode = SWITCH_LN_NAT_MODE(bd_info); -#ifndef P4_IPV6_DISABLE - /* mpls, ethernet, inner_ipv6, pop 1 */ - 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_MPLS_L2VPN_NUM_LABELS_1; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv6_pop1( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_egress_bd_map_table_add_with_set_egress_bd_properties( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &bd_info->egress_bd_entry); - /* mpls, ethernet, inner_ipv6, pop 2 */ - 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_MPLS_L2VPN_NUM_LABELS_2; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv6_pop2( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* mpls, ethernet, inner_ipv6, pop 3 */ - 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_MPLS_L2VPN_NUM_LABELS_3; - o_match_spec.inner_ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_ipv6_pop3( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif /* P4_IPV6_DISABLE */ +p4_pd_status_t switch_pd_egress_bd_map_table_update_entry( + switch_device_t device, + switch_handle_t bd_handle, + switch_bd_info_t *bd_info) { + p4_pd_status_t status = 0; + p4_pd_dc_egress_bd_map_match_spec_t match_spec; + p4_pd_dc_set_egress_bd_properties_action_spec_t action_spec; - /* mpls, ethernet, non_ip, pop 1 */ - 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_MPLS_L2VPN_NUM_LABELS_1; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_non_ip_pop1( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + match_spec.egress_metadata_bd = handle_to_id(bd_handle); + action_spec.action_smac_idx = bd_info->smac_index; + action_spec.action_nat_mode = SWITCH_LN_NAT_MODE(bd_info); - /* mpls, ethernet, inner_ipv6, pop 2 */ - 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_MPLS_L2VPN_NUM_LABELS_2; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_non_ip_pop2( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_egress_bd_map_table_modify_with_set_egress_bd_properties( + g_sess_hdl, device, bd_info->egress_bd_entry, &action_spec); - /* mpls, ethernet, inner_ipv6, pop 3 */ - 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_MPLS_L2VPN_NUM_LABELS_3; - status = p4_pd_dc_tunnel_decap_process_outer_table_add_with_decap_mpls_inner_ethernet_non_ip_pop3( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif /* P4_MPLS_DISABLE */ -#endif /* P4_TUNNEL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} - p4_pd_complete_operations(g_sess_hdl); +p4_pd_status_t switch_pd_egress_bd_map_table_delete_entry( + switch_device_t device, switch_bd_info_t *bd_info) { + p4_pd_status_t status = 0; + if (!bd_info->egress_bd_entry) { return status; -} + } -p4_pd_status_t -switch_pd_tunnel_encap_tables_init_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; + status = p4_pd_dc_egress_bd_map_table_delete( + g_sess_hdl, device, bd_info->egress_bd_entry); -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_tunnel_encap_process_inner_match_spec_t i_match_spec; - p4_pd_dc_tunnel_encap_process_outer_match_spec_t o_match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - /* ipv4, tcp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv4_valid = TRUE; - i_match_spec.tcp_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_tcp_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); - - /* ipv4, udp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv4_valid = TRUE; - i_match_spec.udp_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_udp_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* ipv4, icmp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv4_valid = TRUE; - i_match_spec.icmp_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_icmp_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); +p4_pd_status_t switch_pd_egress_bd_stats_table_add_entry( + switch_device_t device, uint16_t bd, p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_STATS_DISABLE + int index = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_egress_bd_stats_match_spec_t match_spec; - /* ipv4, uknown */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv4_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv4_unknown_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - /* ipv6, tcp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv6_valid = TRUE; - i_match_spec.tcp_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_tcp_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + memset(&match_spec, 0, sizeof(p4_pd_dc_egress_bd_stats_match_spec_t)); - /* ipv6, udp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv6_valid = TRUE; - i_match_spec.udp_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_udp_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + match_spec.egress_metadata_bd = bd; + match_spec.l2_metadata_lkp_pkt_type = 1; - /* ipv6, icmp */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv6_valid = TRUE; - i_match_spec.icmp_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_icmp_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + status = p4_pd_dc_egress_bd_stats_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl[index++]); - /* ipv6, uknown */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - i_match_spec.ipv6_valid = TRUE; - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_ipv6_unknown_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + match_spec.l2_metadata_lkp_pkt_type = 2; + status = p4_pd_dc_egress_bd_stats_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl[index++]); - /* non ip */ - memset(&i_match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_inner_match_spec_t)); - status = p4_pd_dc_tunnel_encap_process_inner_table_add_with_inner_non_ip_rewrite( - g_sess_hdl, - p4_pd_device, - &i_match_spec, - &entry_hdl); + match_spec.l2_metadata_lkp_pkt_type = 4; + status = p4_pd_dc_egress_bd_stats_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl[index++]); +#endif /* P4_STATS_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* default entry */ - status = p4_pd_dc_tunnel_encap_process_outer_set_default_action_nop( - g_sess_hdl, - p4_pd_device, - &entry_hdl); +p4_pd_status_t switch_pd_egress_bd_stats_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_STATS_DISABLE + int index = 0; - /* ipv4 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_IPV4_VXLAN; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_vxlan_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_VXLAN; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_vxlan_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_egress_bd_stats_table_delete( + g_sess_hdl, device, entry_hdl[index++]); -#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; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_vxlan_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_VXLAN; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_vxlan_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif + status = p4_pd_dc_egress_bd_stats_table_delete( + g_sess_hdl, device, entry_hdl[index++]); - /* ipv4 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_IPV4_GENEVE; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_genv_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_GENEVE; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_genv_rewrite( + status = p4_pd_dc_egress_bd_stats_table_delete( + g_sess_hdl, device, entry_hdl[index++]); +#endif /* P4_STATS_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_port_vlan_mapping_table_add_entry( + switch_device_t device, + switch_vlan_t vlan_id0, + switch_vlan_t vlan_id1, + switch_interface_info_t *info, + p4_pd_mbr_hdl_t bd_hdl, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dc_port_vlan_mapping_match_spec_t match_spec; + 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_port_vlan_mapping_match_spec_t)); + + match_spec.ingress_metadata_ifindex = info->ifindex; + if (vlan_id0) { + match_spec.vlan_tag__0__valid = TRUE; + match_spec.vlan_tag__0__vid = vlan_id0; + } + if (vlan_id1) { + match_spec.vlan_tag__1__valid = TRUE; + 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); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_port_vlan_mapping_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + + status = + p4_pd_dc_port_vlan_mapping_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +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) { + p4_pd_status_t status = 0; + p4_pd_dc_egress_vlan_xlate_match_spec_t match_spec; + p4_pd_dc_set_egress_packet_vlan_tagged_action_spec_t action_spec; + 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_egress_vlan_xlate_match_spec_t)); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_egress_packet_vlan_tagged_action_spec_t)); + + match_spec.egress_metadata_ifindex = ifindex; + match_spec.egress_metadata_bd = egress_bd; + if (vlan_id != 0) { + action_spec.action_vlan_id = vlan_id; + status = + p4_pd_dc_egress_vlan_xlate_table_add_with_set_egress_packet_vlan_tagged( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } else { + status = + p4_pd_dc_egress_vlan_xlate_table_add_with_set_egress_packet_vlan_untagged( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); + } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_egress_vlan_xlate_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + status = + p4_pd_dc_egress_vlan_xlate_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ingress_port_mapping_table_add_entry( + switch_device_t device, + switch_ifindex_t ifindex, + switch_port_info_t *port_info) { + 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(&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)); + + match1_spec.standard_metadata_ingress_port = SWITCH_PORT_ID(port_info); + action1_spec.action_ifindex = ifindex; + action1_spec.action_port_type = port_info->port_type; + + match2_spec.standard_metadata_ingress_port = SWITCH_PORT_ID(port_info); + action2_spec.action_if_label = SWITCH_PORT_ID(port_info); + action2_spec.action_qos_group = port_info->ingress_qos_group; + action2_spec.action_tc_qos_group = port_info->tc_qos_group; + action2_spec.action_tc = port_info->tc; + action2_spec.action_trust_dscp = port_info->trust_dscp; + action2_spec.action_trust_pcp = port_info->trust_pcp; + + modify = (port_info->hw_entry[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, port_info->hw_entry[0], &action1_spec); + status = + p4_pd_dc_ingress_port_properties_table_modify_with_set_ingress_port_properties( + g_sess_hdl, 0, port_info->hw_entry[1], &action2_spec); + } else { + status = p4_pd_dc_ingress_port_mapping_table_add_with_set_ifindex( g_sess_hdl, p4_pd_device, - &o_match_spec, - &entry_hdl); + &match1_spec, + &action1_spec, + &port_info->hw_entry[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, + &port_info->hw_entry[1]); + } + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +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 status = 0; + + 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; +} + +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, + switch_qos_group_t qos_group, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_dc_egress_port_mapping_match_spec_t match_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(match_spec)); + + modify = (*entry_hdl != SWITCH_HW_INVALID_HANDLE) ? TRUE : FALSE; + if (!modify) { + match_spec.standard_metadata_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; + action_spec.action_qos_group = qos_group; + status = + p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_normal( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } else if (port_type == SWITCH_PORT_TYPE_FABRIC) { + p4_pd_dc_egress_port_type_fabric_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_ifindex = ifindex; + status = + p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_fabric( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } else if (port_type == SWITCH_PORT_TYPE_CPU) { + p4_pd_dc_egress_port_type_cpu_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_ifindex = ifindex; + status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_cpu( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } + } else { + 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; + action_spec.action_qos_group = qos_group; + status = + p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_normal( + g_sess_hdl, device, *entry_hdl, &action_spec); + } else if (port_type == SWITCH_PORT_TYPE_FABRIC) { + p4_pd_dc_egress_port_type_fabric_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_ifindex = ifindex; + status = + p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_fabric( + g_sess_hdl, device, *entry_hdl, &action_spec); + } else if (port_type == SWITCH_PORT_TYPE_CPU) { + p4_pd_dc_egress_port_type_cpu_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_ifindex = ifindex; + status = + p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_cpu( + g_sess_hdl, device, *entry_hdl, &action_spec); + } + } -#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; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_genv_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_GENEVE; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_genv_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif + p4_pd_complete_operations(g_sess_hdl); + return status; +} -#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; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_nvgre_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_NVGRE; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_nvgre_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &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 status = 0; - /* ipv6 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_IPV6_NVGRE; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_nvgre_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_NVGRE; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv6_nvgre_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); -#endif + status = + p4_pd_dc_egress_port_mapping_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* 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); +p4_pd_status_t switch_pd_rewrite_table_unicast_rewrite_add_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_rw_type_t rw_type, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_dc_rewrite_match_spec_t match_spec; + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; -#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 + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - /* 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); + memset(&match_spec, 0, sizeof(p4_pd_dc_rewrite_match_spec_t)); + match_spec.l3_metadata_nexthop_index = nhop_index; -#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 + if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { + status = p4_pd_dc_rewrite_table_add_with_set_l2_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); + } else { +#ifndef P4_L3_DISABLE + p4_pd_dc_set_l3_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_l3_rewrite_action_spec_t)); + action_spec.action_bd = bd; + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); -#ifndef P4_MPLS_DISABLE - /* mpls, ethernet, push 1 */ - 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_MPLS_L2VPN; - o_match_spec.tunnel_metadata_egress_header_count = 1; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push1_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_MPLS_L2VPN; - o_match_spec.tunnel_metadata_egress_header_count = 1; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push1_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_rewrite_table_add_with_set_l3_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_L3_DISABLE */ + } + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_rewrite_table_tunnel_rewrite_add_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_type_t neigh_type, + switch_neighbor_rw_type_t rw_type, + uint16_t tunnel_index, + switch_encap_type_t encap_type, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_dc_rewrite_match_spec_t match_spec; + 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_rewrite_match_spec_t)); + match_spec.l3_metadata_nexthop_index = nhop_index; + + switch_tunnel_type_egress_t tunnel_type; + switch (encap_type) { + case SWITCH_API_ENCAP_TYPE_VXLAN: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; + } + break; + case SWITCH_API_ENCAP_TYPE_GENEVE: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; + } + break; + case SWITCH_API_ENCAP_TYPE_NVGRE: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE; + } + break; + case SWITCH_API_ENCAP_TYPE_ERSPAN_T3: +#ifndef MIRROR_DISABLE + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3; + } +#endif /* MIRROR_DISABLE */ + 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; + } + + if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { + p4_pd_dc_set_l2_rewrite_with_tunnel_action_spec_t action_spec; + action_spec.action_tunnel_type = tunnel_type; + action_spec.action_tunnel_index = tunnel_index; + status = p4_pd_dc_rewrite_table_add_with_set_l2_rewrite_with_tunnel( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } else { +#ifndef P4_L3_DISABLE + p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t)); + action_spec.action_bd = bd; + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); + action_spec.action_tunnel_type = tunnel_type; + action_spec.action_tunnel_index = tunnel_index; + status = p4_pd_dc_rewrite_table_add_with_set_l3_rewrite_with_tunnel( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_L3_DISABLE */ + } +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_rewrite_table_unicast_rewrite_update_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_rw_type_t rw_type, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + + UNUSED(bd); + UNUSED(nhop_index); + if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { + status = p4_pd_dc_rewrite_table_modify_with_set_l2_rewrite( + g_sess_hdl, device, entry_hdl); + } else { +#ifndef P4_L3_DISABLE + p4_pd_dc_set_l3_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_l3_rewrite_action_spec_t)); + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); + status = p4_pd_dc_rewrite_table_modify_with_set_l3_rewrite( + g_sess_hdl, device, entry_hdl, &action_spec); +#endif /* P4_L3_DISABLE */ + } + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_rewrite_table_tunnel_rewrite_update_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_type_t neigh_type, + switch_neighbor_rw_type_t rw_type, + uint16_t tunnel_index, + switch_encap_type_t encap_type, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + + UNUSED(nhop_index); +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + switch_tunnel_type_egress_t tunnel_type; + switch (encap_type) { + case SWITCH_API_ENCAP_TYPE_VXLAN: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; + } + break; + case SWITCH_API_ENCAP_TYPE_GENEVE: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; + } + break; + case SWITCH_API_ENCAP_TYPE_NVGRE: + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE; + } + break; + case SWITCH_API_ENCAP_TYPE_ERSPAN_T3: +#ifndef MIRROR_DISABLE + if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3; + } +#endif /* MIRROR_DISABLE */ + 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; + } + + if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { + p4_pd_dc_set_l2_rewrite_with_tunnel_action_spec_t action_spec; + action_spec.action_tunnel_type = tunnel_type; + action_spec.action_tunnel_index = tunnel_index; + status = p4_pd_dc_rewrite_table_modify_with_set_l2_rewrite_with_tunnel( + g_sess_hdl, device, entry_hdl, &action_spec); + } else { +#ifndef P4_L3_DISABLE + p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t)); + action_spec.action_bd = bd; + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); + action_spec.action_tunnel_type = tunnel_type; + action_spec.action_tunnel_index = tunnel_index; + status = p4_pd_dc_rewrite_table_modify_with_set_l3_rewrite_with_tunnel( + g_sess_hdl, device, entry_hdl, &action_spec); +#endif /* P4_L3_DISABLE */ + } +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ - /* mpls, ethernet, push 2 */ - 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_MPLS_L2VPN; - o_match_spec.tunnel_metadata_egress_header_count = 2; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push2_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_MPLS_L2VPN; - o_match_spec.tunnel_metadata_egress_header_count = 2; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push2_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* mpls, ethernet, push 3 */ - 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_MPLS_L2VPN; - o_match_spec.tunnel_metadata_egress_header_count = 3; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push3_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_MPLS_L2VPN; - o_match_spec.tunnel_metadata_egress_header_count = 3; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ethernet_push3_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +p4_pd_status_t switch_pd_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; - /* mpls, ip, push 1 */ - 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_MPLS_L3VPN; - o_match_spec.tunnel_metadata_egress_header_count = 1; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push1_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_MPLS_L3VPN; - o_match_spec.tunnel_metadata_egress_header_count = 1; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push1_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_rewrite_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - /* mpls, ip, push 2 */ - 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_MPLS_L3VPN; - o_match_spec.tunnel_metadata_egress_header_count = 2; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push2_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_MPLS_L3VPN; - o_match_spec.tunnel_metadata_egress_header_count = 2; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push2_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); +p4_pd_status_t switch_pd_lag_group_create(switch_device_t device, + p4_pd_grp_hdl_t *pd_group_hdl) { + switch_status_t status = 0; + p4_pd_dev_target_t pd_device; - /* mpls, ip, push 3 */ - 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_MPLS_L3VPN; - o_match_spec.tunnel_metadata_egress_header_count = 3; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push3_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_MPLS_L3VPN; - o_match_spec.tunnel_metadata_egress_header_count = 3; - o_match_spec.multicast_metadata_replica = true; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_mpls_ip_push3_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + pd_device.device_id = device; + pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -#endif /* P4_MPLS_DISABLE */ -#ifndef P4_MIRROR_DISABLE - /* ipv4 erspan */ - 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_ERSPAN_T3; - o_match_spec.multicast_metadata_replica = false; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_ipv4_erspan_t3_rewrite( - g_sess_hdl, - p4_pd_device, - &o_match_spec, - &entry_hdl); + status = p4_pd_dc_lag_action_profile_create_group( + g_sess_hdl, pd_device, MAX_LAG_GROUP_SIZE, pd_group_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} -#endif /* P4_MIRROR_DISABLE */ -#endif /* P4_TUNNEL_DISABLE */ +p4_pd_status_t switch_pd_lag_group_delete(switch_device_t device, + p4_pd_grp_hdl_t pd_group_hdl) { + switch_status_t status = 0; - p4_pd_complete_operations(g_sess_hdl); - return status; + status = + p4_pd_dc_lag_action_profile_del_group(g_sess_hdl, device, pd_group_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_rewrite_table_fabric_add_entry(switch_device_t device, - switch_tunnel_type_egress_t tunnel_type, - uint16_t tunnel_index, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - p4_pd_dc_tunnel_encap_process_outer_match_spec_t match_spec; - p4_pd_dc_fabric_rewrite_action_spec_t action_spec; - switch (tunnel_type) { - case SWITCH_EGRESS_TUNNEL_TYPE_CPU: - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_encap_process_outer_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_fabric_rewrite_action_spec_t)); - match_spec.tunnel_metadata_egress_tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_CPU; - match_spec.tunnel_metadata_egress_header_count = 0; - match_spec.multicast_metadata_replica = false; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_tunnel_encap_process_outer_table_add_with_fabric_rewrite( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - break; - default: - break; - } - p4_pd_complete_operations(g_sess_hdl); - return status; -} +p4_pd_status_t switch_pd_lag_group_table_add_entry( + switch_device_t device, + switch_ifindex_t ifindex, + unsigned int port, + p4_pd_mbr_hdl_t *mbr_hdl, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dc_lag_group_match_spec_t lg_match_spec; + bool modify = FALSE; + p4_pd_dev_target_t pd_device; + p4_pd_dc_set_lag_port_action_spec_t action_spec; -p4_pd_status_t -switch_pd_tunnel_rewrite_cpu_add_entry(switch_device_t device, - uint16_t tunnel_index, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; + pd_device.device_id = device; + pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + memset(&lg_match_spec, 0, sizeof(p4_pd_dc_lag_group_match_spec_t)); - p4_pd_dc_tunnel_rewrite_match_spec_t match_spec; - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_rewrite_match_spec_t)); - match_spec.tunnel_metadata_tunnel_index = tunnel_index; - status = p4_pd_dc_tunnel_rewrite_table_add_with_cpu_rx_rewrite( - g_sess_hdl, - p4_pd_device, - &match_spec, - entry_hdl); + lg_match_spec.ingress_metadata_egress_ifindex = ifindex; - p4_pd_complete_operations(g_sess_hdl); - return status; -} + memset(&action_spec, 0, sizeof(p4_pd_dc_set_lag_port_action_spec_t)); + action_spec.action_port = port; -p4_pd_status_t -switch_pd_tunnel_src_rewrite_table_add_entry(switch_device_t device, - uint16_t tunnel_src_index, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { - p4_pd_dc_tunnel_src_rewrite_match_spec_t v4_match_spec; - p4_pd_dc_rewrite_tunnel_ipv4_src_action_spec_t v4_action_spec; - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_tunnel_src_rewrite_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_ipv4_src_action_spec_t)); - v4_match_spec.tunnel_metadata_tunnel_src_index = tunnel_src_index; - v4_action_spec.action_ip = SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap); - status = p4_pd_dc_tunnel_src_rewrite_table_add_with_rewrite_tunnel_ipv4_src( - g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } else { -#ifndef P4_IPV6_DISABLE - p4_pd_dc_tunnel_src_rewrite_match_spec_t v6_match_spec; - p4_pd_dc_rewrite_tunnel_ipv6_src_action_spec_t v6_action_spec; - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_tunnel_src_rewrite_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_ipv6_src_action_spec_t)); - v6_match_spec.tunnel_metadata_tunnel_src_index = tunnel_src_index; - memcpy(&v6_action_spec.action_ip, SWITCH_IP_ENCAP_IPV6_SRC_IP(ip_encap), 16); - status = p4_pd_dc_tunnel_src_rewrite_table_add_with_rewrite_tunnel_ipv6_src( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); -#endif /* P4_IPV6_DISABLE */ - } -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + modify = (*entry_hdl != 0) ? TRUE : FALSE; + if (modify) { +#if 0 + // TBD + status = p4_pd_dc_lag_group_modify_entry(g_sess_hdl, 0, + *entry_hdl, + &lg_action_spec); +#endif + } else { + status = p4_pd_dc_lag_action_profile_add_member_with_set_lag_port( + g_sess_hdl, pd_device, &action_spec, mbr_hdl); + status = p4_pd_dc_lag_group_add_entry( + g_sess_hdl, pd_device, &lg_match_spec, *mbr_hdl, entry_hdl); + } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_lag_group_table_add_entry_with_selector( + switch_device_t device, + switch_ifindex_t ifindex, + p4_pd_grp_hdl_t pd_group_hdl, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dc_lag_group_match_spec_t lg_match_spec; + bool modify = FALSE; + p4_pd_dev_target_t pd_device; + + pd_device.device_id = device; + pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&lg_match_spec, 0, sizeof(p4_pd_dc_lag_group_match_spec_t)); + + lg_match_spec.ingress_metadata_egress_ifindex = ifindex; + + modify = (*entry_hdl != 0) ? TRUE : FALSE; + if (modify) { +#if 0 + // TBD + status = p4_pd_dc_lag_group_modify_entry(g_sess_hdl, 0, + *entry_hdl, + &lg_action_spec); +#endif + } else { + status = p4_pd_dc_lag_group_add_entry_with_selector( + g_sess_hdl, pd_device, &lg_match_spec, pd_group_hdl, entry_hdl); + } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_lag_member_add(switch_device_t device, + p4_pd_grp_hdl_t pd_group_hdl, + unsigned int port, + p4_pd_mbr_hdl_t *mbr_hdl) { + p4_pd_dev_target_t pd_device; + p4_pd_dc_set_lag_port_action_spec_t action_spec; + + pd_device.device_id = device; + pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + action_spec.action_port = port; + p4_pd_dc_lag_action_profile_add_member_with_set_lag_port( + g_sess_hdl, pd_device, &action_spec, mbr_hdl); + p4_pd_dc_lag_action_profile_add_member_to_group( + g_sess_hdl, device, pd_group_hdl, *mbr_hdl); + p4_pd_complete_operations(g_sess_hdl); + return 0; +} + +p4_pd_status_t switch_pd_lag_member_delete(switch_device_t device, + p4_pd_grp_hdl_t pd_group_hdl, + p4_pd_mbr_hdl_t mbr_hdl) { + p4_pd_dc_lag_action_profile_del_member_from_group( + g_sess_hdl, device, pd_group_hdl, mbr_hdl); + + p4_pd_dc_lag_action_profile_del_member(g_sess_hdl, device, mbr_hdl); + p4_pd_complete_operations(g_sess_hdl); + return 0; +} + +p4_pd_status_t switch_pd_lag_group_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + status = p4_pd_dc_lag_group_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_smac_rewrite_table_add_entry( + switch_device_t device, switch_smac_entry_t *smac_entry) { + p4_pd_status_t status = 0; +#ifndef P4_L3_DISABLE + p4_pd_dc_smac_rewrite_match_spec_t match_spec; + p4_pd_dc_rewrite_smac_action_spec_t action_spec; + 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_smac_rewrite_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_rewrite_smac_action_spec_t)); + match_spec.egress_metadata_smac_idx = smac_entry->smac_index; + memcpy(action_spec.action_smac, &smac_entry->mac, ETH_LEN); + + status = p4_pd_dc_smac_rewrite_table_add_with_rewrite_smac( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &smac_entry->hw_smac_entry); +#endif /* P4_L3_DISABLE */ + + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_src_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE +p4_pd_status_t switch_pd_smac_rewrite_table_delete_entry( + switch_device_t device, switch_smac_entry_t *smac_entry) { + p4_pd_status_t status = 0; +#ifndef P4_L3_DISABLE + status = p4_pd_dc_smac_rewrite_table_delete( + g_sess_hdl, device, smac_entry->hw_smac_entry); +#endif /* P4_L3_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_rid_table_add_entry(switch_device_t device, + uint16_t rid, + uint32_t bd, + bool inner_replica, + uint8_t tunnel_type, + uint16_t tunnel_index, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + p4_pd_dc_rid_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; - status = p4_pd_dc_tunnel_src_rewrite_table_delete(g_sess_hdl, - device, - entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -p4_pd_status_t -switch_pd_tunnel_dst_rewrite_table_add_entry(switch_device_t device, - uint16_t tunnel_dst_index, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - if (SWITCH_IP_ENCAP_DST_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { - p4_pd_dc_tunnel_dst_rewrite_match_spec_t v4_match_spec; - p4_pd_dc_rewrite_tunnel_ipv4_dst_action_spec_t v4_action_spec; - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_tunnel_dst_rewrite_match_spec_t)); - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_ipv4_dst_action_spec_t)); - v4_match_spec.tunnel_metadata_tunnel_dst_index = tunnel_dst_index; - v4_action_spec.action_ip = SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap); - status = p4_pd_dc_tunnel_dst_rewrite_table_add_with_rewrite_tunnel_ipv4_dst( - g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } else { -#ifndef P4_IPV6_DISABLE - p4_pd_dc_tunnel_dst_rewrite_match_spec_t v6_match_spec; - p4_pd_dc_rewrite_tunnel_ipv6_dst_action_spec_t v6_action_spec; - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_tunnel_dst_rewrite_match_spec_t)); - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_rewrite_tunnel_ipv6_dst_action_spec_t)); - v6_match_spec.tunnel_metadata_tunnel_dst_index = tunnel_dst_index; - memcpy(&v6_action_spec.action_ip, SWITCH_IP_ENCAP_IPV6_DST_IP(ip_encap), 16); - status = p4_pd_dc_tunnel_dst_rewrite_table_add_with_rewrite_tunnel_ipv6_dst( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); -#endif /* P4_IPV6_DISABLE */ - } -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + memset(&match_spec, 0, sizeof(p4_pd_dc_rid_match_spec_t)); + match_spec.intrinsic_metadata_egress_rid = rid; + + if (!inner_replica) { + p4_pd_dc_outer_replica_from_rid_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_outer_replica_from_rid_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_tunnel_type = tunnel_type; + action_spec.action_tunnel_index = tunnel_index; + status = p4_pd_dc_rid_table_add_with_outer_replica_from_rid( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } else { + p4_pd_dc_inner_replica_from_rid_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_inner_replica_from_rid_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_tunnel_type = tunnel_type; + action_spec.action_tunnel_index = tunnel_index; + status = p4_pd_dc_rid_table_add_with_inner_replica_from_rid( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } +#endif /* P4_MULTICAST_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_dst_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE +p4_pd_status_t switch_pd_rid_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE - status = p4_pd_dc_tunnel_dst_rewrite_table_delete(g_sess_hdl, - device, - entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_rid_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_MULTICAST_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -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_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - switch_logical_network_t *ln_info = NULL; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +p4_pd_status_t switch_pd_spanning_tree_table_add_entry( + switch_device_t device, + uint16_t stp_group, + switch_ifindex_t ifindex, + switch_stp_state_t stp_state, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L2_DISABLE) && !defined(P4_STP_DISABLE) + p4_pd_dc_spanning_tree_match_spec_t match_spec; + p4_pd_dc_set_stp_state_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; - ln_info = &bd_info->ln_info; - p4_pd_dc_set_bd_properties_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_bd_properties_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); - action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); - action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); - action_spec.action_bd_label = handle_to_id(ln_info->bd_label); - action_spec.action_ipv4_unicast_enabled = - SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - action_spec.action_ipv6_unicast_enabled = - SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info); - action_spec.action_ipv4_multicast_enabled = - SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - action_spec.action_ipv6_multicast_enabled = - SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info); - action_spec.action_igmp_snooping_enabled = - SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); - action_spec.action_mld_snooping_enabled = - SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); - action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; - action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; - action_spec.action_stp_group = handle_to_id(bd_info->stp_handle); - action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); - action_spec.action_learning_enabled = SWITCH_LN_LEARN_ENABLED(bd_info); - - if (SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info)) { - action_spec.action_ipv4_mcast_key_type = 1; - action_spec.action_ipv4_mcast_key = handle_to_id(ln_info->vrf_handle); - } else { - action_spec.action_ipv4_mcast_key_type = 0; - action_spec.action_ipv4_mcast_key = bd; - } + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - if (SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info)) { - action_spec.action_ipv6_mcast_key_type = 1; - action_spec.action_ipv6_mcast_key = handle_to_id(ln_info->vrf_handle); - } else { - action_spec.action_ipv6_mcast_key_type = 0; - action_spec.action_ipv6_mcast_key = bd; - } + memset(&match_spec, 0, sizeof(p4_pd_dc_spanning_tree_match_spec_t)); + memset(&action_spec, 0, sizeof(p4_pd_dc_set_stp_state_action_spec_t)); - status = p4_pd_dc_bd_action_profile_add_member_with_set_bd_properties( - g_sess_hdl, p4_pd_device, &action_spec, &(bd_info->bd_entry)); + match_spec.ingress_metadata_ifindex = ifindex; + match_spec.l2_metadata_stp_group = stp_group; + action_spec.action_stp_state = stp_state; -#ifndef P4_MULTICAST_DISABLE - /* Unknown unicast flood */ - p4_pd_dc_bd_flood_match_spec_t flood_match_spec; - p4_pd_dc_set_bd_flood_mc_index_action_spec_t flood_action_spec; - memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); - memset(&flood_action_spec, 0, - sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); - flood_match_spec.ingress_metadata_bd = bd; - 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); - - /* Unknown multicast flood */ - memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); - memset(&flood_action_spec, 0, - sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); - flood_match_spec.ingress_metadata_bd = bd; - 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); - - /* Unknown broadcast flood */ - memset(&flood_match_spec, 0, sizeof(p4_pd_dc_bd_flood_match_spec_t)); - memset(&flood_action_spec, 0, - sizeof(p4_pd_dc_set_bd_flood_mc_index_action_spec_t)); - flood_match_spec.ingress_metadata_bd = bd; - 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); -#endif + status = p4_pd_dc_spanning_tree_table_add_with_set_stp_state( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_L2_DISABLE && P4_STP_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_spanning_tree_table_update_entry( + switch_device_t device, + uint16_t stp_group, + switch_ifindex_t ifindex, + switch_stp_state_t stp_state, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + UNUSED(stp_group); + UNUSED(ifindex); +#if !defined(P4_L2_DISABLE) && !defined(P4_STP_DISABLE) + p4_pd_dc_set_stp_state_action_spec_t action_spec; - 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)); + memset(&action_spec, 0, sizeof(p4_pd_dc_set_stp_state_action_spec_t)); + action_spec.action_stp_state = stp_state; - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_spanning_tree_table_modify_with_set_stp_state( + g_sess_hdl, device, entry_hdl, &action_spec); +#endif /* P4_L2_DISABLE && P4_STP_DISABLE */ + 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_status_t status = 0; - switch_logical_network_t *ln_info = NULL; - - ln_info = &bd_info->ln_info; - - p4_pd_dc_set_bd_properties_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_bd_properties_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_vrf = handle_to_id(ln_info->vrf_handle); - action_spec.action_rmac_group = handle_to_id(ln_info->rmac_handle); - action_spec.action_mrpf_group = handle_to_id(ln_info->mrpf_group); - action_spec.action_bd_label = handle_to_id(ln_info->bd_label); - action_spec.action_ipv4_unicast_enabled = - SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - action_spec.action_ipv6_unicast_enabled = - SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info); - action_spec.action_ipv4_multicast_enabled = - SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - action_spec.action_ipv6_multicast_enabled = - SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info); - action_spec.action_igmp_snooping_enabled = - SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); - action_spec.action_mld_snooping_enabled = - SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); - action_spec.action_ipv4_urpf_mode = bd_info->ipv4_urpf_mode; - action_spec.action_ipv6_urpf_mode = bd_info->ipv6_urpf_mode; - action_spec.action_stp_group = handle_to_id(bd_info->stp_handle); - action_spec.action_stats_idx = SWITCH_BD_STATS_START_INDEX(bd_info); - action_spec.action_learning_enabled = SWITCH_LN_LEARN_ENABLED(bd_info); - - if (SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info)) { - action_spec.action_ipv4_mcast_key_type = 1; - action_spec.action_ipv4_mcast_key = handle_to_id(ln_info->vrf_handle); - } else { - action_spec.action_ipv4_mcast_key_type = 0; - action_spec.action_ipv4_mcast_key = bd; - } - - if (SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info)) { - action_spec.action_ipv6_mcast_key_type = 1; - action_spec.action_ipv6_mcast_key = handle_to_id(ln_info->vrf_handle); - } else { - action_spec.action_ipv6_mcast_key_type = 0; - action_spec.action_ipv6_mcast_key = bd; - } - - status = p4_pd_dc_bd_action_profile_modify_member_with_set_bd_properties( - g_sess_hdl, device, bd_info->bd_entry, &action_spec); - -#ifndef P4_MULTICAST_DISABLE - /* Unknown unicast flood */ - p4_pd_dc_set_bd_flood_mc_index_action_spec_t flood_action_spec; - 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->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); - - /* 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); - - /* 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); -#endif - - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_spanning_tree_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L2_DISABLE) && !defined(P4_STP_DISABLE) + status = p4_pd_dc_spanning_tree_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_L2_DISABLE && P4_STP_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_bd_table_delete_entry(switch_device_t device, - switch_bd_info_t *bd_info) -{ - p4_pd_status_t status = 0; - - status = p4_pd_dc_bd_action_profile_del_member(g_sess_hdl, device, - bd_info->bd_entry); - -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, - bd_info->uuc_entry); - status = p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, - bd_info->umc_entry); - status = p4_pd_dc_bd_flood_table_delete(g_sess_hdl, device, - bd_info->bcast_entry); -#endif +p4_pd_status_t switch_pd_urpf_bd_table_add_entry(switch_device_t device, + uint16_t urpf_group, + uint16_t bd_index, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_urpf_bd_match_spec_t match_spec; - status = p4_pd_dc_port_vlan_mapping_table_delete(g_sess_hdl, device, - bd_info->cpu_entry); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - p4_pd_complete_operations(g_sess_hdl); - return status; + memset(&match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); + match_spec.l3_metadata_urpf_bd_group = urpf_group; + match_spec.ingress_metadata_bd = bd_index; + status = p4_pd_dc_urpf_bd_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); +#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_egress_bd_map_table_add_entry(switch_device_t device, - switch_handle_t bd_handle, - switch_bd_info_t *bd_info) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_egress_bd_map_match_spec_t match_spec; - p4_pd_dc_set_egress_bd_properties_action_spec_t action_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(match_spec)); - memset(&action_spec, 0, sizeof(action_spec)); - match_spec.egress_metadata_bd = handle_to_id(bd_handle); - action_spec.action_smac_idx = bd_info->smac_index; - - status = p4_pd_dc_egress_bd_map_table_add_with_set_egress_bd_properties( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &bd_info->egress_bd_entry); +p4_pd_status_t switch_pd_urpf_bd_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_urpf_bd_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_egress_bd_map_table_update_entry(switch_device_t device, - switch_handle_t bd_handle, - switch_bd_info_t *bd_info) -{ - p4_pd_status_t status = 0; - p4_pd_dc_egress_bd_map_match_spec_t match_spec; - p4_pd_dc_set_egress_bd_properties_action_spec_t action_spec; +p4_pd_status_t switch_pd_urpf_add_entry(switch_device_t device, + switch_vrf_id_t vrf_id, + switch_ip_addr_t *ip_addr, + uint16_t urpf_group, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; - memset(&match_spec, 0, sizeof(match_spec)); - memset(&action_spec, 0, sizeof(action_spec)); - match_spec.egress_metadata_bd = handle_to_id(bd_handle); - action_spec.action_smac_idx = bd_info->smac_index; - - status = p4_pd_dc_egress_bd_map_table_modify_with_set_egress_bd_properties( - g_sess_hdl, device, bd_info->egress_bd_entry, &action_spec); +#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) + p4_pd_dev_target_t p4_pd_device; + bool host_entry = FALSE; - p4_pd_complete_operations(g_sess_hdl); - return status; -} + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -p4_pd_status_t -switch_pd_egress_bd_map_table_delete_entry(switch_device_t device, - switch_bd_info_t *bd_info) -{ - p4_pd_status_t status = 0; - if (!bd_info->egress_bd_entry) { - return status; + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { +#ifndef IPV4_DISABLE + host_entry = + (ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH) ? TRUE : FALSE; + p4_pd_dc_ipv4_urpf_hit_action_spec_t v4_action_spec; + memset(&v4_action_spec, 0, sizeof(p4_pd_dc_ipv4_urpf_hit_action_spec_t)); + v4_action_spec.action_urpf_bd_group = urpf_group; + if (host_entry) { + p4_pd_dc_ipv4_urpf_match_spec_t v4_match_spec; + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); + v4_match_spec.l3_metadata_vrf = vrf_id; + v4_match_spec.ipv4_metadata_lkp_ipv4_sa = ip_addr->ip.v4addr; + status = p4_pd_dc_ipv4_urpf_table_add_with_ipv4_urpf_hit( + g_sess_hdl, p4_pd_device, &v4_match_spec, &v4_action_spec, entry_hdl); + } else { + p4_pd_dc_ipv4_urpf_lpm_match_spec_t v4_match_spec; + memset(&v4_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); + v4_match_spec.l3_metadata_vrf = vrf_id; + v4_match_spec.ipv4_metadata_lkp_ipv4_sa = ip_addr->ip.v4addr; + v4_match_spec.ipv4_metadata_lkp_ipv4_sa_prefix_length = + ip_addr->prefix_len; + status = p4_pd_dc_ipv4_urpf_lpm_table_add_with_ipv4_urpf_hit( + g_sess_hdl, p4_pd_device, &v4_match_spec, &v4_action_spec, entry_hdl); } +#endif /* IPV4_DISABLE */ + } else { +#ifndef P4_IPV6_DISABLE + host_entry = + (ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH) ? TRUE : FALSE; + p4_pd_dc_ipv6_urpf_hit_action_spec_t v6_action_spec; + memset(&v6_action_spec, 0, sizeof(p4_pd_dc_ipv6_urpf_hit_action_spec_t)); + v6_action_spec.action_urpf_bd_group = urpf_group; + if (host_entry) { + p4_pd_dc_ipv6_urpf_match_spec_t v6_match_spec; + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); + v6_match_spec.l3_metadata_vrf = vrf_id; + memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_sa, ip_addr->ip.v6addr, 16); + status = p4_pd_dc_ipv6_urpf_table_add_with_ipv6_urpf_hit( + g_sess_hdl, p4_pd_device, &v6_match_spec, &v6_action_spec, entry_hdl); + } else { + p4_pd_dc_ipv6_urpf_lpm_match_spec_t v6_match_spec; + memset(&v6_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); + v6_match_spec.l3_metadata_vrf = vrf_id; + memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_sa, ip_addr->ip.v6addr, 16); + v6_match_spec.ipv6_metadata_lkp_ipv6_sa_prefix_length = + ip_addr->prefix_len; + status = p4_pd_dc_ipv6_urpf_lpm_table_add_with_ipv6_urpf_hit( + g_sess_hdl, p4_pd_device, &v6_match_spec, &v6_action_spec, entry_hdl); + } +#endif /* P4_IPV6_DISABLE */ + } +#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - status = p4_pd_dc_egress_bd_map_table_delete(g_sess_hdl, device, - bd_info->egress_bd_entry); - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_egress_bd_stats_table_add_entry( - switch_device_t device, - uint16_t bd, - p4_pd_entry_hdl_t *entry_hdl) -{ - - p4_pd_status_t status = 0; -#ifndef P4_STATS_DISABLE - int index = 0; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_egress_bd_stats_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_egress_bd_stats_match_spec_t)); - - match_spec.egress_metadata_bd = bd; - match_spec.l2_metadata_lkp_pkt_type = 1; - - status = p4_pd_dc_egress_bd_stats_table_add_with_nop( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl[index++]); - - match_spec.l2_metadata_lkp_pkt_type = 2; - status = p4_pd_dc_egress_bd_stats_table_add_with_nop( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl[index++]); - - match_spec.l2_metadata_lkp_pkt_type = 4; - status = p4_pd_dc_egress_bd_stats_table_add_with_nop( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl[index++]); -#endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - - -p4_pd_status_t -switch_pd_egress_bd_stats_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t *entry_hdl) -{ - - p4_pd_status_t status = 0; -#ifndef P4_STATS_DISABLE - int index = 0; - - status = p4_pd_dc_egress_bd_stats_table_delete( - g_sess_hdl, - device, - entry_hdl[index++]); - - status = p4_pd_dc_egress_bd_stats_table_delete( - g_sess_hdl, - device, - entry_hdl[index++]); - - status = p4_pd_dc_egress_bd_stats_table_delete( - g_sess_hdl, - device, - entry_hdl[index++]); -#endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_port_vlan_mapping_table_add_entry(switch_device_t device, - switch_vlan_t vlan_id0, - switch_vlan_t vlan_id1, - switch_interface_info_t *info, - p4_pd_mbr_hdl_t bd_hdl, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dc_port_vlan_mapping_match_spec_t match_spec; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_urpf_update_entry(switch_device_t device, + switch_vrf_id_t vrf_id, + switch_ip_addr_t *ip_addr, + uint16_t urpf_group, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_port_vlan_mapping_match_spec_t)); - - match_spec.ingress_metadata_ifindex = info->ifindex; - if (vlan_id0) { - match_spec.vlan_tag__0__valid = TRUE; - match_spec.vlan_tag__0__vid = vlan_id0; + UNUSED(vrf_id); +#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) + bool host_entry = FALSE; + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { +#ifndef IPV4_DISABLE + host_entry = + (ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH) ? TRUE : FALSE; + p4_pd_dc_ipv4_urpf_hit_action_spec_t v4_action_spec; + memset(&v4_action_spec, 0, sizeof(p4_pd_dc_ipv4_urpf_hit_action_spec_t)); + v4_action_spec.action_urpf_bd_group = urpf_group; + if (host_entry) { + status = p4_pd_dc_ipv4_urpf_table_modify_with_ipv4_urpf_hit( + g_sess_hdl, device, entry_hdl, &v4_action_spec); + } else { + status = p4_pd_dc_ipv4_urpf_lpm_table_modify_with_ipv4_urpf_hit( + g_sess_hdl, device, entry_hdl, &v4_action_spec); } - if (vlan_id1) { - match_spec.vlan_tag__1__valid = TRUE; - match_spec.vlan_tag__1__vid = vlan_id1; +#endif /* P4_IPV4_DISABLE */ + } else { +#ifndef P4_IPV6_DISABLE + host_entry = + (ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH) ? TRUE : FALSE; + p4_pd_dc_ipv6_urpf_hit_action_spec_t v6_action_spec; + memset(&v6_action_spec, 0, sizeof(p4_pd_dc_ipv6_urpf_hit_action_spec_t)); + v6_action_spec.action_urpf_bd_group = urpf_group; + if (host_entry) { + status = p4_pd_dc_ipv6_urpf_table_modify_with_ipv6_urpf_hit( + g_sess_hdl, device, entry_hdl, &v6_action_spec); + } else { + status = p4_pd_dc_ipv6_urpf_lpm_table_modify_with_ipv6_urpf_hit( + g_sess_hdl, device, entry_hdl, &v6_action_spec); } +#endif /* P4_IPV6_DISABLE */ + } +#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - 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; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_port_vlan_mapping_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_urpf_delete_entry(switch_device_t device, + switch_vrf_id_t vrf_id, + switch_ip_addr_t *ip_addr, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; - status = p4_pd_dc_port_vlan_mapping_table_delete(g_sess_hdl, device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -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) -{ - p4_pd_status_t status = 0; - p4_pd_dc_egress_vlan_xlate_match_spec_t match_spec; - p4_pd_dc_set_egress_packet_vlan_tagged_action_spec_t action_spec; - 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_egress_vlan_xlate_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_set_egress_packet_vlan_tagged_action_spec_t)); - - match_spec.egress_metadata_ifindex = ifindex; - match_spec.egress_metadata_bd = egress_bd; - if (vlan_id != 0) { - action_spec.action_vlan_id = vlan_id; - status = p4_pd_dc_egress_vlan_xlate_table_add_with_set_egress_packet_vlan_tagged(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); + UNUSED(vrf_id); +#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) + bool host_entry = FALSE; + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { +#ifndef IPV4_DISABLE + host_entry = + (ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH) ? TRUE : FALSE; + if (host_entry) { + status = p4_pd_dc_ipv4_urpf_table_delete(g_sess_hdl, device, entry_hdl); } else { - status = p4_pd_dc_egress_vlan_xlate_table_add_with_set_egress_packet_vlan_untagged(g_sess_hdl, - p4_pd_device, - &match_spec, - entry_hdl); + status = + p4_pd_dc_ipv4_urpf_lpm_table_delete(g_sess_hdl, device, entry_hdl); } - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_egress_vlan_xlate_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_egress_vlan_xlate_table_delete(g_sess_hdl, device, entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ingress_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_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(&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)); - - match1_spec.ingress_input_port = port_id; - action1_spec.action_ifindex = ifindex; - action1_spec.action_port_type = port_type; - - 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[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); +#endif /* P4_IPV4_DISABLE */ + } else { +#ifndef P4_IPV6_DISABLE + host_entry = + (ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH) ? TRUE : FALSE; + if (host_entry) { + status = p4_pd_dc_ipv6_urpf_table_delete(g_sess_hdl, device, entry_hdl); } else { - status = p4_pd_dc_ingress_port_mapping_table_add_with_set_ifindex( - 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]); + status = + p4_pd_dc_ipv6_urpf_lpm_table_delete(g_sess_hdl, device, entry_hdl); } +#endif /* P4_IPV6_DISABLE */ + } +#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -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 status = 0; +p4_pd_status_t switch_pd_mcast_mgrp_tree_create( + switch_device_t device, + uint16_t mgid_index, + switch_mcast_info_t *mcast_info) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + p4_pd_dev_target_t p4_pd_device; - 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_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_mc_mgrp_create( + g_mc_sess_hdl, p4_pd_device.device_id, mgid_index, &mcast_info->mgrp_hdl); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; } -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_dc_egress_port_mapping_match_spec_t match_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(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; - status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_normal( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } else if (port_type == SWITCH_PORT_TYPE_FABRIC) { - p4_pd_dc_egress_port_type_fabric_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_ifindex = ifindex; - status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_fabric( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } else if (port_type == SWITCH_PORT_TYPE_CPU) { - p4_pd_dc_egress_port_type_cpu_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_ifindex = ifindex; - status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_cpu( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } - } else { - 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; - status = p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_normal( - g_sess_hdl, - device, - *entry_hdl, - &action_spec); - } else if (port_type == SWITCH_PORT_TYPE_FABRIC) { - p4_pd_dc_egress_port_type_fabric_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_ifindex = ifindex; - status = p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_fabric( - g_sess_hdl, - device, - *entry_hdl, - &action_spec); - } else if (port_type == SWITCH_PORT_TYPE_CPU) { - p4_pd_dc_egress_port_type_cpu_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_ifindex = ifindex; - status = p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_cpu( - g_sess_hdl, - device, - *entry_hdl, - &action_spec); - } - } - - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_mcast_mgrp_tree_delete( + switch_device_t device, switch_mcast_info_t *mcast_info) { + p4_pd_status_t status = 0; + UNUSED(device); +#ifndef P4_MULTICAST_DISABLE + status = p4_pd_mc_mgrp_destroy(g_mc_sess_hdl, device, mcast_info->mgrp_hdl); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; } -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 status = 0; - - status = p4_pd_dc_egress_port_mapping_table_delete(g_sess_hdl, - device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_mcast_add_entry(switch_device_t device, + switch_mcast_node_t *node) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + status = p4_pd_mc_node_create(g_mc_sess_hdl, + device, + SWITCH_MCAST_NODE_RID(node), + SWITCH_MCAST_NODE_INFO_PORT_MAP(node), + SWITCH_MCAST_NODE_INFO_LAG_MAP(node), + &(SWITCH_MCAST_NODE_INFO_HW_ENTRY(node))); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; } -p4_pd_status_t -switch_pd_rewrite_table_unicast_rewrite_add_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_rw_type_t rw_type, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_dc_rewrite_match_spec_t match_spec; - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_mcast_update_entry(switch_device_t device, + switch_mcast_node_t *node) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + status = p4_pd_mc_node_update(g_mc_sess_hdl, + device, + SWITCH_MCAST_NODE_INFO_HW_ENTRY(node), + SWITCH_MCAST_NODE_INFO_PORT_MAP(node), + SWITCH_MCAST_NODE_INFO_LAG_MAP(node)); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; +} - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +p4_pd_status_t switch_pd_mcast_delete_entry(switch_device_t device, + switch_mcast_node_t *node) { + p4_pd_status_t status = 0; + UNUSED(device); +#ifndef P4_MULTICAST_DISABLE + status = p4_pd_mc_node_destroy( + g_mc_sess_hdl, device, SWITCH_MCAST_NODE_INFO_HW_ENTRY(node)); + SWITCH_MCAST_NODE_INFO_HW_ENTRY(node) = 0; + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; +} - memset(&match_spec, 0, sizeof(p4_pd_dc_rewrite_match_spec_t)); - match_spec.l3_metadata_nexthop_index = nhop_index; +p4_pd_status_t switch_pd_mcast_mgid_table_add_entry(switch_device_t device, + mc_mgrp_hdl_t mgid_hdl, + switch_mcast_node_t *node) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + status = p4_pd_mc_associate_node(g_mc_sess_hdl, + device, + mgid_hdl, + SWITCH_MCAST_NODE_INFO_HW_ENTRY(node), + 0, + FALSE); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; +} - if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { - status = p4_pd_dc_rewrite_table_add_with_set_l2_rewrite( - g_sess_hdl, - p4_pd_device, - &match_spec, - entry_hdl); - } else { - p4_pd_dc_set_l3_rewrite_action_spec_t action_spec; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_l3_rewrite_action_spec_t)); - action_spec.action_bd = bd; - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); +p4_pd_status_t switch_pd_mcast_mgid_table_delete_entry( + switch_device_t device, mc_mgrp_hdl_t mgid_hdl, switch_mcast_node_t *node) { + p4_pd_status_t status = 0; + UNUSED(device); +#ifndef P4_MULTICAST_DISABLE + status = p4_pd_mc_dissociate_node( + g_mc_sess_hdl, device, mgid_hdl, SWITCH_MCAST_NODE_INFO_HW_ENTRY(node)); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; +} - status = p4_pd_dc_rewrite_table_add_with_set_l3_rewrite( +p4_pd_status_t switch_pd_mcast_lag_port_map_update( + switch_device_t device, uint16_t lag_index, switch_mc_port_map_t port_map) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + status = + p4_pd_mc_set_lag_membership(g_mc_sess_hdl, device, lag_index, port_map); + p4_pd_mc_complete_operations(g_mc_sess_hdl); +#endif /* P4_MULTICAST_DISABLE */ + return status; +} + +p4_pd_status_t switch_pd_system_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_system_key_value_pair_t *system_acl, + switch_acl_system_action_t action_type, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_system_acl_match_spec_t match_spec; + unsigned int i = 0; + bool copy_only = false; + switch_qid_t queue_id = 0; + uint8_t icos = 0; + uint16_t meter_id = 0; + + UNUSED(meter_id); + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_system_acl_match_spec_t)); + if (if_label) { + match_spec.acl_metadata_if_label = if_label; + match_spec.acl_metadata_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_bd_label = bd_label; + match_spec.acl_metadata_bd_label_mask = 0xFFFF; + } + + if (opt_action_params) { + queue_id = opt_action_params->queue_id; + icos = opt_action_params->ingress_cos; + meter_id = handle_to_id(opt_action_params->meter_handle); + } + + for (i = 0; i < count; i++) { + switch (system_acl[i].field) { + case SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE: + match_spec.l2_metadata_lkp_mac_type = system_acl[i].value.eth_type; + match_spec.l2_metadata_lkp_mac_type_mask = + system_acl[i].mask.u.mask & 0xFFFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK: + match_spec.l3_metadata_urpf_check_fail = + system_acl[i].value.urpf_check_fail; + match_spec.l3_metadata_urpf_check_fail_mask = + system_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS: + match_spec.l2_metadata_port_vlan_mapping_miss = + system_acl[i].value.port_vlan_mapping_miss; + match_spec.l2_metadata_port_vlan_mapping_miss_mask = + system_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_ACL_DENY: + match_spec.acl_metadata_acl_deny = system_acl[i].value.acl_deny; + match_spec.acl_metadata_acl_deny_mask = + system_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_L3_COPY: + copy_only = true; + match_spec.l3_metadata_l3_copy = system_acl[i].value.l3_copy; + match_spec.l3_metadata_l3_copy_mask = system_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_IPSG_CHECK: + match_spec.security_metadata_ipsg_check_fail = + system_acl[i].value.ipsg_check; + match_spec.security_metadata_ipsg_check_fail_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_RACL_DENY: + match_spec.acl_metadata_racl_deny = system_acl[i].value.racl_deny; + match_spec.acl_metadata_racl_deny_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_DROP: + match_spec.ingress_metadata_drop_flag = system_acl[i].value.drop_flag; + match_spec.ingress_metadata_drop_flag_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_ROUTED: + match_spec.l3_metadata_routed = system_acl[i].value.routed; + match_spec.l3_metadata_routed_mask = system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL: + match_spec.ipv6_metadata_ipv6_src_is_link_local = + system_acl[i].value.src_is_link_local; + match_spec.ipv6_metadata_ipv6_src_is_link_local_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_BD_CHECK: + match_spec.l3_metadata_same_bd_check = system_acl[i].value.bd_check; + match_spec.l3_metadata_same_bd_check_mask = + system_acl[i].mask.u.mask & 0xFFFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_IF_CHECK: + match_spec.l2_metadata_same_if_check = system_acl[i].value.if_check; + match_spec.l2_metadata_same_if_check_mask = + system_acl[i].mask.u.mask & 0xFFFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK: + match_spec.tunnel_metadata_tunnel_if_check = + system_acl[i].value.tunnel_if_check; + match_spec.tunnel_metadata_tunnel_if_check_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_TTL: + match_spec.l3_metadata_lkp_ip_ttl = system_acl[i].value.ttl; + match_spec.l3_metadata_lkp_ip_ttl_mask = + system_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX: + match_spec.ingress_metadata_egress_ifindex = + system_acl[i].value.out_ifindex; + match_spec.ingress_metadata_egress_ifindex_mask = + system_acl[i].mask.u.mask & 0xFFFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_STP_STATE: + match_spec.l2_metadata_stp_state = system_acl[i].value.stp_state; + match_spec.l2_metadata_stp_state_mask = + system_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_SYSTEM_FIELD_CONTROL_FRAME: + match_spec.ingress_metadata_control_frame = + system_acl[i].value.control_frame; + match_spec.ingress_metadata_control_frame_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED: + match_spec.ipv4_metadata_ipv4_unicast_enabled = + system_acl[i].value.ipv4_enabled; + match_spec.ipv4_metadata_ipv4_unicast_enabled_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_IPV6_ENABLED: + match_spec.ipv6_metadata_ipv6_unicast_enabled = + system_acl[i].value.ipv6_enabled; + match_spec.ipv6_metadata_ipv6_unicast_enabled_mask = + system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_RMAC_HIT: + match_spec.l3_metadata_rmac_hit = system_acl[i].value.rmac_hit; + match_spec.l3_metadata_rmac_hit_mask = system_acl[i].mask.u.mask & 0x1; + break; + case SWITCH_ACL_SYSTEM_FIELD_REASON_CODE: + copy_only = true; + match_spec.fabric_metadata_reason_code = + system_acl[i].value.reason_code; + match_spec.fabric_metadata_reason_code_mask = + system_acl[i].mask.u.mask & 0xFFFF; + break; + default: + break; + } + } + + switch (action_type) { + case SWITCH_ACL_ACTION_NOP: + case SWITCH_ACL_ACTION_PERMIT: + status = p4_pd_dc_system_acl_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); + break; + case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { + if (copy_only) { + p4_pd_dc_redirect_to_cpu_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_redirect_to_cpu_action_spec_t)); + action_spec.action_qid = queue_id; + action_spec.action_icos = icos; + action_spec.action_meter_id = meter_id; + status = + p4_pd_dc_system_acl_table_add_with_redirect_to_cpu(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } else { + p4_pd_dc_redirect_to_cpu_with_reason_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_redirect_to_cpu_action_spec_t)); + action_spec.action_reason_code = + action_params->cpu_redirect.reason_code; + action_spec.action_qid = queue_id; + action_spec.action_icos = icos; + action_spec.action_meter_id = meter_id; + status = p4_pd_dc_system_acl_table_add_with_redirect_to_cpu_with_reason( g_sess_hdl, p4_pd_device, &match_spec, + priority, &action_spec, entry_hdl); - } - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_rewrite_table_tunnel_rewrite_add_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_type_t neigh_type, - switch_neighbor_rw_type_t rw_type, - uint16_t tunnel_index, - switch_encap_type_t encap_type, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_dc_rewrite_match_spec_t match_spec; - 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_rewrite_match_spec_t)); - match_spec.l3_metadata_nexthop_index = nhop_index; - - switch_tunnel_type_egress_t tunnel_type; - switch(encap_type) { - case SWITCH_API_ENCAP_TYPE_VXLAN: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; - } - break; - case SWITCH_API_ENCAP_TYPE_GENEVE: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; - } - break; - case SWITCH_API_ENCAP_TYPE_NVGRE: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE; - } - break; - case SWITCH_API_ENCAP_TYPE_ERSPAN_T3: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3; - } else { - 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; - } - - if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { - p4_pd_dc_set_l2_rewrite_with_tunnel_action_spec_t action_spec; - action_spec.action_tunnel_type = tunnel_type; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_rewrite_table_add_with_set_l2_rewrite_with_tunnel(g_sess_hdl, + } + } break; + case SWITCH_ACL_ACTION_COPY_TO_CPU: { + if (copy_only) { + p4_pd_dc_copy_to_cpu_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + action_spec.action_qid = queue_id; + action_spec.action_icos = icos; + action_spec.action_meter_id = meter_id; + status = p4_pd_dc_system_acl_table_add_with_copy_to_cpu(g_sess_hdl, p4_pd_device, &match_spec, + priority, &action_spec, entry_hdl); - } else { - p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t action_spec; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t)); - action_spec.action_bd = bd; - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); - action_spec.action_tunnel_type = tunnel_type; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_rewrite_table_add_with_set_l3_rewrite_with_tunnel( + } else { + p4_pd_dc_copy_to_cpu_with_reason_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_copy_to_cpu_with_reason_action_spec_t)); + action_spec.action_reason_code = + action_params->cpu_redirect.reason_code; + action_spec.action_qid = queue_id; + action_spec.action_icos = icos; + action_spec.action_meter_id = meter_id; + status = p4_pd_dc_system_acl_table_add_with_copy_to_cpu_with_reason( g_sess_hdl, p4_pd_device, &match_spec, + priority, &action_spec, entry_hdl); - } -#endif /* P4_TUNNEL_DISABLE */ - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_rewrite_table_unicast_rewrite_update_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_rw_type_t rw_type, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - - UNUSED(bd); - UNUSED(nhop_index); - if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { - status = p4_pd_dc_rewrite_table_modify_with_set_l2_rewrite( + } + } break; + case SWITCH_ACL_ACTION_NEGATIVE_MIRROR: +#ifdef NEGATIVE_MIRRORING_ENABLE + if (action_params->drop.reason_code) { + p4_pd_dc_negative_mirror_with_reason_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_negative_mirror_with_reason_action_spec_t)); + action_spec.action_drop_reason = action_params->drop.reason_code; + status = p4_pd_dc_system_acl_table_add_with_negative_mirror_with_reason( g_sess_hdl, - device, + p4_pd_device, + &match_spec, + priority, + &action_spec, entry_hdl); - } else { - p4_pd_dc_set_l3_rewrite_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_l3_rewrite_action_spec_t)); - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); - status = p4_pd_dc_rewrite_table_modify_with_set_l3_rewrite( - g_sess_hdl, - device, - entry_hdl, - &action_spec); - } - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_rewrite_table_tunnel_rewrite_update_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_type_t neigh_type, - switch_neighbor_rw_type_t rw_type, - uint16_t tunnel_index, - switch_encap_type_t encap_type, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - - UNUSED(nhop_index); -#ifndef P4_TUNNEL_DISABLE - switch_tunnel_type_egress_t tunnel_type; - switch (encap_type) { - case SWITCH_API_ENCAP_TYPE_VXLAN: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; - } - break; - case SWITCH_API_ENCAP_TYPE_GENEVE: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; - } - break; - case SWITCH_API_ENCAP_TYPE_NVGRE: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE; - } - break; - case SWITCH_API_ENCAP_TYPE_ERSPAN_T3: - if (neigh_type == SWITCH_API_NEIGHBOR_IPV4_TUNNEL) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3; - } else { - 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; - } - - if (rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L2) { - p4_pd_dc_set_l2_rewrite_with_tunnel_action_spec_t action_spec; - action_spec.action_tunnel_type = tunnel_type; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_rewrite_table_modify_with_set_l2_rewrite_with_tunnel(g_sess_hdl, - device, - entry_hdl, - &action_spec); - } else { - p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t action_spec; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_l3_rewrite_with_tunnel_action_spec_t)); - action_spec.action_bd = bd; - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); - action_spec.action_tunnel_type = tunnel_type; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_rewrite_table_modify_with_set_l3_rewrite_with_tunnel( + } else { + status = p4_pd_dc_system_acl_table_add_with_negative_mirror( + g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); + } +#endif /* NEGATIVE_MIRRORING_ENABLE */ + break; + case SWITCH_ACL_ACTION_DROP: + if (action_params->drop.reason_code) { + p4_pd_dc_drop_packet_with_reason_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_drop_packet_with_reason_action_spec_t)); + action_spec.action_drop_reason = action_params->drop.reason_code; + status = p4_pd_dc_system_acl_table_add_with_drop_packet_with_reason( g_sess_hdl, - device, - entry_hdl, - &action_spec); - } -#endif /* P4_TUNNEL_DISABLE */ + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } else { + status = p4_pd_dc_system_acl_table_add_with_drop_packet( + g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); + } + break; + default: + break; + } - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_rewrite_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - - status = p4_pd_dc_rewrite_table_delete(g_sess_hdl, device, entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_system_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + p4_pd_dc_system_acl_table_delete(g_sess_hdl, device, entry_hdl); + return status; } -p4_pd_status_t -switch_pd_lag_group_create(switch_device_t device, p4_pd_grp_hdl_t *pd_group_hdl) -{ - switch_status_t status = 0; - p4_pd_dev_target_t pd_device; - - pd_device.device_id = device; - pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - status = p4_pd_dc_lag_action_profile_create_group(g_sess_hdl, pd_device, MAX_LAG_GROUP_SIZE, pd_group_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; +#if !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) +static switch_tunnel_type_ingress_t switch_pd_get_mpls_tunnel_type( + switch_mpls_encap_t *mpls_encap) { + switch_tunnel_type_ingress_t tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NONE; + switch (mpls_encap->mpls_type) { + case SWITCH_API_MPLS_TYPE_EOMPLS: + case SWITCH_API_MPLS_TYPE_VPLS: + switch (SWITCH_MPLS_POP_HEADER_COUNT(mpls_encap)) { + case 1: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_1; + break; + case 2: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_2; + break; + case 3: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_3; + break; + default: + break; + } + break; + case SWITCH_API_MPLS_TYPE_IPV4_MPLS: + case SWITCH_API_MPLS_TYPE_IPV6_MPLS: + switch (SWITCH_MPLS_POP_HEADER_COUNT(mpls_encap)) { + case 1: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_1; + break; + case 2: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_2; + break; + case 3: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_3; + break; + default: + break; + } + break; + default: + break; + } + return tunnel_type; } +#endif /* !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) */ - -p4_pd_status_t -switch_pd_lag_group_delete(switch_device_t device, p4_pd_grp_hdl_t pd_group_hdl) -{ - switch_status_t status = 0; - - status = p4_pd_dc_lag_action_profile_del_group(g_sess_hdl, device, pd_group_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_mpls_table_add_entry(switch_device_t device, + switch_mpls_encap_t *mpls_encap, + uint32_t bd_index, + uint32_t label, + switch_bd_info_t *bd_info, + uint16_t egress_ifindex, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_mpls_match_spec_t match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_mpls_match_spec_t)); + match_spec.tunnel_metadata_mpls_label = label; + + switch (mpls_encap->mpls_mode) { + case SWITCH_API_MPLS_TERMINATE: { + switch (mpls_encap->mpls_type) { + case SWITCH_API_MPLS_TYPE_EOMPLS: { + p4_pd_dc_terminate_eompls_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_terminate_eompls_action_spec_t)); + // TODO: This is a hack. Eompls will work only when the inner packet + // is IPV4. + // This is just to avoid programming 3 entries - v4, v6 and non-ip. + // Ideally, irrespective of inner header, eompls has to terminate but + // since we are parsing the inner header, either v4 or v6 valid will + // be set. + match_spec.inner_ipv4_valid = TRUE; + match_spec.inner_ipv6_valid = FALSE; + action_spec.action_bd = bd_index; + action_spec.action_tunnel_type = + switch_pd_get_mpls_tunnel_type(mpls_encap); + status = p4_pd_dc_mpls_table_add_with_terminate_eompls( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_MPLS_TYPE_VPLS: { + p4_pd_dc_terminate_vpls_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_terminate_vpls_action_spec_t)); + // TODO: This is a hack. Eompls will work only when the inner packet + // is IPV4. + // This is just to avoid programming 3 entries - v4, v6 and non-ip. + // Ideally, irrespective of inner header, eompls has to terminate but + // since we are parsing the inner header, either v4 or v6 valid will + // be set. + match_spec.inner_ipv4_valid = TRUE; + match_spec.inner_ipv6_valid = FALSE; + action_spec.action_bd = bd_index; + action_spec.action_tunnel_type = + switch_pd_get_mpls_tunnel_type(mpls_encap); + status = p4_pd_dc_mpls_table_add_with_terminate_vpls( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_MPLS_TYPE_PW: { + p4_pd_dc_terminate_pw_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_terminate_pw_action_spec_t)); + match_spec.inner_ipv4_valid = FALSE; + match_spec.inner_ipv6_valid = FALSE; + action_spec.action_ifindex = egress_ifindex; + status = p4_pd_dc_mpls_table_add_with_terminate_pw( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_MPLS_TYPE_IPV4_MPLS: { +#ifndef P4_IPV4_DISABLE + p4_pd_dc_terminate_ipv4_over_mpls_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_terminate_ipv4_over_mpls_action_spec_t)); + match_spec.inner_ipv4_valid = TRUE; + match_spec.inner_ipv6_valid = FALSE; + action_spec.action_vrf = handle_to_id(mpls_encap->vrf_handle); + action_spec.action_tunnel_type = + switch_pd_get_mpls_tunnel_type(mpls_encap); + status = p4_pd_dc_mpls_table_add_with_terminate_ipv4_over_mpls( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_IPV4_DISABLE */ + } break; + case SWITCH_API_MPLS_TYPE_IPV6_MPLS: { +#ifndef P4_IPV6_DISABLE + p4_pd_dc_terminate_ipv6_over_mpls_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_terminate_ipv6_over_mpls_action_spec_t)); + match_spec.inner_ipv4_valid = FALSE; + match_spec.inner_ipv6_valid = TRUE; + action_spec.action_vrf = handle_to_id(mpls_encap->vrf_handle); + action_spec.action_tunnel_type = + switch_pd_get_mpls_tunnel_type(mpls_encap); + status = p4_pd_dc_mpls_table_add_with_terminate_ipv6_over_mpls( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); +#endif /* P4_IPV6_DISABLE */ + } break; + default: + status = SWITCH_STATUS_INVALID_ENCAP_TYPE; + } + } break; + case SWITCH_API_MPLS_TRANSIT: { + p4_pd_dc_forward_mpls_action_spec_t action_spec; + // TODO: This is a hack. Swap will work only when the inner packet is + // IPV4. + // This is just to avoid programming 3 entries - v4, v6 and non-ip. + match_spec.inner_ipv4_valid = TRUE; + match_spec.inner_ipv6_valid = FALSE; + memset(&action_spec, 0, sizeof(p4_pd_dc_forward_mpls_action_spec_t)); + action_spec.action_nexthop_index = handle_to_id(mpls_encap->nhop_handle); + status = p4_pd_dc_mpls_table_add_with_forward_mpls( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + default: + status = SWITCH_STATUS_INVALID_ENCAP_TYPE; + } +#endif /* !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) */ + p4_pd_complete_operations(g_sess_hdl); + return status; } - -p4_pd_status_t -switch_pd_lag_group_table_add_entry(switch_device_t device, - switch_ifindex_t ifindex, - unsigned int port, - p4_pd_mbr_hdl_t *mbr_hdl, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dc_lag_group_match_spec_t lg_match_spec; - bool modify = FALSE; - p4_pd_dev_target_t pd_device; - p4_pd_dc_set_lag_port_action_spec_t action_spec; - - pd_device.device_id = device; - pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&lg_match_spec, 0, sizeof(p4_pd_dc_lag_group_match_spec_t)); - - lg_match_spec.ingress_metadata_egress_ifindex = ifindex; - - memset(&action_spec, 0, sizeof(p4_pd_dc_set_lag_port_action_spec_t)); - action_spec.action_port = port; - - modify = (*entry_hdl != 0 ) ? TRUE : FALSE; - if (modify) { -#if 0 - // TBD - status = p4_pd_dc_lag_group_modify_entry(g_sess_hdl, 0, - *entry_hdl, - &lg_action_spec); -#endif - } else { - status = p4_pd_dc_lag_action_profile_add_member_with_set_lag_port(g_sess_hdl, - pd_device, - &action_spec, mbr_hdl); - status = p4_pd_dc_lag_group_add_entry(g_sess_hdl, pd_device, - &lg_match_spec, *mbr_hdl, - entry_hdl); - } - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_lag_group_table_add_entry_with_selector(switch_device_t device, - switch_ifindex_t ifindex, - p4_pd_grp_hdl_t pd_group_hdl, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dc_lag_group_match_spec_t lg_match_spec; - bool modify = FALSE; - p4_pd_dev_target_t pd_device; - - pd_device.device_id = device; - pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&lg_match_spec, 0, sizeof(p4_pd_dc_lag_group_match_spec_t)); - - lg_match_spec.ingress_metadata_egress_ifindex = ifindex; - - modify = (*entry_hdl != 0 ) ? TRUE : FALSE; - if (modify) { -#if 0 - // TBD - status = p4_pd_dc_lag_group_modify_entry(g_sess_hdl, 0, - *entry_hdl, - &lg_action_spec); -#endif - } else { - status = p4_pd_dc_lag_group_add_entry_with_selector(g_sess_hdl, pd_device, - &lg_match_spec, pd_group_hdl, - entry_hdl); - } - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_lag_member_add(switch_device_t device, p4_pd_grp_hdl_t pd_group_hdl, - unsigned int port, p4_pd_mbr_hdl_t *mbr_hdl) -{ - p4_pd_dev_target_t pd_device; - p4_pd_dc_set_lag_port_action_spec_t action_spec; - - pd_device.device_id = device; - pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - action_spec.action_port = port; - p4_pd_dc_lag_action_profile_add_member_with_set_lag_port(g_sess_hdl, pd_device, &action_spec, mbr_hdl); - p4_pd_dc_lag_action_profile_add_member_to_group(g_sess_hdl, device, pd_group_hdl, *mbr_hdl); - p4_pd_complete_operations(g_sess_hdl); - return 0; -} - -p4_pd_status_t -switch_pd_lag_member_delete(switch_device_t device, p4_pd_grp_hdl_t pd_group_hdl, - p4_pd_mbr_hdl_t mbr_hdl) -{ - p4_pd_dc_lag_action_profile_del_member_from_group(g_sess_hdl, device, pd_group_hdl, mbr_hdl); - - p4_pd_dc_lag_action_profile_del_member(g_sess_hdl, device, mbr_hdl); - p4_pd_complete_operations(g_sess_hdl); - return 0; -} - - -p4_pd_status_t -switch_pd_lag_group_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_lag_group_table_delete(g_sess_hdl, - device, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_smac_rewrite_table_add_entry(switch_device_t device, - switch_smac_entry_t *smac_entry) -{ - p4_pd_dc_smac_rewrite_match_spec_t match_spec; - p4_pd_dc_rewrite_smac_action_spec_t action_spec; - p4_pd_status_t status = 0; - 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_smac_rewrite_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_rewrite_smac_action_spec_t)); - match_spec.egress_metadata_smac_idx = smac_entry->smac_index; - memcpy(action_spec.action_smac, &smac_entry->mac, ETH_LEN); - - status = p4_pd_dc_smac_rewrite_table_add_with_rewrite_smac( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - &smac_entry->hw_smac_entry); - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_smac_rewrite_table_delete_entry(switch_device_t device, - switch_smac_entry_t *smac_entry) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_smac_rewrite_table_delete(g_sess_hdl, - device, - smac_entry->hw_smac_entry); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_rid_table_add_entry(switch_device_t device, - uint16_t rid, - uint32_t bd, - bool inner_replica, - uint8_t tunnel_type, uint16_t tunnel_index, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - p4_pd_dc_rid_match_spec_t match_spec; - 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_rid_match_spec_t)); - match_spec.egress_egress_rid = rid; - - if (!inner_replica) { - p4_pd_dc_outer_replica_from_rid_action_spec_t action_spec; - memset(&action_spec, 0, - sizeof(p4_pd_dc_outer_replica_from_rid_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_tunnel_type = tunnel_type; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_rid_table_add_with_outer_replica_from_rid( - g_sess_hdl, p4_pd_device, &match_spec, - &action_spec, entry_hdl); - } else { - p4_pd_dc_inner_replica_from_rid_action_spec_t action_spec; - memset(&action_spec, 0, - sizeof(p4_pd_dc_inner_replica_from_rid_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_tunnel_type = tunnel_type; - action_spec.action_tunnel_index = tunnel_index; - status = p4_pd_dc_rid_table_add_with_inner_replica_from_rid( - g_sess_hdl, p4_pd_device, &match_spec, - &action_spec, entry_hdl); - } -#endif /* P4_MULTICAST_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_rid_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - - status = p4_pd_dc_rid_table_delete(g_sess_hdl, - device, - entry_hdl); -#endif /* P4_MULTICAST_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - - -p4_pd_status_t -switch_pd_spanning_tree_table_add_entry(switch_device_t device, - uint16_t stp_group, - switch_ifindex_t ifindex, - switch_stp_state_t stp_state, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_L2_DISABLE) && !defined(P4_STP_DISABLE) - p4_pd_dc_spanning_tree_match_spec_t match_spec; - p4_pd_dc_set_stp_state_action_spec_t action_spec; - 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_spanning_tree_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_set_stp_state_action_spec_t)); - - match_spec.ingress_metadata_ifindex = ifindex; - match_spec.l2_metadata_stp_group = stp_group; - action_spec.action_stp_state = stp_state; - - status = p4_pd_dc_spanning_tree_table_add_with_set_stp_state(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); -#endif /* P4_L2_DISABLE && P4_STP_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_spanning_tree_table_update_entry(switch_device_t device, - uint16_t stp_group, - switch_ifindex_t ifindex, - switch_stp_state_t stp_state, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - UNUSED(stp_group); - UNUSED(ifindex); -#if !defined(P4_L2_DISABLE) && !defined(P4_STP_DISABLE) - p4_pd_dc_set_stp_state_action_spec_t action_spec; - - memset(&action_spec, 0, sizeof(p4_pd_dc_set_stp_state_action_spec_t)); - action_spec.action_stp_state = stp_state; - - status = p4_pd_dc_spanning_tree_table_modify_with_set_stp_state(g_sess_hdl, - device, - entry_hdl, - &action_spec); -#endif /* P4_L2_DISABLE && P4_STP_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_spanning_tree_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_L2_DISABLE) && !defined(P4_STP_DISABLE) - status = p4_pd_dc_spanning_tree_table_delete(g_sess_hdl, device, entry_hdl); -#endif /* P4_L2_DISABLE && P4_STP_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_urpf_bd_table_add_entry(switch_device_t device, - uint16_t urpf_group, - uint16_t bd_index, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_urpf_bd_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); - match_spec.l3_metadata_urpf_bd_group = urpf_group; - match_spec.ingress_metadata_bd = bd_index; - status = p4_pd_dc_urpf_bd_table_add_with_nop(g_sess_hdl, - p4_pd_device, - &match_spec, - entry_hdl); -#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_urpf_bd_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - - status = p4_pd_dc_urpf_bd_table_delete(g_sess_hdl, device, entry_hdl); -#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_urpf_add_entry(switch_device_t device, - switch_vrf_id_t vrf_id, - switch_ip_addr_t *ip_addr, - uint16_t urpf_group, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - -#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - p4_pd_dev_target_t p4_pd_device; - bool host_entry = FALSE; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { -#ifndef IPV4_DISABLE - host_entry = (ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH) ? TRUE : FALSE; - p4_pd_dc_ipv4_urpf_hit_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_ipv4_urpf_hit_action_spec_t)); - v4_action_spec.action_urpf_bd_group = urpf_group; - if (host_entry) { - p4_pd_dc_ipv4_urpf_match_spec_t v4_match_spec; - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); - v4_match_spec.l3_metadata_vrf = vrf_id; - v4_match_spec.ipv4_metadata_lkp_ipv4_sa = ip_addr->ip.v4addr; - status = p4_pd_dc_ipv4_urpf_table_add_with_ipv4_urpf_hit( - g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } else { - p4_pd_dc_ipv4_urpf_lpm_match_spec_t v4_match_spec; - memset(&v4_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); - v4_match_spec.l3_metadata_vrf = vrf_id; - v4_match_spec.ipv4_metadata_lkp_ipv4_sa = ip_addr->ip.v4addr; - v4_match_spec.ipv4_metadata_lkp_ipv4_sa_prefix_length = ip_addr->prefix_len; - status = p4_pd_dc_ipv4_urpf_lpm_table_add_with_ipv4_urpf_hit( - g_sess_hdl, - p4_pd_device, - &v4_match_spec, - &v4_action_spec, - entry_hdl); - } -#endif /* IPV4_DISABLE */ - } else { -#ifndef P4_IPV6_DISABLE - host_entry = (ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH) ? TRUE : FALSE; - p4_pd_dc_ipv6_urpf_hit_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_ipv6_urpf_hit_action_spec_t)); - v6_action_spec.action_urpf_bd_group = urpf_group; - if (host_entry) { - p4_pd_dc_ipv6_urpf_match_spec_t v6_match_spec; - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); - v6_match_spec.l3_metadata_vrf = vrf_id; - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_sa, ip_addr->ip.v6addr, 16); - status = p4_pd_dc_ipv6_urpf_table_add_with_ipv6_urpf_hit( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); - } else { - p4_pd_dc_ipv6_urpf_lpm_match_spec_t v6_match_spec; - memset(&v6_match_spec, 0, sizeof(p4_pd_dc_urpf_bd_match_spec_t)); - v6_match_spec.l3_metadata_vrf = vrf_id; - memcpy(&v6_match_spec.ipv6_metadata_lkp_ipv6_sa, ip_addr->ip.v6addr, 16); - v6_match_spec.ipv6_metadata_lkp_ipv6_sa_prefix_length = ip_addr->prefix_len; - status = p4_pd_dc_ipv6_urpf_lpm_table_add_with_ipv6_urpf_hit( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - &v6_action_spec, - entry_hdl); - } -#endif /* P4_IPV6_DISABLE */ - } -#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_urpf_update_entry(switch_device_t device, - switch_vrf_id_t vrf_id, - switch_ip_addr_t *ip_addr, - uint16_t urpf_group, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - - UNUSED(vrf_id); -#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - bool host_entry = FALSE; - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { -#ifndef IPV4_DISABLE - host_entry = (ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH) ? TRUE : FALSE; - p4_pd_dc_ipv4_urpf_hit_action_spec_t v4_action_spec; - memset(&v4_action_spec, 0, sizeof(p4_pd_dc_ipv4_urpf_hit_action_spec_t)); - v4_action_spec.action_urpf_bd_group = urpf_group; - if (host_entry) { - status = p4_pd_dc_ipv4_urpf_table_modify_with_ipv4_urpf_hit( - g_sess_hdl, - device, - entry_hdl, - &v4_action_spec); - } else { - status = p4_pd_dc_ipv4_urpf_lpm_table_modify_with_ipv4_urpf_hit( - g_sess_hdl, - device, - entry_hdl, - &v4_action_spec); - } -#endif /* P4_IPV4_DISABLE */ - } else { -#ifndef P4_IPV6_DISABLE - host_entry = (ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH) ? TRUE : FALSE; - p4_pd_dc_ipv6_urpf_hit_action_spec_t v6_action_spec; - memset(&v6_action_spec, 0, sizeof(p4_pd_dc_ipv6_urpf_hit_action_spec_t)); - v6_action_spec.action_urpf_bd_group = urpf_group; - if (host_entry) { - status = p4_pd_dc_ipv6_urpf_table_modify_with_ipv6_urpf_hit( - g_sess_hdl, - device, - entry_hdl, - &v6_action_spec); - } else { - status = p4_pd_dc_ipv6_urpf_lpm_table_modify_with_ipv6_urpf_hit( - g_sess_hdl, - device, - entry_hdl, - &v6_action_spec); - } -#endif /* P4_IPV6_DISABLE */ - } -#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_urpf_delete_entry(switch_device_t device, - switch_vrf_id_t vrf_id, - switch_ip_addr_t *ip_addr, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - - UNUSED(vrf_id); -#if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - bool host_entry = FALSE; - if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { -#ifndef IPV4_DISABLE - host_entry = (ip_addr->prefix_len == SWITCH_IPV4_PREFIX_LENGTH) ? TRUE : FALSE; - if (host_entry) { - status = p4_pd_dc_ipv4_urpf_table_delete(g_sess_hdl, - device, - entry_hdl); - } else { - status = p4_pd_dc_ipv4_urpf_lpm_table_delete(g_sess_hdl, - device, - entry_hdl); - } -#endif /* P4_IPV4_DISABLE */ - } else { -#ifndef P4_IPV6_DISABLE - host_entry = (ip_addr->prefix_len == SWITCH_IPV6_PREFIX_LENGTH) ? TRUE : FALSE; - if (host_entry) { - status = p4_pd_dc_ipv6_urpf_table_delete(g_sess_hdl, - device, - entry_hdl); - } else { - status = p4_pd_dc_ipv6_urpf_lpm_table_delete(g_sess_hdl, - device, - entry_hdl); - } -#endif /* P4_IPV6_DISABLE */ - } -#endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_mcast_mgrp_tree_create(switch_device_t device, uint16_t mgid_index, - switch_mcast_info_t *mcast_info) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - status = p4_pd_mc_mgrp_create(g_mc_sess_hdl, p4_pd_device.device_id, - mgid_index, &mcast_info->mgrp_hdl); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_mgrp_tree_delete(switch_device_t device, - switch_mcast_info_t *mcast_info) -{ - p4_pd_status_t status = 0; - UNUSED(device); -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_mgrp_destroy(g_mc_sess_hdl, device, mcast_info->mgrp_hdl); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_add_entry(switch_device_t device, switch_mcast_node_t *node) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_node_create(g_mc_sess_hdl, device, - SWITCH_MCAST_NODE_RID(node), - SWITCH_MCAST_NODE_INFO_PORT_MAP(node), - SWITCH_MCAST_NODE_INFO_LAG_MAP(node), - &(SWITCH_MCAST_NODE_INFO_HW_ENTRY(node))); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_update_entry(switch_device_t device, switch_mcast_node_t *node) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_node_update(g_mc_sess_hdl, device, - SWITCH_MCAST_NODE_INFO_HW_ENTRY(node), - SWITCH_MCAST_NODE_INFO_PORT_MAP(node), - SWITCH_MCAST_NODE_INFO_LAG_MAP(node)); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_delete_entry(switch_device_t device, switch_mcast_node_t *node) -{ - p4_pd_status_t status = 0; - UNUSED(device); -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_node_destroy(g_mc_sess_hdl, device, - SWITCH_MCAST_NODE_INFO_HW_ENTRY(node)); - SWITCH_MCAST_NODE_INFO_HW_ENTRY(node) = 0; - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_mgid_table_add_entry(switch_device_t device, - mc_mgrp_hdl_t mgid_hdl, - switch_mcast_node_t *node) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_associate_node( - g_mc_sess_hdl, - device, - mgid_hdl, - SWITCH_MCAST_NODE_INFO_HW_ENTRY(node), - 0, FALSE); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_mgid_table_delete_entry(switch_device_t device, - mc_mgrp_hdl_t mgid_hdl, - switch_mcast_node_t *node) -{ - p4_pd_status_t status = 0; - UNUSED(device); -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_dissociate_node(g_mc_sess_hdl, device, mgid_hdl, - SWITCH_MCAST_NODE_INFO_HW_ENTRY(node)); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_mcast_lag_port_map_update(switch_device_t device, uint16_t lag_index, - switch_mc_port_map_t port_map) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - status = p4_pd_mc_set_lag_membership(g_mc_sess_hdl, device, lag_index, port_map); - p4_pd_mc_complete_operations(g_mc_sess_hdl); -#endif /* P4_MULTICAST_DISABLE */ - return status; -} - -p4_pd_status_t -switch_pd_system_acl_table_add_entry(switch_device_t device, - uint16_t if_label, uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_system_key_value_pair_t *system_acl, - switch_acl_system_action_t action_type, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_system_acl_match_spec_t match_spec; - unsigned int i = 0; - bool copy_only = false; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_system_acl_match_spec_t)); - if (if_label) { - match_spec.acl_metadata_if_label = if_label; - match_spec.acl_metadata_if_label_mask = 0xFFFF; - } - if (bd_label) { - match_spec.acl_metadata_bd_label = bd_label; - match_spec.acl_metadata_bd_label_mask = 0xFFFF; - } - - for (i = 0; i < count; i++) { - switch (system_acl[i].field) { - case SWITCH_ACL_SYSTEM_FIELD_ETH_TYPE: - match_spec.l2_metadata_lkp_mac_type = system_acl[i].value.eth_type; - match_spec.l2_metadata_lkp_mac_type_mask = system_acl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_SOURCE_MAC: - memcpy(match_spec.l2_metadata_lkp_mac_sa, system_acl[i].value.source_mac.mac_addr, ETH_LEN); - memcpy(match_spec.l2_metadata_lkp_mac_sa_mask, &system_acl[i].mask.u.mask, ETH_LEN); - break; - case SWITCH_ACL_SYSTEM_FIELD_DEST_MAC: - memcpy(match_spec.l2_metadata_lkp_mac_da, system_acl[i].value.dest_mac.mac_addr, ETH_LEN); - memcpy(match_spec.l2_metadata_lkp_mac_da_mask, &system_acl[i].mask.u.mask, ETH_LEN); - break; - case SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK: - match_spec.l3_metadata_urpf_check_fail = system_acl[i].value.urpf_check_fail; - match_spec.l3_metadata_urpf_check_fail_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS: - match_spec.l2_metadata_port_vlan_mapping_miss = system_acl[i].value.port_vlan_mapping_miss; - match_spec.l2_metadata_port_vlan_mapping_miss_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_ACL_DENY: - match_spec.acl_metadata_acl_deny = system_acl[i].value.acl_deny; - match_spec.acl_metadata_acl_deny_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_ACL_COPY: - copy_only = true; - match_spec.acl_metadata_acl_copy = system_acl[i].value.acl_copy; - match_spec.acl_metadata_acl_copy_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_L3_COPY: - copy_only = true; - match_spec.l3_metadata_l3_copy = system_acl[i].value.l3_copy; - match_spec.l3_metadata_l3_copy_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_IPSG_CHECK: - match_spec.security_metadata_ipsg_check_fail = system_acl[i].value.ipsg_check; - match_spec.security_metadata_ipsg_check_fail_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_RACL_DENY: - match_spec.acl_metadata_racl_deny = system_acl[i].value.racl_deny; - match_spec.acl_metadata_racl_deny_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_DROP: - match_spec.ingress_metadata_drop_flag = system_acl[i].value.drop_flag; - match_spec.ingress_metadata_drop_flag_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_ROUTED: - match_spec.l3_metadata_routed = system_acl[i].value.routed; - match_spec.l3_metadata_routed_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_LINK_LOCAL: - match_spec.ipv6_metadata_ipv6_src_is_link_local = system_acl[i].value.src_is_link_local; - match_spec.ipv6_metadata_ipv6_src_is_link_local_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_BD_CHECK: - match_spec.l3_metadata_same_bd_check = system_acl[i].value.bd_check; - match_spec.l3_metadata_same_bd_check_mask = system_acl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_IF_CHECK: - match_spec.l2_metadata_same_if_check = system_acl[i].value.if_check; - match_spec.l2_metadata_same_if_check_mask = system_acl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_TUNNEL_IF_CHECK: - match_spec.tunnel_metadata_tunnel_if_check = system_acl[i].value.tunnel_if_check; - match_spec.tunnel_metadata_tunnel_if_check_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_TTL: - match_spec.l3_metadata_lkp_ip_ttl = system_acl[i].value.ttl; - match_spec.l3_metadata_lkp_ip_ttl_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX: - match_spec.ingress_metadata_egress_ifindex = system_acl[i].value.out_ifindex; - match_spec.ingress_metadata_egress_ifindex_mask = system_acl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_STP_STATE: - match_spec.l2_metadata_stp_state = system_acl[i].value.stp_state; - match_spec.l2_metadata_stp_state_mask = system_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_SYSTEM_FIELD_CONTROL_FRAME: - match_spec.ingress_metadata_control_frame = system_acl[i].value.control_frame; - match_spec.ingress_metadata_control_frame_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_IPV4_ENABLED: - match_spec.ipv4_metadata_ipv4_unicast_enabled = system_acl[i].value.ipv4_enabled; - match_spec.ipv4_metadata_ipv4_unicast_enabled_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_IPV6_ENABLED: - match_spec.ipv6_metadata_ipv6_unicast_enabled = system_acl[i].value.ipv6_enabled; - match_spec.ipv6_metadata_ipv6_unicast_enabled_mask = system_acl[i].mask.u.mask & 0x1; - break; - case SWITCH_ACL_SYSTEM_FIELD_RMAC_HIT: - match_spec.l3_metadata_rmac_hit = system_acl[i].value.rmac_hit; - match_spec.l3_metadata_rmac_hit_mask = system_acl[i].mask.u.mask & 0x1; - break; - default: - break; - } - } - - switch (action_type) { - case SWITCH_ACL_ACTION_NOP: - case SWITCH_ACL_ACTION_PERMIT: - status = p4_pd_dc_system_acl_table_add_with_nop( - g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); - break; - case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: - { - p4_pd_dc_redirect_to_cpu_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_redirect_to_cpu_action_spec_t)); - action_spec.action_reason_code = action_params->cpu_redirect.reason_code; - status = p4_pd_dc_system_acl_table_add_with_redirect_to_cpu( - g_sess_hdl, p4_pd_device, &match_spec, priority, - &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_COPY_TO_CPU: - { - if (copy_only) { - status = p4_pd_dc_system_acl_table_add_with_copy_to_cpu( - g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); - } else { - p4_pd_dc_copy_to_cpu_with_reason_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_copy_to_cpu_with_reason_action_spec_t)); - action_spec.action_reason_code = action_params->cpu_redirect.reason_code; - status = p4_pd_dc_system_acl_table_add_with_copy_to_cpu_with_reason( - g_sess_hdl, p4_pd_device, &match_spec, priority, - &action_spec, entry_hdl); - } - } - break; - case SWITCH_ACL_ACTION_NEGATIVE_MIRROR: - { -#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 /* BMV2 */ - status = p4_pd_dc_system_acl_table_add_with_negative_mirror( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, -#ifndef BMV2 - &action_spec, -#endif /* BMV2 */ - entry_hdl); - } - break; - case SWITCH_ACL_ACTION_DROP: - if (action_params->drop.reason_code) { -#ifndef P4_STATS_DISABLE - p4_pd_dc_drop_packet_with_reason_action_spec_t action_spec; - memset(&action_spec, 0, - sizeof(p4_pd_dc_drop_packet_with_reason_action_spec_t)); - action_spec.action_drop_reason = - action_params->drop.reason_code; -#endif - status = p4_pd_dc_system_acl_table_add_with_drop_packet_with_reason( - g_sess_hdl, p4_pd_device, &match_spec, priority, -#ifndef P4_STATS_DISABLE - &action_spec, -#endif - entry_hdl); - } else { - status = p4_pd_dc_system_acl_table_add_with_drop_packet( - g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); - } - break; - default: - break; - } - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_system_acl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - p4_pd_dc_system_acl_table_delete (g_sess_hdl, device, entry_hdl); - return status; -} - -#if !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) -static switch_tunnel_type_ingress_t -switch_pd_get_mpls_tunnel_type(switch_mpls_encap_t *mpls_encap) -{ - switch_tunnel_type_ingress_t tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NONE; - switch (mpls_encap->mpls_type) { - case SWITCH_API_MPLS_TYPE_EOMPLS: - case SWITCH_API_MPLS_TYPE_VPLS: - switch (SWITCH_MPLS_POP_HEADER_COUNT(mpls_encap)) { - case 1: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_1; - break; - case 2: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_2; - break; - case 3: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L2VPN_NUM_LABELS_3; - break; - default: - break; - } - break; - case SWITCH_API_MPLS_TYPE_IPV4_MPLS: - case SWITCH_API_MPLS_TYPE_IPV6_MPLS: - switch (SWITCH_MPLS_POP_HEADER_COUNT(mpls_encap)) { - case 1: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_1; - break; - case 2: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_2; - break; - case 3: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_MPLS_L3VPN_NUM_LABELS_3; - break; - default: - break; - } - break; - default: - break; - } - return tunnel_type; -} -#endif /* !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) */ - -p4_pd_status_t -switch_pd_mpls_table_add_entry(switch_device_t device, switch_mpls_encap_t *mpls_encap, - uint32_t bd_index, uint32_t label, - switch_bd_info_t *bd_info, - uint16_t egress_ifindex, p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_mpls_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_mpls_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_mpls_match_spec_t)); - match_spec.tunnel_metadata_mpls_label = label; - - switch (mpls_encap->mpls_mode) { - case SWITCH_API_MPLS_TERMINATE: - { - switch (mpls_encap->mpls_type) { - case SWITCH_API_MPLS_TYPE_EOMPLS: - { - p4_pd_dc_terminate_eompls_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_terminate_eompls_action_spec_t)); - //TODO: This is a hack. Eompls will work only when the inner packet is IPV4. - //This is just to avoid programming 3 entries - v4, v6 and non-ip. - // Ideally, irrespective of inner header, eompls has to terminate but - // since we are parsing the inner header, either v4 or v6 valid will be set. - match_spec.inner_ipv4_valid = TRUE; - match_spec.inner_ipv6_valid = FALSE; - action_spec.action_bd = bd_index; - action_spec.action_tunnel_type = - switch_pd_get_mpls_tunnel_type(mpls_encap); - status = p4_pd_dc_mpls_table_add_with_terminate_eompls( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } - break; - case SWITCH_API_MPLS_TYPE_VPLS: - { - p4_pd_dc_terminate_vpls_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_terminate_vpls_action_spec_t)); - //TODO: This is a hack. Eompls will work only when the inner packet is IPV4. - //This is just to avoid programming 3 entries - v4, v6 and non-ip. - // Ideally, irrespective of inner header, eompls has to terminate but - // since we are parsing the inner header, either v4 or v6 valid will be set. - match_spec.inner_ipv4_valid = TRUE; - match_spec.inner_ipv6_valid = FALSE; - action_spec.action_bd = bd_index; - action_spec.action_tunnel_type = - switch_pd_get_mpls_tunnel_type(mpls_encap); - status = p4_pd_dc_mpls_table_add_with_terminate_vpls( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } - break; - case SWITCH_API_MPLS_TYPE_PW: - { - p4_pd_dc_terminate_pw_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_terminate_pw_action_spec_t)); - match_spec.inner_ipv4_valid = FALSE; - match_spec.inner_ipv6_valid = FALSE; - action_spec.action_ifindex = egress_ifindex; - status = p4_pd_dc_mpls_table_add_with_terminate_pw( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } - break; - case SWITCH_API_MPLS_TYPE_IPV4_MPLS: - { -#ifndef P4_IPV4_DISABLE - p4_pd_dc_terminate_ipv4_over_mpls_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_terminate_ipv4_over_mpls_action_spec_t)); - match_spec.inner_ipv4_valid = TRUE; - match_spec.inner_ipv6_valid = FALSE; - action_spec.action_vrf = handle_to_id(mpls_encap->vrf_handle); - action_spec.action_tunnel_type = - switch_pd_get_mpls_tunnel_type(mpls_encap); - status = p4_pd_dc_mpls_table_add_with_terminate_ipv4_over_mpls( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); -#endif /* P4_IPV4_DISABLE */ - } - break; - case SWITCH_API_MPLS_TYPE_IPV6_MPLS: - { -#ifndef P4_IPV6_DISABLE - p4_pd_dc_terminate_ipv6_over_mpls_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_terminate_ipv6_over_mpls_action_spec_t)); - match_spec.inner_ipv4_valid = FALSE; - match_spec.inner_ipv6_valid = TRUE; - action_spec.action_vrf = handle_to_id(mpls_encap->vrf_handle); - action_spec.action_tunnel_type = - switch_pd_get_mpls_tunnel_type(mpls_encap); - status = p4_pd_dc_mpls_table_add_with_terminate_ipv6_over_mpls( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); -#endif /* P4_IPV6_DISABLE */ - } - break; - default: - status = SWITCH_STATUS_INVALID_ENCAP_TYPE; - } - } - break; - case SWITCH_API_MPLS_TRANSIT: - { - p4_pd_dc_forward_mpls_action_spec_t action_spec; - //TODO: This is a hack. Swap will work only when the inner packet is IPV4. - //This is just to avoid programming 3 entries - v4, v6 and non-ip. - match_spec.inner_ipv4_valid = TRUE; - match_spec.inner_ipv6_valid = FALSE; - memset(&action_spec, 0, sizeof(p4_pd_dc_forward_mpls_action_spec_t)); - action_spec.action_nexthop_index = handle_to_id(mpls_encap->nhop_handle); - status = p4_pd_dc_mpls_table_add_with_forward_mpls( - g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } - break; - default: - status = SWITCH_STATUS_INVALID_ENCAP_TYPE; - } + status = p4_pd_dc_mpls_table_delete(g_sess_hdl, device, entry_hdl); #endif /* !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_mpls_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_rewrite_table_mpls_add_entry( + switch_device_t device, + uint32_t tunnel_index, + uint16_t smac_index, + uint16_t dmac_index, + switch_mpls_encap_t *mpls_encap, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) - status = p4_pd_dc_mpls_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_tunnel_rewrite_match_spec_t match_spec; + switch_mpls_t *mpls_stack = NULL; + uint8_t header_count = 1; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_rewrite_match_spec_t)); + match_spec.tunnel_metadata_tunnel_index = tunnel_index; + + switch (mpls_encap->mpls_action) { + case SWITCH_API_MPLS_ACTION_PUSH: + header_count = SWITCH_MPLS_PUSH_HEADER_COUNT(mpls_encap); + mpls_stack = SWITCH_MPLS_PUSH_HEADER(mpls_encap); + break; + case SWITCH_API_MPLS_ACTION_SWAP_PUSH: + header_count = SWITCH_MPLS_SWAP_PUSH_HEADER_COUNT(mpls_encap); + mpls_stack = SWITCH_MPLS_SWAP_PUSH_HEADER(mpls_encap); + break; + default: + header_count = 0; + } + + switch (header_count) { + case 1: { + p4_pd_dc_set_mpls_rewrite_push1_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_rewrite_push1_action_spec_t)); + action_spec.action_smac_idx = smac_index; + action_spec.action_dmac_idx = dmac_index; + action_spec.action_label1 = mpls_stack[0].label; + action_spec.action_ttl1 = mpls_stack[0].ttl; + action_spec.action_exp1 = mpls_stack[0].exp; + status = p4_pd_dc_tunnel_rewrite_table_add_with_set_mpls_rewrite_push1( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case 2: { + p4_pd_dc_set_mpls_rewrite_push2_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_rewrite_push2_action_spec_t)); + action_spec.action_smac_idx = smac_index; + action_spec.action_dmac_idx = dmac_index; + action_spec.action_label1 = mpls_stack[0].label; + action_spec.action_ttl1 = mpls_stack[0].ttl; + action_spec.action_exp1 = mpls_stack[0].exp; + action_spec.action_label2 = mpls_stack[1].label; + action_spec.action_ttl2 = mpls_stack[1].ttl; + action_spec.action_exp2 = mpls_stack[1].exp; + status = p4_pd_dc_tunnel_rewrite_table_add_with_set_mpls_rewrite_push2( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case 3: { + p4_pd_dc_set_mpls_rewrite_push3_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_rewrite_push3_action_spec_t)); + action_spec.action_smac_idx = smac_index; + action_spec.action_dmac_idx = dmac_index; + action_spec.action_label1 = mpls_stack[0].label; + action_spec.action_ttl1 = mpls_stack[0].ttl; + action_spec.action_exp1 = mpls_stack[0].exp; + action_spec.action_label2 = mpls_stack[1].label; + action_spec.action_ttl2 = mpls_stack[1].ttl; + action_spec.action_exp2 = mpls_stack[1].exp; + action_spec.action_label3 = mpls_stack[2].label; + action_spec.action_ttl3 = mpls_stack[2].ttl; + action_spec.action_exp3 = mpls_stack[2].exp; + status = p4_pd_dc_tunnel_rewrite_table_add_with_set_mpls_rewrite_push3( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + default: + status = SWITCH_STATUS_INVALID_ENCAP_TYPE; + } #endif /* !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_tunnel_rewrite_table_mpls_add_entry(switch_device_t device, uint32_t tunnel_index, - uint16_t smac_index, uint16_t dmac_index, - switch_mpls_encap_t *mpls_encap, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_tunnel_rewrite_match_spec_t match_spec; - switch_mpls_t *mpls_stack = NULL; - uint8_t header_count = 1; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_tunnel_rewrite_match_spec_t)); - match_spec.tunnel_metadata_tunnel_index = tunnel_index; - - switch (mpls_encap->mpls_action) { - case SWITCH_API_MPLS_ACTION_PUSH: - header_count = SWITCH_MPLS_PUSH_HEADER_COUNT(mpls_encap); - mpls_stack = SWITCH_MPLS_PUSH_HEADER(mpls_encap); - break; - case SWITCH_API_MPLS_ACTION_SWAP_PUSH: - header_count = SWITCH_MPLS_SWAP_PUSH_HEADER_COUNT(mpls_encap); - mpls_stack = SWITCH_MPLS_SWAP_PUSH_HEADER(mpls_encap); - break; - default: - header_count = 0; - } - - switch (header_count) { - case 1: - { - p4_pd_dc_set_mpls_rewrite_push1_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_rewrite_push1_action_spec_t)); - action_spec.action_smac_idx = smac_index; - action_spec.action_dmac_idx = dmac_index; - action_spec.action_label1 = mpls_stack[0].label; - action_spec.action_ttl1 = mpls_stack[0].ttl; - action_spec.action_exp1 = mpls_stack[0].exp; - status = p4_pd_dc_tunnel_rewrite_table_add_with_set_mpls_rewrite_push1(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_rewrite_table_mpls_rewrite_add_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + uint16_t tunnel_index, + switch_neighbor_type_t neigh_type, + switch_mac_addr_t dmac, + uint32_t label, + uint8_t header_count, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_MPLS_DISABLE + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_rewrite_match_spec_t match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_rewrite_match_spec_t)); + match_spec.l3_metadata_nexthop_index = nhop_index; + switch (neigh_type) { + case SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN: { + p4_pd_dc_set_mpls_push_rewrite_l2_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_push_rewrite_l2_action_spec_t)); + action_spec.action_tunnel_index = tunnel_index; + action_spec.action_header_count = header_count; + status = p4_pd_dc_rewrite_table_add_with_set_mpls_push_rewrite_l2( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN: { + p4_pd_dc_set_mpls_push_rewrite_l3_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_push_rewrite_l3_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_tunnel_index = tunnel_index; + action_spec.action_header_count = header_count; + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); + status = p4_pd_dc_rewrite_table_add_with_set_mpls_push_rewrite_l3( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN: { + p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t)); + action_spec.action_label = label; + action_spec.action_tunnel_index = tunnel_index; + action_spec.action_header_count = header_count; + status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l2( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN: { + p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_label = label; + action_spec.action_tunnel_index = tunnel_index; + action_spec.action_header_count = header_count; + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); + status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l3( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN: { + header_count = 0; + p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t)); + action_spec.action_label = label; + action_spec.action_tunnel_index = tunnel_index; + action_spec.action_header_count = header_count; + status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l2( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN: { + header_count = 0; + p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t)); + action_spec.action_bd = bd; + action_spec.action_label = label; + action_spec.action_tunnel_index = tunnel_index; + action_spec.action_header_count = header_count; + memcpy(action_spec.action_dmac, &dmac, ETH_LEN); + status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l3( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + default: + header_count = 0; + } +#endif /* P4_MPLS_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ipv4_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ip_key_value_pair_t *ip_acl, + switch_acl_ip_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_ACL_DISABLE) && !defined(P4_IPV4_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_ip_acl_match_spec_t match_spec; + unsigned int i = 0; + switch_meter_idx_t meter_index = 0; + switch_stats_idx_t stats_index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + if (opt_action_params) { + meter_index = handle_to_id(opt_action_params->meter_handle); + stats_index = handle_to_id(opt_action_params->counter_handle); + } + + memset(&match_spec, 0, sizeof(p4_pd_dc_ip_acl_match_spec_t)); + + if (if_label) { + match_spec.acl_metadata_if_label = if_label; + match_spec.acl_metadata_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_bd_label = bd_label; + match_spec.acl_metadata_bd_label_mask = 0xFFFF; + } + for (i = 0; i < count; i++) { + switch (ip_acl[i].field) { + case SWITCH_ACL_IP_FIELD_IPV4_SRC: + match_spec.ipv4_metadata_lkp_ipv4_sa = ip_acl[i].value.ipv4_source; + match_spec.ipv4_metadata_lkp_ipv4_sa_mask = + ip_acl[i].mask.u.mask & 0xFFFFFFFF; break; - case 2: - { - p4_pd_dc_set_mpls_rewrite_push2_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_rewrite_push2_action_spec_t)); - action_spec.action_smac_idx = smac_index; - action_spec.action_dmac_idx = dmac_index; - action_spec.action_label1 = mpls_stack[0].label; - action_spec.action_ttl1 = mpls_stack[0].ttl; - action_spec.action_exp1 = mpls_stack[0].exp; - action_spec.action_label2 = mpls_stack[1].label; - action_spec.action_ttl2 = mpls_stack[1].ttl; - action_spec.action_exp2 = mpls_stack[1].exp; - status = p4_pd_dc_tunnel_rewrite_table_add_with_set_mpls_rewrite_push2(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_IPV4_DEST: + match_spec.ipv4_metadata_lkp_ipv4_da = ip_acl[i].value.ipv4_dest; + match_spec.ipv4_metadata_lkp_ipv4_da_mask = + ip_acl[i].mask.u.mask & 0xFFFFFFFF; + ; break; - case 3: - { - p4_pd_dc_set_mpls_rewrite_push3_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_rewrite_push3_action_spec_t)); - action_spec.action_smac_idx = smac_index; - action_spec.action_dmac_idx = dmac_index; - action_spec.action_label1 = mpls_stack[0].label; - action_spec.action_ttl1 = mpls_stack[0].ttl; - action_spec.action_exp1 = mpls_stack[0].exp; - action_spec.action_label2 = mpls_stack[1].label; - action_spec.action_ttl2 = mpls_stack[1].ttl; - action_spec.action_exp2 = mpls_stack[1].exp; - action_spec.action_label3 = mpls_stack[2].label; - action_spec.action_ttl3 = mpls_stack[2].ttl; - action_spec.action_exp3 = mpls_stack[2].exp; - status = p4_pd_dc_tunnel_rewrite_table_add_with_set_mpls_rewrite_push3(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_IP_PROTO: + match_spec.l3_metadata_lkp_ip_proto = ip_acl[i].value.ip_proto; + match_spec.l3_metadata_lkp_ip_proto_mask = ip_acl[i].mask.u.mask & 0xFF; break; - default: - status = SWITCH_STATUS_INVALID_ENCAP_TYPE; - } -#endif /* !defined(P4_MPLS_DISABLE) && !defined(P4_TUNNEL_DISABLE) */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_rewrite_table_mpls_rewrite_add_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - uint16_t tunnel_index, - switch_neighbor_type_t neigh_type, - switch_mac_addr_t dmac, - uint32_t label, - uint8_t header_count, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_MPLS_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_rewrite_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_rewrite_match_spec_t)); - match_spec.l3_metadata_nexthop_index = nhop_index; - switch (neigh_type) { - case SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN: - { - p4_pd_dc_set_mpls_push_rewrite_l2_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_push_rewrite_l2_action_spec_t)); - action_spec.action_tunnel_index = tunnel_index; - action_spec.action_header_count = header_count; - status = p4_pd_dc_rewrite_table_add_with_set_mpls_push_rewrite_l2(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT: + match_spec.l3_metadata_lkp_l4_sport = ip_acl[i].value.l4_source_port; + match_spec.l3_metadata_lkp_l4_sport_mask = + ip_acl[i].mask.u.mask & 0xFFFF; break; - case SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN: - { - p4_pd_dc_set_mpls_push_rewrite_l3_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_push_rewrite_l3_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_tunnel_index = tunnel_index; - action_spec.action_header_count = header_count; - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); - status = p4_pd_dc_rewrite_table_add_with_set_mpls_push_rewrite_l3(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_L4_DEST_PORT: + match_spec.l3_metadata_lkp_l4_dport = ip_acl[i].value.l4_dest_port; + match_spec.l3_metadata_lkp_l4_dport_mask = + ip_acl[i].mask.u.mask & 0xFFFF; break; - case SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN: - { - p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t)); - action_spec.action_label = label; - action_spec.action_tunnel_index = tunnel_index; - action_spec.action_header_count = header_count; - status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l2(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_ICMP_TYPE: + match_spec.l3_metadata_lkp_l4_sport |= ip_acl[i].value.icmp_type << 8; + match_spec.l3_metadata_lkp_l4_sport_mask |= + (ip_acl[i].mask.u.mask & 0xFF) << 8; break; - case SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN: - { - p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_label = label; - action_spec.action_tunnel_index = tunnel_index; - action_spec.action_header_count = header_count; - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); - status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l3(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_ICMP_CODE: + match_spec.l3_metadata_lkp_l4_sport |= ip_acl[i].value.icmp_code; + match_spec.l3_metadata_lkp_l4_sport_mask |= + ip_acl[i].mask.u.mask & 0xFF; break; - case SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN: - { - header_count = 0; - p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l2_action_spec_t)); - action_spec.action_label = label; - action_spec.action_tunnel_index = tunnel_index; - action_spec.action_header_count = header_count; - status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l2(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_TCP_FLAGS: + match_spec.tcp_flags = ip_acl[i].value.tcp_flags; + match_spec.tcp_flags_mask = ip_acl[i].mask.u.mask & 0xFF; break; - case SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN: - { - header_count = 0; - p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_set_mpls_swap_push_rewrite_l3_action_spec_t)); - action_spec.action_bd = bd; - action_spec.action_label = label; - action_spec.action_tunnel_index = tunnel_index; - action_spec.action_header_count = header_count; - memcpy(action_spec.action_dmac, &dmac, ETH_LEN); - status = p4_pd_dc_rewrite_table_add_with_set_mpls_swap_push_rewrite_l3(g_sess_hdl, - p4_pd_device, - &match_spec, - &action_spec, - entry_hdl); - } + case SWITCH_ACL_IP_FIELD_TTL: + match_spec.l3_metadata_lkp_ip_ttl = ip_acl[i].value.ttl; + match_spec.l3_metadata_lkp_ip_ttl_mask = ip_acl[i].mask.u.mask & 0xFF; + break; + default: break; - default: - header_count = 0; - } -#endif /* P4_MPLS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ipv4_acl_table_add_entry(switch_device_t device, uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_ip_key_value_pair_t *ip_acl, - switch_acl_ip_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_ACL_DISABLE) && !defined(P4_IPV4_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_ip_acl_match_spec_t match_spec; - unsigned int i = 0; - switch_meter_idx_t meter_index = 0; - switch_stats_idx_t stats_index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - if (opt_action_params) { - meter_index = handle_to_id(opt_action_params->meter_handle); - stats_index = handle_to_id(opt_action_params->counter_handle); - } - - memset(&match_spec, 0, sizeof(p4_pd_dc_ip_acl_match_spec_t)); - - if (if_label) { - match_spec.acl_metadata_if_label = if_label; - match_spec.acl_metadata_if_label_mask = 0xFFFF; - } - if (bd_label) { - match_spec.acl_metadata_bd_label = bd_label; - match_spec.acl_metadata_bd_label_mask = 0xFFFF; } - for (i = 0; i < count; i++) { - switch(ip_acl[i].field) { - case SWITCH_ACL_IP_FIELD_IPV4_SRC: - match_spec.ipv4_metadata_lkp_ipv4_sa = ip_acl[i].value.ipv4_source; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = ip_acl[i].mask.u.mask & 0xFFFFFFFF; - break; - case SWITCH_ACL_IP_FIELD_IPV4_DEST: - match_spec.ipv4_metadata_lkp_ipv4_da = ip_acl[i].value.ipv4_dest; - match_spec.ipv4_metadata_lkp_ipv4_da_mask = ip_acl[i].mask.u.mask & 0xFFFFFFFF;; - break; - case SWITCH_ACL_IP_FIELD_IP_PROTO: - match_spec.l3_metadata_lkp_ip_proto = ip_acl[i].value.ip_proto; - match_spec.l3_metadata_lkp_ip_proto_mask = ip_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ip_acl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = ip_acl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_IP_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ip_acl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = ip_acl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_IP_FIELD_ICMP_TYPE: - match_spec.l3_metadata_lkp_l4_sport |= ip_acl[i].value.icmp_type << 8; - match_spec.l3_metadata_lkp_l4_sport_mask |= (ip_acl[i].mask.u.mask & 0xFF) << 8; - break; - case SWITCH_ACL_IP_FIELD_ICMP_CODE: - match_spec.l3_metadata_lkp_l4_sport |= ip_acl[i].value.icmp_code; - match_spec.l3_metadata_lkp_l4_sport_mask |= ip_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_IP_FIELD_TCP_FLAGS: - match_spec.tcp_flags = ip_acl[i].value.tcp_flags; - match_spec.tcp_flags_mask = ip_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_IP_FIELD_TTL: - match_spec.l3_metadata_lkp_ip_ttl = ip_acl[i].value.ttl; - match_spec.l3_metadata_lkp_ip_ttl_mask = ip_acl[i].mask.u.mask & 0xFF; - break; - default: - break; + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_acl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + if (opt_action_params) { + action_spec.action_nat_mode = opt_action_params->nat_mode; + } + status = p4_pd_dc_ip_acl_table_add_with_acl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_acl_permit_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; + if (opt_action_params) { + action_spec.action_nat_mode = opt_action_params->nat_mode; + } + status = p4_pd_dc_ip_acl_table_add_with_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_REDIRECT: { + switch_handle_t handle = action_params->redirect.handle; + if (switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { + p4_pd_dc_acl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = handle_to_id(handle); + if (opt_action_params) { + action_spec.action_nat_mode = opt_action_params->nat_mode; } - } - switch (action) { - case SWITCH_ACL_ACTION_DROP: - { - p4_pd_dc_acl_deny_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ip_acl_table_add_with_acl_deny( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_PERMIT: - { - p4_pd_dc_acl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ip_acl_table_add_with_acl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_REDIRECT: - { - switch_handle_t handle = action_params->redirect.handle; - if(switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { - p4_pd_dc_acl_redirect_nexthop_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = handle_to_id(handle); - p4_pd_dc_ip_acl_table_add_with_acl_redirect_nexthop( - g_sess_hdl, p4_pd_device, - &match_spec, priority, &action_spec, entry_hdl); - } - } - break; - case SWITCH_ACL_ACTION_SET_MIRROR: - { - p4_pd_dc_acl_mirror_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - action_spec.action_session_id = - handle_to_id(opt_action_params->mirror_handle); - status = p4_pd_dc_ip_acl_table_add_with_acl_mirror( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - 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_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = - switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); - status = p4_pd_dc_ip_acl_table_add_with_acl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_COPY_TO_CPU: - { - p4_pd_dc_acl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_copy = true; - 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; - status = p4_pd_dc_ip_acl_table_add_with_acl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - default: - break; - } + p4_pd_dc_ip_acl_table_add_with_acl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } + } break; + case SWITCH_ACL_ACTION_SET_MIRROR: { +#ifndef P4_MIRROR_DISABLE + p4_pd_dc_acl_mirror_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + action_spec.action_session_id = + handle_to_id(opt_action_params->mirror_handle); + if (opt_action_params) { + action_spec.action_nat_mode = opt_action_params->nat_mode; + } + status = p4_pd_dc_ip_acl_table_add_with_acl_mirror(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); +#endif /* P4_MIRROR_DISABLE */ + } break; + 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_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + if (opt_action_params) { + action_spec.action_nat_mode = opt_action_params->nat_mode; + } + status = p4_pd_dc_ip_acl_table_add_with_acl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_COPY_TO_CPU: { + p4_pd_dc_acl_permit_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; + if (opt_action_params) { + action_spec.action_nat_mode = opt_action_params->nat_mode; + } + status = p4_pd_dc_ip_acl_table_add_with_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + default: + break; + } #endif /* P4_ACL_DISABLE && P4_IPV4_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_ipv4_acl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_ipv4_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_IPV4_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_ip_acl_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_dc_ip_acl_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV4_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ipv6_acl_table_add_entry(switch_device_t device, uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_ipv6_key_value_pair_t *ipv6_acl, - switch_acl_ipv6_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ipv6_key_value_pair_t *ipv6_acl, + switch_acl_ipv6_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_ipv6_acl_match_spec_t match_spec; - unsigned int i = 0; - switch_meter_idx_t meter_index = 0; - switch_stats_idx_t stats_index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - if (opt_action_params) { - meter_index = handle_to_id(opt_action_params->meter_handle); - stats_index = handle_to_id(opt_action_params->counter_handle); - } - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_acl_match_spec_t)); - - if (if_label) { - match_spec.acl_metadata_if_label = if_label; - match_spec.acl_metadata_if_label_mask = 0xFFFF; - } - if (bd_label) { - match_spec.acl_metadata_bd_label = bd_label; - match_spec.acl_metadata_bd_label_mask = 0xFFFF; - } - for (i = 0; i < count; i++) { - switch(ipv6_acl[i].field) { - case SWITCH_ACL_IPV6_FIELD_IPV6_SRC: - memcpy(match_spec.ipv6_metadata_lkp_ipv6_sa, - ipv6_acl[i].value.ipv6_source.u.addr8, 16); - memcpy(match_spec.ipv6_metadata_lkp_ipv6_sa_mask, - ipv6_acl[i].mask.u.mask.u.addr8, 16); - break; - case SWITCH_ACL_IPV6_FIELD_IPV6_DEST: - memcpy(match_spec.ipv6_metadata_lkp_ipv6_da, - ipv6_acl[i].value.ipv6_dest.u.addr8, 16); - memcpy(match_spec.ipv6_metadata_lkp_ipv6_da_mask, - ipv6_acl[i].mask.u.mask.u.addr8, 16); - break; - case SWITCH_ACL_IPV6_FIELD_IP_PROTO: - match_spec.l3_metadata_lkp_ip_proto = ipv6_acl[i].value.ip_proto; - match_spec.l3_metadata_lkp_ip_proto_mask = ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; - break; - case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ipv6_acl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = ipv6_acl[i].mask.u.mask.u.addr16[0] & 0xFFFF; - break; - case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ipv6_acl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = ipv6_acl[i].mask.u.mask.u.addr16[0] & 0xFFFF; - break; - case SWITCH_ACL_IPV6_FIELD_ICMP_TYPE: - match_spec.l3_metadata_lkp_l4_sport |= ipv6_acl[i].value.icmp_type << 8; - match_spec.l3_metadata_lkp_l4_sport_mask |= (ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF) << 8; - break; - case SWITCH_ACL_IPV6_FIELD_ICMP_CODE: - match_spec.l3_metadata_lkp_l4_sport |= ipv6_acl[i].value.icmp_code; - match_spec.l3_metadata_lkp_l4_sport_mask |= ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; - break; - case SWITCH_ACL_IPV6_FIELD_TCP_FLAGS: - match_spec.tcp_flags = ipv6_acl[i].value.tcp_flags; - match_spec.tcp_flags_mask = ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; - break; - case SWITCH_ACL_IPV6_FIELD_TTL: - break; - default: - break; - } - } - switch (action) { - case SWITCH_ACL_ACTION_DROP: - { - p4_pd_dc_acl_deny_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv6_acl_table_add_with_acl_deny( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_PERMIT: - { - p4_pd_dc_acl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv6_acl_table_add_with_acl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_REDIRECT: - { - switch_handle_t handle = action_params->redirect.handle; - if(switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { - p4_pd_dc_acl_redirect_nexthop_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = handle_to_id(handle); - status = p4_pd_dc_ipv6_acl_table_add_with_acl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - } - break; - 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_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = - switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); - status = p4_pd_dc_ipv6_acl_table_add_with_acl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_COPY_TO_CPU: - { - p4_pd_dc_acl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_copy = true; - 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; - status = p4_pd_dc_ipv6_acl_table_add_with_acl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - default: - break; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_ipv6_acl_match_spec_t match_spec; + unsigned int i = 0; + switch_meter_idx_t meter_index = 0; + switch_stats_idx_t stats_index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + if (opt_action_params) { + meter_index = handle_to_id(opt_action_params->meter_handle); + stats_index = handle_to_id(opt_action_params->counter_handle); + } + + memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_acl_match_spec_t)); + + if (if_label) { + match_spec.acl_metadata_if_label = if_label; + match_spec.acl_metadata_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_bd_label = bd_label; + match_spec.acl_metadata_bd_label_mask = 0xFFFF; + } + for (i = 0; i < count; i++) { + switch (ipv6_acl[i].field) { + case SWITCH_ACL_IPV6_FIELD_IPV6_SRC: + memcpy(match_spec.ipv6_metadata_lkp_ipv6_sa, + ipv6_acl[i].value.ipv6_source.u.addr8, + 16); + memcpy(match_spec.ipv6_metadata_lkp_ipv6_sa_mask, + ipv6_acl[i].mask.u.mask.u.addr8, + 16); + break; + case SWITCH_ACL_IPV6_FIELD_IPV6_DEST: + memcpy(match_spec.ipv6_metadata_lkp_ipv6_da, + ipv6_acl[i].value.ipv6_dest.u.addr8, + 16); + memcpy(match_spec.ipv6_metadata_lkp_ipv6_da_mask, + ipv6_acl[i].mask.u.mask.u.addr8, + 16); + break; + case SWITCH_ACL_IPV6_FIELD_IP_PROTO: + match_spec.l3_metadata_lkp_ip_proto = ipv6_acl[i].value.ip_proto; + match_spec.l3_metadata_lkp_ip_proto_mask = + ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; + break; + case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT: + match_spec.l3_metadata_lkp_l4_sport = ipv6_acl[i].value.l4_source_port; + match_spec.l3_metadata_lkp_l4_sport_mask = + ipv6_acl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + break; + case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT: + match_spec.l3_metadata_lkp_l4_dport = ipv6_acl[i].value.l4_dest_port; + match_spec.l3_metadata_lkp_l4_dport_mask = + ipv6_acl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + break; + case SWITCH_ACL_IPV6_FIELD_ICMP_TYPE: + match_spec.l3_metadata_lkp_l4_sport |= ipv6_acl[i].value.icmp_type << 8; + match_spec.l3_metadata_lkp_l4_sport_mask |= + (ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF) << 8; + break; + case SWITCH_ACL_IPV6_FIELD_ICMP_CODE: + match_spec.l3_metadata_lkp_l4_sport |= ipv6_acl[i].value.icmp_code; + match_spec.l3_metadata_lkp_l4_sport_mask |= + ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; + break; + case SWITCH_ACL_IPV6_FIELD_TCP_FLAGS: + match_spec.tcp_flags = ipv6_acl[i].value.tcp_flags; + match_spec.tcp_flags_mask = ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; + break; + case SWITCH_ACL_IPV6_FIELD_TTL: + break; + default: + break; } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_acl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + status = p4_pd_dc_ipv6_acl_table_add_with_acl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_acl_permit_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; + status = p4_pd_dc_ipv6_acl_table_add_with_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_REDIRECT: { + switch_handle_t handle = action_params->redirect.handle; + if (switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { + p4_pd_dc_acl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = handle_to_id(handle); + status = + p4_pd_dc_ipv6_acl_table_add_with_acl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } + } break; + 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_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + status = + p4_pd_dc_ipv6_acl_table_add_with_acl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_COPY_TO_CPU: { + p4_pd_dc_acl_permit_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; + status = p4_pd_dc_ipv6_acl_table_add_with_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + default: + break; + } #endif /* P4_IPV6_DISABLE && P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_ipv6_acl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_ipv6_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_ipv6_acl_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_dc_ipv6_acl_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV6_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ipv4_racl_table_add_entry(switch_device_t device, uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_ip_racl_key_value_pair_t *ip_racl, - switch_acl_ip_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ipv4_racl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ip_racl_key_value_pair_t *ip_racl, + switch_acl_ip_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_ACL_DISABLE) && !defined(P4_IPV4_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_ipv4_racl_match_spec_t match_spec; - unsigned int i = 0; - switch_meter_idx_t meter_index = 0; - switch_stats_idx_t stats_index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_racl_match_spec_t)); - - if (opt_action_params) { - meter_index = handle_to_id(opt_action_params->meter_handle); - UNUSED(meter_index); - stats_index = handle_to_id(opt_action_params->counter_handle); - } - - if (bd_label) { - match_spec.acl_metadata_bd_label = bd_label; - match_spec.acl_metadata_bd_label_mask = 0xFFFF; - } - for (i = 0; i < count; i++) { - switch(ip_racl[i].field) { - case SWITCH_ACL_IP_RACL_FIELD_IPV4_SRC: - match_spec.ipv4_metadata_lkp_ipv4_sa = ip_racl[i].value.ipv4_source; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = ip_racl[i].mask.u.mask & 0xFFFFFFFF; - break; - case SWITCH_ACL_IP_RACL_FIELD_IPV4_DEST: - match_spec.ipv4_metadata_lkp_ipv4_da = ip_racl[i].value.ipv4_dest; - match_spec.ipv4_metadata_lkp_ipv4_da_mask = ip_racl[i].mask.u.mask & 0xFFFFFFFF; - break; - case SWITCH_ACL_IP_RACL_FIELD_IP_PROTO: - match_spec.l3_metadata_lkp_ip_proto = ip_racl[i].value.ip_proto; - match_spec.l3_metadata_lkp_ip_proto_mask = ip_racl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ip_racl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = ip_racl[i].mask.u.mask & 0xFFFF; - break; - case SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ip_racl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = ip_racl[i].mask.u.mask & 0xFFFF; - break; - default: - break; - } - } - switch (action) { - case SWITCH_ACL_ACTION_DROP: - { - p4_pd_dc_racl_deny_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv4_racl_table_add_with_racl_deny( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_PERMIT: - { - p4_pd_dc_racl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv4_racl_table_add_with_racl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_REDIRECT: - { - switch_handle_t handle = action_params->redirect.handle; - if(switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { - p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = handle_to_id(handle); - status = p4_pd_dc_ipv4_racl_table_add_with_racl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - } - break; - case SWITCH_ACL_ACTION_SET_NATMODE: - break; - case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: - { - p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = - switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); - status = p4_pd_dc_ipv4_racl_table_add_with_racl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_COPY_TO_CPU: - { - p4_pd_dc_racl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_copy = true; - action_spec.action_acl_copy_reason = - action_params->cpu_redirect.reason_code; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv4_racl_table_add_with_racl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - default: - break; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_ipv4_racl_match_spec_t match_spec; + unsigned int i = 0; + switch_meter_idx_t meter_index = 0; + switch_stats_idx_t stats_index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_racl_match_spec_t)); + + if (opt_action_params) { + meter_index = handle_to_id(opt_action_params->meter_handle); + UNUSED(meter_index); + stats_index = handle_to_id(opt_action_params->counter_handle); + } + + if (bd_label) { + match_spec.acl_metadata_bd_label = bd_label; + match_spec.acl_metadata_bd_label_mask = 0xFFFF; + } + for (i = 0; i < count; i++) { + switch (ip_racl[i].field) { + case SWITCH_ACL_IP_RACL_FIELD_IPV4_SRC: + match_spec.ipv4_metadata_lkp_ipv4_sa = ip_racl[i].value.ipv4_source; + match_spec.ipv4_metadata_lkp_ipv4_sa_mask = + ip_racl[i].mask.u.mask & 0xFFFFFFFF; + break; + case SWITCH_ACL_IP_RACL_FIELD_IPV4_DEST: + match_spec.ipv4_metadata_lkp_ipv4_da = ip_racl[i].value.ipv4_dest; + match_spec.ipv4_metadata_lkp_ipv4_da_mask = + ip_racl[i].mask.u.mask & 0xFFFFFFFF; + break; + case SWITCH_ACL_IP_RACL_FIELD_IP_PROTO: + match_spec.l3_metadata_lkp_ip_proto = ip_racl[i].value.ip_proto; + match_spec.l3_metadata_lkp_ip_proto_mask = + ip_racl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT: + match_spec.l3_metadata_lkp_l4_sport = ip_racl[i].value.l4_source_port; + match_spec.l3_metadata_lkp_l4_sport_mask = + ip_racl[i].mask.u.mask & 0xFFFF; + break; + case SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT: + match_spec.l3_metadata_lkp_l4_dport = ip_racl[i].value.l4_dest_port; + match_spec.l3_metadata_lkp_l4_dport_mask = + ip_racl[i].mask.u.mask & 0xFFFF; + break; + default: + break; } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_racl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_stats_index = stats_index; + status = p4_pd_dc_ipv4_racl_table_add_with_racl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_racl_permit_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_stats_index = stats_index; + status = p4_pd_dc_ipv4_racl_table_add_with_racl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_REDIRECT: { + switch_handle_t handle = action_params->redirect.handle; + if (switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { + p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = handle_to_id(handle); + status = p4_pd_dc_ipv4_racl_table_add_with_racl_redirect_nexthop( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } + } break; + case SWITCH_ACL_ACTION_SET_NATMODE: + break; + case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { + p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + status = + p4_pd_dc_ipv4_racl_table_add_with_racl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_COPY_TO_CPU: { + p4_pd_dc_racl_permit_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_stats_index = stats_index; + status = p4_pd_dc_ipv4_racl_table_add_with_racl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + default: + break; + } #endif /* P4_ACL_DISABLE && P4_IPV4_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_ipv4_racl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_ipv4_racl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_IPV4_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_ipv4_racl_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_dc_ipv4_racl_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_IPV4_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ipv6_racl_table_add_entry(switch_device_t device, uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_ipv6_racl_key_value_pair_t *ipv6_racl, - switch_acl_ipv6_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_ipv6_racl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ipv6_racl_key_value_pair_t *ipv6_racl, + switch_acl_ipv6_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_ipv6_racl_match_spec_t match_spec; - unsigned int i = 0; - switch_meter_idx_t meter_index = 0; - switch_stats_idx_t stats_index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_racl_match_spec_t)); - - if (opt_action_params) { - meter_index = handle_to_id(opt_action_params->meter_handle); - UNUSED(meter_index); - stats_index = handle_to_id(opt_action_params->counter_handle); - } - - if (bd_label) { - match_spec.acl_metadata_bd_label = bd_label; - match_spec.acl_metadata_bd_label_mask = 0xFFFF; - } - for (i = 0; i < count; i++) { - switch(ipv6_racl[i].field) { - case SWITCH_ACL_IPV6_RACL_FIELD_IPV6_SRC: - break; - case SWITCH_ACL_IPV6_RACL_FIELD_IPV6_DEST: - break; - case SWITCH_ACL_IPV6_RACL_FIELD_IP_PROTO: - match_spec.l3_metadata_lkp_ip_proto = ipv6_racl[i].value.ip_proto; - match_spec.l3_metadata_lkp_ip_proto_mask = ipv6_racl[i].mask.u.mask.u.addr8[0] & 0xFF; - break; - case SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ipv6_racl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = ipv6_racl[i].mask.u.mask.u.addr16[0] & 0xFFFF; - break; - case SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ipv6_racl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = ipv6_racl[i].mask.u.mask.u.addr16[0] & 0xFFFF; - break; - default: - break; - } - } - switch (action) { - case SWITCH_ACL_ACTION_DROP: - { - p4_pd_dc_racl_deny_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv6_racl_table_add_with_racl_deny( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_PERMIT: - { - p4_pd_dc_racl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv6_racl_table_add_with_racl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_REDIRECT: - { - switch_handle_t handle = action_params->redirect.handle; - if(switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { - p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = handle_to_id(handle); - p4_pd_dc_ipv6_racl_table_add_with_racl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - } - break; - case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: - { - p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = - switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); - status = p4_pd_dc_ipv6_racl_table_add_with_racl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_COPY_TO_CPU: - { - p4_pd_dc_racl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_copy = true; - action_spec.action_acl_copy_reason = - action_params->cpu_redirect.reason_code; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_ipv6_racl_table_add_with_racl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_SET_NATMODE: - break; - default: - break; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_ipv6_racl_match_spec_t match_spec; + unsigned int i = 0; + switch_meter_idx_t meter_index = 0; + switch_stats_idx_t stats_index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_racl_match_spec_t)); + + if (opt_action_params) { + meter_index = handle_to_id(opt_action_params->meter_handle); + UNUSED(meter_index); + stats_index = handle_to_id(opt_action_params->counter_handle); + } + + if (bd_label) { + match_spec.acl_metadata_bd_label = bd_label; + match_spec.acl_metadata_bd_label_mask = 0xFFFF; + } + for (i = 0; i < count; i++) { + switch (ipv6_racl[i].field) { + case SWITCH_ACL_IPV6_RACL_FIELD_IPV6_SRC: + break; + case SWITCH_ACL_IPV6_RACL_FIELD_IPV6_DEST: + break; + case SWITCH_ACL_IPV6_RACL_FIELD_IP_PROTO: + match_spec.l3_metadata_lkp_ip_proto = ipv6_racl[i].value.ip_proto; + match_spec.l3_metadata_lkp_ip_proto_mask = + ipv6_racl[i].mask.u.mask.u.addr8[0] & 0xFF; + break; + case SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT: + match_spec.l3_metadata_lkp_l4_sport = ipv6_racl[i].value.l4_source_port; + match_spec.l3_metadata_lkp_l4_sport_mask = + ipv6_racl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + break; + case SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT: + match_spec.l3_metadata_lkp_l4_dport = ipv6_racl[i].value.l4_dest_port; + match_spec.l3_metadata_lkp_l4_dport_mask = + ipv6_racl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + break; + default: + break; } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_racl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_stats_index = stats_index; + status = p4_pd_dc_ipv6_racl_table_add_with_racl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_racl_permit_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_stats_index = stats_index; + status = p4_pd_dc_ipv6_racl_table_add_with_racl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_REDIRECT: { + switch_handle_t handle = action_params->redirect.handle; + if (switch_handle_get_type(handle) == SWITCH_HANDLE_TYPE_NHOP) { + p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = handle_to_id(handle); + p4_pd_dc_ipv6_racl_table_add_with_racl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } + } break; + case SWITCH_ACL_ACTION_REDIRECT_TO_CPU: { + p4_pd_dc_racl_redirect_nexthop_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_stats_index = stats_index; + action_spec.action_nexthop_index = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + status = + p4_pd_dc_ipv6_racl_table_add_with_racl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_COPY_TO_CPU: { + p4_pd_dc_racl_permit_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_stats_index = stats_index; + status = p4_pd_dc_ipv6_racl_table_add_with_racl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_SET_NATMODE: + break; + default: + break; + } #endif /* P4_IPV6_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ipv6_racl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_ipv6_racl_table_delete(g_sess_hdl, device, entry_hdl); -#endif /* P4_IPV6_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_mac_acl_table_add_entry(switch_device_t device, uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_mac_key_value_pair_t *mac_acl, - switch_acl_mac_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_L2_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_mac_acl_match_spec_t match_spec; - unsigned int i = 0; - switch_meter_idx_t meter_index = 0; - switch_stats_idx_t stats_index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_mac_acl_match_spec_t)); - - if (opt_action_params) { - meter_index = handle_to_id(opt_action_params->meter_handle); - stats_index = handle_to_id(opt_action_params->counter_handle); - } - - if (if_label) { - match_spec.acl_metadata_if_label = if_label; - match_spec.acl_metadata_if_label_mask = 0xFFFF; - } - if (bd_label) { - match_spec.acl_metadata_bd_label = bd_label; - match_spec.acl_metadata_bd_label_mask = 0xFFFF; - } - for (i = 0; i < count; i++) { - switch(mac_acl[i].field) { - case SWITCH_ACL_MAC_FIELD_ETH_TYPE: - match_spec.l2_metadata_lkp_mac_type = mac_acl[i].value.eth_type; - match_spec.l2_metadata_lkp_mac_type_mask = mac_acl[i].mask.u.mask16 & 0xFFFF; - break; - case SWITCH_ACL_MAC_FIELD_SOURCE_MAC: - memcpy(match_spec.l2_metadata_lkp_mac_sa, mac_acl[i].value.source_mac, 6); - memcpy(match_spec.l2_metadata_lkp_mac_sa_mask, mac_acl[i].mask.u.mac_mask, 6); - break; - case SWITCH_ACL_MAC_FIELD_DEST_MAC: - memcpy(match_spec.l2_metadata_lkp_mac_da, mac_acl[i].value.dest_mac, 6); - memcpy(match_spec.l2_metadata_lkp_mac_da_mask, mac_acl[i].mask.u.mac_mask, 6); - break; - default: - break; - } - } - switch (action) { - case SWITCH_ACL_ACTION_DROP: - { - p4_pd_dc_acl_deny_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_mac_acl_table_add_with_acl_deny( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_PERMIT: - { - p4_pd_dc_acl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - status = p4_pd_dc_mac_acl_table_add_with_acl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - 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_meter_index = meter_index; - action_spec.action_acl_stats_index = stats_index; - action_spec.action_nexthop_index = - switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); - p4_pd_dc_mac_acl_table_add_with_acl_redirect_nexthop( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_COPY_TO_CPU: - { - p4_pd_dc_acl_permit_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); - action_spec.action_acl_copy = true; - 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; - status = p4_pd_dc_mac_acl_table_add_with_acl_permit( - g_sess_hdl, p4_pd_device, &match_spec, - priority, &action_spec, entry_hdl); - } - break; - case SWITCH_ACL_ACTION_REDIRECT: - break; - default: - break; - } -#endif /* P4_L2_DISABLE && P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_mac_acl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_L2_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_mac_acl_table_delete(g_sess_hdl, device, entry_hdl); -#endif /* P4_L2_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_egr_acl_table_add_entry(switch_device_t device, - uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_egr_key_value_pair_t *egr_acl, - switch_acl_egr_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl) -{ - unsigned int i; - p4_pd_status_t status = 0; - (void)bd_label; - (void)if_label; - -#ifndef P4_ACL_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_egress_acl_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_egress_acl_match_spec_t)); - for (i=0; i < count; i++) { - switch(egr_acl[i].field) { - case SWITCH_ACL_EGR_DEST_PORT: - { - match_spec.egress_egress_port_mask = 0xFFFF; - match_spec.egress_egress_port = - handle_to_id(egr_acl[i].value.egr_port); - } - break; - case SWITCH_ACL_EGR_DEFLECT: - { - match_spec.intrinsic_metadata_deflection_flag = - egr_acl[i].value.deflection_flag ? 0x1 : 0; - match_spec.intrinsic_metadata_deflection_flag_mask = 0xFF; - } - break; - case SWITCH_ACL_EGR_L3_MTU_CHECK: - { - match_spec.l3_metadata_l3_mtu_check = - egr_acl[i].value.l3_mtu_check; - match_spec.l3_metadata_l3_mtu_check_mask = 0xFFFF; - } - break; - default: - break; - } - } - - switch (action) { - case SWITCH_ACL_EGR_ACTION_NOP: - status = p4_pd_dc_egress_acl_table_add_with_nop(g_sess_hdl, - p4_pd_device, &match_spec, priority, - entry_hdl); - break; - case SWITCH_ACL_EGR_ACTION_SET_MIRROR: - { - p4_pd_dc_egress_mirror_action_spec_t action_spec; - action_spec.action_session_id = - handle_to_id(opt_action_params->mirror_handle); - status = p4_pd_dc_egress_acl_table_add_with_egress_mirror( - g_sess_hdl, p4_pd_device, &match_spec, priority, - &action_spec, entry_hdl); - break; - } - case SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU: - { - p4_pd_dc_egress_redirect_to_cpu_action_spec_t action_spec; - action_spec.action_reason_code = - action_params->cpu_redirect.reason_code; - status = p4_pd_dc_egress_acl_table_add_with_egress_redirect_to_cpu( - g_sess_hdl, p4_pd_device, &match_spec, priority, - &action_spec, entry_hdl); - break; - } - default: - break; - } -#endif /* P4_ACL_DISABLE */ - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_egr_acl_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_egress_acl_table_delete(g_sess_hdl, device, entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_qos_acl_table_add_entry(switch_device_t device, uint16_t if_label, - uint16_t bd_label, uint16_t priority, - unsigned int count, - switch_acl_qos_key_value_pair_t *qos_acl, - switch_acl_mac_action_t action, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; -#ifndef P4_ACL_DISABLE -#ifndef P4_QOS_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_qos_match_spec_t match_spec; - unsigned int i = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_qos_match_spec_t)); - - if (if_label) { - match_spec.acl_metadata_if_label = if_label; - match_spec.acl_metadata_if_label_mask = 0xFFFF; - } - for (i = 0; i < count; i++) { - switch(qos_acl[i].field) { - case SWITCH_ACL_QOS_FIELD_IPV4_SRC: - match_spec.ipv4_metadata_lkp_ipv4_sa = qos_acl[i].value.ipv4_source; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = qos_acl[i].mask.u.mask & 0xFFFFFFFF; - break; - case SWITCH_ACL_QOS_FIELD_IPV4_DEST: - match_spec.ipv4_metadata_lkp_ipv4_da = qos_acl[i].value.ipv4_dest; - match_spec.ipv4_metadata_lkp_ipv4_da_mask = qos_acl[i].mask.u.mask & 0xFFFFFFFF;; - break; - case SWITCH_ACL_QOS_FIELD_IP_PROTO: - match_spec.l3_metadata_lkp_ip_proto = qos_acl[i].value.ip_proto; - match_spec.l3_metadata_lkp_ip_proto_mask = qos_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_QOS_FIELD_TC: - match_spec.l3_metadata_lkp_ip_tc = qos_acl[i].value.tc; - match_spec.l3_metadata_lkp_ip_tc_mask = qos_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_QOS_FIELD_EXP: - match_spec.tunnel_metadata_mpls_exp = qos_acl[i].value.exp; - match_spec.tunnel_metadata_mpls_exp_mask = qos_acl[i].mask.u.mask & 0xFF; - break; - case SWITCH_ACL_QOS_FIELD_DSCP: - match_spec.qos_metadata_outer_dscp = qos_acl[i].value.dscp; - match_spec.qos_metadata_outer_dscp_mask = qos_acl[i].mask.u.mask & 0xFF; - break; - default: - break; - } - } - switch (action) { - case SWITCH_ACL_QOS_ACTION_COS: - { - p4_pd_dc_apply_cos_marking_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_apply_cos_marking_action_spec_t)); - status = p4_pd_dc_qos_table_add_with_apply_cos_marking(g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &action_spec, - entry_hdl); - } - break; - case SWITCH_ACL_QOS_ACTION_DSCP: - { - p4_pd_dc_apply_dscp_marking_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_apply_dscp_marking_action_spec_t)); - status = p4_pd_dc_qos_table_add_with_apply_dscp_marking(g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &action_spec, - entry_hdl); - } - break; - case SWITCH_ACL_QOS_ACTION_TC: - { - p4_pd_dc_apply_tc_marking_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(p4_pd_dc_apply_tc_marking_action_spec_t)); - status = p4_pd_dc_qos_table_add_with_apply_tc_marking(g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &action_spec, - entry_hdl); - } - break; - default: - break; - } -#endif /* P4_QOS_DISABLE */ -#endif /* P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_qos_acl_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; -#if !defined(P4_QOS_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_qos_table_delete(g_sess_hdl, device, entry_hdl); -#endif /* P4_QOS_DISABLE & P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_ingress_fabric_table_add_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dc_fabric_ingress_dst_lkp_match_spec_t match_spec; - memset(&match_spec, 0, sizeof(p4_pd_dc_fabric_ingress_dst_lkp_match_spec_t)); - match_spec.fabric_header_dstDevice = device; - status = p4_pd_dc_fabric_ingress_dst_lkp_table_add_with_terminate_cpu_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -/* - * DEFAULT ENTRIES - * TODO: Remove them once the default action can be specified in P4. - */ - -p4_pd_status_t -switch_pd_ip_mcast_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_MULTICAST_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - -#ifndef P4_IPV4_DISABLE -#ifndef P4_TUNNEL_DISABLE - status = p4_pd_dc_outer_ipv4_multicast_set_default_action_on_miss( - g_sess_hdl, p4_pd_device, &entry_hdl); - 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 -#ifndef P4_TUNNEL_DISABLE - status = p4_pd_dc_outer_ipv6_multicast_set_default_action_on_miss( - g_sess_hdl, p4_pd_device, &entry_hdl); - 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 */ - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_validate_outer_ethernet_add_default_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; - p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t action_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&action_spec, 0, - sizeof(p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_OUTER_ETHERNET_MISS; - status = p4_pd_dc_validate_outer_ethernet_set_default_action_malformed_outer_ethernet_packet( - g_sess_hdl, - p4_pd_device, - &action_spec, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_validate_outer_ip_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_L3_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - -#ifndef P4_IPV4_DISABLE - p4_pd_dc_validate_outer_ipv4_packet_match_spec_t match_spec; - p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t action_spec; - - /* default entry */ - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_OUTER_IP_MISS; - status = p4_pd_dc_validate_outer_ipv4_packet_set_default_action_set_malformed_outer_ipv4_packet( - g_sess_hdl, - p4_pd_device, - &action_spec, - &entry_hdl); - - /* ipv4 src is loopback */ - memset(&match_spec, 0, - 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_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, - p4_pd_device, - &match_spec, - 10, - &action_spec, - &entry_hdl); - - /* ipv4 src is multicast */ - memset(&match_spec, 0, - 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_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, - p4_pd_device, - &match_spec, - 11, - &action_spec, - &entry_hdl); - - /* ttl is zero */ - memset(&match_spec, 0, - 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_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, - p4_pd_device, - &match_spec, - 12, - &action_spec, - &entry_hdl); - - /* version is 4 and packet is okay */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ipv4_packet_match_spec_t)); - match_spec.ipv4_version = 0x04; - match_spec.ipv4_version_mask = 0xff; - status = p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_valid_outer_ipv4_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - 13, - &entry_hdl); - - /* invalid version */ - memset(&match_spec, 0, - 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)); - action_spec.action_drop_reason = DROP_OUTER_IP_VERSION_INVALID; - status = p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_malformed_outer_ipv4_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - 14, - &action_spec, - &entry_hdl); -#endif /* P4_IPV4_DISABLE */ - -#ifndef P4_IPV6_DISABLE - p4_pd_dc_validate_outer_ipv6_packet_match_spec_t v6_match_spec; - p4_pd_dc_set_malformed_outer_ipv6_packet_action_spec_t v6_action_spec; - - /* default entry */ - memset(&v6_action_spec, 0, - sizeof(p4_pd_dc_set_malformed_outer_ipv6_packet_action_spec_t)); - v6_action_spec.action_drop_reason = DROP_OUTER_IP_MISS; - status = p4_pd_dc_validate_outer_ipv6_packet_set_default_action_set_malformed_outer_ipv6_packet( - g_sess_hdl, - p4_pd_device, - &v6_action_spec, - &entry_hdl); - - /* ipv6 src is multicast */ - memset(&v6_match_spec, 0, - 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_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, - p4_pd_device, - &v6_match_spec, - 11, - &v6_action_spec, - &entry_hdl); - - /* ttl is zero */ - memset(&v6_match_spec, 0, - 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_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, - p4_pd_device, - &v6_match_spec, - 12, - &v6_action_spec, - &entry_hdl); - - /* version is 6 and packet is okay */ - memset(&v6_match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ipv6_packet_match_spec_t)); - v6_match_spec.ipv6_version = 0x06; - v6_match_spec.ipv6_version_mask = 0xff; - status = p4_pd_dc_validate_outer_ipv6_packet_table_add_with_set_valid_outer_ipv6_packet( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - 13, - &entry_hdl); - - /* invalid version */ - memset(&v6_match_spec, 0, - 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_action_spec.action_drop_reason = DROP_OUTER_IP_VERSION_INVALID; - status = p4_pd_dc_validate_outer_ipv6_packet_table_add_with_set_malformed_outer_ipv6_packet( - g_sess_hdl, - p4_pd_device, - &v6_match_spec, - 14, - &v6_action_spec, - &entry_hdl); -#endif /* P4_IPV6_DISABLE */ - -#endif /* P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_ipv6_racl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) + p4_pd_dc_ipv6_racl_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_IPV6_DISABLE & P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_mac_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_mac_key_value_pair_t *mac_acl, + switch_acl_mac_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L2_DISABLE) && !defined(P4_ACL_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_mac_acl_match_spec_t match_spec; + unsigned int i = 0; + switch_meter_idx_t meter_index = 0; + switch_stats_idx_t stats_index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_mac_acl_match_spec_t)); + + if (opt_action_params) { + meter_index = handle_to_id(opt_action_params->meter_handle); + stats_index = handle_to_id(opt_action_params->counter_handle); + } + + if (if_label) { + match_spec.acl_metadata_if_label = if_label; + match_spec.acl_metadata_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_bd_label = bd_label; + match_spec.acl_metadata_bd_label_mask = 0xFFFF; + } + for (i = 0; i < count; i++) { + switch (mac_acl[i].field) { + case SWITCH_ACL_MAC_FIELD_ETH_TYPE: + match_spec.l2_metadata_lkp_mac_type = mac_acl[i].value.eth_type; + match_spec.l2_metadata_lkp_mac_type_mask = + mac_acl[i].mask.u.mask16 & 0xFFFF; + break; + case SWITCH_ACL_MAC_FIELD_SOURCE_MAC: + memcpy(match_spec.l2_metadata_lkp_mac_sa, + mac_acl[i].value.source_mac.mac_addr, + ETH_LEN); + memcpy(match_spec.l2_metadata_lkp_mac_sa_mask, + &mac_acl[i].mask.u.mask, + ETH_LEN); + break; + case SWITCH_ACL_MAC_FIELD_DEST_MAC: + memcpy(match_spec.l2_metadata_lkp_mac_da, + mac_acl[i].value.dest_mac.mac_addr, + ETH_LEN); + memcpy(match_spec.l2_metadata_lkp_mac_da_mask, + &mac_acl[i].mask.u.mask, + ETH_LEN); + break; + default: + break; + } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_acl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_meter_index = meter_index; + action_spec.action_acl_stats_index = stats_index; + status = p4_pd_dc_mac_acl_table_add_with_acl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_acl_permit_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; + status = p4_pd_dc_mac_acl_table_add_with_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + 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 = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + p4_pd_dc_mac_acl_table_add_with_acl_redirect_nexthop(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_COPY_TO_CPU: { + p4_pd_dc_acl_permit_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; + status = p4_pd_dc_mac_acl_table_add_with_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_REDIRECT: + break; + default: + break; + } +#endif /* P4_L2_DISABLE && P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_outer_rmac_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_mac_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L2_DISABLE) && !defined(P4_ACL_DISABLE) + p4_pd_dc_mac_acl_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_L2_DISABLE & P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_egr_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_egr_key_value_pair_t *egr_acl, + switch_acl_egr_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + (void)bd_label; + (void)if_label; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +#ifndef P4_ACL_DISABLE + unsigned int i; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_egress_acl_match_spec_t match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_egress_acl_match_spec_t)); + for (i = 0; i < count; i++) { + switch (egr_acl[i].field) { + case SWITCH_ACL_EGR_DEST_PORT: { + match_spec.standard_metadata_egress_port_mask = 0xFFFF; + match_spec.standard_metadata_egress_port = + handle_to_id(egr_acl[i].value.egr_port); + } break; + case SWITCH_ACL_EGR_DEFLECT: { + match_spec.intrinsic_metadata_deflection_flag = + egr_acl[i].value.deflection_flag ? 0x1 : 0; + match_spec.intrinsic_metadata_deflection_flag_mask = 0xFF; + } break; + case SWITCH_ACL_EGR_L3_MTU_CHECK: { + match_spec.l3_metadata_l3_mtu_check = egr_acl[i].value.l3_mtu_check; + match_spec.l3_metadata_l3_mtu_check_mask = 0xFFFF; + } break; + default: + break; + } + } + + switch (action) { + case SWITCH_ACL_EGR_ACTION_NOP: + status = p4_pd_dc_egress_acl_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); + break; + case SWITCH_ACL_EGR_ACTION_SET_MIRROR: { +#if !defined(P4_MIRROR_DISABLE) + p4_pd_dc_egress_mirror_action_spec_t action_spec; + action_spec.action_session_id = + handle_to_id(opt_action_params->mirror_handle); + status = p4_pd_dc_egress_acl_table_add_with_egress_mirror(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + break; +#endif /* P4_MIRROR_DISABLE */ + } + case SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU: { + p4_pd_dc_egress_redirect_to_cpu_action_spec_t action_spec; + action_spec.action_reason_code = action_params->cpu_redirect.reason_code; + status = p4_pd_dc_egress_acl_table_add_with_egress_redirect_to_cpu( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + break; + } + default: + break; + } +#endif /* P4_ACL_DISABLE */ - status = p4_pd_dc_outer_rmac_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_src_vtep_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_egr_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_ACL_DISABLE + status = p4_pd_dc_egress_acl_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); +#endif /* P4_ACL_DISABLE */ + return status; +} - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +p4_pd_status_t switch_pd_ingress_fabric_table_add_entry( + switch_device_t device) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; -#ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ipv4_src_vtep_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); -#endif /* P4_IPV4_DISABLE */ -#ifndef P4_IPV6_DISABLE - status = p4_pd_dc_ipv6_src_vtep_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); -#endif /* P4_IPV6_DISABLE */ + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -#endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dc_fabric_ingress_dst_lkp_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(p4_pd_dc_fabric_ingress_dst_lkp_match_spec_t)); + match_spec.fabric_header_dstDevice = device; + status = p4_pd_dc_fabric_ingress_dst_lkp_table_add_with_terminate_cpu_packet( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_dest_vtep_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +/* + * DEFAULT ENTRIES + * TODO: Remove them once the default action can be specified in P4. + */ + +p4_pd_status_t switch_pd_ip_mcast_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_MULTICAST_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ipv4_dest_vtep_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); +#ifndef P4_TUNNEL_DISABLE + status = p4_pd_dc_outer_ipv4_multicast_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + 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 - status = p4_pd_dc_ipv6_dest_vtep_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); +#ifndef P4_TUNNEL_DISABLE + status = p4_pd_dc_outer_ipv6_multicast_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + 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 */ -#endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_smac_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_validate_outer_ethernet_add_default_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; + p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t action_spec; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_tunnel_smac_rewrite_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_OUTER_ETHERNET_MISS; + status = + p4_pd_dc_validate_outer_ethernet_set_default_action_malformed_outer_ethernet_packet( + g_sess_hdl, p4_pd_device, &action_spec, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + return status; } -p4_pd_status_t -switch_pd_tunnel_dmac_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_validate_outer_ip_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_L3_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_tunnel_dmac_rewrite_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); +#ifndef P4_IPV4_DISABLE + p4_pd_dc_validate_outer_ipv4_packet_match_spec_t match_spec; + p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t action_spec; + + /* default entry */ + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_malformed_outer_ipv4_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_OUTER_IP_MISS; + status = + p4_pd_dc_validate_outer_ipv4_packet_set_default_action_set_malformed_outer_ipv4_packet( + g_sess_hdl, p4_pd_device, &action_spec, &entry_hdl); + + /* ipv4 src is loopback */ + memset( + &match_spec, 0, 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_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, p4_pd_device, &match_spec, 10, &action_spec, &entry_hdl); + + /* ipv4 src is multicast */ + memset( + &match_spec, 0, 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_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, p4_pd_device, &match_spec, 11, &action_spec, &entry_hdl); + + /* ttl is zero */ + memset( + &match_spec, 0, 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_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, p4_pd_device, &match_spec, 12, &action_spec, &entry_hdl); + + /* version is 4 and packet is okay */ + memset( + &match_spec, 0, sizeof(p4_pd_dc_validate_outer_ipv4_packet_match_spec_t)); + match_spec.ipv4_version = 0x04; + match_spec.ipv4_version_mask = 0xff; + status = + p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_valid_outer_ipv4_packet( + g_sess_hdl, p4_pd_device, &match_spec, 13, &entry_hdl); + + /* invalid version */ + memset( + &match_spec, 0, 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)); + action_spec.action_drop_reason = DROP_OUTER_IP_VERSION_INVALID; + status = + p4_pd_dc_validate_outer_ipv4_packet_table_add_with_set_malformed_outer_ipv4_packet( + g_sess_hdl, p4_pd_device, &match_spec, 14, &action_spec, &entry_hdl); +#endif /* P4_IPV4_DISABLE */ -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; +#ifndef P4_IPV6_DISABLE + p4_pd_dc_validate_outer_ipv6_packet_match_spec_t v6_match_spec; + p4_pd_dc_set_malformed_outer_ipv6_packet_action_spec_t v6_action_spec; + + /* default entry */ + memset(&v6_action_spec, + 0, + sizeof(p4_pd_dc_set_malformed_outer_ipv6_packet_action_spec_t)); + v6_action_spec.action_drop_reason = DROP_OUTER_IP_MISS; + status = + p4_pd_dc_validate_outer_ipv6_packet_set_default_action_set_malformed_outer_ipv6_packet( + g_sess_hdl, p4_pd_device, &v6_action_spec, &entry_hdl); + + /* ipv6 src is multicast */ + memset(&v6_match_spec, + 0, + 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_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, + p4_pd_device, + &v6_match_spec, + 11, + &v6_action_spec, + &entry_hdl); + + /* ttl is zero */ + memset(&v6_match_spec, + 0, + 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_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, + p4_pd_device, + &v6_match_spec, + 12, + &v6_action_spec, + &entry_hdl); + + /* version is 6 and packet is okay */ + memset(&v6_match_spec, + 0, + sizeof(p4_pd_dc_validate_outer_ipv6_packet_match_spec_t)); + v6_match_spec.ipv6_version = 0x06; + v6_match_spec.ipv6_version_mask = 0xff; + status = + p4_pd_dc_validate_outer_ipv6_packet_table_add_with_set_valid_outer_ipv6_packet( + g_sess_hdl, p4_pd_device, &v6_match_spec, 13, &entry_hdl); + + /* invalid version */ + memset(&v6_match_spec, + 0, + 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_action_spec.action_drop_reason = DROP_OUTER_IP_VERSION_INVALID; + status = + p4_pd_dc_validate_outer_ipv6_packet_table_add_with_set_malformed_outer_ipv6_packet( + g_sess_hdl, + p4_pd_device, + &v6_match_spec, + 14, + &v6_action_spec, + &entry_hdl); +#endif /* P4_IPV6_DISABLE */ + +#endif /* P4_L3_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_outer_rmac_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - status = p4_pd_dc_tunnel_rewrite_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + status = p4_pd_dc_outer_rmac_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_port_vlan_mapping_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; - p4_pd_mbr_hdl_t mbr_hdl; - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_src_vtep_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = 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); - status = p4_pd_dc_port_vlan_mapping_set_default_entry(g_sess_hdl, - p4_pd_device, - mbr_hdl, - &entry_hdl); +#ifndef P4_IPV4_DISABLE + status = p4_pd_dc_ipv4_src_vtep_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_IPV4_DISABLE */ +#ifndef P4_IPV6_DISABLE + status = p4_pd_dc_ipv6_src_vtep_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; +#endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_validate_packet_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - int priority = 100; - int i; - p4_pd_dc_validate_packet_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - status = p4_pd_dc_validate_packet_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - - /* src is multicast */ - p4_pd_dc_set_malformed_packet_action_spec_t action_spec; - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_sa[0] = 0x01; - match_spec.l2_metadata_lkp_mac_sa_mask[0] = 0x01; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_SRC_MAC_MULTICAST; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); - - /* dst is zero */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_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(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_DST_MAC_ZERO; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); - - /* IPv4 TTL is zero */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_ttl = 0; - match_spec.l3_metadata_lkp_ip_ttl_mask = 0xff; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_TTL_ZERO; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); +p4_pd_status_t switch_pd_dest_vtep_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) && !defined(P4_L3_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - /* IPv6 TTL is zero */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_ttl = 0; - match_spec.l3_metadata_lkp_ip_ttl_mask = 0xff; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_TTL_ZERO; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - /* ipv4 src is loopback */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.ipv4_metadata_lkp_ipv4_sa = 0x7f000000; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xff000000; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_SRC_LOOPBACK; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); +#ifndef P4_IPV4_DISABLE + status = p4_pd_dc_ipv4_dest_vtep_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_IPV4_DISABLE */ +#ifndef P4_IPV6_DISABLE + status = p4_pd_dc_ipv6_dest_vtep_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ - /* ipv4 src is multicast */ +#endif /* P4_TUNNEL_DISABLE && P4_L3_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_smac_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_tunnel_smac_rewrite_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_dmac_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_tunnel_dmac_rewrite_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_tunnel_rewrite_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_port_vlan_mapping_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; + p4_pd_mbr_hdl_t mbr_hdl; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = 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); + status = p4_pd_dc_port_vlan_mapping_set_default_entry( + g_sess_hdl, p4_pd_device, mbr_hdl, &entry_hdl); + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_validate_packet_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + int priority = 100; + int i; + p4_pd_dc_validate_packet_match_spec_t match_spec; + p4_pd_dc_set_malformed_packet_action_spec_t action_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_validate_packet_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + /* src mac is zero */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_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(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_SRC_MAC_ZERO; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + /* src is multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l2_metadata_lkp_mac_sa[0] = 0x01; + match_spec.l2_metadata_lkp_mac_sa_mask[0] = 0x01; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_SRC_MAC_MULTICAST; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + + /* dst is zero */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_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(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_DST_MAC_ZERO; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + + /* IPv4 TTL is zero */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.l3_metadata_lkp_ip_ttl = 0; + match_spec.l3_metadata_lkp_ip_ttl_mask = 0xff; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_TTL_ZERO; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + + /* IPv6 TTL is zero */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.l3_metadata_lkp_ip_ttl = 0; + match_spec.l3_metadata_lkp_ip_ttl_mask = 0xff; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_TTL_ZERO; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + + /* ipv4 src is loopback */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.ipv4_metadata_lkp_ipv4_sa = 0x7f000000; + match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xff000000; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_SRC_LOOPBACK; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + + /* ipv4 src is multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.ipv4_metadata_lkp_ipv4_sa = 0xe0000000; + match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xf0000000; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_SRC_MULTICAST; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); + + /* ipv4 version invalid */ + for (i = 0; i < 16; i++) { + if (i == 4) { + continue; + } memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.ipv4_metadata_lkp_ipv4_sa = 0xe0000000; - match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xf0000000; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_SRC_MULTICAST; + match_spec.l3_metadata_lkp_ip_version = i; + match_spec.l3_metadata_lkp_ip_version_mask = 0xff; + memset( + &action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_VERSION_INVALID; status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( g_sess_hdl, p4_pd_device, @@ -6121,61 +5926,22 @@ switch_pd_validate_packet_table_add_default_entry(switch_device_t device) priority++, &action_spec, &entry_hdl); - - /* ipv4 version invalid */ - for (i = 0; i < 16; i++) { - if (i == 4) { - continue; - } - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_version = i; - match_spec.l3_metadata_lkp_ip_version_mask = 0xff; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_VERSION_INVALID; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); - } + } #ifndef IPV6_DISABLE - /* ipv6 version invalid */ - for (i = 0; i < 16; i++) { - if (i == 6) { - continue; - } - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_version = i; - match_spec.l3_metadata_lkp_ip_version_mask = 0xff; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_VERSION_INVALID; - status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &action_spec, - &entry_hdl); + /* ipv6 version invalid */ + for (i = 0; i < 16; i++) { + if (i == 6) { + continue; } - - /* ipv6 src is multicast */ memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xff; - match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xff; - memset(&action_spec, 0, - sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); - action_spec.action_drop_reason = DROP_IP_SRC_MULTICAST; + match_spec.l3_metadata_lkp_ip_version = i; + match_spec.l3_metadata_lkp_ip_version_mask = 0xff; + memset( + &action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_VERSION_INVALID; status = p4_pd_dc_validate_packet_table_add_with_set_malformed_packet( g_sess_hdl, p4_pd_device, @@ -6183,3126 +5949,2983 @@ switch_pd_validate_packet_table_add_default_entry(switch_device_t device) priority++, &action_spec, &entry_hdl); + } + + /* ipv6 src is multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xff; + match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xff; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_malformed_packet_action_spec_t)); + action_spec.action_drop_reason = DROP_IP_SRC_MULTICAST; + status = + p4_pd_dc_validate_packet_table_add_with_set_malformed_packet(g_sess_hdl, + p4_pd_device, + &match_spec, + priority++, + &action_spec, + &entry_hdl); #endif /* IPV6_DISABLE */ - /* broadcast */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_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; - status = p4_pd_dc_validate_packet_table_add_with_set_broadcast( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &entry_hdl); + /* broadcast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_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; + status = p4_pd_dc_validate_packet_table_add_with_set_broadcast( + g_sess_hdl, p4_pd_device, &match_spec, priority++, &entry_hdl); #ifndef IPV6_DISABLE - /* multicast, source is ipv6 link local */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0x01; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xfe; - match_spec.ipv6_metadata_lkp_ipv6_sa[1] = 0x80; - match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xff; - match_spec.ipv6_metadata_lkp_ipv6_sa_mask[1] = 0xff; - status = p4_pd_dc_validate_packet_table_add_with_set_multicast_and_ipv6_src_is_link_local( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &entry_hdl); + /* multicast, source is ipv6 link local */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l2_metadata_lkp_mac_da[0] = 0x01; + match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xfe; + match_spec.ipv6_metadata_lkp_ipv6_sa[1] = 0x80; + match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xff; + match_spec.ipv6_metadata_lkp_ipv6_sa_mask[1] = 0xff; + status = + p4_pd_dc_validate_packet_table_add_with_set_multicast_and_ipv6_src_is_link_local( + g_sess_hdl, p4_pd_device, &match_spec, priority++, &entry_hdl); #endif /* IPV6_DISABLE */ - /* multicast */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l2_metadata_lkp_mac_da[0] = 0x01; - match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; - status = p4_pd_dc_validate_packet_table_add_with_set_multicast( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &entry_hdl); + /* multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l2_metadata_lkp_mac_da[0] = 0x01; + match_spec.l2_metadata_lkp_mac_da_mask[0] = 0x01; + status = p4_pd_dc_validate_packet_table_add_with_set_multicast( + g_sess_hdl, p4_pd_device, &match_spec, priority++, &entry_hdl); #ifndef IPV6_DISABLE - /* unicast, source is ipv6 link local */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xfe; - match_spec.ipv6_metadata_lkp_ipv6_sa[1] = 0x80; - match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xfe; - match_spec.ipv6_metadata_lkp_ipv6_sa_mask[1] = 0x80; - status = p4_pd_dc_validate_packet_table_add_with_set_unicast_and_ipv6_src_is_link_local( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &entry_hdl); + /* unicast, source is ipv6 link local */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.ipv6_metadata_lkp_ipv6_sa[0] = 0xfe; + match_spec.ipv6_metadata_lkp_ipv6_sa[1] = 0x80; + match_spec.ipv6_metadata_lkp_ipv6_sa_mask[0] = 0xfe; + match_spec.ipv6_metadata_lkp_ipv6_sa_mask[1] = 0x80; + status = + p4_pd_dc_validate_packet_table_add_with_set_unicast_and_ipv6_src_is_link_local( + g_sess_hdl, p4_pd_device, &match_spec, priority++, &entry_hdl); #endif /* IPV6_DISABLE */ - /* unicast */ - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); - status = p4_pd_dc_validate_packet_table_add_with_set_unicast( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority++, - &entry_hdl); + /* unicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_packet_match_spec_t)); + status = p4_pd_dc_validate_packet_table_add_with_set_unicast( + g_sess_hdl, p4_pd_device, &match_spec, priority++, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_acl_table_add_default_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; +p4_pd_status_t switch_pd_acl_table_add_default_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; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_system_acl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_system_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #ifndef P4_ACL_DISABLE #ifndef P4_L2_DISABLE - status = p4_pd_dc_mac_acl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_mac_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_L2_DISABLE */ #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ip_acl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ip_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); - status = p4_pd_dc_ipv4_racl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv4_racl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV4_DISABLE */ #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_ipv6_acl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv6_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); - status = p4_pd_dc_ipv6_racl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv6_racl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV6_DISABLE */ #endif /* P4_ACL_DISABLE */ -#ifndef P4_QOS_DISABLE - status = p4_pd_dc_qos_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); -#endif /* P4_QOS_DISABLE */ - #ifndef P4_STATS_DISABLE - status = p4_pd_dc_drop_stats_set_default_action_drop_stats_update( - g_sess_hdl, - p4_pd_device, - &entry_hdl); - - status = p4_pd_dc_acl_stats_set_default_action_acl_stats_update( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_drop_stats_set_default_action_drop_stats_update( + g_sess_hdl, p4_pd_device, &entry_hdl); +#ifndef P4_ACL_DISABLE + status = p4_pd_dc_acl_stats_set_default_action_acl_stats_update( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_ACL_DISABLE */ #endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_inner_rmac_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; +switch_status_t switch_pd_inner_rmac_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_rmac_set_default_action_rmac_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_rmac_set_default_action_rmac_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_fwd_result_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; +switch_status_t switch_pd_fwd_result_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_fwd_result_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_fwd_result_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } +switch_status_t switch_pd_nexthop_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; -switch_status_t -switch_pd_nexthop_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_nexthop_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_nexthop_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_lag_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; - p4_pd_mbr_hdl_t mbr_hdl; - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +switch_status_t switch_pd_lag_table_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; + p4_pd_mbr_hdl_t mbr_hdl; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_lag_action_profile_add_member_with_set_lag_miss(g_sess_hdl, - p4_pd_device, - &mbr_hdl); + status = p4_pd_dc_lag_action_profile_add_member_with_set_lag_miss( + g_sess_hdl, p4_pd_device, &mbr_hdl); - status = p4_pd_dc_lag_group_set_default_entry(g_sess_hdl, - p4_pd_device, - mbr_hdl, - &entry_hdl); + status = p4_pd_dc_lag_group_set_default_entry( + g_sess_hdl, p4_pd_device, mbr_hdl, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_egress_filter_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_egress_filter_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifdef EGRESS_FILTER - p4_pd_dev_target_t p4_pd_device; - 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; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_egress_filter_set_default_action_egress_filter_check( - g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_egress_filter_drop_set_default_action_set_egress_filter_drop( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_egress_filter_set_default_action_egress_filter_check( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = + p4_pd_dc_egress_filter_drop_set_default_action_set_egress_filter_drop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* EGRESS_FILTER */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_rid_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_rid_table_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_MULTICAST_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_rid_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = + p4_pd_dc_rid_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; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_replica_type_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_replica_type_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_MULTICAST_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_replica_type_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_replica_type_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; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_mac_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_mac_table_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_L2_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_smac_set_default_action_smac_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_dmac_set_default_action_dmac_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_smac_set_default_action_smac_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_dmac_set_default_action_dmac_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_L2_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_egress_bd_map_table_add_default_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; +switch_status_t switch_pd_egress_bd_map_table_add_default_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; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_egress_bd_map_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_egress_bd_map_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_egress_vni_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_egress_vni_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_egress_vni_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_egress_vni_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_ip_fib_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_ip_fib_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_L3_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ipv4_fib_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_ipv4_fib_lpm_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv4_fib_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_ipv4_fib_lpm_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV4_DISABLE */ #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_ipv6_fib_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_ipv6_fib_lpm_set_default_action_on_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv6_fib_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_ipv6_fib_lpm_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV6_DISABLE */ #endif /* P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_ip_urpf_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_ip_urpf_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; #if !defined(P4_L3_DISABLE) && !defined(P4_URPF_DISABLE) - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_ipv4_urpf_set_default_action_on_miss( - g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_ipv4_urpf_lpm_set_default_action_urpf_miss( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv4_urpf_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_ipv4_urpf_lpm_set_default_action_urpf_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV4_DISABLE */ #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_ipv6_urpf_set_default_action_on_miss( - g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_ipv6_urpf_lpm_set_default_action_urpf_miss( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ipv6_urpf_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_ipv6_urpf_lpm_set_default_action_urpf_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV6_DISABLE */ - status = p4_pd_dc_urpf_bd_set_default_action_urpf_bd_miss( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_urpf_bd_set_default_action_urpf_bd_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_L3_DISABLE && P4_URPF_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_rewrite_set_default_action_set_l2_rewrite( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_rewrite_set_default_action_set_l2_rewrite( + g_sess_hdl, p4_pd_device, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_rewrite_multicast_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_rewrite_multicast_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + 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; + (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); + 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; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_egress_vlan_xlate_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_egress_vlan_xlate_table_add_default_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_egress_vlan_xlate_set_default_action_set_egress_packet_vlan_untagged( - g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = + p4_pd_dc_egress_vlan_xlate_set_default_action_set_egress_packet_vlan_untagged( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_egress_acl_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_egress_acl_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_ACL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_egress_acl_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_egress_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_ACL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_vlan_decap_table_add_default_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; +p4_pd_status_t switch_pd_vlan_decap_table_add_default_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; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_vlan_decap_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_vlan_decap_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_src_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_tunnel_src_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_tunnel_src_rewrite_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_tunnel_src_rewrite_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_dst_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_tunnel_dst_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_tunnel_dst_rewrite_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); -#endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + status = p4_pd_dc_tunnel_dst_rewrite_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE*/ + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_tunnel_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_TUNNEL_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - 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_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_status_t switch_pd_adjust_lkp_fields_table_add_default_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; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - 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); + status = p4_pd_dc_adjust_lkp_fields_set_default_action_non_ip_lkp( + g_sess_hdl, p4_pd_device, &entry_hdl); + + p4_pd_dc_adjust_lkp_fields_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.ipv4_valid = true; + status = p4_pd_dc_adjust_lkp_fields_table_add_with_ipv4_lkp( + g_sess_hdl, p4_pd_device, &match_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); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.ipv6_valid = true; + status = p4_pd_dc_adjust_lkp_fields_table_add_with_ipv6_lkp( + g_sess_hdl, p4_pd_device, &match_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); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_tunnel_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_TUNNEL_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_tunnel_set_default_action_tunnel_lookup_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_tunnel_lookup_miss_set_default_action_non_ip_lkp( + 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_lookup_miss_match_spec_t match1_spec; + memset(&match1_spec, 0, sizeof(match1_spec)); + match1_spec.ipv4_valid = true; + status = p4_pd_dc_tunnel_lookup_miss_table_add_with_ipv4_lkp( + g_sess_hdl, p4_pd_device, &match1_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); + memset(&match1_spec, 0, sizeof(match1_spec)); + match1_spec.ipv6_valid = true; + status = p4_pd_dc_tunnel_lookup_miss_table_add_with_ipv6_lkp( + g_sess_hdl, p4_pd_device, &match1_spec, &entry_hdl); #endif #endif /* P4_TUNNEL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_bd_stats_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_bd_stats_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_STATS_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_ingress_bd_stats_set_default_action_update_ingress_bd_stats( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_ingress_bd_stats_set_default_action_update_ingress_bd_stats( + g_sess_hdl, p4_pd_device, &entry_hdl); - status = p4_pd_dc_egress_bd_stats_set_default_action_nop( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_egress_bd_stats_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_bd_flood_table_add_default_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_bd_flood_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef MULTICAST_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_bd_flood_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_bd_flood_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* MULTICAST_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } /*************** INIT Entries ***************************/ -p4_pd_status_t -switch_pd_fwd_result_table_add_init_entry(switch_device_t device) -{ - p4_pd_dc_fwd_result_match_spec_t match_spec; - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - uint16_t prio = 1000; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.acl_metadata_acl_redirect = 1; - match_spec.acl_metadata_acl_redirect_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_acl_redirect_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l3_metadata_fib_hit = 1; - match_spec.l3_metadata_fib_hit_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_fib_redirect_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l2_metadata_l2_redirect = 1; - match_spec.l2_metadata_l2_redirect_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_l2_redirect_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l3_metadata_rmac_hit = 1; - match_spec.l3_metadata_rmac_hit_mask = 1; - match_spec.l3_metadata_fib_hit = 0; - match_spec.l3_metadata_fib_hit_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_cpu_redirect_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); +p4_pd_status_t switch_pd_fwd_result_table_add_init_entry( + switch_device_t device) { + p4_pd_dc_fwd_result_match_spec_t match_spec; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + uint16_t prio = 1000; -#ifndef P4_MULTICAST_DISABLE - prio = 2000; - // mroute = hit, bridge = x, rpf = pass - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_route_hit = 1; - match_spec.multicast_metadata_mcast_route_hit_mask = 1; - match_spec.multicast_metadata_mcast_rpf_group = 0; - match_spec.multicast_metadata_mcast_rpf_group_mask = 0xFFFF; - match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; - match_spec.multicast_metadata_mcast_mode_mask = 0xff; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_route_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_route_hit = 1; - match_spec.multicast_metadata_mcast_route_hit_mask = 1; - match_spec.multicast_metadata_mcast_rpf_group = 0xFFFF; - match_spec.multicast_metadata_mcast_rpf_group_mask = 0xFFFF; - match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_BIDIR; - match_spec.multicast_metadata_mcast_mode_mask = 0xff; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_route_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // mroute = hit, bridge = hit, rpf = fail - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_route_hit = 1; - match_spec.multicast_metadata_mcast_route_hit_mask = 1; - match_spec.multicast_metadata_mcast_bridge_hit = 1; - match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; - match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; - match_spec.multicast_metadata_mcast_mode_mask = 0xff; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_bridge_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // mroute = hit, bridge = miss, rpf = fail, igmp snooping enabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_route_hit = 1; - match_spec.multicast_metadata_mcast_route_hit_mask = 1; - match_spec.multicast_metadata_mcast_bridge_hit = 0; - match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; - match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; - match_spec.multicast_metadata_mcast_mode_mask = 0xff; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.multicast_metadata_igmp_snooping_enabled = 1; - match_spec.multicast_metadata_igmp_snooping_enabled_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // mroute = hit, bridge = miss, rpf = fail, mld snooping enabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_route_hit = 1; - match_spec.multicast_metadata_mcast_route_hit_mask = 1; - match_spec.multicast_metadata_mcast_bridge_hit = 0; - match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; - match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; - match_spec.multicast_metadata_mcast_mode_mask = 0xff; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.multicast_metadata_mld_snooping_enabled = 1; - match_spec.multicast_metadata_mld_snooping_enabled_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // mroute = hit, bridge = miss, rpf = fail, igmp/mld snooping disabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_route_hit = 1; - match_spec.multicast_metadata_mcast_route_hit_mask = 1; - match_spec.multicast_metadata_mcast_bridge_hit = 0; - match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; - match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; - match_spec.multicast_metadata_mcast_mode_mask = 0xff; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_flood( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // bridge = hit - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.multicast_metadata_mcast_bridge_hit = 1; - match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_bridge_action( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // bridge = miss, pkt_type = multicast, igmp snooping enabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; - match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.multicast_metadata_igmp_snooping_enabled = 1; - match_spec.multicast_metadata_igmp_snooping_enabled_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // bridge = miss, pkt_type = multicast, mld snooping enabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; - match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - match_spec.multicast_metadata_mld_snooping_enabled = 1; - match_spec.multicast_metadata_mld_snooping_enabled_mask = 1; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); - - // bridge = miss, pkt_type = multicast, igmp/mld snooping disabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; - match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_flood( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - // bridge = miss, pkt_type = multicast, igmp/mld snooping disabled - memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); - match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; - match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; - match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; - match_spec.l3_metadata_lkp_ip_type_mask = 0xff; - status = p4_pd_dc_fwd_result_table_add_with_set_multicast_flood( - g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); +#ifndef P4_ACL_DISABLE + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.acl_metadata_acl_redirect = 1; + match_spec.acl_metadata_acl_redirect_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_acl_redirect_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); +#endif /* P4_ACL_DISABLE */ + +#ifndef P4_NAT_DISABLE + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l3_metadata_rmac_hit = 1; + match_spec.l3_metadata_rmac_hit_mask = 1; + match_spec.nat_metadata_nat_hit = 1; + match_spec.nat_metadata_nat_hit_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_nat_redirect_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); +#endif /* P4_NAT_DISABLE */ + + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l3_metadata_fib_hit = 1; + match_spec.l3_metadata_fib_hit_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_fib_redirect_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l2_metadata_l2_redirect = 1; + match_spec.l2_metadata_l2_redirect_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_l2_redirect_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l3_metadata_rmac_hit = 1; + match_spec.l3_metadata_rmac_hit_mask = 1; + match_spec.l3_metadata_fib_hit = 0; + match_spec.l3_metadata_fib_hit_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_cpu_redirect_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + +#ifndef P4_MULTICAST_DISABLE + prio = 2000; + // mroute = hit, bridge = x, rpf = pass + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_route_hit = 1; + match_spec.multicast_metadata_mcast_route_hit_mask = 1; + match_spec.multicast_metadata_mcast_rpf_group = 0; + match_spec.multicast_metadata_mcast_rpf_group_mask = 0xFFFF; + match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; + match_spec.multicast_metadata_mcast_mode_mask = 0xff; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_route_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_route_hit = 1; + match_spec.multicast_metadata_mcast_route_hit_mask = 1; + match_spec.multicast_metadata_mcast_rpf_group = 0xFFFF; + match_spec.multicast_metadata_mcast_rpf_group_mask = 0xFFFF; + match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_BIDIR; + match_spec.multicast_metadata_mcast_mode_mask = 0xff; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_route_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // mroute = hit, bridge = hit, rpf = fail + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_route_hit = 1; + match_spec.multicast_metadata_mcast_route_hit_mask = 1; + match_spec.multicast_metadata_mcast_bridge_hit = 1; + match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; + match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; + match_spec.multicast_metadata_mcast_mode_mask = 0xff; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_bridge_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // mroute = hit, bridge = miss, rpf = fail, igmp snooping enabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_route_hit = 1; + match_spec.multicast_metadata_mcast_route_hit_mask = 1; + match_spec.multicast_metadata_mcast_bridge_hit = 0; + match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; + match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; + match_spec.multicast_metadata_mcast_mode_mask = 0xff; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.multicast_metadata_igmp_snooping_enabled = 1; + match_spec.multicast_metadata_igmp_snooping_enabled_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // mroute = hit, bridge = miss, rpf = fail, mld snooping enabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_route_hit = 1; + match_spec.multicast_metadata_mcast_route_hit_mask = 1; + match_spec.multicast_metadata_mcast_bridge_hit = 0; + match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; + match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; + match_spec.multicast_metadata_mcast_mode_mask = 0xff; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.multicast_metadata_mld_snooping_enabled = 1; + match_spec.multicast_metadata_mld_snooping_enabled_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // mroute = hit, bridge = miss, rpf = fail, igmp/mld snooping disabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_route_hit = 1; + match_spec.multicast_metadata_mcast_route_hit_mask = 1; + match_spec.multicast_metadata_mcast_bridge_hit = 0; + match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; + match_spec.multicast_metadata_mcast_mode = SWITCH_API_MCAST_IPMC_PIM_SM; + match_spec.multicast_metadata_mcast_mode_mask = 0xff; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_flood( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // bridge = hit + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.multicast_metadata_mcast_bridge_hit = 1; + match_spec.multicast_metadata_mcast_bridge_hit_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_bridge_action( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // bridge = miss, pkt_type = multicast, igmp snooping enabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; + match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.multicast_metadata_igmp_snooping_enabled = 1; + match_spec.multicast_metadata_igmp_snooping_enabled_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // bridge = miss, pkt_type = multicast, mld snooping enabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; + match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + match_spec.multicast_metadata_mld_snooping_enabled = 1; + match_spec.multicast_metadata_mld_snooping_enabled_mask = 1; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_drop( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // bridge = miss, pkt_type = multicast, igmp/mld snooping disabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; + match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv4; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_flood( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); + + // bridge = miss, pkt_type = multicast, igmp/mld snooping disabled + memset(&match_spec, 0, sizeof(p4_pd_dc_fwd_result_match_spec_t)); + match_spec.l2_metadata_lkp_pkt_type = SWITCH_VLAN_FLOOD_UMC; + match_spec.l2_metadata_lkp_pkt_type_mask = 0xff; + match_spec.l3_metadata_lkp_ip_type = SWITCH_IP_TYPE_IPv6; + match_spec.l3_metadata_lkp_ip_type_mask = 0xff; + status = p4_pd_dc_fwd_result_table_add_with_set_multicast_flood( + g_sess_hdl, p4_pd_device, &match_spec, prio++, &entry_hdl); #endif /* P4_MULTICAST_DISABLE */ - (void)prio; + (void)prio; - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_learn_notify_table_add_init_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_learn_notify_table_add_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef L2_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_learn_notify_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - // add default entry - status = p4_pd_dc_learn_notify_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - - // stp_state == none and l2 src miss - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_miss = 1; - match_spec.l2_metadata_l2_src_miss_mask = 1; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_NONE; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 900, - &entry_hdl); - - // stp_state == disabled and l2 src miss - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_miss = 1; - match_spec.l2_metadata_l2_src_miss_mask = 1; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_DISABLED; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 901, - &entry_hdl); - - // stp_state == learning and l2 src miss - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_miss = 1; - match_spec.l2_metadata_l2_src_miss_mask = 1; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_LEARNING; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 902, - &entry_hdl); - - // stp_state == forwarding and l2 src miss - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_miss = 1; - match_spec.l2_metadata_l2_src_miss_mask = 1; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 903, - &entry_hdl); - - // stp_state == none and l2 src move - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_move = 0; - match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_NONE; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_nop(g_sess_hdl, - p4_pd_device, - &match_spec, - 1000, - &entry_hdl); - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_NONE; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1001, - &entry_hdl); - - // stp_state == disabled and l2 src move - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_move = 0; - match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_DISABLED; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_nop(g_sess_hdl, - p4_pd_device, - &match_spec, - 1002, - &entry_hdl); - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_DISABLED; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1003, - &entry_hdl); - - // stp_state == learning and l2 src move - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_move = 0; - match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_LEARNING; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_nop(g_sess_hdl, - p4_pd_device, - &match_spec, - 1004, - &entry_hdl); - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_LEARNING; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1005, - &entry_hdl); - - // stp_state == forwarding and l2 src move - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_l2_src_move = 0; - match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_nop(g_sess_hdl, - p4_pd_device, - &match_spec, - 1006, - &entry_hdl); - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; - match_spec.l2_metadata_stp_state_mask = 0xF; - status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( - g_sess_hdl, - p4_pd_device, - &match_spec, - 1007, - &entry_hdl); - - p4_pd_complete_operations(g_sess_hdl); + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_learn_notify_match_spec_t match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + // add default entry + status = p4_pd_dc_learn_notify_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + // stp_state == none and l2 src miss + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_miss = 1; + match_spec.l2_metadata_l2_src_miss_mask = 1; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_NONE; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 900, &entry_hdl); + + // stp_state == disabled and l2 src miss + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_miss = 1; + match_spec.l2_metadata_l2_src_miss_mask = 1; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_DISABLED; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 901, &entry_hdl); + + // stp_state == learning and l2 src miss + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_miss = 1; + match_spec.l2_metadata_l2_src_miss_mask = 1; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_LEARNING; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 902, &entry_hdl); + + // stp_state == forwarding and l2 src miss + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_miss = 1; + match_spec.l2_metadata_l2_src_miss_mask = 1; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 903, &entry_hdl); + + // stp_state == none and l2 src move + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_move = 0; + match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_NONE; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_NONE; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 1001, &entry_hdl); + + // stp_state == disabled and l2 src move + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_move = 0; + match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_DISABLED; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, 1002, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_DISABLED; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 1003, &entry_hdl); + + // stp_state == learning and l2 src move + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_move = 0; + match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_LEARNING; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, 1004, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_LEARNING; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 1005, &entry_hdl); + + // stp_state == forwarding and l2 src move + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_l2_src_move = 0; + match_spec.l2_metadata_l2_src_move_mask = 0xFFFF; + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, 1006, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.l2_metadata_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; + match_spec.l2_metadata_stp_state_mask = 0xF; + status = p4_pd_dc_learn_notify_table_add_with_generate_learn_notify( + g_sess_hdl, p4_pd_device, &match_spec, 1007, &entry_hdl); + + p4_pd_complete_operations(g_sess_hdl); #endif - return status; -} - -p4_pd_status_t -switch_pd_validate_outer_ethernet_table_init_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - p4_pd_dc_validate_outer_ethernet_match_spec_t match_spec; - p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t action_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - /* mac sa 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)); - 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); - - /* 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.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); - - /* 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)); - 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); - - /* double tagged broadcast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* double tagged multicast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* double tagged unicast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* single tagged broadcast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* single tagged multicast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* single tagged unicast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* untagged packet broadcast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* untagged packet multicast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - /* untagged packet unicast */ - memset(&match_spec, 0, - sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); - 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); - - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_vlan_decap_table_init_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - p4_pd_dc_vlan_decap_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - memset(&match_spec, 0, sizeof(p4_pd_dc_vlan_decap_match_spec_t)); - match_spec.vlan_tag__0__valid = 1; - match_spec.vlan_tag__1__valid = 0; - status = p4_pd_dc_vlan_decap_table_add_with_remove_vlan_single_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl); - - memset(&match_spec, 0, sizeof(p4_pd_dc_vlan_decap_match_spec_t)); - match_spec.vlan_tag__0__valid = 1; - match_spec.vlan_tag__1__valid = 1; - status = p4_pd_dc_vlan_decap_table_add_with_remove_vlan_double_tagged( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_validate_mpls_packet_table_init_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_validate_outer_ethernet_table_init_entry( + switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + p4_pd_dc_validate_outer_ethernet_match_spec_t match_spec; + p4_pd_dc_malformed_outer_ethernet_packet_action_spec_t action_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + /* mac sa 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)); + 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); + + /* 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.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); + + /* 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)); + 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); + + /* double tagged broadcast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* double tagged multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* double tagged unicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* single tagged broadcast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* single tagged multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* single tagged unicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* untagged packet broadcast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* untagged packet multicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + /* untagged packet unicast */ + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_outer_ethernet_match_spec_t)); + 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); + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_vlan_decap_table_init_entry(switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + p4_pd_dc_vlan_decap_match_spec_t match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_vlan_decap_match_spec_t)); + match_spec.vlan_tag__0__valid = 1; + match_spec.vlan_tag__1__valid = 0; + status = p4_pd_dc_vlan_decap_table_add_with_remove_vlan_single_tagged( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl); + + memset(&match_spec, 0, sizeof(p4_pd_dc_vlan_decap_match_spec_t)); + match_spec.vlan_tag__0__valid = 1; + match_spec.vlan_tag__1__valid = 1; + status = p4_pd_dc_vlan_decap_table_add_with_remove_vlan_double_tagged( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_validate_mpls_packet_table_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #if !defined(P4_TUNNEL_DISABLE) && !defined(P4_MPLS_DISABLE) - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - uint16_t priority = 1; - p4_pd_dc_validate_mpls_packet_match_spec_t match_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - priority++; - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); - match_spec.mpls_0__valid = 0x1; - match_spec.mpls_1__valid = 0x1; - match_spec.mpls_2__valid = 0x1; - status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &entry_hdl); - - - priority++; - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); - match_spec.mpls_0__valid = 0x1; - match_spec.mpls_1__valid = 0x1; - match_spec.mpls_2__valid = 0x1; - match_spec.mpls_2__bos = 0x1; - match_spec.mpls_2__bos_mask = 0x1; - status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &entry_hdl); - - priority++; - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); - match_spec.mpls_0__valid = 0x1; - match_spec.mpls_1__valid = 0x1; - match_spec.mpls_1__bos = 0x1; - match_spec.mpls_1__bos_mask = 0x1; - status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &entry_hdl); - - priority++; - memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); - match_spec.mpls_0__valid = 0x1; - match_spec.mpls_0__bos = 0x1; - match_spec.mpls_0__bos_mask = 0x1; - status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &entry_hdl); + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + uint16_t priority = 1; + p4_pd_dc_validate_mpls_packet_match_spec_t match_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + priority++; + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); + match_spec.mpls_0__valid = 0x1; + match_spec.mpls_1__valid = 0x1; + match_spec.mpls_2__valid = 0x1; + status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( + g_sess_hdl, p4_pd_device, &match_spec, priority, &entry_hdl); + + priority++; + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); + match_spec.mpls_0__valid = 0x1; + match_spec.mpls_1__valid = 0x1; + match_spec.mpls_2__valid = 0x1; + match_spec.mpls_2__bos = 0x1; + match_spec.mpls_2__bos_mask = 0x1; + status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( + g_sess_hdl, p4_pd_device, &match_spec, priority, &entry_hdl); + + priority++; + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); + match_spec.mpls_0__valid = 0x1; + match_spec.mpls_1__valid = 0x1; + match_spec.mpls_1__bos = 0x1; + match_spec.mpls_1__bos_mask = 0x1; + status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( + g_sess_hdl, p4_pd_device, &match_spec, priority, &entry_hdl); + + priority++; + memset(&match_spec, 0, sizeof(p4_pd_dc_validate_mpls_packet_match_spec_t)); + match_spec.mpls_0__valid = 0x1; + match_spec.mpls_0__bos = 0x1; + match_spec.mpls_0__bos_mask = 0x1; + status = p4_pd_dc_validate_mpls_packet_table_add_with_set_valid_mpls_label1( + g_sess_hdl, p4_pd_device, &match_spec, priority, &entry_hdl); #endif /* !defined(P4_TUNNEL_DISABLE) && !defined(P4_MPLS_DISABLE) */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_fabric_header_table_init_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_fabric_header_table_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifdef FABRIC_ENABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_mbr_hdl_t mbr_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - status = p4_pd_dc_fabric_lag_action_profile_add_member_with_nop( - g_sess_hdl, - p4_pd_device, - &mbr_hdl); - status = p4_pd_dc_fabric_lag_set_default_entry(g_sess_hdl, - p4_pd_device, - mbr_hdl, - &entry_hdl); + p4_pd_entry_hdl_t entry_hdl; + p4_pd_mbr_hdl_t mbr_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_fabric_lag_action_profile_add_member_with_nop( + g_sess_hdl, p4_pd_device, &mbr_hdl); + status = p4_pd_dc_fabric_lag_set_default_entry( + g_sess_hdl, p4_pd_device, mbr_hdl, &entry_hdl); #endif /* FABRIC_ENABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_egress_port_mapping_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; +p4_pd_status_t switch_pd_egress_port_mapping_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; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - p4_pd_dc_egress_port_type_normal_action_spec_t action_spec; - memset(&action_spec, 0, sizeof(action_spec)); + p4_pd_dc_egress_port_type_normal_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); - status = - p4_pd_dc_egress_port_mapping_set_default_action_egress_port_type_normal( - g_sess_hdl, - p4_pd_device, - &action_spec, - &entry_hdl); + status = + p4_pd_dc_egress_port_mapping_set_default_action_egress_port_type_normal( + g_sess_hdl, p4_pd_device, &action_spec, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_compute_hashes_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; +p4_pd_status_t switch_pd_compute_hashes_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; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_compute_ipv4_hashes_set_default_action_compute_lkp_ipv4_hash( - g_sess_hdl, p4_pd_device, &entry_hdl); + status = + p4_pd_dc_compute_ipv4_hashes_set_default_action_compute_lkp_ipv4_hash( + g_sess_hdl, p4_pd_device, &entry_hdl); #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_compute_ipv6_hashes_set_default_action_compute_lkp_ipv6_hash( - g_sess_hdl, p4_pd_device, &entry_hdl); + status = + p4_pd_dc_compute_ipv6_hashes_set_default_action_compute_lkp_ipv6_hash( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_IPV6_DISABLE */ - status = p4_pd_dc_compute_non_ip_hashes_set_default_action_compute_lkp_non_ip_hash( - g_sess_hdl, p4_pd_device, &entry_hdl); +#ifndef P4_L2_DISABLE + status = + p4_pd_dc_compute_non_ip_hashes_set_default_action_compute_lkp_non_ip_hash( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L2_DISABLE */ - p4_pd_dc_compute_other_hashes_match_spec_t match_spec_other; - memset(&match_spec_other, 0, sizeof(match_spec_other)); - match_spec_other.hash_metadata_hash1 = 0; - status = p4_pd_dc_compute_other_hashes_table_add_with_computed_one_hash( - g_sess_hdl, p4_pd_device, &match_spec_other, &entry_hdl); - status = p4_pd_dc_compute_other_hashes_set_default_action_computed_two_hashes( - g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_dc_compute_other_hashes_match_spec_t match_spec_other; + memset(&match_spec_other, 0, sizeof(match_spec_other)); + match_spec_other.hash_metadata_hash1 = 0; + status = p4_pd_dc_compute_other_hashes_table_add_with_computed_one_hash( + g_sess_hdl, p4_pd_device, &match_spec_other, &entry_hdl); + status = p4_pd_dc_compute_other_hashes_set_default_action_computed_two_hashes( + g_sess_hdl, p4_pd_device, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_replica_type_table_init_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_replica_type_table_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef P4_MULTICAST_DISABLE - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - p4_pd_dc_replica_type_match_spec_t match_spec; - memset(&match_spec, 0, sizeof(match_spec)); + p4_pd_dc_replica_type_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(match_spec)); - match_spec.multicast_metadata_replica = 0x1; - match_spec.egress_metadata_same_bd_check = 0; - match_spec.egress_metadata_same_bd_check_mask = 0xFFFF; + match_spec.multicast_metadata_replica = 0x1; + match_spec.egress_metadata_same_bd_check = 0; + match_spec.egress_metadata_same_bd_check_mask = 0xFFFF; - status = p4_pd_dc_replica_type_table_add_with_set_replica_copy_bridged( - g_sess_hdl, p4_pd_device, &match_spec, 100, &entry_hdl); + status = p4_pd_dc_replica_type_table_add_with_set_replica_copy_bridged( + g_sess_hdl, p4_pd_device, &match_spec, 100, &entry_hdl); #endif /* P4_MULTICAST_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -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; +switch_status_t 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; + 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; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; #ifndef P4_MULTICAST_DISABLE - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.ipv4_valid = 0x1; - match_spec.ipv6_valid = 0x0; - match_spec.ipv4_dstAddr = 0xe0000000; - match_spec.ipv4_dstAddr_mask = 0xf0000000; - status = p4_pd_dc_rewrite_multicast_table_add_with_rewrite_ipv4_multicast( - g_sess_hdl, p4_pd_device, &match_spec, 100, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.ipv4_valid = 0x1; + match_spec.ipv6_valid = 0x0; + match_spec.ipv4_dstAddr = 0xe0000000; + match_spec.ipv4_dstAddr_mask = 0xf0000000; + 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)entry_hdl; + (void)p4_pd_device; #endif #if !defined(P4_IPV6_DISABLE) && !defined(P4_MULTICAST_DISABLE) - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.ipv4_valid = 0x0; - match_spec.ipv6_valid = 0x1; - match_spec.ipv6_dstAddr[0] = 0xff; - match_spec.ipv6_dstAddr_mask[0] = 0xff; - status = p4_pd_dc_rewrite_multicast_table_add_with_rewrite_ipv6_multicast( - g_sess_hdl, p4_pd_device, &match_spec, 101, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.ipv4_valid = 0x0; + match_spec.ipv6_valid = 0x1; + match_spec.ipv6_dstAddr[0] = 0xff; + match_spec.ipv6_dstAddr_mask[0] = 0xff; + status = p4_pd_dc_rewrite_multicast_table_add_with_rewrite_ipv6_multicast( + g_sess_hdl, p4_pd_device, &match_spec, 101, &entry_hdl); #endif /* P4_IPV6_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_l3_rewrite_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; - p4_pd_dc_l3_rewrite_match_spec_t match_spec; +switch_status_t switch_pd_l3_rewrite_table_init_entry(switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_L3_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_l3_rewrite_match_spec_t match_spec; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; #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); + 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_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); + 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) - 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; + 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); + 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); + 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 */ #ifndef P4_MPLS_DISABLE - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.mpls_0__valid = 0x1; - status = p4_pd_dc_l3_rewrite_table_add_with_mpls_rewrite( - g_sess_hdl, p4_pd_device, &match_spec, 300, &entry_hdl); + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.mpls_0__valid = 0x1; + status = p4_pd_dc_l3_rewrite_table_add_with_mpls_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, 300, &entry_hdl); #endif /* P4_MPLS_DISABLE */ +#endif /* P4_L3_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_bd_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats) -{ - p4_pd_status_t status = 0; +p4_pd_status_t 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 - p4_pd_counter_value_t counter; - p4_pd_dev_target_t p4_pd_device; - int index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - 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, - bd_stats->stats_idx[index], - COUNTER_READ_HW_SYNC); - bd_stats->counters[index].num_packets = counter.packets; - bd_stats->counters[index].num_bytes = counter.bytes; - } + p4_pd_counter_value_t counter; + p4_pd_dev_target_t p4_pd_device; + int index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + 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, + bd_stats->stats_idx[index], + COUNTER_READ_HW_SYNC); + bd_stats->counters[index].num_packets = counter.packets; + bd_stats->counters[index].num_bytes = counter.bytes; + } #endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_bd_egress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats) -{ - p4_pd_status_t status = 0; +p4_pd_status_t 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 - p4_pd_counter_value_t counter; - p4_pd_dev_target_t p4_pd_device; - int index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - for (index = 0; index < 3; index++) { - counter = p4_pd_dc_counter_read_egress_bd_stats( - g_sess_hdl, - p4_pd_device, - bd_stats->stats_hw_entry[index], - COUNTER_READ_HW_SYNC); - 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; - } + p4_pd_counter_value_t counter; + p4_pd_dev_target_t p4_pd_device; + int index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + for (index = 0; index < 3; index++) { + counter = + p4_pd_dc_counter_read_egress_bd_stats(g_sess_hdl, + p4_pd_device, + bd_stats->stats_hw_entry[index], + COUNTER_READ_HW_SYNC); + 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); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_drop_stats_get(switch_device_t device, int num_counters, - uint64_t *counters) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_drop_stats_get(switch_device_t device, + int num_counters, + uint64_t *counters) { + p4_pd_status_t status = 0; #ifndef P4_STATS_DISABLE - p4_pd_counter_value_t counter; - p4_pd_dev_target_t p4_pd_device; - int index = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - for (index = 0; index < num_counters; index++) { - counter = p4_pd_dc_counter_read_drop_stats(g_sess_hdl, - p4_pd_device, - index, - COUNTER_READ_HW_SYNC); - *(counters + index) = counter.packets; - counter = p4_pd_dc_counter_read_drop_stats_2(g_sess_hdl, - p4_pd_device, - index, - COUNTER_READ_HW_SYNC); - *(counters + index) += counter.packets; - } + p4_pd_counter_value_t counter; + p4_pd_dev_target_t p4_pd_device; + int index = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + for (index = 0; index < num_counters; index++) { + counter = p4_pd_dc_counter_read_drop_stats( + g_sess_hdl, p4_pd_device, index, COUNTER_READ_HW_SYNC); + *(counters + index) = counter.packets; + counter = p4_pd_dc_counter_read_drop_stats_2( + g_sess_hdl, p4_pd_device, index, COUNTER_READ_HW_SYNC); + *(counters + index) += counter.packets; + } #endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_stats_get(switch_device_t device, switch_meter_info_t *meter_info) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_stats_get(switch_device_t device, + switch_meter_info_t *meter_info) { + p4_pd_status_t status = 0; #if !defined(P4_METER_DISABLE) && !defined(P4_STATS_DISABLE) - p4_pd_counter_value_t counter; - p4_pd_dev_target_t p4_pd_device; - int index = 0; - switch_meter_stats_info_t *stats_info = NULL; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - stats_info = meter_info->stats_info; - - for (index = 0; index < SWITCH_METER_COLOR_MAX; index++) { - counter = p4_pd_dc_counter_read_meter_stats( - g_sess_hdl, - p4_pd_device, - meter_info->action_pd_hdl[index], - COUNTER_READ_HW_SYNC); - stats_info->counters[index].num_packets = counter.packets; - stats_info->counters[index].num_bytes = counter.bytes; - } + p4_pd_counter_value_t counter; + p4_pd_dev_target_t p4_pd_device; + int index = 0; + switch_meter_stats_info_t *stats_info = NULL; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + stats_info = meter_info->stats_info; + + for (index = 0; index < SWITCH_COLOR_MAX; index++) { + counter = + p4_pd_dc_counter_read_meter_stats(g_sess_hdl, + p4_pd_device, + meter_info->action_pd_hdl[index], + COUNTER_READ_HW_SYNC); + stats_info->counters[index].num_packets = counter.packets; + stats_info->counters[index].num_bytes = counter.bytes; + } #endif /* P4_METER_DISABLE && P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_storm_control_stats_get(switch_device_t device, switch_meter_info_t *meter_info) -{ - p4_pd_status_t status = 0; -#ifndef P4_STATS_DISABLE - p4_pd_counter_value_t counter; - p4_pd_dev_target_t p4_pd_device; - int index = 0; - switch_meter_stats_info_t *stats_info = NULL; +p4_pd_status_t switch_pd_storm_control_stats_get( + switch_device_t device, switch_meter_info_t *meter_info) { + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; +#if !defined(P4_STORM_CONTROL_DISABLE) && !defined(P4_STATS_DISABLE) + p4_pd_counter_value_t counter; + p4_pd_dev_target_t p4_pd_device; + int index = 0; + switch_meter_stats_info_t *stats_info = NULL; - stats_info = meter_info->stats_info; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -#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, - p4_pd_device, - meter_info->action_pd_hdl[index], - COUNTER_READ_HW_SYNC); - 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; + stats_info = meter_info->stats_info; + + for (index = 0; index < SWITCH_METER_STATS_MAX; index++) { + counter = p4_pd_dc_counter_read_storm_control_stats( + g_sess_hdl, + p4_pd_device, + meter_info->action_pd_hdl[index], + COUNTER_READ_HW_SYNC); + stats_info->counters[index].num_packets = counter.packets; + stats_info->counters[index].num_bytes = counter.bytes; + } +#endif /* !P4_STATS_DISABLE && !P4_STATS_DISABLE */ + + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_acl_stats_get(switch_device_t device, - uint16_t acl_stats_index, - switch_counter_t *acl_counter) -{ - p4_pd_status_t status = 0; -#ifndef P4_STATS_DISABLE - p4_pd_counter_value_t counter; - p4_pd_dev_target_t p4_pd_device; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - counter = p4_pd_dc_counter_read_acl_stats( - g_sess_hdl, - p4_pd_device, - acl_stats_index, - COUNTER_READ_HW_SYNC); - acl_counter->num_packets = counter.packets; - acl_counter->num_bytes = counter.bytes; -#endif /* P4_STATS_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; +p4_pd_status_t switch_pd_acl_stats_get(switch_device_t device, + uint16_t acl_stats_index, + switch_counter_t *acl_counter) { + p4_pd_status_t status = 0; +#if !defined(P4_STATS_DISABLE) && !defined(P4_ACL_DISABLE) + p4_pd_counter_value_t counter; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + counter = p4_pd_dc_counter_read_acl_stats( + g_sess_hdl, p4_pd_device, acl_stats_index, COUNTER_READ_HW_SYNC); + acl_counter->num_packets = counter.packets; + acl_counter->num_bytes = counter.bytes; +#endif /* P4_STATS_DISABLE && P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; } /* Mirror session manager APIs */ // conversion utils -p4_pd_mirror_type_e -switch_pd_p4_pd_mirror_type(switch_mirror_session_type_t type) -{ - p4_pd_mirror_type_e pd_mirror_type = 0; - switch (type) - { - case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: - pd_mirror_type = PD_MIRROR_TYPE_NORM; - break; - case SWITCH_MIRROR_SESSION_TYPE_COALESCE: - pd_mirror_type = PD_MIRROR_TYPE_COAL; - break; - case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: - default: - pd_mirror_type = PD_MIRROR_TYPE_MAX; - break; - } - return pd_mirror_type; -} +p4_pd_mirror_type_e switch_pd_p4_pd_mirror_type( + switch_mirror_session_type_t type) { + p4_pd_mirror_type_e pd_mirror_type = 0; + switch (type) { + case SWITCH_MIRROR_SESSION_TYPE_SIMPLE: + pd_mirror_type = PD_MIRROR_TYPE_NORM; + break; + case SWITCH_MIRROR_SESSION_TYPE_COALESCE: + pd_mirror_type = PD_MIRROR_TYPE_COAL; + break; + case SWITCH_MIRROR_SESSION_TYPE_TRUNCATE: + default: + pd_mirror_type = PD_MIRROR_TYPE_MAX; + break; + } + return pd_mirror_type; +} + +p4_pd_direction_t switch_pd_p4_pd_direction(switch_direction_t dir) { + switch (dir) { + case SWITCH_API_DIRECTION_BOTH: + return PD_DIR_BOTH; + case SWITCH_API_DIRECTION_INGRESS: + return PD_DIR_INGRESS; + case SWITCH_API_DIRECTION_EGRESS: + return PD_DIR_EGRESS; + default: + break; + } + return PD_DIR_NONE; +} + +p4_pd_status_t switch_pd_mirror_session_update( + switch_device_t device, + switch_handle_t mirror_handle, + switch_mirror_info_t *mirror_info) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + switch_api_mirror_info_t *api_mirror_info = NULL; + + api_mirror_info = &mirror_info->api_mirror_info; + status = p4_pd_mirror_session_update( + g_sess_hdl, + p4_pd_device, + switch_pd_p4_pd_mirror_type(api_mirror_info->session_type), + switch_pd_p4_pd_direction(api_mirror_info->direction), + handle_to_id(mirror_handle), + handle_to_id(api_mirror_info->egress_port), + api_mirror_info->max_pkt_len, + api_mirror_info->cos, + false, /*c2c*/ + api_mirror_info->extract_len, + api_mirror_info->timeout_usec, + (uint32_t *)&mirror_info->pkt_hdr, + mirror_info->hdr_len, + api_mirror_info->enable); + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_mirror_session_delete(switch_device_t device, + switch_handle_t mirror_handle) { + p4_pd_status_t status = 0; + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + status = p4_pd_mirror_session_delete( + g_sess_hdl, p4_pd_device, handle_to_id(mirror_handle)); + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_mirror_table_entry_add( + switch_device_t device, + switch_handle_t mirror_handle, + switch_mirror_info_t *mirror_info) { + p4_pd_status_t status = 0; + +#if !defined(P4_MIRROR_DISABLE) + p4_pd_dc_mirror_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + switch_api_mirror_info_t *api_mirror_info = NULL; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + match_spec.i2e_metadata_mirror_session_id = handle_to_id(mirror_handle); + api_mirror_info = &mirror_info->api_mirror_info; + + switch (api_mirror_info->mirror_type) { + case SWITCH_MIRROR_TYPE_LOCAL: + break; + case SWITCH_MIRROR_TYPE_REMOTE: { + p4_pd_dc_set_mirror_bd_action_spec_t action_spec; + action_spec.action_bd = handle_to_id(mirror_info->vlan_handle); + status = + p4_pd_dc_mirror_table_add_with_set_mirror_bd(g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &mirror_info->pd_hdl); + } break; + case SWITCH_MIRROR_TYPE_ENHANCED_REMOTE: { + p4_pd_dc_set_mirror_nhop_action_spec_t action_spec; + action_spec.action_nhop_idx = handle_to_id(api_mirror_info->nhop_handle); + status = + p4_pd_dc_mirror_table_add_with_set_mirror_nhop(g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &mirror_info->pd_hdl); + } break; -p4_pd_direction_t -switch_pd_p4_pd_direction(switch_direction_t dir) -{ - switch(dir) { - case SWITCH_API_DIRECTION_BOTH: return PD_DIR_BOTH; - case SWITCH_API_DIRECTION_INGRESS: return PD_DIR_INGRESS; - case SWITCH_API_DIRECTION_EGRESS: return PD_DIR_EGRESS; - default: break; - } - return PD_DIR_NONE; -} - -p4_pd_status_t -switch_pd_mirror_session_update(switch_device_t device, - switch_handle_t mirror_handle, - switch_mirror_info_t *mirror_info) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - switch_api_mirror_info_t *api_mirror_info = NULL; - - api_mirror_info = &mirror_info->api_mirror_info; - status = p4_pd_dc_mirror_session_update(g_sess_hdl, p4_pd_device, - switch_pd_p4_pd_mirror_type(api_mirror_info->session_type), - switch_pd_p4_pd_direction(api_mirror_info->direction), - handle_to_id(mirror_handle), - handle_to_id(api_mirror_info->egress_port), - api_mirror_info->max_pkt_len, - api_mirror_info->cos, - false, /*c2c*/ - api_mirror_info->extract_len, - api_mirror_info->timeout_usec, - (uint32_t *)&mirror_info->pkt_hdr, - mirror_info->hdr_len, - api_mirror_info->enable); + default: + break; + } - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); +#endif /* P4_MIRROR_DISABLE */ + + return status; } -p4_pd_status_t -switch_pd_mirror_session_delete(switch_device_t device, - switch_handle_t mirror_handle) -{ - p4_pd_status_t status = 0; - p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +p4_pd_status_t switch_pd_mirror_table_entry_delete( + switch_device_t device, switch_mirror_info_t *mirror_info) { + p4_pd_status_t status = 0; - status = p4_pd_dc_mirror_session_delete(g_sess_hdl, - p4_pd_device, - handle_to_id(mirror_handle)); +#if !defined(P4_MIRROR_DISABLE) + status = + p4_pd_dc_mirror_table_delete(g_sess_hdl, device, mirror_info->pd_hdl); + p4_pd_complete_operations(g_sess_hdl); +#endif /* P4_MIRROR_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + return status; } -p4_pd_status_t -switch_pd_mirror_table_entry_add(switch_device_t device, - switch_handle_t mirror_handle, - switch_mirror_info_t *mirror_info) -{ - p4_pd_status_t status = 0; - p4_pd_dc_mirror_match_spec_t match_spec; - p4_pd_dev_target_t p4_pd_device; - switch_api_mirror_info_t *api_mirror_info = NULL; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - - match_spec.i2e_metadata_mirror_session_id = handle_to_id(mirror_handle); - api_mirror_info = &mirror_info->api_mirror_info; - - switch (api_mirror_info->mirror_type) { - case SWITCH_MIRROR_TYPE_LOCAL: - break; - case SWITCH_MIRROR_TYPE_REMOTE: - { - p4_pd_dc_set_mirror_bd_action_spec_t action_spec; - action_spec.action_bd = handle_to_id(mirror_info->vlan_handle); - status = p4_pd_dc_mirror_table_add_with_set_mirror_bd(g_sess_hdl, - p4_pd_device, &match_spec, &action_spec, - &mirror_info->pd_hdl); - } - break; - case SWITCH_MIRROR_TYPE_ENHANCED_REMOTE: - { - p4_pd_dc_set_mirror_nhop_action_spec_t action_spec; - action_spec.action_nhop_idx = handle_to_id(api_mirror_info->nhop_handle); - status = p4_pd_dc_mirror_table_add_with_set_mirror_nhop(g_sess_hdl, - p4_pd_device, &match_spec, &action_spec, - &mirror_info->pd_hdl); - } - break; +switch_status_t switch_pd_mirror_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; - default: - break; - } +#ifndef P4_MIRROR_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + status = p4_pd_dc_mirror_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_complete_operations(g_sess_hdl); +#endif /* P4_MIRROR_DISABLE */ + + return status; } -p4_pd_status_t -switch_pd_mirror_table_entry_delete(switch_device_t device, - switch_mirror_info_t *mirror_info) -{ - p4_pd_status_t status = 0; +switch_status_t switch_pd_mtu_table_add_ipv4_check(switch_device_t device, + uint16_t mtu_index, + uint32_t mtu) { + p4_pd_status_t status = 0; + + p4_pd_dc_mtu_match_spec_t match_spec; + p4_pd_dc_ipv4_mtu_check_action_spec_t action_spec; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - status = p4_pd_dc_mirror_table_delete(g_sess_hdl, device, - mirror_info->pd_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - p4_pd_complete_operations(g_sess_hdl); - return status; -} + memset(&match_spec, 0, sizeof(p4_pd_dc_mtu_match_spec_t)); + match_spec.l3_metadata_mtu_index = mtu_index; + match_spec.ipv4_valid = 1; + match_spec.ipv6_valid = 0; -switch_status_t -switch_pd_mirror_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; + memset(&action_spec, 0, sizeof(p4_pd_dc_ipv4_mtu_check_action_spec_t)); + action_spec.action_l3_mtu = mtu; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + status = p4_pd_dc_mtu_table_add_with_ipv4_mtu_check( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &entry_hdl); - status = p4_pd_dc_mirror_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_mtu_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; +switch_status_t switch_pd_mtu_table_add_ipv6_check(switch_device_t device, + uint16_t mtu_index, + uint32_t mtu) { + p4_pd_status_t status = 0; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + p4_pd_dc_mtu_match_spec_t match_spec; + p4_pd_dc_ipv6_mtu_check_action_spec_t action_spec; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - status = p4_pd_dc_mtu_set_default_action_mtu_miss(g_sess_hdl, - p4_pd_device, - &entry_hdl); - status = p4_pd_dc_tunnel_mtu_set_default_action_tunnel_mtu_miss( - g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - p4_pd_complete_operations(g_sess_hdl); - return status; -} + memset(&match_spec, 0, sizeof(p4_pd_dc_mtu_match_spec_t)); + match_spec.l3_metadata_mtu_index = mtu_index; + match_spec.ipv4_valid = 0; + match_spec.ipv6_valid = 1; -switch_status_t -switch_pd_l3_rewrite_table_add_default_entry(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; + memset(&action_spec, 0, sizeof(p4_pd_dc_ipv6_mtu_check_action_spec_t)); + action_spec.action_l3_mtu = mtu; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + status = p4_pd_dc_mtu_table_add_with_ipv6_mtu_check( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, &entry_hdl); - status = p4_pd_dc_l3_rewrite_set_default_action_nop(g_sess_hdl, - p4_pd_device, - &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_neg_mirror_add_entry(switch_device_t device) -{ - p4_pd_status_t status = 0; -#if !defined(P4_ACL_DISABLE) - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; +p4_pd_status_t switch_pd_mtu_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + status = p4_pd_dc_mtu_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +switch_status_t switch_pd_mtu_table_add_default_entry(switch_device_t device) { + p4_pd_status_t status = 0; - // create an entry for negative mirroring - // Key: egr_port = 0, deflection_flag = 1 - p4_pd_dc_egress_acl_match_spec_t match_spec; - memset(&match_spec, 0, sizeof(p4_pd_dc_egress_acl_match_spec_t)); - match_spec.intrinsic_metadata_deflection_flag = 0x1; - match_spec.intrinsic_metadata_deflection_flag_mask = 0xFF; +#if !defined(P4_TUNNEL_DISABLE) || !defined(P4_MIRROR_DISABLE) + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - // Action: egress_mirror_drop - p4_pd_dc_egress_mirror_drop_action_spec_t action_spec; - action_spec.action_session_id = SWITCH_NEGATIVE_MIRROR_SESSION_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - status = p4_pd_dc_egress_acl_table_add_with_egress_mirror_drop( - g_sess_hdl, p4_pd_device, &match_spec, 0, /* highest priority */ - &action_spec, &entry_hdl); -#endif +#ifndef P4_L3_DISABLE + status = p4_pd_dc_mtu_set_default_action_mtu_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L3_DISABLE */ + status = p4_pd_dc_tunnel_mtu_set_default_action_tunnel_mtu_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; -} + p4_pd_complete_operations(g_sess_hdl); +#endif /* P4_TUNNEL_DISABLE || P4_MIRROR_DISABLE */ -#ifdef P4_INT_EP_ENABLE -static int bit_count_array[16]={0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; -static int -_bit_count(uint64_t val) -{ - int i, count; - count =0; - i= 0; - while (i < (int)sizeof(val)*2) { - count += bit_count_array[val & 0xF]; - val >>= 4; - i++; - } - return count; + return status; } -#endif -#ifdef P4_INT_TRANSIT_ENABLE -p4_pd_status_t -switch_pd_int_transit_enable(switch_device_t device, int32_t switch_id, - int32_t prio, p4_pd_entry_hdl_t *entry_hdl) -{ - // supports only vxlan-GPE. Add more underlay encap later - p4_pd_dc_int_insert_match_spec_t match_spec; - p4_pd_dc_int_transit_action_spec_t action_spec; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +switch_status_t switch_pd_l3_rewrite_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_L3_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; - match_spec.int_metadata_i2e_source = 0; - match_spec.int_metadata_i2e_source_mask = (uint8_t)-1; - match_spec.int_metadata_i2e_sink = 0; - match_spec.int_metadata_i2e_sink_mask = (uint8_t)-1; - match_spec.int_header_valid = 1; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - action_spec.action_switch_id = switch_id; + status = p4_pd_dc_l3_rewrite_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_L3_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} - (void) prio; // remove - status = p4_pd_dc_int_insert_table_add_with_int_transit(g_sess_hdl, - p4_pd_device, &match_spec, 0, - &action_spec, entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; +#ifdef P4_INT_EP_ENABLE +static int bit_count_array[16] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; +static int _bit_count(uint64_t val) { + int i, count; + count = 0; + i = 0; + while (i < (int)sizeof(val) * 2) { + count += bit_count_array[val & 0xF]; + val >>= 4; + i++; + } + return count; } +#endif -p4_pd_status_t -switch_pd_int_transit_disable(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; - status = p4_pd_dc_int_insert_table_delete(g_sess_hdl, device, entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; +#ifdef P4_INT_TRANSIT_ENABLE +p4_pd_status_t switch_pd_int_transit_enable(switch_device_t device, + int32_t switch_id, + int32_t prio, + p4_pd_entry_hdl_t *entry_hdl) { + // supports only vxlan-GPE. Add more underlay encap later + p4_pd_dc_int_insert_match_spec_t match_spec; + p4_pd_dc_int_transit_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + match_spec.int_metadata_i2e_source = 0; + match_spec.int_metadata_i2e_source_mask = (uint8_t)-1; + match_spec.int_metadata_i2e_sink = 0; + match_spec.int_metadata_i2e_sink_mask = (uint8_t)-1; + match_spec.int_header_valid = 1; + + action_spec.action_switch_id = switch_id; + + (void)prio; // remove + status = p4_pd_dc_int_insert_table_add_with_int_transit( + g_sess_hdl, p4_pd_device, &match_spec, 0, &action_spec, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_int_transit_disable(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + status = p4_pd_dc_int_insert_table_delete(g_sess_hdl, device, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } #endif #ifdef P4_INT_EP_ENABLE -p4_pd_status_t -switch_pd_int_src_enable(switch_device_t device, int32_t switch_id, - switch_ip_addr_t *src, - switch_ip_addr_t *dst, - uint8_t hop_cnt, uint16_t ins_mask, - int32_t prio, p4_pd_entry_hdl_t *entry_hdl, bool vtep_src) -{ - // currently assume vxlan-GPE as underlay, - // Program two tables - int_source and int_insert - // ip addresses are client IP addresses - p4_pd_dc_int_insert_match_spec_t insert_match_spec; - p4_pd_dc_int_src_action_spec_t insert_action_spec; - - p4_pd_dc_int_source_match_spec_t src_match_spec; - - p4_pd_dev_target_t p4_pd_device; - int ins_cnt; - p4_pd_status_t status = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - - insert_match_spec.int_metadata_i2e_source = 1; - insert_match_spec.int_metadata_i2e_source_mask = (uint8_t)-1; - insert_match_spec.int_metadata_i2e_sink = 0; - insert_match_spec.int_metadata_i2e_sink_mask = (uint8_t)-1; - insert_match_spec.int_header_valid = 0; - - insert_action_spec.action_switch_id = switch_id; - insert_action_spec.action_hop_cnt = hop_cnt; - insert_action_spec.action_ins_mask0003 = (ins_mask >> 12) & 0xF; - insert_action_spec.action_ins_mask0407 = (ins_mask >> 8) & 0xF; - ins_cnt = _bit_count((uint64_t)ins_mask); - insert_action_spec.action_ins_cnt = ins_cnt; - insert_action_spec.action_ins_byte_cnt = (ins_cnt * 4) + 12; // 12 for headers - insert_action_spec.action_total_words = - (insert_action_spec.action_ins_byte_cnt / 4); - - status = p4_pd_dc_int_insert_table_add_with_int_src(g_sess_hdl, - p4_pd_device, &insert_match_spec, 0, - &insert_action_spec, entry_hdl); - - if (status) { - p4_pd_complete_operations(g_sess_hdl); - return status; - } - // make sure upstream device has not already added INT info - src_match_spec.int_header_valid = 0; - if (vtep_src) { - // use outer(no inner present) addrs since frame is not encapped yet - src_match_spec.ipv4_valid = 1; - src_match_spec.ipv4_metadata_lkp_ipv4_sa = src->ip.v4addr; - src_match_spec.ipv4_metadata_lkp_ipv4_sa_mask = (uint32_t)-1; - - src_match_spec.ipv4_metadata_lkp_ipv4_da = dst->ip.v4addr; - src_match_spec.ipv4_metadata_lkp_ipv4_da_mask = (uint32_t)-1; - // inner are not valid - src_match_spec.inner_ipv4_valid = 0; - src_match_spec.inner_ipv4_srcAddr = 0; - src_match_spec.inner_ipv4_srcAddr_mask = 0; // ignore - src_match_spec.inner_ipv4_dstAddr = 0; - src_match_spec.inner_ipv4_dstAddr_mask = 0; // ignore - } else { - // use inner addr since frame is already encapped upstream - src_match_spec.ipv4_valid = 1; - src_match_spec.ipv4_metadata_lkp_ipv4_sa = 0; - src_match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0; // ignore - src_match_spec.ipv4_metadata_lkp_ipv4_da = 0; - src_match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0; // ignore - // inner are not valid - src_match_spec.inner_ipv4_valid = 1; - src_match_spec.inner_ipv4_srcAddr = src->ip.v4addr; - src_match_spec.inner_ipv4_srcAddr_mask = (uint32_t)-1; - src_match_spec.inner_ipv4_dstAddr = dst->ip.v4addr; - src_match_spec.inner_ipv4_dstAddr_mask = (uint32_t)-1; - } +p4_pd_status_t switch_pd_int_src_enable(switch_device_t device, + int32_t switch_id, + switch_ip_addr_t *src, + switch_ip_addr_t *dst, + uint8_t hop_cnt, + uint16_t ins_mask, + int32_t prio, + p4_pd_entry_hdl_t *entry_hdl, + bool vtep_src) { + // currently assume vxlan-GPE as underlay, + // Program two tables - int_source and int_insert + // ip addresses are client IP addresses + p4_pd_dc_int_insert_match_spec_t insert_match_spec; + p4_pd_dc_int_src_action_spec_t insert_action_spec; + + p4_pd_dc_int_source_match_spec_t src_match_spec; + + p4_pd_dev_target_t p4_pd_device; + int ins_cnt; + p4_pd_status_t status = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + insert_match_spec.int_metadata_i2e_source = 1; + insert_match_spec.int_metadata_i2e_source_mask = (uint8_t)-1; + insert_match_spec.int_metadata_i2e_sink = 0; + insert_match_spec.int_metadata_i2e_sink_mask = (uint8_t)-1; + insert_match_spec.int_header_valid = 0; + + insert_action_spec.action_switch_id = switch_id; + insert_action_spec.action_hop_cnt = hop_cnt; + insert_action_spec.action_ins_mask0003 = (ins_mask >> 12) & 0xF; + insert_action_spec.action_ins_mask0407 = (ins_mask >> 8) & 0xF; + ins_cnt = _bit_count((uint64_t)ins_mask); + insert_action_spec.action_ins_cnt = ins_cnt; + insert_action_spec.action_ins_byte_cnt = + (ins_cnt * 4) + 12; // 12 for headers + insert_action_spec.action_total_words = + (insert_action_spec.action_ins_byte_cnt / 4); + + status = p4_pd_dc_int_insert_table_add_with_int_src(g_sess_hdl, + p4_pd_device, + &insert_match_spec, + 0, + &insert_action_spec, + entry_hdl); - // cleanup on failure - TBD - status = p4_pd_dc_int_source_table_add_with_int_set_src (g_sess_hdl, - p4_pd_device, &src_match_spec, prio, - entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + if (status) { + p4_pd_complete_operations(g_sess_hdl); + return status; + } + // make sure upstream device has not already added INT info + src_match_spec.int_header_valid = 0; + if (vtep_src) { + // use outer(no inner present) addrs since frame is not encapped yet + src_match_spec.ipv4_valid = 1; + src_match_spec.ipv4_metadata_lkp_ipv4_sa = src->ip.v4addr; + src_match_spec.ipv4_metadata_lkp_ipv4_sa_mask = (uint32_t)-1; + + src_match_spec.ipv4_metadata_lkp_ipv4_da = dst->ip.v4addr; + src_match_spec.ipv4_metadata_lkp_ipv4_da_mask = (uint32_t)-1; + // inner are not valid + src_match_spec.inner_ipv4_valid = 0; + src_match_spec.inner_ipv4_srcAddr = 0; + src_match_spec.inner_ipv4_srcAddr_mask = 0; // ignore + src_match_spec.inner_ipv4_dstAddr = 0; + src_match_spec.inner_ipv4_dstAddr_mask = 0; // ignore + } else { + // use inner addr since frame is already encapped upstream + src_match_spec.ipv4_valid = 1; + src_match_spec.ipv4_metadata_lkp_ipv4_sa = 0; + src_match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0; // ignore + src_match_spec.ipv4_metadata_lkp_ipv4_da = 0; + src_match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0; // ignore + // inner are not valid + src_match_spec.inner_ipv4_valid = 1; + src_match_spec.inner_ipv4_srcAddr = src->ip.v4addr; + src_match_spec.inner_ipv4_srcAddr_mask = (uint32_t)-1; + src_match_spec.inner_ipv4_dstAddr = dst->ip.v4addr; + src_match_spec.inner_ipv4_dstAddr_mask = (uint32_t)-1; + } + + // cleanup on failure - TBD + status = p4_pd_dc_int_source_table_add_with_int_set_src( + g_sess_hdl, p4_pd_device, &src_match_spec, prio, entry_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; } #endif #ifdef P4_INT_EP_ENABLE -p4_pd_status_t -switch_pd_int_sink_enable(switch_device_t device, - switch_ip_addr_t *dst, - uint32_t mirror_id, - int32_t prio, p4_pd_entry_hdl_t *entry_hdl, bool use_client_ip) -{ - // XXX currently assume vxlan-GPE, need underlay-type parameter - p4_pd_dc_int_terminate_match_spec_t match_spec; - p4_pd_dc_int_sink_gpe_action_spec_t action_spec; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - - match_spec.int_header_valid = 1; - match_spec.vxlan_gpe_int_header_valid = 1; - if (use_client_ip) { - match_spec.inner_ipv4_valid = 1; - match_spec.inner_ipv4_dstAddr = dst->ip.v4addr; - match_spec.inner_ipv4_dstAddr_mask = (uint32_t)-1; - // ignore outer ips - match_spec.ipv4_valid = 1; - match_spec.ipv4_metadata_lkp_ipv4_da = 0; - match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0; // * - } else { - // ignore inner ip - match_spec.inner_ipv4_valid = 1; - match_spec.inner_ipv4_dstAddr = 0; - match_spec.inner_ipv4_dstAddr_mask = 0; // * - // use outer ips - match_spec.ipv4_valid = 1; - match_spec.ipv4_metadata_lkp_ipv4_da = dst->ip.v4addr; - match_spec.ipv4_metadata_lkp_ipv4_da_mask = (uint32_t)-1; - } +p4_pd_status_t switch_pd_int_sink_enable(switch_device_t device, + switch_ip_addr_t *dst, + uint32_t mirror_id, + int32_t prio, + p4_pd_entry_hdl_t *entry_hdl, + bool use_client_ip) { + // XXX currently assume vxlan-GPE, need underlay-type parameter + p4_pd_dc_int_terminate_match_spec_t match_spec; + p4_pd_dc_int_sink_gpe_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + match_spec.int_header_valid = 1; + match_spec.vxlan_gpe_int_header_valid = 1; + if (use_client_ip) { + match_spec.inner_ipv4_valid = 1; + match_spec.inner_ipv4_dstAddr = dst->ip.v4addr; + match_spec.inner_ipv4_dstAddr_mask = (uint32_t)-1; + // ignore outer ips + match_spec.ipv4_valid = 1; + match_spec.ipv4_metadata_lkp_ipv4_da = 0; + match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0; // * + } else { + // ignore inner ip + match_spec.inner_ipv4_valid = 1; + match_spec.inner_ipv4_dstAddr = 0; + match_spec.inner_ipv4_dstAddr_mask = 0; // * + // use outer ips + match_spec.ipv4_valid = 1; + match_spec.ipv4_metadata_lkp_ipv4_da = dst->ip.v4addr; + match_spec.ipv4_metadata_lkp_ipv4_da_mask = (uint32_t)-1; + } + + action_spec.action_mirror_id = mirror_id; + + status = p4_pd_dc_int_terminate_table_add_with_int_sink_gpe( + g_sess_hdl, p4_pd_device, &match_spec, prio, &action_spec, entry_hdl); + + // program int_sink_update_outer table to remove and update any outer + // headers + { + p4_pd_dc_int_sink_update_outer_match_spec_t match_spec; - action_spec.action_mirror_id = mirror_id; - - status = p4_pd_dc_int_terminate_table_add_with_int_sink_gpe(g_sess_hdl, - p4_pd_device, &match_spec, prio, - &action_spec, entry_hdl); - - // program int_sink_update_outer table to remove and update any outer - // headers - { - p4_pd_dc_int_sink_update_outer_match_spec_t match_spec; - - match_spec.vxlan_gpe_int_header_valid = 1; - match_spec.ipv4_valid = 1; - match_spec.int_metadata_i2e_sink = 1; + match_spec.vxlan_gpe_int_header_valid = 1; + match_spec.ipv4_valid = 1; + match_spec.int_metadata_i2e_sink = 1; - status = p4_pd_dc_int_sink_update_outer_table_add_with_int_sink_update_vxlan_gpe_v4(g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); - } + status = + p4_pd_dc_int_sink_update_outer_table_add_with_int_sink_update_vxlan_gpe_v4( + g_sess_hdl, p4_pd_device, &match_spec, entry_hdl); + } - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } #endif #ifdef P4_INT_ENABLE -p4_pd_status_t -switch_pd_int_tables_init(switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - int i; - uint16_t key, mask; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +p4_pd_status_t switch_pd_int_tables_init(switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + int i; + uint16_t key, mask; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; #ifdef P4_INT_EP_ENABLE - // int_source Table - p4_pd_dc_int_source_set_default_action_int_set_no_src(g_sess_hdl, - p4_pd_device, &entry_hdl); - // int_terminate - default is no_terminate - p4_pd_dc_int_terminate_set_default_action_int_no_sink(g_sess_hdl, - p4_pd_device, &entry_hdl); - - // int_sink_update_outer - p4_pd_dc_int_sink_update_outer_set_default_action_nop(g_sess_hdl, - p4_pd_device, &entry_hdl); + // int_source Table + p4_pd_dc_int_source_set_default_action_int_set_no_src( + g_sess_hdl, p4_pd_device, &entry_hdl); + // int_terminate - default is no_terminate + p4_pd_dc_int_terminate_set_default_action_int_no_sink( + g_sess_hdl, p4_pd_device, &entry_hdl); + + // int_sink_update_outer + p4_pd_dc_int_sink_update_outer_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif - // int_insert - default : do not insert INT information - p4_pd_dc_int_insert_set_default_action_int_reset(g_sess_hdl, p4_pd_device, - &entry_hdl); - // int_meta_header_update - increment total_cnt (default) on - // successful addition of INT data. Else set E bit - p4_pd_dc_int_meta_header_update_set_default_action_int_update_total_hop_cnt( - g_sess_hdl, p4_pd_device, &entry_hdl); - - // int_meta_header_update - Set E bit if insert_cnt is 0 - { - p4_pd_dc_int_meta_header_update_match_spec_t match_spec; - match_spec.int_metadata_insert_cnt = 0; - match_spec.int_metadata_insert_cnt_mask = 0xFF; - p4_pd_dc_int_meta_header_update_table_add_with_int_set_e_bit( - g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); - } - - // INT encap - outer header update - p4_pd_dc_int_outer_encap_set_default_action_nop (g_sess_hdl, - p4_pd_device, &entry_hdl); + // int_insert - default : do not insert INT information + p4_pd_dc_int_insert_set_default_action_int_reset( + g_sess_hdl, p4_pd_device, &entry_hdl); + // int_meta_header_update - increment total_cnt (default) on + // successful addition of INT data. Else set E bit + p4_pd_dc_int_meta_header_update_set_default_action_int_update_total_hop_cnt( + g_sess_hdl, p4_pd_device, &entry_hdl); + + // int_meta_header_update - Set E bit if insert_cnt is 0 + { + p4_pd_dc_int_meta_header_update_match_spec_t match_spec; + match_spec.int_metadata_insert_cnt = 0; + match_spec.int_metadata_insert_cnt_mask = 0xFF; + p4_pd_dc_int_meta_header_update_table_add_with_int_set_e_bit( + g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); + } + + // INT encap - outer header update + p4_pd_dc_int_outer_encap_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #ifdef P4_INT_TRANSIT_ENABLE - { - // Trasit - p4_pd_dc_int_outer_encap_match_spec_t match_spec; - - match_spec.int_metadata_i2e_source = 0; - match_spec.ipv4_valid = 1; - match_spec.vxlan_gpe_valid = 1; - match_spec.tunnel_metadata_egress_tunnel_type = 0; - match_spec.tunnel_metadata_egress_tunnel_type_mask = 0; // * - p4_pd_dc_int_outer_encap_table_add_with_int_update_vxlan_gpe_ipv4( - g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); - } + { + // Trasit + p4_pd_dc_int_outer_encap_match_spec_t match_spec; + + match_spec.int_metadata_i2e_source = 0; + match_spec.ipv4_valid = 1; + match_spec.vxlan_gpe_valid = 1; + match_spec.tunnel_metadata_egress_tunnel_type = 0; + match_spec.tunnel_metadata_egress_tunnel_type_mask = 0; // * + p4_pd_dc_int_outer_encap_table_add_with_int_update_vxlan_gpe_ipv4( + g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); + } #endif #ifdef P4_INT_EP_ENABLE - { - // INT source - // create two entries to handle int src with and w/o vtep-src - p4_pd_dc_int_outer_encap_match_spec_t match_spec; - match_spec.int_metadata_i2e_source = 1; - match_spec.ipv4_valid = 1; - match_spec.vxlan_gpe_valid = 1; // VTEP is upstream - // since this node is trasit for vxlan tunnel_type is not initialized - // in the datapath - match_spec.tunnel_metadata_egress_tunnel_type = 0; - match_spec.tunnel_metadata_egress_tunnel_type_mask = 0; // * - p4_pd_dc_int_outer_encap_table_add_with_int_add_update_vxlan_gpe_ipv4 - (g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); - - // This node is VTEP src too - match_spec.int_metadata_i2e_source = 1; - match_spec.ipv4_valid = 1; - match_spec.vxlan_gpe_valid = 0; - match_spec.tunnel_metadata_egress_tunnel_type = - SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN_GPE; - match_spec.tunnel_metadata_egress_tunnel_type_mask = -1; - p4_pd_dc_int_outer_encap_table_add_with_int_add_update_vxlan_gpe_ipv4 - (g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); - } + { + // INT source + // create two entries to handle int src with and w/o vtep-src + p4_pd_dc_int_outer_encap_match_spec_t match_spec; + match_spec.int_metadata_i2e_source = 1; + match_spec.ipv4_valid = 1; + match_spec.vxlan_gpe_valid = 1; // VTEP is upstream + // since this node is trasit for vxlan tunnel_type is not initialized + // in the datapath + match_spec.tunnel_metadata_egress_tunnel_type = 0; + match_spec.tunnel_metadata_egress_tunnel_type_mask = 0; // * + p4_pd_dc_int_outer_encap_table_add_with_int_add_update_vxlan_gpe_ipv4( + g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); + + // This node is VTEP src too + match_spec.int_metadata_i2e_source = 1; + match_spec.ipv4_valid = 1; + match_spec.vxlan_gpe_valid = 0; + match_spec.tunnel_metadata_egress_tunnel_type = + SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN_GPE; + match_spec.tunnel_metadata_egress_tunnel_type_mask = -1; + p4_pd_dc_int_outer_encap_table_add_with_int_add_update_vxlan_gpe_ipv4( + g_sess_hdl, p4_pd_device, &match_spec, 0, &entry_hdl); + } #endif - // int_inst_0003 int_inst_0407 int_inst_0811 int_inst_1215 - // Program all 16 entries with 16 unique actions for each - // pattern in each table - for (i=0; i<16; i++) { - p4_pd_dc_int_inst_0003_match_spec_t match_0003_spec; - switch (i) { - case 0: - match_0003_spec.int_header_instruction_mask_0003 = 0; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i0( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; + // int_inst_0003 int_inst_0407 int_inst_0811 int_inst_1215 + // Program all 16 entries with 16 unique actions for each + // pattern in each table + for (i = 0; i < 16; i++) { + p4_pd_dc_int_inst_0003_match_spec_t match_0003_spec; + switch (i) { + case 0: + match_0003_spec.int_header_instruction_mask_0003 = 0; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i0( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; - case 1: - match_0003_spec.int_header_instruction_mask_0003 = 1; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i1( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; + case 1: + match_0003_spec.int_header_instruction_mask_0003 = 1; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i1( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; - case 2: - match_0003_spec.int_header_instruction_mask_0003 = 2; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i2( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; + case 2: + match_0003_spec.int_header_instruction_mask_0003 = 2; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i2( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; - case 3: - match_0003_spec.int_header_instruction_mask_0003 = 3; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i3( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 4: - match_0003_spec.int_header_instruction_mask_0003 = 4; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i4( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 5: - match_0003_spec.int_header_instruction_mask_0003 = 5; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i5( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 6: - match_0003_spec.int_header_instruction_mask_0003 = 6; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i6( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 7: - match_0003_spec.int_header_instruction_mask_0003 = 7; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i7( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 8: - match_0003_spec.int_header_instruction_mask_0003 = 8; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i8( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 9: - match_0003_spec.int_header_instruction_mask_0003 = 9; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i9( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 10: - match_0003_spec.int_header_instruction_mask_0003 = 10; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i10( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 11: - match_0003_spec.int_header_instruction_mask_0003 = 11; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i11( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 12: - match_0003_spec.int_header_instruction_mask_0003 = 12; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i12( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 13: - match_0003_spec.int_header_instruction_mask_0003 = 13; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i13( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 14: - match_0003_spec.int_header_instruction_mask_0003 = 14; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i14( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - - case 15: - match_0003_spec.int_header_instruction_mask_0003 = 15; - p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i15( - g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); - break; - } + case 3: + match_0003_spec.int_header_instruction_mask_0003 = 3; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i3( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 4: + match_0003_spec.int_header_instruction_mask_0003 = 4; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i4( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 5: + match_0003_spec.int_header_instruction_mask_0003 = 5; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i5( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 6: + match_0003_spec.int_header_instruction_mask_0003 = 6; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i6( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 7: + match_0003_spec.int_header_instruction_mask_0003 = 7; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i7( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 8: + match_0003_spec.int_header_instruction_mask_0003 = 8; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i8( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 9: + match_0003_spec.int_header_instruction_mask_0003 = 9; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i9( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 10: + match_0003_spec.int_header_instruction_mask_0003 = 10; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i10( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 11: + match_0003_spec.int_header_instruction_mask_0003 = 11; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i11( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 12: + match_0003_spec.int_header_instruction_mask_0003 = 12; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i12( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 13: + match_0003_spec.int_header_instruction_mask_0003 = 13; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i13( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 14: + match_0003_spec.int_header_instruction_mask_0003 = 14; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i14( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; + + case 15: + match_0003_spec.int_header_instruction_mask_0003 = 15; + p4_pd_dc_int_inst_0003_table_add_with_int_set_header_0003_i15( + g_sess_hdl, p4_pd_device, &match_0003_spec, &entry_hdl); + break; } - for (i=0; i<16; i++) { - p4_pd_dc_int_inst_0407_match_spec_t match_0407_spec; - switch (i) { - case 0: - match_0407_spec.int_header_instruction_mask_0407 = 0; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i0( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; + } + for (i = 0; i < 16; i++) { + p4_pd_dc_int_inst_0407_match_spec_t match_0407_spec; + switch (i) { + case 0: + match_0407_spec.int_header_instruction_mask_0407 = 0; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i0( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; - case 1: - match_0407_spec.int_header_instruction_mask_0407 = 1; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i1( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; + case 1: + match_0407_spec.int_header_instruction_mask_0407 = 1; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i1( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; - case 2: - match_0407_spec.int_header_instruction_mask_0407 = 2; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i2( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; + case 2: + match_0407_spec.int_header_instruction_mask_0407 = 2; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i2( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; - case 3: - match_0407_spec.int_header_instruction_mask_0407 = 3; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i3( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 4: - match_0407_spec.int_header_instruction_mask_0407 = 4; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i4( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 5: - match_0407_spec.int_header_instruction_mask_0407 = 5; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i5( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 6: - match_0407_spec.int_header_instruction_mask_0407 = 6; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i6( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 7: - match_0407_spec.int_header_instruction_mask_0407 = 7; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i7( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 8: - match_0407_spec.int_header_instruction_mask_0407 = 8; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i8( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 9: - match_0407_spec.int_header_instruction_mask_0407 = 9; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i9( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 10: - match_0407_spec.int_header_instruction_mask_0407 = 10; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i10( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 11: - match_0407_spec.int_header_instruction_mask_0407 = 11; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i11( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 12: - match_0407_spec.int_header_instruction_mask_0407 = 12; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i12( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 13: - match_0407_spec.int_header_instruction_mask_0407 = 13; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i13( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 14: - match_0407_spec.int_header_instruction_mask_0407 = 14; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i14( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - - case 15: - match_0407_spec.int_header_instruction_mask_0407 = 15; - p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i15( - g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); - break; - } + case 3: + match_0407_spec.int_header_instruction_mask_0407 = 3; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i3( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 4: + match_0407_spec.int_header_instruction_mask_0407 = 4; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i4( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 5: + match_0407_spec.int_header_instruction_mask_0407 = 5; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i5( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 6: + match_0407_spec.int_header_instruction_mask_0407 = 6; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i6( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 7: + match_0407_spec.int_header_instruction_mask_0407 = 7; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i7( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 8: + match_0407_spec.int_header_instruction_mask_0407 = 8; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i8( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 9: + match_0407_spec.int_header_instruction_mask_0407 = 9; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i9( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 10: + match_0407_spec.int_header_instruction_mask_0407 = 10; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i10( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 11: + match_0407_spec.int_header_instruction_mask_0407 = 11; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i11( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 12: + match_0407_spec.int_header_instruction_mask_0407 = 12; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i12( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 13: + match_0407_spec.int_header_instruction_mask_0407 = 13; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i13( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 14: + match_0407_spec.int_header_instruction_mask_0407 = 14; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i14( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; + + case 15: + match_0407_spec.int_header_instruction_mask_0407 = 15; + p4_pd_dc_int_inst_0407_table_add_with_int_set_header_0407_i15( + g_sess_hdl, p4_pd_device, &match_0407_spec, &entry_hdl); + break; } - // bits 8-15 are not defined - not programmed - use default action - p4_pd_dc_int_inst_0811_set_default_action_nop(g_sess_hdl, p4_pd_device, - &entry_hdl); - p4_pd_dc_int_inst_1215_set_default_action_nop(g_sess_hdl, p4_pd_device, - &entry_hdl); - p4_pd_dc_int_bos_set_default_action_nop(g_sess_hdl, p4_pd_device, - &entry_hdl); - // Setup the table to set BOS bit on the last value - // bits 8-15 are not defined in INT spec mask them off - key = 0x8000; mask = 0xF000; - for (i=0; i<16; i++) { - // int_bos - set bos bit based on the last (least significant) bit set - // in the instruction.. i.e. all lower bits should be 0 - // mask.. Install most specific entry at the top for MSb as - // {key = 0x8000, mask = 0xffff} - // {key = 0x4000, mask = 0x7fff} ... - // And lowest entry for LSb as - // {key = 0x0001, mask = 0x0001} - - p4_pd_dc_int_bos_match_spec_t match_spec; - - // total_cnt must be 0 to insert BOS bit - match_spec.int_header_total_hop_cnt = 0; - match_spec.int_header_total_hop_cnt_mask = 0xff; - // split the key and mask in 4 bits - match_spec.int_header_instruction_mask_0003 = (key >> 12) & 0xF; - match_spec.int_header_instruction_mask_0003_mask = - (mask >> 12) & 0xF; - match_spec.int_header_instruction_mask_0407 = (key >> 8) & 0xF; - match_spec.int_header_instruction_mask_0407_mask = - (mask >> 8) & 0xF; - match_spec.int_header_instruction_mask_0811 = (key >> 4) & 0xF; - match_spec.int_header_instruction_mask_0811_mask = - (mask >> 4) & 0xF; - match_spec.int_header_instruction_mask_1215 = (key) & 0xF; - match_spec.int_header_instruction_mask_1215_mask = (mask) & 0xF; - - switch(i) { - case 0: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_0_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 1: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_1_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 2: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_2_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 3: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_3_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 4: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_4_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 5: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_5_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 6: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_6_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 7: - { - p4_pd_dc_int_bos_table_add_with_int_set_header_7_bos(g_sess_hdl, - p4_pd_device, &match_spec, i, &entry_hdl); - break; - } - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - default: - // NOP - not supported bits 8-15 - p4_pd_dc_int_bos_table_add_with_nop(g_sess_hdl, p4_pd_device, - &match_spec, 15, &entry_hdl); - break; - } - key >>= 1; mask >>= 1; + } + // bits 8-15 are not defined - not programmed - use default action + p4_pd_dc_int_inst_0811_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_dc_int_inst_1215_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_dc_int_bos_set_default_action_nop(g_sess_hdl, p4_pd_device, &entry_hdl); + // Setup the table to set BOS bit on the last value + // bits 8-15 are not defined in INT spec mask them off + key = 0x8000; + mask = 0xF000; + for (i = 0; i < 16; i++) { + // int_bos - set bos bit based on the last (least significant) bit set + // in the instruction.. i.e. all lower bits should be 0 + // mask.. Install most specific entry at the top for MSb as + // {key = 0x8000, mask = 0xffff} + // {key = 0x4000, mask = 0x7fff} ... + // And lowest entry for LSb as + // {key = 0x0001, mask = 0x0001} + + p4_pd_dc_int_bos_match_spec_t match_spec; + + // total_cnt must be 0 to insert BOS bit + match_spec.int_header_total_hop_cnt = 0; + match_spec.int_header_total_hop_cnt_mask = 0xff; + // split the key and mask in 4 bits + match_spec.int_header_instruction_mask_0003 = (key >> 12) & 0xF; + match_spec.int_header_instruction_mask_0003_mask = (mask >> 12) & 0xF; + match_spec.int_header_instruction_mask_0407 = (key >> 8) & 0xF; + match_spec.int_header_instruction_mask_0407_mask = (mask >> 8) & 0xF; + match_spec.int_header_instruction_mask_0811 = (key >> 4) & 0xF; + match_spec.int_header_instruction_mask_0811_mask = (mask >> 4) & 0xF; + match_spec.int_header_instruction_mask_1215 = (key)&0xF; + match_spec.int_header_instruction_mask_1215_mask = (mask)&0xF; + + switch (i) { + case 0: { + p4_pd_dc_int_bos_table_add_with_int_set_header_0_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 1: { + p4_pd_dc_int_bos_table_add_with_int_set_header_1_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 2: { + p4_pd_dc_int_bos_table_add_with_int_set_header_2_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 3: { + p4_pd_dc_int_bos_table_add_with_int_set_header_3_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 4: { + p4_pd_dc_int_bos_table_add_with_int_set_header_4_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 5: { + p4_pd_dc_int_bos_table_add_with_int_set_header_5_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 6: { + p4_pd_dc_int_bos_table_add_with_int_set_header_6_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 7: { + p4_pd_dc_int_bos_table_add_with_int_set_header_7_bos( + g_sess_hdl, p4_pd_device, &match_spec, i, &entry_hdl); + break; + } + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + default: + // NOP - not supported bits 8-15 + p4_pd_dc_int_bos_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, 15, &entry_hdl); + break; } - p4_pd_complete_operations(g_sess_hdl); - return status; + key >>= 1; + mask >>= 1; + } + p4_pd_complete_operations(g_sess_hdl); + return status; } -#endif // P4_INT_ENABLE +#endif // P4_INT_ENABLE -p4_pd_status_t -switch_pd_storm_control_table_add_default_entry( - switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_storm_control_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #if !defined(P4_METER_DISABLE) && !defined(P4_STORM_CONTROL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - 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; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_storm_control_set_default_action_nop( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_storm_control_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); - status = p4_pd_dc_storm_control_stats_set_default_action_nop( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_storm_control_stats_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_METER_DISABLE && P4_STORM_CONTROL_DISABLE */ - return status; + return status; } -p4_pd_status_t -switch_pd_storm_control_meter_add_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_storm_control_meter_add_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info) { + p4_pd_status_t status = 0; #if !defined(P4_METER_DISABLE) && !defined(P4_STORM_CONTROL_DISABLE) - p4_pd_dev_target_t p4_pd_device; - switch_api_meter_t *api_meter_info = NULL; + p4_pd_dev_target_t p4_pd_device; + switch_api_meter_t *api_meter_info = NULL; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - api_meter_info = &meter_info->api_meter_info; - if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { - p4_pd_bytes_meter_spec_t meter_spec; - memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); - meter_spec.cir_kbps = api_meter_info->cir; - meter_spec.cburst_kbits = api_meter_info->cbs; - meter_spec.pir_kbps = api_meter_info->pir; - meter_spec.pburst_kbits = api_meter_info->pbs; - meter_spec.meter_type = api_meter_info->color_source == - SWITCH_METER_COLOR_SOURCE_BLIND ? - PD_METER_TYPE_COLOR_UNAWARE : - PD_METER_TYPE_COLOR_AWARE; - status = p4_pd_dc_meter_set_storm_control_meter( - g_sess_hdl, - p4_pd_device, - meter_idx, - &meter_spec); - } else { - p4_pd_packets_meter_spec_t meter_spec; - memset(&meter_spec, 0, sizeof(p4_pd_packets_meter_spec_t)); - meter_spec.cir_pps = api_meter_info->cir; - meter_spec.cburst_pkts = api_meter_info->cbs; - meter_spec.pir_pps = api_meter_info->pir; - meter_spec.pburst_pkts = api_meter_info->pbs; - meter_spec.meter_type = api_meter_info->color_source == - SWITCH_METER_COLOR_SOURCE_BLIND ? - PD_METER_TYPE_COLOR_UNAWARE : - PD_METER_TYPE_COLOR_AWARE; - (void) meter_spec; - } + api_meter_info = &meter_info->api_meter_info; + if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { + p4_pd_bytes_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + meter_spec.cir_kbps = api_meter_info->cir; + meter_spec.cburst_kbits = api_meter_info->cbs; + meter_spec.pir_kbps = api_meter_info->pir; + meter_spec.pburst_kbits = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + status = p4_pd_dc_meter_set_storm_control_meter( + g_sess_hdl, p4_pd_device, meter_idx, &meter_spec); + } else { + p4_pd_packets_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_packets_meter_spec_t)); + meter_spec.cir_pps = api_meter_info->cir; + meter_spec.cburst_pkts = api_meter_info->cbs; + meter_spec.pir_pps = api_meter_info->pir; + meter_spec.pburst_pkts = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + (void)meter_spec; + } #endif /* P4_METER_DISABLE && P4_STORM_CONTROL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; -} - -p4_pd_status_t -switch_pd_storm_control_table_add_entry( - switch_device_t device, - switch_port_t port, - uint16_t priority, - switch_packet_type_t pkt_type, - switch_meter_idx_t meter_idx, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_storm_control_table_add_entry( + switch_device_t device, + switch_port_t port, + uint16_t priority, + switch_packet_type_t pkt_type, + switch_meter_idx_t meter_idx, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_METER_DISABLE) && !defined(P4_STORM_CONTROL_DISABLE) - p4_pd_dc_storm_control_match_spec_t match_spec; - p4_pd_dc_set_storm_control_meter_action_spec_t action_spec; - p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_storm_control_match_spec_t match_spec; + p4_pd_dc_set_storm_control_meter_action_spec_t action_spec; + p4_pd_dev_target_t p4_pd_device; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_storm_control_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_set_storm_control_meter_action_spec_t)); + memset(&match_spec, 0, sizeof(p4_pd_dc_storm_control_match_spec_t)); + memset( + &action_spec, 0, sizeof(p4_pd_dc_set_storm_control_meter_action_spec_t)); - match_spec.l2_metadata_lkp_pkt_type = pkt_type; - match_spec.l2_metadata_lkp_pkt_type_mask = 0xFF; - match_spec.ingress_input_port = port; + match_spec.l2_metadata_lkp_pkt_type = pkt_type; + match_spec.l2_metadata_lkp_pkt_type_mask = 0xFF; + match_spec.standard_metadata_ingress_port = port; - action_spec.action_meter_idx = meter_idx; + action_spec.action_meter_idx = meter_idx; - status = p4_pd_dc_storm_control_table_add_with_set_storm_control_meter( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &action_spec, - entry_hdl); + status = p4_pd_dc_storm_control_table_add_with_set_storm_control_meter( + g_sess_hdl, p4_pd_device, &match_spec, priority, &action_spec, entry_hdl); #endif /* P4_METER_DISABLE && P4_STORM_CONTROL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_storm_control_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_storm_control_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #if !defined(P4_METER_DISABLE) && !defined(P4_STORM_CONTROL_DISABLE) - status = p4_pd_dc_storm_control_table_delete( - g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_storm_control_table_delete(g_sess_hdl, device, entry_hdl); #endif /* P4_METER_DISABLE && P4_STORM_CONTROL_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_index_table_add_default_entry( - switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_index_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - p4_pd_dev_target_t p4_pd_device; - p4_pd_entry_hdl_t entry_hdl; - p4_pd_bytes_meter_spec_t meter_spec; + p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; + p4_pd_bytes_meter_spec_t meter_spec; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); - meter_spec.meter_type = PD_METER_TYPE_COLOR_UNAWARE; - status = p4_pd_dc_meter_index_set_default_action_nop( - g_sess_hdl, - p4_pd_device, - &meter_spec, - &entry_hdl); + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + meter_spec.meter_type = PD_METER_TYPE_COLOR_UNAWARE; + status = p4_pd_dc_meter_index_set_default_action_nop( + g_sess_hdl, p4_pd_device, &meter_spec, &entry_hdl); #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_index_table_add_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_index_table_add_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - p4_pd_dc_meter_index_match_spec_t match_spec; - p4_pd_dev_target_t p4_pd_device; - switch_api_meter_t *api_meter_info = NULL; + p4_pd_dc_meter_index_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + switch_api_meter_t *api_meter_info = NULL; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_meter_index_match_spec_t)); + memset(&match_spec, 0, sizeof(p4_pd_dc_meter_index_match_spec_t)); - match_spec.meter_metadata_meter_index = meter_idx; + match_spec.meter_metadata_meter_index = meter_idx; - api_meter_info = &meter_info->api_meter_info; - if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { - p4_pd_bytes_meter_spec_t meter_spec; - memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); - meter_spec.cir_kbps = api_meter_info->cir; - meter_spec.cburst_kbits = api_meter_info->cbs; - meter_spec.pir_kbps = api_meter_info->pir; - meter_spec.pburst_kbits = api_meter_info->pbs; - meter_spec.meter_type = api_meter_info->color_source == - SWITCH_METER_COLOR_SOURCE_BLIND ? - PD_METER_TYPE_COLOR_UNAWARE : - PD_METER_TYPE_COLOR_AWARE; - status = p4_pd_dc_meter_index_table_add_with_nop( - g_sess_hdl, - p4_pd_device, - &match_spec, - &meter_spec, - entry_hdl); - } else { - p4_pd_packets_meter_spec_t meter_spec; - memset(&meter_spec, 0, sizeof(p4_pd_packets_meter_spec_t)); - meter_spec.cir_pps = api_meter_info->cir; - meter_spec.cburst_pkts = api_meter_info->cbs; - meter_spec.pir_pps = api_meter_info->pir; - meter_spec.pburst_pkts = api_meter_info->pbs; - meter_spec.meter_type = api_meter_info->color_source == - SWITCH_METER_COLOR_SOURCE_BLIND ? - PD_METER_TYPE_COLOR_UNAWARE : - PD_METER_TYPE_COLOR_AWARE; - (void) meter_spec; - } + api_meter_info = &meter_info->api_meter_info; + if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { + p4_pd_bytes_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + meter_spec.cir_kbps = api_meter_info->cir; + meter_spec.cburst_kbits = api_meter_info->cbs; + meter_spec.pir_kbps = api_meter_info->pir; + meter_spec.pburst_kbits = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + status = p4_pd_dc_meter_index_table_add_with_nop( + g_sess_hdl, p4_pd_device, &match_spec, &meter_spec, entry_hdl); + } else { + p4_pd_packets_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_packets_meter_spec_t)); + meter_spec.cir_pps = api_meter_info->cir; + meter_spec.cburst_pkts = api_meter_info->cbs; + meter_spec.pir_pps = api_meter_info->pir; + meter_spec.pburst_pkts = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + (void)meter_spec; + } #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_index_table_update_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_index_table_update_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - switch_api_meter_t *api_meter_info = NULL; + switch_api_meter_t *api_meter_info = NULL; - api_meter_info = &meter_info->api_meter_info; - if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { - p4_pd_bytes_meter_spec_t meter_spec; - memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); - meter_spec.cir_kbps = api_meter_info->cir; - meter_spec.cburst_kbits = api_meter_info->cbs; - meter_spec.pir_kbps = api_meter_info->pir; - meter_spec.pburst_kbits = api_meter_info->pbs; - meter_spec.meter_type = api_meter_info->color_source == - SWITCH_METER_COLOR_SOURCE_BLIND ? - PD_METER_TYPE_COLOR_UNAWARE : - PD_METER_TYPE_COLOR_AWARE; - - status = p4_pd_dc_meter_index_table_modify_with_nop( - g_sess_hdl, - device, - entry_hdl, - &meter_spec); - } else { - p4_pd_packets_meter_spec_t meter_spec; - memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); - meter_spec.cir_pps = api_meter_info->cir; - meter_spec.cburst_pkts = api_meter_info->cbs; - meter_spec.pir_pps = api_meter_info->pir; - meter_spec.pburst_pkts = api_meter_info->pbs; - meter_spec.meter_type = api_meter_info->color_source == - SWITCH_METER_COLOR_SOURCE_BLIND ? - PD_METER_TYPE_COLOR_UNAWARE : - PD_METER_TYPE_COLOR_AWARE; - /* - status = p4_pd_dc_meter_index_table_modify_with_nop( - g_sess_hdl, - device, - entry_hdl, - &meter_spec); - */ - (void) meter_spec; - } + api_meter_info = &meter_info->api_meter_info; + if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { + p4_pd_bytes_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + meter_spec.cir_kbps = api_meter_info->cir; + meter_spec.cburst_kbits = api_meter_info->cbs; + meter_spec.pir_kbps = api_meter_info->pir; + meter_spec.pburst_kbits = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + + status = p4_pd_dc_meter_index_table_modify_with_nop( + g_sess_hdl, device, entry_hdl, &meter_spec); + } else { + p4_pd_packets_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + meter_spec.cir_pps = api_meter_info->cir; + meter_spec.cburst_pkts = api_meter_info->cbs; + meter_spec.pir_pps = api_meter_info->pir; + meter_spec.pburst_pkts = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + /* + status = p4_pd_dc_meter_index_table_modify_with_nop( + g_sess_hdl, + device, + entry_hdl, + &meter_spec); + */ + (void)meter_spec; + } #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_index_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_index_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - status = p4_pd_dc_meter_index_table_delete( - g_sess_hdl, - device, - entry_hdl); + status = p4_pd_dc_meter_index_table_delete(g_sess_hdl, device, entry_hdl); #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_action_table_add_default_entry( - switch_device_t device) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_action_table_add_default_entry( + switch_device_t device) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - p4_pd_dev_target_t p4_pd_device; - 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; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_meter_action_set_default_action_meter_permit( - g_sess_hdl, - p4_pd_device, - &entry_hdl); + status = p4_pd_dc_meter_action_set_default_action_meter_permit( + g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* METER_DISABLE */ - return status; + return status; } -p4_pd_status_t -switch_pd_meter_action_table_add_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_action_table_add_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - p4_pd_dc_meter_action_match_spec_t match_spec; - p4_pd_dev_target_t p4_pd_device; - switch_api_meter_t *api_meter_info = NULL; - switch_meter_color_t color; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - - api_meter_info = &meter_info->api_meter_info; - - for (color = 0; color < SWITCH_METER_COLOR_MAX; color++) { - memset(&match_spec, 0, sizeof(p4_pd_dc_meter_index_match_spec_t)); - match_spec.meter_metadata_meter_index = meter_idx; - match_spec.meter_metadata_meter_color = color; - - switch (api_meter_info->action[color]) { - case SWITCH_ACL_ACTION_PERMIT: - status = p4_pd_dc_meter_action_table_add_with_meter_permit( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl[color]); - break; - case SWITCH_ACL_ACTION_DROP: - status = p4_pd_dc_meter_action_table_add_with_meter_deny( - g_sess_hdl, - p4_pd_device, - &match_spec, - &entry_hdl[color]); - break; - default: - return SWITCH_STATUS_INVALID_PARAMETER; - } + p4_pd_dc_meter_action_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + switch_api_meter_t *api_meter_info = NULL; + switch_color_t color; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + api_meter_info = &meter_info->api_meter_info; + + for (color = 0; color < SWITCH_COLOR_MAX; color++) { + memset(&match_spec, 0, sizeof(p4_pd_dc_meter_index_match_spec_t)); + match_spec.meter_metadata_meter_index = meter_idx; + match_spec.meter_metadata_packet_color = color; + + switch (api_meter_info->action[color]) { + case SWITCH_ACL_ACTION_PERMIT: + status = p4_pd_dc_meter_action_table_add_with_meter_permit( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl[color]); + break; + case SWITCH_ACL_ACTION_DROP: + status = p4_pd_dc_meter_action_table_add_with_meter_deny( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl[color]); + break; + default: + return SWITCH_STATUS_INVALID_PARAMETER; } + } #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_action_table_update_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t *entry_hdl) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_action_table_update_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - switch_api_meter_t *api_meter_info = NULL; - switch_meter_color_t color; - - api_meter_info = &meter_info->api_meter_info; - - for (color = 0; color < SWITCH_METER_COLOR_MAX; color++) { - switch (api_meter_info->action[color]) { - case SWITCH_ACL_ACTION_PERMIT: - status = p4_pd_dc_meter_action_table_modify_with_meter_permit( - g_sess_hdl, - device, - entry_hdl[color]); - break; - case SWITCH_ACL_ACTION_DROP: - status = p4_pd_dc_meter_action_table_modify_with_meter_deny( - g_sess_hdl, - device, - entry_hdl[color]); - break; - default: - return SWITCH_STATUS_INVALID_PARAMETER; - } + switch_api_meter_t *api_meter_info = NULL; + switch_color_t color; + + api_meter_info = &meter_info->api_meter_info; + + for (color = 0; color < SWITCH_COLOR_MAX; color++) { + switch (api_meter_info->action[color]) { + case SWITCH_ACL_ACTION_PERMIT: + status = p4_pd_dc_meter_action_table_modify_with_meter_permit( + g_sess_hdl, device, entry_hdl[color]); + break; + case SWITCH_ACL_ACTION_DROP: + status = p4_pd_dc_meter_action_table_modify_with_meter_deny( + g_sess_hdl, device, entry_hdl[color]); + break; + default: + return SWITCH_STATUS_INVALID_PARAMETER; } + } #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_meter_action_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t *entry_hdl) { - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_meter_action_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; #ifndef METER_DISABLE - switch_meter_color_t color; - for (color = 0; color < SWITCH_METER_COLOR_MAX; color++) { - status = p4_pd_dc_meter_action_table_delete( - g_sess_hdl, - device, - entry_hdl[color]); - } + switch_color_t color; + for (color = 0; color < SWITCH_COLOR_MAX; color++) { + status = p4_pd_dc_meter_action_table_delete( + g_sess_hdl, device, entry_hdl[color]); + } #endif /* METER_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_switch_config_params_update (switch_device_t device) -{ - p4_pd_entry_hdl_t entry_hdl; - p4_pd_dev_target_t p4_pd_device; - p4_pd_status_t status = 0; - p4_pd_dc_set_config_parameters_action_spec_t cfg_action; +switch_status_t switch_pd_switch_config_params_update(switch_device_t device) { + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + p4_pd_status_t status = 0; + p4_pd_dc_set_config_parameters_action_spec_t cfg_action; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - memset(&cfg_action, 0, sizeof(cfg_action)); - switch_config_action_populate(device, &cfg_action); + memset(&cfg_action, 0, sizeof(cfg_action)); + switch_config_action_populate(device, &cfg_action); - status = - p4_pd_dc_switch_config_params_set_default_action_set_config_parameters( - g_sess_hdl, - p4_pd_device, - &cfg_action, - &entry_hdl); + status = + p4_pd_dc_switch_config_params_set_default_action_set_config_parameters( + g_sess_hdl, p4_pd_device, &cfg_action, &entry_hdl); - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -switch_status_t -switch_pd_switch_config_params_table_init (switch_device_t device) -{ - switch_config_params_init(device); - return switch_pd_switch_config_params_update(device); +switch_status_t switch_pd_switch_config_params_table_init( + switch_device_t device) { + switch_config_params_init(device); + return switch_pd_switch_config_params_update(device); } // sFlow APIs -p4_pd_status_t -switch_pd_sflow_tables_init(switch_device_t device) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +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; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + p4_pd_dev_target_t p4_pd_device; + p4_pd_entry_hdl_t entry_hdl; - p4_pd_dc_sflow_ingress_set_default_action_nop( - g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - p4_pd_dc_sflow_ing_take_sample_set_default_action_nop( - g_sess_hdl, p4_pd_device, &entry_hdl); + p4_pd_dc_sflow_ingress_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); -#else - (void)device; - return status; + p4_pd_dc_sflow_ing_take_sample_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); #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, - uint32_t priority, - uint32_t sample_rate, - switch_sflow_info_t *sflow_info, - switch_sflow_match_entry_t *match_entry) -{ - switch_status_t status = SWITCH_STATUS_FAILURE; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_sflow_ingress_match_spec_t ingress_sflow_match; - p4_pd_dc_sflow_ing_session_enable_action_spec_t action_spec; - - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; - memset(&ingress_sflow_match, 0, sizeof(ingress_sflow_match)); - - if (match_key->port != SWITCH_API_INVALID_HANDLE) { - ingress_sflow_match.ingress_metadata_ifindex = - switch_api_interface_get(match_key->port)->ifindex; - ingress_sflow_match.ingress_metadata_ifindex_mask = -1; - } - if (match_key->vlan) { - // TBD - } - if (match_key->sip) { - ingress_sflow_match.ipv4_metadata_lkp_ipv4_sa = match_key->sip; - ingress_sflow_match.ipv4_metadata_lkp_ipv4_sa_mask = - match_key->sip_mask; - } - if (match_key->dip) { - ingress_sflow_match.ipv4_metadata_lkp_ipv4_da = match_key->dip; - ingress_sflow_match.ipv4_metadata_lkp_ipv4_da_mask = - match_key->dip_mask; - } - if (sample_rate == 0) { - // use the sample_rate from the session - sample_rate = sflow_info->api_info.sample_rate; - } - // divide the RNG space (31bits) into equal chunks based on rate - action_spec.action_rate_thr = (uint32_t)(((uint32_t)-1 >> 1) / sample_rate); - action_spec.action_session_id = sflow_info->session_id; - status = p4_pd_dc_sflow_ingress_table_add_with_sflow_ing_session_enable( - g_sess_hdl, p4_pd_device, &ingress_sflow_match, priority, - &action_spec, &match_entry->ingress_sflow_ent_hdl - ); - p4_pd_complete_operations(g_sess_hdl); - return status; + return status; } -static switch_status_t -switch_pd_sflow_ingress_table_delete (switch_device_t device, - switch_sflow_match_entry_t *match_entry) -{ - switch_status_t status = SWITCH_STATUS_FAILURE; - - status = p4_pd_dc_sflow_ingress_table_delete(g_sess_hdl, device, - match_entry->ingress_sflow_ent_hdl); - p4_pd_complete_operations(g_sess_hdl); - 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, + uint32_t priority, + uint32_t sample_rate, + switch_sflow_info_t *sflow_info, + switch_sflow_match_entry_t *match_entry) { + switch_status_t status = SWITCH_STATUS_FAILURE; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_sflow_ingress_match_spec_t ingress_sflow_match; + p4_pd_dc_sflow_ing_session_enable_action_spec_t action_spec; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + memset(&ingress_sflow_match, 0, sizeof(ingress_sflow_match)); + + if (match_key->port != SWITCH_API_INVALID_HANDLE) { + ingress_sflow_match.ingress_metadata_ifindex = + switch_api_interface_get(match_key->port)->ifindex; + ingress_sflow_match.ingress_metadata_ifindex_mask = -1; + } + if (match_key->vlan) { + // TBD + } + if (match_key->sip) { + ingress_sflow_match.ipv4_metadata_lkp_ipv4_sa = match_key->sip; + ingress_sflow_match.ipv4_metadata_lkp_ipv4_sa_mask = match_key->sip_mask; + } + if (match_key->dip) { + ingress_sflow_match.ipv4_metadata_lkp_ipv4_da = match_key->dip; + ingress_sflow_match.ipv4_metadata_lkp_ipv4_da_mask = match_key->dip_mask; + } + if (sample_rate == 0) { + // use the sample_rate from the session + sample_rate = sflow_info->api_info.sample_rate; + } + // divide the RNG space (31bits) into equal chunks based on rate + action_spec.action_rate_thr = (uint32_t)(((uint32_t)-1 >> 1) / sample_rate); + action_spec.action_session_id = sflow_info->session_id; + status = p4_pd_dc_sflow_ingress_table_add_with_sflow_ing_session_enable( + g_sess_hdl, + p4_pd_device, + &ingress_sflow_match, + priority, + &action_spec, + &match_entry->ingress_sflow_ent_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +static switch_status_t switch_pd_sflow_ingress_table_delete( + switch_device_t device, switch_sflow_match_entry_t *match_entry) { + switch_status_t status = SWITCH_STATUS_FAILURE; + + status = p4_pd_dc_sflow_ingress_table_delete( + g_sess_hdl, device, match_entry->ingress_sflow_ent_hdl); + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +switch_status_t switch_pd_sflow_match_table_delete( + switch_device_t device, switch_sflow_match_entry_t *match_entry) { + switch_status_t status = SWITCH_STATUS_FAILURE; + if (match_entry->ingress_sflow_ent_hdl != SWITCH_API_INVALID_HANDLE) { + status = switch_pd_sflow_ingress_table_delete(device, match_entry); + } + // XXX - delete egress entries if present + return status; +} + +switch_status_t switch_pd_mirror_table_sflow_add( + switch_device_t device, switch_sflow_info_t *sflow_info) { + switch_status_t status = SWITCH_STATUS_FAILURE; + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_mirror_match_spec_t match_spec; + p4_pd_dc_sflow_pkt_to_cpu_action_spec_t action_spec; + + if ((sflow_info->api_info.collector_type != SFLOW_COLLECTOR_TYPE_CPU) || + (sflow_info->api_info.sample_mode != SWITCH_SFLOW_SAMPLE_PKT)) { + // if collector == REMOTE : set action as sflow_pkt_to_remote - TBD + return status; + } + // if collector == CPU : set action as sflow_pkt_to_cpu + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + match_spec.i2e_metadata_mirror_session_id = + handle_to_id(sflow_info->mirror_hdl); + action_spec.action_reason_code = SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE; + status = p4_pd_dc_mirror_table_add_with_sflow_pkt_to_cpu( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &sflow_info->mirror_table_ent_hdl); + + p4_pd_complete_operations(g_sess_hdl); + + return status; +} + +switch_status_t switch_pd_sflow_session_create( + switch_device_t device, switch_sflow_info_t *sflow_info) { + switch_status_t status = SWITCH_STATUS_FAILURE; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + if ((sflow_info->api_info.collector_type == SFLOW_COLLECTOR_TYPE_CPU) && + (sflow_info->api_info.sample_mode == SWITCH_SFLOW_SAMPLE_PKT)) { + p4_pd_dc_sflow_ing_pkt_to_cpu_action_spec_t action_spec; + p4_pd_dc_sflow_ing_take_sample_match_spec_t match_spec; + match_spec.ingress_metadata_sflow_take_sample = 0x80000000; // Bit 31 set + match_spec.ingress_metadata_sflow_take_sample_mask = + 0x80000000; // Bit 31 set + match_spec.sflow_metadata_sflow_session_id = sflow_info->session_id; + + action_spec.action_sflow_i2e_mirror_id = + handle_to_id(sflow_info->mirror_hdl); + + // For sflow to cpu, program ing_take_sample table in ingress pipeline to + // perform mirroring and set correct reason code + status = p4_pd_dc_sflow_ing_take_sample_table_add_with_sflow_ing_pkt_to_cpu( + g_sess_hdl, + p4_pd_device, + &match_spec, + 0, + &action_spec, + &sflow_info->ing_take_sample_table_ent_hdl); -switch_status_t -switch_pd_sflow_match_table_delete (switch_device_t device, - switch_sflow_match_entry_t *match_entry) -{ - switch_status_t status = SWITCH_STATUS_FAILURE; - if (match_entry->ingress_sflow_ent_hdl != SWITCH_API_INVALID_HANDLE) { - status = switch_pd_sflow_ingress_table_delete(device, match_entry); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } - // XXX - delete egress entries if present - return status; + // For sflow to cpu, program mirror table in egress pipeline to + // send pkt to CPU + status = switch_pd_mirror_table_sflow_add(device, sflow_info); + } else { + // XXX - Not supported yet + assert(0); + } + return status; +} + +switch_status_t switch_pd_sflow_session_delete( + switch_device_t device, switch_sflow_info_t *sflow_info) { + bool op_started = false; + if (sflow_info->mirror_table_ent_hdl != SWITCH_API_INVALID_HANDLE) { + p4_pd_dc_mirror_table_delete( + g_sess_hdl, device, sflow_info->mirror_table_ent_hdl); + sflow_info->mirror_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + op_started = true; + } + if (sflow_info->ing_take_sample_table_ent_hdl != SWITCH_API_INVALID_HANDLE) { + p4_pd_dc_sflow_ing_take_sample_table_delete( + g_sess_hdl, device, sflow_info->ing_take_sample_table_ent_hdl); + sflow_info->ing_take_sample_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + op_started = true; + } + if (op_started) { + p4_pd_complete_operations(g_sess_hdl); + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_pd_sflow_counter_read( + switch_device_t device, + switch_sflow_match_entry_t *match_entry, + switch_counter_t *sw_counter) { + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + p4_pd_counter_value_t counter; + counter = p4_pd_dc_counter_read_sflow_ingress_session_pkt_counter( + g_sess_hdl, + p4_pd_device, + match_entry->ingress_sflow_ent_hdl, + COUNTER_READ_HW_SYNC); + sw_counter->num_packets = counter.packets; + sw_counter->num_bytes = counter.bytes; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_pd_sflow_counter_write( + switch_device_t device, + switch_sflow_match_entry_t *match_entry, + switch_counter_t val) { + p4_pd_dev_target_t p4_pd_device; + p4_pd_counter_value_t counter; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + counter.packets = val.num_packets; + counter.bytes = val.num_bytes; + return p4_pd_dc_counter_write_sflow_ingress_session_pkt_counter( + g_sess_hdl, p4_pd_device, match_entry->ingress_sflow_ent_hdl, counter); } -switch_status_t -switch_pd_mirror_table_sflow_add (switch_device_t device, - switch_sflow_info_t *sflow_info) -{ - switch_status_t status = SWITCH_STATUS_FAILURE; - p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_mirror_match_spec_t match_spec; - - if ((sflow_info->api_info.collector_type != SFLOW_COLLECTOR_TYPE_CPU) || - (sflow_info->api_info.sample_mode != SWITCH_SFLOW_SAMPLE_PKT)) { - // if collector == REMOTE : set action as sflow_pkt_to_remote - TBD - return status; - } - // if collector == CPU : set action as sflow_pkt_to_cpu - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +#endif - memset(&match_spec, 0, sizeof(match_spec)); - match_spec.i2e_metadata_mirror_session_id = handle_to_id(sflow_info->mirror_hdl); - status = p4_pd_dc_mirror_table_add_with_sflow_pkt_to_cpu( - g_sess_hdl, p4_pd_device, &match_spec, - &sflow_info->mirror_table_ent_hdl); +void switch_pd_stats_update_cb(int device, void *cookie) { return; } - p4_pd_complete_operations(g_sess_hdl); +p4_pd_status_t switch_pd_stats_update(switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_STATS_DISABLE + p4_pd_dev_target_t p4_pd_device; - return status; -} + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; -switch_status_t -switch_pd_sflow_session_create (switch_device_t device, - switch_sflow_info_t *sflow_info) -{ - switch_status_t status = SWITCH_STATUS_FAILURE; - p4_pd_dev_target_t p4_pd_device; +#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 /* P4_STORM_CONTROL_DISABLE */ - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; +#ifndef P4_ACL_DISABLE + status = p4_pd_dc_counter_hw_sync_acl_stats( + g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); +#endif /* P4_ACL_DISABLE */ - if ((sflow_info->api_info.collector_type == SFLOW_COLLECTOR_TYPE_CPU) && - (sflow_info->api_info.sample_mode == SWITCH_SFLOW_SAMPLE_PKT)) { + status = p4_pd_dc_counter_hw_sync_egress_bd_stats( + g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); - p4_pd_dc_sflow_ing_pkt_to_cpu_action_spec_t action_spec; - p4_pd_dc_sflow_ing_take_sample_match_spec_t match_spec; - match_spec.ingress_metadata_sflow_take_sample = 0x80000000; // Bit 31 set - match_spec.ingress_metadata_sflow_take_sample_mask = 0x80000000; // Bit 31 set - match_spec.sflow_metadata_sflow_session_id = sflow_info->session_id; + status = p4_pd_dc_counter_hw_sync_ingress_bd_stats( + g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); - action_spec.action_sflow_i2e_mirror_id = handle_to_id( - sflow_info->mirror_hdl); - action_spec.action_reason_code = SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE; +#ifndef P4_METER_DISABLE + status = p4_pd_dc_counter_hw_sync_meter_stats( + g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); +#endif /* P4_METER_DISABLE */ - // For sflow to cpu, program ing_take_sample table in ingress pipeline to - // perform mirroring and set correct reason code - status = p4_pd_dc_sflow_ing_take_sample_table_add_with_sflow_ing_pkt_to_cpu( - g_sess_hdl, p4_pd_device, &match_spec, 0, &action_spec, - &sflow_info->ing_take_sample_table_ent_hdl); + status = p4_pd_dc_counter_hw_sync_drop_stats( + g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - // For sflow to cpu, program mirror table in egress pipeline to - // send pkt to CPU - status = switch_pd_mirror_table_sflow_add (device, sflow_info); - } else { - // XXX - Not supported yet - assert(0); - } - return status; + status = p4_pd_dc_counter_hw_sync_drop_stats_2( + g_sess_hdl, p4_pd_device, &switch_pd_stats_update_cb, NULL); +#endif /* P4_STATS_DISABLE */ + return status; } -switch_status_t -switch_pd_sflow_session_delete (switch_device_t device, - switch_sflow_info_t *sflow_info) -{ - bool op_started = false; - if (sflow_info->mirror_table_ent_hdl != SWITCH_API_INVALID_HANDLE) { - p4_pd_dc_mirror_table_delete(g_sess_hdl, device, - sflow_info->mirror_table_ent_hdl); - sflow_info->mirror_table_ent_hdl = SWITCH_API_INVALID_HANDLE; - op_started = true; - } - if (sflow_info->ing_take_sample_table_ent_hdl != SWITCH_API_INVALID_HANDLE) { - - p4_pd_dc_sflow_ing_take_sample_table_delete( g_sess_hdl, device, - sflow_info->ing_take_sample_table_ent_hdl); - sflow_info->ing_take_sample_table_ent_hdl = SWITCH_API_INVALID_HANDLE; - op_started = true; - } - if (op_started) { - p4_pd_complete_operations(g_sess_hdl); - } - return SWITCH_STATUS_SUCCESS; -} -#endif +p4_pd_status_t switch_pd_hostif_meter_set(switch_device_t device, + uint16_t meter_id, + switch_meter_info_t *meter_info, + bool enable) { + p4_pd_status_t status = 0; -void -switch_pd_stats_update_cb(int device, void *cookie) -{ - return; -} +#ifndef P4_METER_DISABLE -p4_pd_status_t -switch_pd_stats_update(switch_device_t device) -{ - p4_pd_status_t status = 0; -#ifndef P4_STATS_DISABLE - p4_pd_dev_target_t p4_pd_device; + p4_pd_dev_target_t p4_pd_device; + switch_api_meter_t *api_meter_info = NULL; - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; -#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, - &switch_pd_stats_update_cb, - NULL); - - status = p4_pd_dc_counter_hw_sync_egress_bd_stats( - g_sess_hdl, - p4_pd_device, - &switch_pd_stats_update_cb, - NULL); - - status = p4_pd_dc_counter_hw_sync_ingress_bd_stats( - g_sess_hdl, - p4_pd_device, - &switch_pd_stats_update_cb, - NULL); + if (enable) { + if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { + p4_pd_bytes_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + meter_spec.cir_kbps = api_meter_info->cir; + meter_spec.cburst_kbits = api_meter_info->cbs; + meter_spec.pir_kbps = api_meter_info->pir; + meter_spec.pburst_kbits = api_meter_info->pbs; + meter_spec.meter_type = + api_meter_info->color_source == SWITCH_METER_COLOR_SOURCE_BLIND + ? PD_METER_TYPE_COLOR_UNAWARE + : PD_METER_TYPE_COLOR_AWARE; + status = p4_pd_dc_meter_set_copp( + g_sess_hdl, p4_pd_device, meter_id, &meter_spec); + } + } else { + if (api_meter_info->meter_type == SWITCH_METER_TYPE_BYTES) { + p4_pd_bytes_meter_spec_t meter_spec; + memset(&meter_spec, 0, sizeof(p4_pd_bytes_meter_spec_t)); + status = p4_pd_dc_meter_set_copp( + g_sess_hdl, p4_pd_device, meter_id, &meter_spec); + } + } -#ifndef P4_METER_DISABLE - status = p4_pd_dc_counter_hw_sync_meter_stats( - g_sess_hdl, - p4_pd_device, - &switch_pd_stats_update_cb, - NULL); #endif /* P4_METER_DISABLE */ - status = p4_pd_dc_counter_hw_sync_drop_stats( - g_sess_hdl, - p4_pd_device, - &switch_pd_stats_update_cb, - NULL); - - status = p4_pd_dc_counter_hw_sync_drop_stats_2( - g_sess_hdl, - p4_pd_device, - &switch_pd_stats_update_cb, - NULL); -#endif /* P4_STATS_DISABLE */ - return status; + return status; } diff --git a/switchapi/src/switch_pd.h b/switchapi/src/switch_pd.h index 241211d..482b671 100644 --- a/switchapi/src/switch_pd.h +++ b/switchapi/src/switch_pd.h @@ -26,6 +26,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -33,1039 +34,1145 @@ extern "C" { #include #include #include +#include +#include +#include #include "switch_interface_int.h" #include "switch_hostif_int.h" #include "switch_vlan_int.h" #include "switch_l2_int.h" #include "switch_l3_int.h" #include "switch_mcast_int.h" +#include "switch_nat_int.h" #include "switch_port_int.h" #include "switch_rmac_int.h" #include "switch_defines.h" #include "switch_mirror_int.h" #include "switch_meter_int.h" #include "switch_sflow_int.h" +#include "switch_buffer_int.h" +#include "switch_qos_int.h" #define SWITCH_MAX_DEVICE 32 -p4_pd_status_t -switch_pd_client_init(switch_device_t device); +p4_pd_status_t switch_pd_client_init(switch_device_t device); /* Dmac table PD API's */ -p4_pd_status_t -switch_pd_dmac_table_add_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - uint16_t nhop_index, - uint16_t mgid_index, - uint32_t aging_time, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_dmac_table_update_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - uint16_t nhop_index, - uint16_t mgid_index, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_dmac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_dmac_table_add_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + uint16_t nhop_index, + uint16_t mgid_index, + uint32_t aging_time, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_dmac_table_update_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + uint16_t nhop_index, + uint16_t mgid_index, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_dmac_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl); /* Smac table PD API's */ -p4_pd_status_t -switch_pd_smac_table_add_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_smac_table_update_entry(switch_device_t device, - switch_api_mac_entry_t *mac_entry, - switch_interface_info_t *intf_info, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_smac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_mac_table_set_learning_timeout(switch_device_t device, uint32_t timeout); - -p4_pd_status_t -switch_pd_nexthop_table_add_entry(switch_device_t device, - uint16_t nhop, - uint16_t bd, - switch_ifindex_t ifindex, - bool flood, - uint32_t mc_index, - bool tunnel, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_nexthop_table_update_entry(switch_device_t device, - uint16_t nhop_index, - uint16_t bd, - switch_ifindex_t ifindex, - bool flood, - uint32_t mc_index, - bool tunnel, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_nexthop_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_ecmp_group_create(switch_device_t device, - p4_pd_grp_hdl_t *p4_pd_group_hdl); - -p4_pd_status_t -switch_pd_ecmp_group_delete(switch_device_t device, - p4_pd_grp_hdl_t p4_pd_group_hdl); -p4_pd_status_t -switch_pd_ecmp_member_add(switch_device_t device, - p4_pd_grp_hdl_t p4_pd_group_hdl, - uint16_t nhop_index, - switch_interface_info_t *intf_info, - p4_pd_mbr_hdl_t *mbr_hdl); - -p4_pd_status_t -switch_pd_ecmp_member_delete(switch_device_t device, - p4_pd_grp_hdl_t p4_pd_group_hdl, - p4_pd_mbr_hdl_t mbr_hdl); - -p4_pd_status_t -switch_pd_ecmp_group_table_add_entry_with_selector( - switch_device_t device, uint16_t ecmp_index, +p4_pd_status_t switch_pd_smac_table_add_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_smac_table_update_entry( + switch_device_t device, + switch_api_mac_entry_t *mac_entry, + switch_interface_info_t *intf_info, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_smac_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_mac_table_set_learning_timeout(switch_device_t device, + uint32_t timeout); + +p4_pd_status_t switch_pd_nexthop_table_add_entry(switch_device_t device, + uint16_t nhop, + uint16_t bd, + switch_ifindex_t ifindex, + bool flood, + uint32_t mc_index, + bool tunnel, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_nexthop_table_update_entry( + switch_device_t device, + uint16_t nhop_index, + uint16_t bd, + switch_ifindex_t ifindex, + bool flood, + uint32_t mc_index, + bool tunnel, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_nexthop_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_ecmp_group_create(switch_device_t device, + p4_pd_grp_hdl_t *p4_pd_group_hdl); + +p4_pd_status_t switch_pd_ecmp_group_delete(switch_device_t device, + p4_pd_grp_hdl_t p4_pd_group_hdl); +p4_pd_status_t switch_pd_ecmp_member_add(switch_device_t device, + p4_pd_grp_hdl_t p4_pd_group_hdl, + uint16_t nhop_index, + switch_interface_info_t *intf_info, + p4_pd_mbr_hdl_t *mbr_hdl); + +p4_pd_status_t switch_pd_ecmp_member_delete(switch_device_t device, + p4_pd_grp_hdl_t p4_pd_group_hdl, + p4_pd_mbr_hdl_t mbr_hdl); + +p4_pd_status_t switch_pd_ecmp_group_table_add_entry_with_selector( + switch_device_t device, + uint16_t ecmp_index, p4_pd_grp_hdl_t p4_pd_group_hdl, p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_ecmp_group_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_ip_fib_add_entry(switch_device_t device, - switch_handle_t vrf, - switch_ip_addr_t *ipaddr, - bool ecmp, - switch_handle_t nexthop, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_ip_fib_update_entry(switch_device_t device, - switch_handle_t vrf, - switch_ip_addr_t *ipaddr, - bool ecmp, - switch_handle_t nexthop, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_ip_fib_delete_entry(switch_device_t device, - switch_ip_addr_t *ip_addr, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_inner_rmac_table_add_entry(switch_device_t device, - switch_handle_t rmac_group, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_inner_rmac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_outer_rmac_table_add_entry(switch_device_t device, - switch_handle_t rmac_group, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_outer_rmac_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_src_vtep_table_add_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - switch_ifindex_t ifindex, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_src_vtep_table_delete_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_dest_vtep_table_add_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_dest_vtep_table_delete_entry(switch_device_t device, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_tunnel_rewrite_table_add_entry(switch_device_t device, - uint16_t tunnel_index, - uint16_t sip_index, uint16_t dip_index, - uint16_t smac_index, - uint16_t dmac_index, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_rewrite_table_fabric_add_entry(switch_device_t device, - switch_tunnel_type_egress_t tunnel_type, - uint16_t tunnel_index, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_rewrite_cpu_add_entry(switch_device_t device, - uint16_t tunnel_index, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_rewrite_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_table_add_entry(switch_device_t device, - switch_encap_type_t encap_type, - uint16_t tunnel_vni, - switch_rid_t rid, - switch_bd_info_t *bd_info, - switch_ip_encap_t *ip_encap, - switch_handle_t bd_handle, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_egress_vni_table_add_entry(switch_device_t device, - switch_handle_t egress_bd, - uint16_t tunnel_vni, - uint8_t tunnel_type, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_egress_vni_table_delete_entry(switch_device_t device_id, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_src_rewrite_table_add_entry(switch_device_t device, - uint16_t tunnel_src_index, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_ecmp_group_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_ip_fib_add_entry(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ipaddr, + bool ecmp, + switch_handle_t nexthop, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_ip_fib_update_entry(switch_device_t device, + switch_handle_t vrf, + switch_ip_addr_t *ipaddr, + bool ecmp, + switch_handle_t nexthop, + p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_ip_fib_delete_entry(switch_device_t device, + switch_ip_addr_t *ip_addr, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_inner_rmac_table_add_entry( + switch_device_t device, + switch_handle_t rmac_group, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_inner_rmac_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_tunnel_src_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_outer_rmac_table_add_entry( + switch_device_t device, + switch_handle_t rmac_group, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_outer_rmac_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_src_vtep_table_add_entry(switch_device_t device, + switch_ip_encap_t *ip_encap, + switch_ifindex_t ifindex, + p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_tunnel_dst_rewrite_table_add_entry(switch_device_t device, - uint16_t tunnel_dst_index, - switch_ip_encap_t *ip_encap, - p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_src_vtep_table_delete_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_tunnel_dst_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_tunnel_smac_rewrite_table_add_entry(switch_device_t device, - uint16_t smac_index, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_smac_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_tunnel_dmac_rewrite_table_add_entry(switch_device_t device, - uint16_t dmac_index, - switch_mac_addr_t *mac, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_tunnel_dmac_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -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_status_t -switch_pd_bd_table_update_entry(switch_device_t device, - uint16_t bd, switch_bd_info_t *bd_info); - -p4_pd_status_t -switch_pd_bd_table_delete_entry(switch_device_t device, - switch_bd_info_t *bd_info); - -p4_pd_status_t -switch_pd_egress_bd_map_table_add_entry(switch_device_t device, - switch_handle_t bd_handle, - switch_bd_info_t *bd_info); - -p4_pd_status_t -switch_pd_egress_bd_map_table_update_entry(switch_device_t device, - switch_handle_t bd_handle, - switch_bd_info_t *bd_info); - -p4_pd_status_t -switch_pd_egress_bd_map_table_delete_entry(switch_device_t device, - switch_bd_info_t *bd_info); - -p4_pd_status_t -switch_pd_port_vlan_mapping_table_add_entry(switch_device_t device, - switch_vlan_t vlan_id0, - switch_vlan_t vlan_id1, - switch_interface_info_t *info, - p4_pd_mbr_hdl_t bd_hdl, - p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_dest_vtep_table_add_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -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_dest_vtep_table_delete_entry( + switch_device_t device, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_tunnel_rewrite_table_add_entry( + switch_device_t device, + uint16_t tunnel_index, + uint16_t sip_index, + uint16_t dip_index, + uint16_t smac_index, + uint16_t dmac_index, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_rewrite_table_fabric_add_entry( + switch_device_t device, + switch_tunnel_type_egress_t tunnel_type, + uint16_t tunnel_index, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_tunnel_rewrite_cpu_add_entry( + switch_device_t device, + uint16_t tunnel_index, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_tunnel_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_tunnel_table_add_entry(switch_device_t device, + switch_encap_type_t encap_type, + uint16_t tunnel_vni, + switch_rid_t rid, + switch_bd_info_t *bd_info, + switch_ip_encap_t *ip_encap, + switch_handle_t bd_handle, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_tunnel_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_egress_vni_table_add_entry( + switch_device_t device, + switch_handle_t egress_bd, + uint16_t tunnel_vni, + uint8_t tunnel_type, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_egress_vni_table_delete_entry( + switch_device_t device_id, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_tunnel_src_rewrite_table_add_entry( + switch_device_t device, + uint16_t tunnel_src_index, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_tunnel_src_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_tunnel_dst_rewrite_table_add_entry( + switch_device_t device, + uint16_t tunnel_dst_index, + switch_ip_encap_t *ip_encap, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_tunnel_dst_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_tunnel_smac_rewrite_table_add_entry( + switch_device_t device, + uint16_t smac_index, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_tunnel_smac_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_tunnel_dmac_rewrite_table_add_entry( + switch_device_t device, + uint16_t dmac_index, + switch_mac_addr_t *mac, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_tunnel_dmac_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +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_status_t switch_pd_bd_table_update_entry(switch_device_t device, + uint16_t bd, + switch_bd_info_t *bd_info); + +p4_pd_status_t switch_pd_bd_table_delete_entry(switch_device_t device, + switch_bd_info_t *bd_info); + +p4_pd_status_t switch_pd_egress_bd_map_table_add_entry( + switch_device_t device, + switch_handle_t bd_handle, + switch_bd_info_t *bd_info); + +p4_pd_status_t switch_pd_egress_bd_map_table_update_entry( + switch_device_t device, + switch_handle_t bd_handle, + switch_bd_info_t *bd_info); + +p4_pd_status_t switch_pd_egress_bd_map_table_delete_entry( + switch_device_t device, switch_bd_info_t *bd_info); + +p4_pd_status_t switch_pd_port_vlan_mapping_table_add_entry( + switch_device_t device, + switch_vlan_t vlan_id0, + switch_vlan_t vlan_id1, + switch_interface_info_t *info, + p4_pd_mbr_hdl_t bd_hdl, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t 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); + +p4_pd_status_t switch_pd_egress_vlan_xlate_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_ingress_port_mapping_table_add_entry( + switch_device_t device, + switch_ifindex_t ifindex, + switch_port_info_t *port_info); + +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, + switch_qos_group_t qos_group, + 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 -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); - -p4_pd_status_t -switch_pd_ingress_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_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 -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); /* * Rewrite table */ -p4_pd_status_t -switch_pd_rewrite_table_unicast_rewrite_add_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_rw_type_t rw_type, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_rewrite_table_unicast_rewrite_update_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_rw_type_t rw_type, - p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_rewrite_table_tunnel_rewrite_add_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_type_t neigh_type, - switch_neighbor_rw_type_t rw_type, - uint16_t tunnel_index, - switch_encap_type_t encap_type, +p4_pd_status_t switch_pd_rewrite_table_unicast_rewrite_add_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_rw_type_t rw_type, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_rewrite_table_unicast_rewrite_update_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_rw_type_t rw_type, + p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_rewrite_table_tunnel_rewrite_add_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_type_t neigh_type, + switch_neighbor_rw_type_t rw_type, + uint16_t tunnel_index, + switch_encap_type_t encap_type, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_rewrite_table_tunnel_rewrite_update_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + switch_mac_addr_t dmac, + switch_neighbor_type_t neigh_type, + switch_neighbor_rw_type_t rw_type, + uint16_t tunnel_index, + switch_encap_type_t encap_type, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_lag_group_create(switch_device_t device, + p4_pd_grp_hdl_t *p4_pd_group_hdl); +p4_pd_status_t switch_pd_lag_group_delete(switch_device_t device, + p4_pd_grp_hdl_t p4_pd_group_hdl); +p4_pd_status_t switch_pd_lag_member_add(switch_device_t device, + p4_pd_grp_hdl_t p4_pd_group_hdl, + unsigned int port, + p4_pd_mbr_hdl_t *mbr_hdl); +p4_pd_status_t switch_pd_lag_member_delete(switch_device_t device, + p4_pd_grp_hdl_t p4_pd_group_hdl, + p4_pd_mbr_hdl_t mbr_hdl); +p4_pd_status_t switch_pd_lag_group_table_add_entry( + switch_device_t device, + switch_ifindex_t ifindex, + unsigned int port, + p4_pd_mbr_hdl_t *mbr_hdl, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_lag_group_table_add_entry_with_selector( + switch_device_t device, + switch_ifindex_t ifindex, + p4_pd_grp_hdl_t p4_pd_group_hdl, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_lag_group_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_smac_rewrite_table_add_entry( + switch_device_t device, switch_smac_entry_t *smac_entry); + +p4_pd_status_t switch_pd_smac_rewrite_table_delete_entry( + switch_device_t device, switch_smac_entry_t *smac_entry); + +p4_pd_status_t switch_pd_nat_init(switch_device_t device); + +p4_pd_status_t switch_pd_nat_table_add_entry(switch_device_t device, + switch_interface_info_t *intf_info, + switch_nat_info_t *nat_info, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_nat_table_delete_entry(switch_device_t device, + switch_nat_info_t *nat_info, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_nat_rewrite_table_add_entry( + switch_device_t device, + switch_nat_info_t *nat_info, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_nat_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_cpu_rewrite_add_entry(switch_device_t device, + switch_port_t port_id); +p4_pd_status_t switch_pd_rid_table_add_entry(switch_device_t device, + uint16_t rid, + uint32_t bd, + bool inner_replica, + uint8_t tunnel_type, + uint16_t tunnel_index, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_rid_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_mcast_table_add_entry( + switch_device_t device, + uint16_t mgid_index, + switch_mcast_mode_t mc_mode, + switch_mcast_group_info_t *group_info, + bool core_entry, + bool vrf_entry, + uint16_t rpf_group); + +p4_pd_status_t switch_pd_mcast_table_delete_entry( + switch_device_t device, + switch_mcast_group_info_t *group_info, + bool core_entry, + bool vrf_entry); + +p4_pd_status_t switch_pd_spanning_tree_table_add_entry( + switch_device_t device, + uint16_t stp_group, + switch_ifindex_t ifindex, + switch_stp_state_t stp_state, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_spanning_tree_table_update_entry( + switch_device_t device, + uint16_t stp_group, + switch_ifindex_t ifindex, + switch_stp_state_t stp_state, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_spanning_tree_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_urpf_bd_table_add_entry(switch_device_t device, + uint16_t urpf_group, + uint16_t bd_index, p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_urpf_bd_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); -p4_pd_status_t -switch_pd_rewrite_table_tunnel_rewrite_update_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - switch_mac_addr_t dmac, - switch_neighbor_type_t neigh_type, - switch_neighbor_rw_type_t rw_type, - uint16_t tunnel_index, - switch_encap_type_t encap_type, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_rewrite_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t switch_pd_lag_group_create(switch_device_t device, p4_pd_grp_hdl_t *p4_pd_group_hdl); -p4_pd_status_t switch_pd_lag_group_delete(switch_device_t device, p4_pd_grp_hdl_t p4_pd_group_hdl); -p4_pd_status_t switch_pd_lag_member_add(switch_device_t device, p4_pd_grp_hdl_t p4_pd_group_hdl, - unsigned int port, p4_pd_mbr_hdl_t *mbr_hdl); -p4_pd_status_t switch_pd_lag_member_delete(switch_device_t device, p4_pd_grp_hdl_t p4_pd_group_hdl, - p4_pd_mbr_hdl_t mbr_hdl); -p4_pd_status_t -switch_pd_lag_group_table_add_entry(switch_device_t device, - switch_ifindex_t ifindex, - unsigned int port, - p4_pd_mbr_hdl_t *mbr_hdl, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_lag_group_table_add_entry_with_selector(switch_device_t device, - switch_ifindex_t ifindex, - p4_pd_grp_hdl_t p4_pd_group_hdl, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_lag_group_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_smac_rewrite_table_add_entry(switch_device_t device, - switch_smac_entry_t *smac_entry); - -p4_pd_status_t -switch_pd_smac_rewrite_table_delete_entry(switch_device_t device, - switch_smac_entry_t *smac_entry); - -p4_pd_status_t -switch_pd_cpu_rewrite_add_entry(switch_device_t device, - switch_port_t port_id); -p4_pd_status_t -switch_pd_rid_table_add_entry(switch_device_t device, - uint16_t rid, - uint32_t bd, - bool inner_replica, - uint8_t tunnel_type, uint16_t tunnel_index, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_rid_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_mcast_table_add_entry(switch_device_t device, - uint16_t mgid_index, - switch_mcast_mode_t mc_mode, - switch_mcast_group_info_t *group_info, - bool core_entry, bool vrf_entry, - uint16_t rpf_group); - -p4_pd_status_t -switch_pd_mcast_table_delete_entry(switch_device_t device, - switch_mcast_group_info_t *group_info, - bool core_entry, bool vrf_entry); - -p4_pd_status_t -switch_pd_spanning_tree_table_add_entry(switch_device_t device, - uint16_t stp_group, - switch_ifindex_t ifindex, - switch_stp_state_t stp_state, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_spanning_tree_table_update_entry(switch_device_t device, - uint16_t stp_group, - switch_ifindex_t ifindex, - switch_stp_state_t stp_state, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_spanning_tree_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_urpf_bd_table_add_entry(switch_device_t device, - uint16_t urpf_group, - uint16_t bd_index, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_urpf_bd_table_delete_entry(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_urpf_add_entry(switch_device_t device, - switch_vrf_id_t vrf_id, - switch_ip_addr_t *ip_addr, - uint16_t urpf_group, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_urpf_update_entry(switch_device_t device, - switch_vrf_id_t vrf_id, - switch_ip_addr_t *ip_addr, - uint16_t urpf_group, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_urpf_delete_entry(switch_device_t device, - switch_vrf_id_t vrf_id, - switch_ip_addr_t *ip_addr, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_mcast_mgrp_tree_create(switch_device_t device, uint16_t mgid_index, - switch_mcast_info_t *mcast_info); -p4_pd_status_t -switch_pd_mcast_mgrp_tree_delete(switch_device_t device, - switch_mcast_info_t *mcast_info); - -p4_pd_status_t -switch_pd_mcast_add_entry(switch_device_t device, switch_mcast_node_t *node); - -p4_pd_status_t -switch_pd_mcast_update_entry(switch_device_t device, switch_mcast_node_t *node); - -p4_pd_status_t -switch_pd_mcast_delete_entry(switch_device_t device, switch_mcast_node_t *node); - -p4_pd_status_t -switch_pd_mcast_mgid_table_add_entry(switch_device_t device, - mc_mgrp_hdl_t mgid, - switch_mcast_node_t *node); - -p4_pd_status_t -switch_pd_mcast_mgid_table_delete_entry(switch_device_t device, - mc_mgrp_hdl_t mgid_hdl, - switch_mcast_node_t *node); - -p4_pd_status_t -switch_pd_mcast_lag_port_map_update(switch_device_t device, uint16_t lag_index, - switch_mc_port_map_t port_map); - -p4_pd_status_t -switch_pd_mpls_table_add_entry(switch_device_t device, switch_mpls_encap_t *mpls_encap, - uint32_t bd_index, uint32_t label, - switch_bd_info_t *bd_info, - uint16_t egress_ifindex, p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_mpls_table_delete_entry(switch_device_t device, p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_tunnel_rewrite_table_mpls_add_entry(switch_device_t device, uint32_t tunnel_index, - uint16_t smac_index, uint16_t dmac_index, - switch_mpls_encap_t *mpls_encap, - p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_rewrite_table_mpls_rewrite_add_entry(switch_device_t device, - uint16_t bd, - uint16_t nhop_index, - uint16_t tunnel_index, - switch_neighbor_type_t neigh_type, - switch_mac_addr_t dmac, - uint32_t label, - uint8_t header_count, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_ipv4_acl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_ip_key_value_pair_t *ip_acl, - switch_acl_ip_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_ipv4_acl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_ipv6_acl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_ipv6_key_value_pair_t *ipv6_acl, - switch_acl_ipv6_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_ipv6_acl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_ipv4_racl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_ip_racl_key_value_pair_t *ip_racl, - switch_acl_ip_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_ipv4_racl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_ipv6_racl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_ipv6_racl_key_value_pair_t *ip_racl, - switch_acl_ipv6_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_ipv6_racl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_mac_acl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_mac_key_value_pair_t *mac_acl, - switch_acl_mac_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_mac_acl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_qos_acl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_qos_key_value_pair_t *qos_acl, - switch_acl_mac_action_t action, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_qos_acl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_system_acl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_system_key_value_pair_t *system_acl, - switch_acl_system_action_t action_type, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_system_acl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_egr_acl_table_add_entry( - switch_device_t device, - uint16_t if_label, - uint16_t bd_label, - uint16_t priority, - unsigned int count, - switch_acl_egr_key_value_pair_t *egr_acl, - switch_acl_egr_action_t action, - switch_acl_action_params_t *action_params, - switch_acl_opt_action_params_t *opt_action_params, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_egr_acl_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_bd_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats); - -p4_pd_status_t -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, - uint64_t *counters); - -p4_pd_status_t -switch_pd_ingress_fabric_table_add_entry(switch_device_t device); -//TODO: Add delete entry for outer_mac table +p4_pd_status_t switch_pd_urpf_add_entry(switch_device_t device, + switch_vrf_id_t vrf_id, + switch_ip_addr_t *ip_addr, + uint16_t urpf_group, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_urpf_update_entry(switch_device_t device, + switch_vrf_id_t vrf_id, + switch_ip_addr_t *ip_addr, + uint16_t urpf_group, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_urpf_delete_entry(switch_device_t device, + switch_vrf_id_t vrf_id, + switch_ip_addr_t *ip_addr, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_mcast_mgrp_tree_create( + switch_device_t device, + uint16_t mgid_index, + switch_mcast_info_t *mcast_info); +p4_pd_status_t switch_pd_mcast_mgrp_tree_delete( + switch_device_t device, switch_mcast_info_t *mcast_info); + +p4_pd_status_t switch_pd_mcast_add_entry(switch_device_t device, + switch_mcast_node_t *node); + +p4_pd_status_t switch_pd_mcast_update_entry(switch_device_t device, + switch_mcast_node_t *node); + +p4_pd_status_t switch_pd_mcast_delete_entry(switch_device_t device, + switch_mcast_node_t *node); + +p4_pd_status_t switch_pd_mcast_mgid_table_add_entry(switch_device_t device, + mc_mgrp_hdl_t mgid, + switch_mcast_node_t *node); + +p4_pd_status_t switch_pd_mcast_mgid_table_delete_entry( + switch_device_t device, mc_mgrp_hdl_t mgid_hdl, switch_mcast_node_t *node); + +p4_pd_status_t switch_pd_mcast_lag_port_map_update( + switch_device_t device, uint16_t lag_index, switch_mc_port_map_t port_map); + +p4_pd_status_t switch_pd_mpls_table_add_entry(switch_device_t device, + switch_mpls_encap_t *mpls_encap, + uint32_t bd_index, + uint32_t label, + switch_bd_info_t *bd_info, + uint16_t egress_ifindex, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_mpls_table_delete_entry(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_tunnel_rewrite_table_mpls_add_entry( + switch_device_t device, + uint32_t tunnel_index, + uint16_t smac_index, + uint16_t dmac_index, + switch_mpls_encap_t *mpls_encap, + p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_rewrite_table_mpls_rewrite_add_entry( + switch_device_t device, + uint16_t bd, + uint16_t nhop_index, + uint16_t tunnel_index, + switch_neighbor_type_t neigh_type, + switch_mac_addr_t dmac, + uint32_t label, + uint8_t header_count, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_ipv4_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ip_key_value_pair_t *ip_acl, + switch_acl_ip_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_ipv4_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ipv6_key_value_pair_t *ipv6_acl, + switch_acl_ipv6_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_ipv6_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_ipv4_racl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ip_racl_key_value_pair_t *ip_racl, + switch_acl_ip_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_ipv4_racl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_ipv6_racl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ipv6_racl_key_value_pair_t *ip_racl, + switch_acl_ipv6_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_ipv6_racl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_mac_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_mac_key_value_pair_t *mac_acl, + switch_acl_mac_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_mac_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_system_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_system_key_value_pair_t *system_acl, + switch_acl_system_action_t action_type, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_system_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_egr_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_egr_key_value_pair_t *egr_acl, + switch_acl_egr_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_egr_acl_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_bd_ingress_stats_get(switch_device_t device, + switch_bd_stats_t *bd_stats); + +p4_pd_status_t 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, + uint64_t *counters); + +p4_pd_status_t switch_pd_ingress_fabric_table_add_entry(switch_device_t device); +// TODO: Add delete entry for outer_mac table // Default Entries -p4_pd_status_t -switch_pd_ip_mcast_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_ip_mcast_add_default_entry(switch_device_t device); + +p4_pd_status_t switch_pd_validate_outer_ethernet_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_validate_outer_ethernet_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_validate_outer_ip_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_validate_outer_ip_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_storm_control_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_storm_control_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_outer_rmac_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_outer_rmac_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_src_vtep_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_src_vtep_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_dest_vtep_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_dest_vtep_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_validate_packet_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_validate_packet_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_port_vlan_mapping_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_port_vlan_mapping_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_acl_table_add_default_entry(switch_device_t device); -p4_pd_status_t -switch_pd_acl_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_inner_rmac_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_inner_rmac_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_fwd_result_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_fwd_result_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_nexthop_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_nexthop_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_lag_table_add_default_entry(switch_device_t device); -switch_status_t -switch_pd_lag_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_rid_table_add_default_entry(switch_device_t device); -switch_status_t -switch_pd_rid_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_replica_type_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_replica_type_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_mac_table_add_default_entry(switch_device_t device); -switch_status_t -switch_pd_mac_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_egress_bd_map_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_egress_bd_map_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_egress_vni_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_egress_vni_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_ip_fib_add_default_entry(switch_device_t device); -switch_status_t -switch_pd_ip_fib_add_default_entry(switch_device_t device); +switch_status_t switch_pd_ip_urpf_add_default_entry(switch_device_t device); -switch_status_t -switch_pd_ip_urpf_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_smac_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_smac_rewrite_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_dmac_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_dmac_rewrite_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_rewrite_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_fwd_result_table_add_init_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_fwd_result_table_add_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_rewrite_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_rewrite_multicast_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_rewrite_multicast_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_egress_vlan_xlate_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_egress_vlan_xlate_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_cpu_rewrite_add_default_entry(switch_device_t device); -p4_pd_status_t -switch_pd_cpu_rewrite_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_egress_acl_add_default_entry(switch_device_t device); -p4_pd_status_t -switch_pd_egress_acl_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_vlan_decap_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_vlan_decap_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_src_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_src_rewrite_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_dst_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_dst_rewrite_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_adjust_lkp_fields_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_table_add_default_entry(switch_device_t device); -p4_pd_status_t -switch_pd_bd_stats_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_bd_stats_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_bd_flood_table_add_default_entry(switch_device_t device); +p4_pd_status_t switch_pd_bd_flood_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_mtu_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_mtu_table_add_default_entry(switch_device_t device); -switch_status_t -switch_pd_l3_rewrite_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_l3_rewrite_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_learn_notify_table_add_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_learn_notify_table_add_init_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_encap_tables_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_encap_tables_init_entry(switch_device_t device); -p4_pd_status_t -switch_pd_tunnel_decap_tables_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_tunnel_decap_tables_init_entry(switch_device_t device); -p4_pd_status_t -switch_pd_validate_outer_ethernet_table_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_validate_outer_ethernet_table_init_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_vlan_decap_table_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_vlan_decap_table_init_entry(switch_device_t device); -p4_pd_status_t -switch_pd_validate_mpls_packet_table_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_validate_mpls_packet_table_init_entry( + switch_device_t device); -switch_status_t -switch_pd_egress_filter_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_egress_filter_table_add_default_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_fabric_header_table_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_fabric_header_table_init_entry(switch_device_t device); -p4_pd_status_t -switch_pd_egress_port_mapping_table_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_egress_port_mapping_table_init_entry( + switch_device_t device); -p4_pd_status_t -switch_pd_compute_hashes_init_entry(switch_device_t device); +p4_pd_status_t switch_pd_compute_hashes_init_entry(switch_device_t device); -switch_status_t -switch_pd_switch_config_params_update(switch_device_t device); +switch_status_t switch_pd_switch_config_params_update(switch_device_t device); -switch_status_t -switch_pd_switch_config_params_table_init(switch_device_t device); +switch_status_t switch_pd_switch_config_params_table_init( + switch_device_t device); -switch_status_t -switch_pd_replica_type_table_init_entry(switch_device_t device); +switch_status_t switch_pd_replica_type_table_init_entry(switch_device_t device); -switch_status_t -switch_pd_rewrite_multicast_table_init_entry(switch_device_t device); +switch_status_t switch_pd_rewrite_multicast_table_init_entry( + switch_device_t device); -switch_status_t -switch_pd_l3_rewrite_table_init_entry(switch_device_t device); +switch_status_t switch_pd_l3_rewrite_table_init_entry(switch_device_t device); -p4_pd_status_t -switch_pd_sflow_tables_init(switch_device_t device); +p4_pd_status_t switch_pd_sflow_tables_init(switch_device_t device); // mirroring apis -p4_pd_status_t -switch_pd_mirror_session_update(switch_device_t device, - switch_handle_t mirror_handle, - switch_mirror_info_t *mirror_info); +p4_pd_status_t switch_pd_mirror_session_update( + switch_device_t device, + switch_handle_t mirror_handle, + switch_mirror_info_t *mirror_info); + +p4_pd_status_t switch_pd_mirror_session_delete(switch_device_t device, + switch_handle_t mirror_handle); -p4_pd_status_t -switch_pd_mirror_session_delete(switch_device_t device, - switch_handle_t mirror_handle); +p4_pd_status_t switch_pd_mirror_table_entry_add( + switch_device_t device, + switch_handle_t mirror_handle, + switch_mirror_info_t *mirror_info); -p4_pd_status_t -switch_pd_mirror_table_entry_add(switch_device_t device, - switch_handle_t mirror_handle, - switch_mirror_info_t *mirror_info); +p4_pd_status_t switch_pd_mirror_table_entry_delete( + switch_device_t device, switch_mirror_info_t *mirror_info); -p4_pd_status_t -switch_pd_mirror_table_entry_delete(switch_device_t device, - switch_mirror_info_t *mirror_info); +switch_status_t switch_pd_mirror_table_add_default_entry( + switch_device_t device); -switch_status_t -switch_pd_mirror_table_add_default_entry(switch_device_t device); +switch_status_t switch_pd_mtu_table_add_ipv4_check(switch_device_t device, + uint16_t mtu_index, + uint32_t mtu); -switch_status_t -switch_pd_neg_mirror_add_entry(switch_device_t device); +switch_status_t switch_pd_mtu_table_add_ipv6_check(switch_device_t device, + uint16_t mtu_index, + uint32_t mtu); -p4_pd_status_t -p4_pd_complete_operations(p4_pd_sess_hdl_t shdl); +p4_pd_status_t p4_pd_complete_operations(p4_pd_sess_hdl_t shdl); -p4_pd_status_t -p4_pd_client_init(p4_pd_sess_hdl_t *sess_hdl, uint32_t max_txn_size); +p4_pd_status_t p4_pd_client_init(p4_pd_sess_hdl_t *sess_hdl); #ifdef P4_INT_TRANSIT_ENABLE // INT APIs -p4_pd_status_t -switch_pd_int_tables_init(switch_device_t device); +p4_pd_status_t switch_pd_int_tables_init(switch_device_t device); -p4_pd_status_t -switch_pd_int_transit_enable(switch_device_t device, int32_t swid, - int32_t idx, p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_int_transit_enable(switch_device_t device, + int32_t swid, + int32_t idx, + p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_int_transit_disable(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); +p4_pd_status_t switch_pd_int_transit_disable(switch_device_t device, + p4_pd_entry_hdl_t entry_hdl); #endif #ifdef P4_INT_EP_ENABLE -p4_pd_status_t -switch_pd_int_src_enable(switch_device_t device, int32_t switch_id, - switch_ip_addr_t *src, - switch_ip_addr_t *dst, - uint8_t hop_cnt, uint16_t ins_mask, - int32_t idx, p4_pd_entry_hdl_t *entry_hdl, - bool vtep_src); +p4_pd_status_t switch_pd_int_src_enable(switch_device_t device, + int32_t switch_id, + switch_ip_addr_t *src, + switch_ip_addr_t *dst, + uint8_t hop_cnt, + uint16_t ins_mask, + int32_t idx, + p4_pd_entry_hdl_t *entry_hdl, + bool vtep_src); #endif #ifdef P4_INT_EP_ENABLE -p4_pd_status_t -switch_pd_int_sink_enable(switch_device_t device, - switch_ip_addr_t *dst, - uint32_t mirror_id, - int32_t prio, p4_pd_entry_hdl_t *entry_hdl, - bool use_client_ip); +p4_pd_status_t switch_pd_int_sink_enable(switch_device_t device, + switch_ip_addr_t *dst, + uint32_t mirror_id, + int32_t prio, + p4_pd_entry_hdl_t *entry_hdl, + bool use_client_ip); #endif -p4_pd_status_t -switch_pd_storm_control_table_add_default_entry( - switch_device_t device); - -p4_pd_status_t -switch_pd_storm_control_meter_add_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info); - -p4_pd_status_t -switch_pd_storm_control_table_add_entry( - switch_device_t device, - switch_port_t port, - uint16_t priority, - switch_packet_type_t pkt_type, - switch_meter_idx_t meter_idx, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_storm_control_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_meter_index_table_add_default_entry( - switch_device_t device); - -p4_pd_status_t -switch_pd_meter_index_table_add_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_meter_index_table_update_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_meter_index_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t entry_hdl); - -p4_pd_status_t -switch_pd_meter_action_table_add_default_entry( - switch_device_t device); - -p4_pd_status_t -switch_pd_meter_action_table_add_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t *entry_hdl); - - -p4_pd_status_t -switch_pd_meter_action_table_update_entry( - switch_device_t device, - switch_meter_idx_t meter_idx, - switch_meter_info_t *meter_info, - p4_pd_entry_hdl_t *entry_hdl); - -p4_pd_status_t -switch_pd_meter_action_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_storm_control_table_add_default_entry( + switch_device_t device); + +p4_pd_status_t switch_pd_storm_control_meter_add_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info); + +p4_pd_status_t switch_pd_storm_control_table_add_entry( + switch_device_t device, + switch_port_t port, + uint16_t priority, + switch_packet_type_t pkt_type, + switch_meter_idx_t meter_idx, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_storm_control_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_meter_index_table_add_default_entry( + switch_device_t device); + +p4_pd_status_t switch_pd_meter_index_table_add_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_meter_index_table_update_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_meter_index_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_meter_action_table_add_default_entry( + switch_device_t device); + +p4_pd_status_t switch_pd_meter_action_table_add_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_meter_action_table_update_entry( + switch_device_t device, + switch_meter_idx_t meter_idx, + switch_meter_info_t *meter_info, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_meter_action_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t *entry_hdl); #ifdef P4_SFLOW_ENABLE -switch_status_t -switch_pd_sflow_ingress_table_add (switch_device_t device, - switch_sflow_match_key_t *match_key, - uint32_t priority, uint32_t sample_rate, - switch_sflow_info_t *sflow_info, - switch_sflow_match_entry_t *entry); -switch_status_t -switch_pd_sflow_match_table_delete (switch_device_t device, - switch_sflow_match_entry_t *match_entry); -switch_status_t -switch_pd_sflow_session_create (switch_device_t device, - switch_sflow_info_t *sflow_info); - -switch_status_t -switch_pd_sflow_session_delete (switch_device_t device, - switch_sflow_info_t *sflow_info); +switch_status_t switch_pd_sflow_ingress_table_add( + switch_device_t device, + switch_sflow_match_key_t *match_key, + uint32_t priority, + uint32_t sample_rate, + switch_sflow_info_t *sflow_info, + switch_sflow_match_entry_t *entry); +switch_status_t switch_pd_sflow_match_table_delete( + switch_device_t device, switch_sflow_match_entry_t *match_entry); +switch_status_t switch_pd_sflow_session_create(switch_device_t device, + switch_sflow_info_t *sflow_info); + +switch_status_t switch_pd_sflow_session_delete(switch_device_t device, + switch_sflow_info_t *sflow_info); + +switch_status_t switch_pd_sflow_counter_read( + switch_device_t device, + switch_sflow_match_entry_t *match_entry, + switch_counter_t *sw_counter); + +switch_status_t switch_pd_sflow_counter_write( + switch_device_t device, + switch_sflow_match_entry_t *match_entry, + switch_counter_t val); #endif -p4_pd_status_t -switch_pd_stats_update(switch_device_t device); +p4_pd_status_t switch_pd_stats_update(switch_device_t device); + +p4_pd_status_t switch_pd_meter_stats_get(switch_device_t device, + switch_meter_info_t *meter_info); + +p4_pd_status_t switch_pd_storm_control_stats_get( + switch_device_t device, switch_meter_info_t *meter_info); + +p4_pd_status_t switch_pd_egress_bd_stats_table_add_entry( + switch_device_t device, uint16_t bd, p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_egress_bd_stats_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_acl_stats_get(switch_device_t device, + uint16_t acl_stats_index, + switch_counter_t *acl_counter); + +switch_status_t switch_pd_ingress_pool_init( + switch_device_t device, switch_buffer_pool_info_t *pool_info); + +switch_status_t switch_pd_egress_pool_init( + switch_device_t device, switch_buffer_pool_info_t *pool_info); + +p4_pd_status_t switch_pd_buffer_pool_set(switch_device_t device, + switch_pd_pool_id_t pool_id, + uint32_t pool_size); -p4_pd_status_t -switch_pd_meter_stats_get(switch_device_t device, switch_meter_info_t *meter_info); +p4_pd_status_t switch_pd_buffer_pool_color_drop_enable( + switch_device_t device, switch_pd_pool_id_t pool_id, bool enable); -p4_pd_status_t -switch_pd_storm_control_stats_get(switch_device_t device, switch_meter_info_t *meter_info); +p4_pd_status_t switch_pd_buffer_pool_pfc_limit(switch_device_t device, + switch_pd_pool_id_t pool_id, + uint8_t icos, + uint32_t num_bytes); -p4_pd_status_t -switch_pd_egress_bd_stats_table_add_entry( - switch_device_t device, - uint16_t bd, - p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_buffer_skid_limit_set(switch_device_t device, + uint32_t num_bytes); -p4_pd_status_t -switch_pd_egress_bd_stats_table_delete_entry( - switch_device_t device, - p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_buffer_skid_hysteresis_set(switch_device_t device, + uint32_t num_bytes); + +p4_pd_status_t switch_pd_buffer_pool_color_limit_set( + switch_device_t device, + switch_pd_pool_id_t pool_id, + switch_color_t color, + uint32_t num_bytes); + +switch_status_t switch_pd_buffer_pool_color_hysteresis_set( + switch_device_t device, switch_color_t color, uint32_t num_bytes); + +p4_pd_status_t switch_pd_qos_default_entry_add(switch_device_t device); + +p4_pd_status_t switch_pd_qos_map_ingress_entry_add( + switch_device_t device, + switch_qos_map_ingress_t qos_map_type, + switch_qos_group_t qos_group_id, + switch_qos_map_t *qos_map, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_qos_map_ingress_entry_delete( + switch_device_t device, + switch_qos_map_ingress_t qos_map_type, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_qos_map_egress_entry_add( + switch_device_t device, + switch_qos_map_egress_t qos_map_type, + switch_qos_group_t qos_group_id, + switch_qos_map_t *qos_map, + p4_pd_entry_hdl_t *entry_hdl); -p4_pd_status_t -switch_pd_acl_stats_get( - switch_device_t device, - uint16_t acl_stats_index, - switch_counter_t *acl_counter); +p4_pd_status_t switch_pd_qos_map_egress_entry_delete( + switch_device_t device, + switch_qos_map_egress_t qos_map_type, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_port_drop_limit_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes); + +p4_pd_status_t switch_pd_port_drop_hysteresis_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes); + +p4_pd_status_t switch_pd_port_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + uint8_t *cos_to_icos); + +p4_pd_status_t switch_pd_port_flowcontrol_mode_set( + switch_device_t device, + switch_handle_t port_handle, + switch_flowcontrol_type_t flow_control); + +p4_pd_status_t switch_pd_ppg_create(switch_device_t device, + switch_handle_t port_handle, + switch_tm_ppg_hdl_t *ppg_handle); + +p4_pd_status_t switch_pd_ppg_delete(switch_device_t device, + switch_tm_ppg_hdl_t ppg_handle); + +p4_pd_status_t switch_pd_port_ppg_tc_mapping(switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint8_t icos_bmp); + +p4_pd_status_t switch_pd_ppg_lossless_enable(switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + bool enable); + +p4_pd_status_t switch_pd_ppg_guaranteed_limit_set( + switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint32_t num_bytes); + +p4_pd_status_t switch_pd_ppg_skid_limit_set(switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint32_t num_bytes); + +p4_pd_status_t switch_pd_ppg_skid_hysteresis_set( + switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint32_t num_bytes); + +p4_pd_status_t switch_pd_ppg_pool_usage_set( + switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + switch_pd_pool_id_t pool_id, + switch_api_buffer_profile_t *buffer_profile_info, + bool enable); + +p4_pd_status_t switch_pd_queue_pool_usage_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t qid, + switch_pd_pool_id_t pool_id, + switch_api_buffer_profile_t *buffer_profile_info, + bool enable); + +p4_pd_status_t switch_pd_queue_color_drop_enable(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool enable); + +p4_pd_status_t switch_pd_queue_color_limit_set(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + switch_color_t color, + uint32_t limit); + +p4_pd_status_t switch_pd_queue_color_hysteresis_set(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + switch_color_t color, + uint32_t limit); + +p4_pd_status_t switch_pd_queue_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint8_t cos); + +p4_pd_status_t switch_pd_queue_port_mapping(switch_device_t device, + switch_handle_t port_handle, + uint8_t queue_count, + uint8_t *queue_mapping); + +p4_pd_status_t switch_pd_queue_scheduling_enable(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool enable); + +p4_pd_status_t switch_pd_queue_scheduling_strict_priority_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint32_t priority); + +p4_pd_status_t switch_pd_queue_scheduling_remaining_bw_priority_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint32_t priority); + +p4_pd_status_t switch_pd_queue_scheduling_dwrr_weight_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint16_t weight); + +p4_pd_status_t switch_pd_queue_scheduling_guaranteed_shaping_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool pps, + uint32_t burst_size, + uint32_t rate); + +p4_pd_status_t switch_pd_queue_scheduling_dwrr_shaping_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool pps, + uint32_t burst_size, + uint32_t rate); + +p4_pd_status_t switch_pd_hostif_meter_set(switch_device_t device, + uint16_t meter_id, + switch_meter_info_t *meter_info, + bool enable); #ifdef __cplusplus } diff --git a/switchapi/src/switch_pd_buffer.c b/switchapi/src/switch_pd_buffer.c new file mode 100644 index 0000000..cc623a7 --- /dev/null +++ b/switchapi/src/switch_pd_buffer.c @@ -0,0 +1,78 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "p4features.h" +#include "switch_pd.h" +#include "switch_defines.h" + +extern p4_pd_sess_hdl_t g_sess_hdl; + +switch_status_t switch_pd_ingress_pool_init( + switch_device_t device, switch_buffer_pool_info_t *pool_info) { + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_pd_egress_pool_init( + switch_device_t device, switch_buffer_pool_info_t *pool_info) { + return SWITCH_STATUS_SUCCESS; +} + +p4_pd_status_t switch_pd_buffer_pool_set(switch_device_t device, + switch_pd_pool_id_t pool_id, + uint32_t pool_size) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_buffer_pool_color_drop_enable( + switch_device_t device, switch_pd_pool_id_t pool_id, bool enable) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_buffer_pool_color_limit_set( + switch_device_t device, + switch_pd_pool_id_t pool_id, + switch_color_t color, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +switch_status_t switch_pd_buffer_pool_color_hysteresis_set( + switch_device_t device, switch_color_t color, uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_buffer_skid_limit_set(switch_device_t device, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_buffer_skid_hysteresis_set(switch_device_t device, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_buffer_pool_pfc_limit(switch_device_t device, + switch_pd_pool_id_t pool_id, + uint8_t icos, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} diff --git a/switchapi/src/switch_pd_mcast.c b/switchapi/src/switch_pd_mcast.c index 23e7085..c7a1f76 100644 --- a/switchapi/src/switch_pd_mcast.c +++ b/switchapi/src/switch_pd_mcast.c @@ -22,567 +22,789 @@ limitations under the License. extern p4_pd_sess_hdl_t g_sess_hdl; -p4_pd_status_t -switch_pd_mcast_table_add_entry(switch_device_t device, - uint16_t mgid_index, - switch_mcast_mode_t mc_mode, - switch_mcast_group_info_t *group_info, - bool core_entry, bool vrf_entry, - uint16_t rpf_group) -{ - p4_pd_status_t status = 0; +p4_pd_status_t switch_pd_mcast_table_add_entry( + switch_device_t device, + uint16_t mgid_index, + switch_mcast_mode_t mc_mode, + switch_mcast_group_info_t *group_info, + bool core_entry, + bool vrf_entry, + uint16_t rpf_group) { + p4_pd_status_t status = 0; #ifndef P4_MULTICAST_DISABLE - p4_pd_dev_target_t p4_pd_device; - switch_mcast_group_key_t *group_key; + p4_pd_dev_target_t p4_pd_device; + switch_mcast_group_key_t *group_key; - group_key = &(group_info->group_key); - p4_pd_device.device_id = device; - p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + group_key = &(group_info->group_key); + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - if (core_entry) { + if (core_entry) { #ifndef P4_TUNNEL_DISABLE - if (group_key->sg_entry) { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + if (group_key->sg_entry) { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - if (vrf_entry) { - p4_pd_dc_outer_ipv4_multicast_match_spec_t match_spec; - p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv4_multicast_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t)); - - 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_srcAddr = SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key); - match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + if (vrf_entry) { + p4_pd_dc_outer_ipv4_multicast_match_spec_t match_spec; + p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv4_multicast_match_spec_t)); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t)); + + 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_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; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_outer_ipv4_multicast_table_add_with_outer_multicast_route_s_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->outer_hw_entry)); - } else { - p4_pd_dc_outer_ipv4_multicast_match_spec_t match_spec; - p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv4_multicast_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t)); - - 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_srcAddr = SWITCH_MCAST_GROUP_IPV4_SRC_IP(group_key); - match_spec.ipv4_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_outer_ipv4_multicast_table_add_with_outer_multicast_route_s_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->outer_hw_entry)); + } else { + p4_pd_dc_outer_ipv4_multicast_match_spec_t match_spec; + p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv4_multicast_match_spec_t)); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t)); + + 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_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; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - status = p4_pd_dc_outer_ipv4_multicast_table_add_with_outer_multicast_bridge_s_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->outer_hw_entry)); - } + status = + p4_pd_dc_outer_ipv4_multicast_table_add_with_outer_multicast_bridge_s_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->outer_hw_entry)); + } #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - if (vrf_entry) { - p4_pd_dc_outer_ipv6_multicast_match_spec_t match_spec; - p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv6_multicast_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t)); - - 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_srcAddr), - &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - memcpy(&(match_spec.ipv6_dstAddr), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); + if (vrf_entry) { + p4_pd_dc_outer_ipv6_multicast_match_spec_t match_spec; + p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv6_multicast_match_spec_t)); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_outer_multicast_route_s_g_hit_action_spec_t)); + + 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_srcAddr), + &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), + 16); + memcpy(&(match_spec.ipv6_dstAddr), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); #ifdef OUTER_MULTICAST_TREE_ENABLED - action_spec.action_mc_index = mgid_index; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_outer_ipv6_multicast_table_add_with_outer_multicast_route_s_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->outer_hw_entry)); - } else { - p4_pd_dc_outer_ipv6_multicast_match_spec_t match_spec; - p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv6_multicast_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t)); - - 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_srcAddr), - &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - memcpy(&(match_spec.ipv6_dstAddr), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_outer_ipv6_multicast_table_add_with_outer_multicast_route_s_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->outer_hw_entry)); + } else { + p4_pd_dc_outer_ipv6_multicast_match_spec_t match_spec; + p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv6_multicast_match_spec_t)); + memset(&action_spec, + 0, + sizeof(p4_pd_dc_outer_multicast_bridge_s_g_hit_action_spec_t)); + + 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_srcAddr), + &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), + 16); + memcpy(&(match_spec.ipv6_dstAddr), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); #ifdef OUTER_MULTICAST_TREE_ENABLED - action_spec.action_mc_index = mgid_index; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - status = p4_pd_dc_outer_ipv6_multicast_table_add_with_outer_multicast_bridge_s_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->outer_hw_entry)); - } + status = + p4_pd_dc_outer_ipv6_multicast_table_add_with_outer_multicast_bridge_s_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->outer_hw_entry)); + } #endif /* P4_IPV6_DISABLE */ - } - } else { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + } + } else { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - if (vrf_entry) { - if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) { - p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t match_spec; - p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv4_multicast_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t)); - - 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_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - match_spec.ipv4_dstAddr_mask = 0xffffffff; + if (vrf_entry) { + if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) { + p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t match_spec; + p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t + action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv4_multicast_match_spec_t)); + memset( + &action_spec, + 0, + sizeof( + p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t)); + + 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_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; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_outer_ipv4_multicast_star_g_table_add_with_outer_multicast_route_sm_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, 1000, - &action_spec, &(group_info->outer_hw_entry)); - } else { - p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t match_spec; - p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t)); - - 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_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - match_spec.ipv4_dstAddr_mask = 0xffffffff; + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_outer_ipv4_multicast_star_g_table_add_with_outer_multicast_route_sm_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + &(group_info->outer_hw_entry)); + } else { + p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t match_spec; + p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t + action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t)); + memset( + &action_spec, + 0, + sizeof( + p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t)); + + 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_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; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_outer_ipv4_multicast_star_g_table_add_with_outer_multicast_route_bidir_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, 1000, - &action_spec, &(group_info->outer_hw_entry)); - } - } else { - p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t match_spec; - p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t)); - - 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_dstAddr = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - match_spec.ipv4_dstAddr_mask = 0xffffffff; + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_outer_ipv4_multicast_star_g_table_add_with_outer_multicast_route_bidir_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + &(group_info->outer_hw_entry)); + } + } else { + p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t match_spec; + p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv4_multicast_star_g_match_spec_t)); + memset( + &action_spec, + 0, + sizeof(p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t)); + + 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_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; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - status = p4_pd_dc_outer_ipv4_multicast_star_g_table_add_with_outer_multicast_bridge_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, 1000, - &action_spec, &(group_info->outer_hw_entry)); - } + status = + p4_pd_dc_outer_ipv4_multicast_star_g_table_add_with_outer_multicast_bridge_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + &(group_info->outer_hw_entry)); + } #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - if (vrf_entry) { - if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) { - p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t match_spec; - p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv6_multicast_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t)); - - 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_dstAddr), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); + if (vrf_entry) { + if (mc_mode == SWITCH_API_MCAST_IPMC_PIM_SM) { + p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t match_spec; + p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t + action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv6_multicast_match_spec_t)); + memset( + &action_spec, + 0, + sizeof( + p4_pd_dc_outer_multicast_route_sm_star_g_hit_action_spec_t)); + + 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_dstAddr), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); #ifdef OUTER_MULTICAST_TREE_ENABLED - action_spec.action_mc_index = mgid_index; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_outer_ipv6_multicast_star_g_table_add_with_outer_multicast_route_sm_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, 1000, - &action_spec, &(group_info->outer_hw_entry)); - } else { - p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t match_spec; - p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t)); - - 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_dstAddr), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_outer_ipv6_multicast_star_g_table_add_with_outer_multicast_route_sm_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + &(group_info->outer_hw_entry)); + } else { + p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t match_spec; + p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t + action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t)); + memset( + &action_spec, + 0, + sizeof( + p4_pd_dc_outer_multicast_route_bidir_star_g_hit_action_spec_t)); + + 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_dstAddr), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); #ifdef OUTER_MULTICAST_TREE_ENABLED - action_spec.action_mc_index = mgid_index; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_outer_ipv6_multicast_star_g_table_add_with_outer_multicast_route_bidir_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, 1000, - &action_spec, &(group_info->outer_hw_entry)); - } - } else { - p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t match_spec; - p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t)); - memset(&action_spec, 0, sizeof(p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t)); - - 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_dstAddr), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_outer_ipv6_multicast_star_g_table_add_with_outer_multicast_route_bidir_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + &(group_info->outer_hw_entry)); + } + } else { + p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t match_spec; + p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_outer_ipv6_multicast_star_g_match_spec_t)); + memset( + &action_spec, + 0, + sizeof(p4_pd_dc_outer_multicast_bridge_star_g_hit_action_spec_t)); + + 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_dstAddr), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + memset(&(match_spec.ipv6_dstAddr_mask), 0xff, 16); #ifdef OUTER_MULTICAST_TREE_ENABLED - action_spec.action_mc_index = mgid_index; + action_spec.action_mc_index = mgid_index; #endif /* OUTER_MULTICAST_TREE_ENABLED */ - status = p4_pd_dc_outer_ipv6_multicast_star_g_table_add_with_outer_multicast_bridge_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, 1000, - &action_spec, &(group_info->outer_hw_entry)); - } -#endif /* P4_IPV6_DISABLE */ - } + status = + p4_pd_dc_outer_ipv6_multicast_star_g_table_add_with_outer_multicast_bridge_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + &(group_info->outer_hw_entry)); } -#endif /* P4_TUNNEL_DISABLE */ +#endif /* P4_IPV6_DISABLE */ + } } +#endif /* P4_TUNNEL_DISABLE */ + } - if (group_key->sg_entry) { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + if (group_key->sg_entry) { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - if (vrf_entry) { + 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_multicast_route_match_spec_t)); - match_spec.l3_metadata_vrf = 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); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_route_s_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - action_spec.action_mcast_rpf_group = rpf_group; - - 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)); + p4_pd_dc_ipv4_multicast_route_match_spec_t match_spec; + p4_pd_dc_multicast_route_s_g_hit_action_spec_t action_spec; + + memset( + &match_spec, 0, sizeof(p4_pd_dc_ipv4_multicast_route_match_spec_t)); + match_spec.l3_metadata_vrf = 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); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_route_s_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + action_spec.action_mcast_rpf_group = rpf_group; + + 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 { + } 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_multicast_bridge_match_spec_t)); - match_spec.ingress_metadata_bd = 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); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - - 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)); + p4_pd_dc_ipv4_multicast_bridge_match_spec_t match_spec; + p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv4_multicast_bridge_match_spec_t)); + match_spec.ingress_metadata_bd = 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); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + + 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 { + } else { #ifndef P4_IPV6_DISABLE - if (vrf_entry) { + 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_multicast_route_match_spec_t)); - match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_sa), - &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_route_s_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - action_spec.action_mcast_rpf_group = rpf_group; - - 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)); + p4_pd_dc_ipv6_multicast_route_match_spec_t match_spec; + p4_pd_dc_multicast_route_s_g_hit_action_spec_t action_spec; + + memset( + &match_spec, 0, sizeof(p4_pd_dc_ipv6_multicast_route_match_spec_t)); + match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_sa), + &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), + 16); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_route_s_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + action_spec.action_mcast_rpf_group = rpf_group; + + 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 { + } 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_multicast_bridge_match_spec_t)); - match_spec.ingress_metadata_bd = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_sa), - &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), 16); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - - 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)); + p4_pd_dc_ipv6_multicast_bridge_match_spec_t match_spec; + p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv6_multicast_bridge_match_spec_t)); + match_spec.ingress_metadata_bd = handle_to_id(group_key->bd_vrf_handle); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_sa), + &(SWITCH_MCAST_GROUP_IPV6_SRC_IP(group_key)), + 16); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_bridge_s_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + + 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 */ - } - } else { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + } + } else { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - if (vrf_entry) { + 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t)); - match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_route_sm_star_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_ipv4_multicast_route_star_g_table_add_with_multicast_route_sm_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->inner_hw_entry)); - } else { - p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t match_spec; - p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t)); - match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_ipv4_multicast_route_star_g_table_add_with_multicast_route_bidir_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->inner_hw_entry)); - } + 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; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t)); + match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_da = + SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_route_sm_star_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_ipv4_multicast_route_star_g_table_add_with_multicast_route_sm_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->inner_hw_entry)); + } else { + p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t match_spec; + p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv4_multicast_route_star_g_match_spec_t)); + match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_da = + SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + + memset( + &action_spec, + 0, + sizeof(p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_ipv4_multicast_route_star_g_table_add_with_multicast_route_bidir_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->inner_hw_entry)); + } #endif /* P4_L3_MULTICAST_DISABLE */ - } else { + } 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv4_multicast_bridge_star_g_match_spec_t)); - match_spec.ingress_metadata_bd = handle_to_id(group_key->bd_vrf_handle); - match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_bridge_star_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - - 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)); + 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; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv4_multicast_bridge_star_g_match_spec_t)); + match_spec.ingress_metadata_bd = handle_to_id(group_key->bd_vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_da = + SWITCH_MCAST_GROUP_IPV4_GRP_IP(group_key); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_bridge_star_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + + 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 { + } else { #ifndef P4_IPV6_DISABLE - if (vrf_entry) { + 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t)); - match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_route_sm_star_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_ipv6_multicast_route_star_g_table_add_with_multicast_route_sm_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->inner_hw_entry)); - } else { - p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t match_spec; - p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t action_spec; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t)); - match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - action_spec.action_mcast_rpf_group = rpf_group; - - status = p4_pd_dc_ipv6_multicast_route_star_g_table_add_with_multicast_route_bidir_star_g_hit( - g_sess_hdl, p4_pd_device, &match_spec, &action_spec, - &(group_info->inner_hw_entry)); - } + 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; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t)); + match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_route_sm_star_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_ipv6_multicast_route_star_g_table_add_with_multicast_route_sm_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->inner_hw_entry)); + } else { + p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t match_spec; + p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t action_spec; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv6_multicast_route_star_g_match_spec_t)); + match_spec.l3_metadata_vrf = handle_to_id(group_key->bd_vrf_handle); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + + memset( + &action_spec, + 0, + sizeof(p4_pd_dc_multicast_route_bidir_star_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + action_spec.action_mcast_rpf_group = rpf_group; + + status = + p4_pd_dc_ipv6_multicast_route_star_g_table_add_with_multicast_route_bidir_star_g_hit( + g_sess_hdl, + p4_pd_device, + &match_spec, + &action_spec, + &(group_info->inner_hw_entry)); + } #endif /* P4_L3_MULTICAST_DISABLE */ - } else { + } 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; - - memset(&match_spec, 0, sizeof(p4_pd_dc_ipv6_multicast_bridge_star_g_match_spec_t)); - match_spec.ingress_metadata_bd = handle_to_id(group_key->bd_vrf_handle); - memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), - &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), 16); - - memset(&action_spec, 0, sizeof(p4_pd_dc_multicast_bridge_star_g_hit_action_spec_t)); - action_spec.action_mc_index = mgid_index; - - 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)); + 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; + + memset(&match_spec, + 0, + sizeof(p4_pd_dc_ipv6_multicast_bridge_star_g_match_spec_t)); + match_spec.ingress_metadata_bd = handle_to_id(group_key->bd_vrf_handle); + memcpy(&(match_spec.ipv6_metadata_lkp_ipv6_da), + &(SWITCH_MCAST_GROUP_IPV6_GRP_IP(group_key)), + 16); + + memset(&action_spec, + 0, + sizeof(p4_pd_dc_multicast_bridge_star_g_hit_action_spec_t)); + action_spec.action_mc_index = mgid_index; + + 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 */ - } } + } #endif /* P4_MULTICAST_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } -p4_pd_status_t -switch_pd_mcast_table_delete_entry(switch_device_t device, - switch_mcast_group_info_t *group_info, - bool core_entry, bool vrf_entry) +p4_pd_status_t switch_pd_mcast_table_delete_entry( + switch_device_t device, + switch_mcast_group_info_t *group_info, + bool core_entry, + bool vrf_entry) { - p4_pd_status_t status = 0; + p4_pd_status_t status = 0; #ifndef P4_MULTICAST_DISABLE - switch_mcast_group_key_t *group_key; - group_key = &(group_info->group_key); + switch_mcast_group_key_t *group_key; + group_key = &(group_info->group_key); - if (core_entry) { + if (core_entry) { #ifndef P4_TUNNEL_DISABLE - if (group_key->sg_entry) { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + if (group_key->sg_entry) { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_outer_ipv4_multicast_table_delete( - g_sess_hdl, device, group_info->outer_hw_entry); + status = p4_pd_dc_outer_ipv4_multicast_table_delete( + g_sess_hdl, device, group_info->outer_hw_entry); #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_outer_ipv6_multicast_table_delete( - g_sess_hdl, device, group_info->outer_hw_entry); + status = p4_pd_dc_outer_ipv6_multicast_table_delete( + g_sess_hdl, device, group_info->outer_hw_entry); #endif /* P4_IPV6_DISABLE */ - } - } else { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + } + } else { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - status = p4_pd_dc_outer_ipv4_multicast_star_g_table_delete( - g_sess_hdl, device, group_info->outer_hw_entry); + status = p4_pd_dc_outer_ipv4_multicast_star_g_table_delete( + g_sess_hdl, device, group_info->outer_hw_entry); #endif /* P4_IPV4_DISABLE */ - } else { + } else { #ifndef P4_IPV6_DISABLE - status = p4_pd_dc_outer_ipv6_multicast_star_g_table_delete( - g_sess_hdl, device, group_info->outer_hw_entry); + status = p4_pd_dc_outer_ipv6_multicast_star_g_table_delete( + g_sess_hdl, device, group_info->outer_hw_entry); #endif /* P4_IPV6_DISABLE */ - } - } -#endif /* P4_TUNNEL_DISABLE */ + } } +#endif /* P4_TUNNEL_DISABLE */ + } - if (group_key->sg_entry) { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + if (group_key->sg_entry) { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - if (vrf_entry) { + 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); + status = p4_pd_dc_ipv4_multicast_route_table_delete( + g_sess_hdl, device, group_info->inner_hw_entry); #endif /* P4_L3_MULTICAST_DISABLE */ - } else { + } else { #ifndef P4_L2_MULTICAST_DISABLE - status = p4_pd_dc_ipv4_multicast_bridge_table_delete( - g_sess_hdl, device, group_info->inner_hw_entry); + 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 { + } else { #ifndef P4_IPV6_DISABLE - if (vrf_entry) { + 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); + status = p4_pd_dc_ipv6_multicast_route_table_delete( + g_sess_hdl, device, group_info->inner_hw_entry); #endif /* P4_L3_MULTICAST_DISABLE */ - } else { + } else { #ifndef P4_L2_MULTICAST_DISABLE - status = p4_pd_dc_ipv6_multicast_bridge_table_delete( - g_sess_hdl, device, group_info->inner_hw_entry); + 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 */ - } - } else { - if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { + } + } else { + if (SWITCH_MCAST_GROUP_IP_TYPE(group_key) == SWITCH_API_IP_ADDR_V4) { #ifndef P4_IPV4_DISABLE - if (vrf_entry) { + 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); + 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 { + } 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); + 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 { + } else { #ifndef P4_IPV6_DISABLE - if (vrf_entry) { + 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); + 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 { + } 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); + 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 */ - } } + } #endif /* P4_MULTICAST_DISABLE */ - p4_pd_complete_operations(g_sess_hdl); - return status; + p4_pd_complete_operations(g_sess_hdl); + return status; } diff --git a/switchapi/src/switch_pd_nat.c b/switchapi/src/switch_pd_nat.c new file mode 100644 index 0000000..5e5bcd7 --- /dev/null +++ b/switchapi/src/switch_pd_nat.c @@ -0,0 +1,324 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "p4features.h" +#include "switch_pd.h" +#include "switch_defines.h" + +extern p4_pd_sess_hdl_t g_sess_hdl; + +p4_pd_status_t switch_pd_nat_init(switch_device_t device) { + p4_pd_status_t status = 0; +#ifndef P4_NAT_DISABLE + p4_pd_entry_hdl_t entry_hdl; + + p4_pd_dev_target_t p4_pd_device; + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + /* ingress tables */ + status = p4_pd_dc_nat_twice_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_nat_dst_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_nat_src_set_default_action_on_miss( + g_sess_hdl, p4_pd_device, &entry_hdl); + status = p4_pd_dc_nat_flow_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + /* egress tables */ + status = p4_pd_dc_egress_nat_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#endif /* P4_NAT_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_nat_table_add_entry(switch_device_t device, + switch_interface_info_t *intf_info, + switch_nat_info_t *nat_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_NAT_DISABLE + p4_pd_dev_target_t p4_pd_device; + switch_api_nat_info_t *api_nat_info = NULL; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + api_nat_info = &nat_info->api_nat_info; + switch (api_nat_info->nat_rw_type) { + case SWITCH_NAT_RW_TYPE_SRC: { + p4_pd_dc_nat_flow_match_spec_t match_spec; + p4_pd_dc_set_src_nat_rewrite_index_action_spec_t action_spec; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + + match_spec.l3_metadata_vrf = handle_to_id(api_nat_info->vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_NAT_SRC_IP(api_nat_info); + match_spec.l3_metadata_vrf_mask = 0xFFFF; + match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xFFFFFFFF; + action_spec.action_nat_rewrite_index = nat_info->nat_rw_index; + + status = p4_pd_dc_nat_flow_table_add_with_set_src_nat_rewrite_index( + g_sess_hdl, p4_pd_device, &match_spec, 0, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_TCP: + case SWITCH_NAT_RW_TYPE_SRC_UDP: { + p4_pd_dc_nat_src_match_spec_t match_spec; + p4_pd_dc_set_src_nat_rewrite_index_action_spec_t action_spec; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + + match_spec.l3_metadata_vrf = handle_to_id(api_nat_info->vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_NAT_SRC_IP(api_nat_info); + match_spec.l3_metadata_lkp_ip_proto = api_nat_info->protocol; + match_spec.l3_metadata_lkp_l4_sport = api_nat_info->src_port; + action_spec.action_nat_rewrite_index = nat_info->nat_rw_index; + + status = p4_pd_dc_nat_src_table_add_with_set_src_nat_rewrite_index( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_DST: { + p4_pd_dc_nat_flow_match_spec_t match_spec; + p4_pd_dc_set_dst_nat_nexthop_index_action_spec_t action_spec; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + + match_spec.l3_metadata_vrf = api_nat_info->vrf_handle; + match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_NAT_DST_IP(api_nat_info); + match_spec.l3_metadata_vrf_mask = 0xFFFF; + match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0xFFFFFFFF; + action_spec.action_nexthop_index = + handle_to_id(api_nat_info->nhop_handle); + action_spec.action_nat_rewrite_index = nat_info->nat_rw_index; + + status = p4_pd_dc_nat_flow_table_add_with_set_dst_nat_nexthop_index( + g_sess_hdl, p4_pd_device, &match_spec, 0, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_DST_TCP: + case SWITCH_NAT_RW_TYPE_DST_UDP: { + p4_pd_dc_nat_dst_match_spec_t match_spec; + p4_pd_dc_set_dst_nat_nexthop_index_action_spec_t action_spec; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + + match_spec.l3_metadata_vrf = api_nat_info->vrf_handle; + match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_NAT_DST_IP(api_nat_info); + match_spec.l3_metadata_lkp_ip_proto = api_nat_info->protocol; + match_spec.l3_metadata_lkp_l4_dport = api_nat_info->dst_port; + action_spec.action_nexthop_index = + handle_to_id(api_nat_info->nhop_handle); + action_spec.action_nat_rewrite_index = nat_info->nat_rw_index; + + status = p4_pd_dc_nat_dst_table_add_with_set_dst_nat_nexthop_index( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_DST: { + p4_pd_dc_nat_flow_match_spec_t match_spec; + p4_pd_dc_set_twice_nat_nexthop_index_action_spec_t action_spec; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + + match_spec.l3_metadata_vrf = handle_to_id(api_nat_info->vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_NAT_SRC_IP(api_nat_info); + match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_NAT_DST_IP(api_nat_info); + match_spec.l3_metadata_vrf_mask = 0xFFFF; + match_spec.ipv4_metadata_lkp_ipv4_sa_mask = 0xFFFFFFFF; + match_spec.ipv4_metadata_lkp_ipv4_da_mask = 0xFFFFFFFF; + action_spec.action_nexthop_index = + handle_to_id(api_nat_info->nhop_handle); + action_spec.action_nat_rewrite_index = nat_info->nat_rw_index; + + status = p4_pd_dc_nat_flow_table_add_with_set_twice_nat_nexthop_index( + g_sess_hdl, p4_pd_device, &match_spec, 0, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_DST_TCP: + case SWITCH_NAT_RW_TYPE_SRC_DST_UDP: { + p4_pd_dc_nat_twice_match_spec_t match_spec; + p4_pd_dc_set_twice_nat_nexthop_index_action_spec_t action_spec; + + memset(&match_spec, 0, sizeof(match_spec)); + memset(&action_spec, 0, sizeof(action_spec)); + + match_spec.l3_metadata_vrf = handle_to_id(api_nat_info->vrf_handle); + match_spec.ipv4_metadata_lkp_ipv4_sa = SWITCH_NAT_SRC_IP(api_nat_info); + match_spec.ipv4_metadata_lkp_ipv4_da = SWITCH_NAT_DST_IP(api_nat_info); + match_spec.l3_metadata_lkp_ip_proto = api_nat_info->protocol; + match_spec.l3_metadata_lkp_l4_sport = api_nat_info->src_port; + match_spec.l3_metadata_lkp_l4_dport = api_nat_info->dst_port; + action_spec.action_nexthop_index = + handle_to_id(api_nat_info->nhop_handle); + action_spec.action_nat_rewrite_index = nat_info->nat_rw_index; + + status = p4_pd_dc_nat_twice_table_add_with_set_twice_nat_nexthop_index( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + } +#endif /* P4_NAT_DISABLE */ + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_nat_table_delete_entry(switch_device_t device, + switch_nat_info_t *nat_info, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_NAT_DISABLE + switch_api_nat_info_t *api_nat_info = NULL; + + api_nat_info = &nat_info->api_nat_info; + switch (api_nat_info->nat_rw_type) { + case SWITCH_NAT_RW_TYPE_SRC: + case SWITCH_NAT_RW_TYPE_DST: + case SWITCH_NAT_RW_TYPE_SRC_DST: + status = p4_pd_dc_nat_flow_table_delete(g_sess_hdl, device, entry_hdl); + break; + case SWITCH_NAT_RW_TYPE_SRC_TCP: + case SWITCH_NAT_RW_TYPE_SRC_UDP: + status = p4_pd_dc_nat_src_table_delete(g_sess_hdl, device, entry_hdl); + break; + case SWITCH_NAT_RW_TYPE_DST_TCP: + case SWITCH_NAT_RW_TYPE_DST_UDP: + status = p4_pd_dc_nat_dst_table_delete(g_sess_hdl, device, entry_hdl); + break; + case SWITCH_NAT_RW_TYPE_SRC_DST_TCP: + case SWITCH_NAT_RW_TYPE_SRC_DST_UDP: + status = p4_pd_dc_nat_twice_table_delete(g_sess_hdl, device, entry_hdl); + break; + } +#endif /* P4_NAT_DISABLE */ + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_nat_rewrite_table_add_entry( + switch_device_t device, + switch_nat_info_t *nat_info, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_NAT_DISABLE + p4_pd_dc_egress_nat_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + switch_api_nat_info_t *api_nat_info = NULL; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(match_spec)); + match_spec.nat_metadata_nat_rewrite_index = nat_info->nat_rw_index; + + api_nat_info = &nat_info->api_nat_info; + switch (api_nat_info->nat_rw_type) { + case SWITCH_NAT_RW_TYPE_SRC: { + p4_pd_dc_set_nat_src_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_src_ip = SWITCH_NAT_RW_SRC_IP(api_nat_info); + status = p4_pd_dc_egress_nat_table_add_with_set_nat_src_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_DST: { + p4_pd_dc_set_nat_dst_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_dst_ip = SWITCH_NAT_RW_DST_IP(api_nat_info); + status = p4_pd_dc_egress_nat_table_add_with_set_nat_dst_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_DST: { + p4_pd_dc_set_nat_src_dst_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_src_ip = SWITCH_NAT_RW_SRC_IP(api_nat_info); + action_spec.action_dst_ip = SWITCH_NAT_RW_DST_IP(api_nat_info); + status = p4_pd_dc_egress_nat_table_add_with_set_nat_src_dst_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_UDP: { + p4_pd_dc_set_nat_src_udp_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_src_ip = SWITCH_NAT_RW_SRC_IP(api_nat_info); + action_spec.action_src_port = api_nat_info->rw_src_port; + status = p4_pd_dc_egress_nat_table_add_with_set_nat_src_udp_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_DST_UDP: { + p4_pd_dc_set_nat_dst_udp_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_dst_ip = SWITCH_NAT_RW_DST_IP(api_nat_info); + action_spec.action_dst_port = api_nat_info->rw_dst_port; + status = p4_pd_dc_egress_nat_table_add_with_set_nat_dst_udp_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_DST_UDP: { + p4_pd_dc_set_nat_src_dst_udp_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_src_ip = SWITCH_NAT_RW_SRC_IP(api_nat_info); + action_spec.action_src_port = api_nat_info->rw_src_port; + action_spec.action_dst_ip = SWITCH_NAT_RW_DST_IP(api_nat_info); + action_spec.action_dst_port = api_nat_info->rw_dst_port; + status = p4_pd_dc_egress_nat_table_add_with_set_nat_src_dst_udp_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_TCP: { + p4_pd_dc_set_nat_src_tcp_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_src_ip = SWITCH_NAT_RW_SRC_IP(api_nat_info); + action_spec.action_src_port = api_nat_info->rw_src_port; + status = p4_pd_dc_egress_nat_table_add_with_set_nat_src_tcp_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_DST_TCP: { + p4_pd_dc_set_nat_dst_tcp_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_dst_ip = SWITCH_NAT_RW_DST_IP(api_nat_info); + action_spec.action_dst_port = api_nat_info->rw_dst_port; + status = p4_pd_dc_egress_nat_table_add_with_set_nat_dst_tcp_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + case SWITCH_NAT_RW_TYPE_SRC_DST_TCP: { + p4_pd_dc_set_nat_src_dst_tcp_rewrite_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_src_ip = SWITCH_NAT_RW_SRC_IP(api_nat_info); + action_spec.action_src_port = api_nat_info->rw_src_port; + action_spec.action_dst_ip = SWITCH_NAT_RW_DST_IP(api_nat_info); + action_spec.action_dst_port = api_nat_info->rw_dst_port; + status = p4_pd_dc_egress_nat_table_add_with_set_nat_src_dst_tcp_rewrite( + g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); + } break; + } +#endif /* P4_NAT_DISABLE */ + + p4_pd_complete_operations(g_sess_hdl); + return status; +} + +p4_pd_status_t switch_pd_nat_rewrite_table_delete_entry( + switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + +#ifndef P4_NAT_DISABLE + status = p4_pd_dc_egress_nat_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_NAT_DISABLE */ + + p4_pd_complete_operations(g_sess_hdl); + return status; +} diff --git a/switchapi/src/switch_pd_ppg.c b/switchapi/src/switch_pd_ppg.c new file mode 100644 index 0000000..76a42d9 --- /dev/null +++ b/switchapi/src/switch_pd_ppg.c @@ -0,0 +1,109 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "p4features.h" +#include "switch_pd.h" +#include "switch_defines.h" + +extern p4_pd_sess_hdl_t g_sess_hdl; + +p4_pd_status_t switch_pd_port_drop_limit_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_port_drop_hysteresis_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_port_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + uint8_t *cos_to_icos) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_port_flowcontrol_mode_set( + switch_device_t device, + switch_handle_t port_handle, + switch_flowcontrol_type_t flow_control) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_create(switch_device_t device, + switch_handle_t port_handle, + switch_tm_ppg_hdl_t *ppg_handle) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_delete(switch_device_t device, + switch_tm_ppg_hdl_t ppg_handle) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_port_ppg_tc_mapping(switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint8_t icos_bmp) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_lossless_enable(switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + bool enable) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_pool_usage_set( + switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + switch_pd_pool_id_t pool_id, + switch_api_buffer_profile_t *buffer_profile_info, + bool enable) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_guaranteed_limit_set( + switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_skid_limit_set(switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_ppg_skid_hysteresis_set( + switch_device_t device, + switch_tm_ppg_hdl_t tm_ppg_handle, + uint32_t num_bytes) { + p4_pd_status_t status = 0; + return status; +} diff --git a/switchapi/src/switch_pd_qos.c b/switchapi/src/switch_pd_qos.c new file mode 100644 index 0000000..182d45a --- /dev/null +++ b/switchapi/src/switch_pd_qos.c @@ -0,0 +1,300 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "p4features.h" +#include "switch_pd.h" +#include "switch_defines.h" + +extern p4_pd_sess_hdl_t g_sess_hdl; + +p4_pd_status_t switch_pd_qos_default_entry_add(switch_device_t device) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + +#ifndef P4_QOS_DISABLE + + 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 = PD_DEV_PIPE_ALL; + + p4_pd_dc_ingress_qos_map_dscp_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + p4_pd_dc_ingress_qos_map_pcp_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + p4_pd_dc_traffic_class_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + p4_pd_dc_egress_qos_map_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_QOS_DISABLE */ + + return status; +} + +p4_pd_status_t switch_pd_qos_map_ingress_entry_add( + switch_device_t device, + switch_qos_map_ingress_t qos_map_type, + switch_qos_group_t qos_group_id, + switch_qos_map_t *qos_map, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_QOS_DISABLE + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + switch (qos_map_type) { + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC: { + p4_pd_dc_ingress_qos_map_dscp_match_spec_t match_spec; + memset( + &match_spec, 0, sizeof(p4_pd_dc_ingress_qos_map_dscp_match_spec_t)); + match_spec.qos_metadata_ingress_qos_group = qos_group_id; + match_spec.qos_metadata_ingress_qos_group_mask = 0xFF; + match_spec.l3_metadata_lkp_dscp = qos_map->dscp; + match_spec.l3_metadata_lkp_dscp_mask = 0xFF; + p4_pd_dc_set_ingress_tc_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_ingress_tc_action_spec_t)); + action_spec.action_tc = qos_map->tc; + status = p4_pd_dc_ingress_qos_map_dscp_table_add_with_set_ingress_tc( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC: { + p4_pd_dc_ingress_qos_map_pcp_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(p4_pd_dc_ingress_qos_map_pcp_match_spec_t)); + match_spec.qos_metadata_ingress_qos_group = qos_group_id; + match_spec.qos_metadata_ingress_qos_group_mask = 0xFF; + match_spec.l2_metadata_lkp_pcp = qos_map->pcp; + match_spec.l2_metadata_lkp_pcp_mask = 0xFF; + p4_pd_dc_set_ingress_tc_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_ingress_tc_action_spec_t)); + action_spec.action_tc = qos_map->tc; + status = p4_pd_dc_ingress_qos_map_pcp_table_add_with_set_ingress_tc( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR: { + p4_pd_dc_ingress_qos_map_dscp_match_spec_t match_spec; + memset( + &match_spec, 0, sizeof(p4_pd_dc_ingress_qos_map_dscp_match_spec_t)); + match_spec.qos_metadata_ingress_qos_group = qos_group_id; + match_spec.qos_metadata_ingress_qos_group_mask = 0xFF; + match_spec.l3_metadata_lkp_dscp = qos_map->dscp; + match_spec.l3_metadata_lkp_dscp_mask = 0xFF; + p4_pd_dc_set_ingress_color_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_ingress_color_action_spec_t)); + action_spec.action_color = qos_map->color; + status = p4_pd_dc_ingress_qos_map_dscp_table_add_with_set_ingress_color( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR: { + p4_pd_dc_ingress_qos_map_pcp_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(p4_pd_dc_ingress_qos_map_pcp_match_spec_t)); + match_spec.qos_metadata_ingress_qos_group = qos_group_id; + match_spec.qos_metadata_ingress_qos_group_mask = 0xFF; + match_spec.l2_metadata_lkp_pcp = qos_map->pcp; + match_spec.l2_metadata_lkp_pcp_mask = 0xFF; + p4_pd_dc_set_ingress_color_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(p4_pd_dc_set_ingress_color_action_spec_t)); + action_spec.action_color = qos_map->color; + status = p4_pd_dc_ingress_qos_map_pcp_table_add_with_set_ingress_color( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC_AND_COLOR: { + p4_pd_dc_ingress_qos_map_dscp_match_spec_t match_spec; + memset( + &match_spec, 0, sizeof(p4_pd_dc_ingress_qos_map_dscp_match_spec_t)); + match_spec.qos_metadata_ingress_qos_group = qos_group_id; + match_spec.qos_metadata_ingress_qos_group_mask = 0xFF; + match_spec.l3_metadata_lkp_dscp = qos_map->dscp; + match_spec.l3_metadata_lkp_dscp_mask = 0xFF; + p4_pd_dc_set_ingress_tc_and_color_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_ingress_tc_and_color_action_spec_t)); + action_spec.action_tc = qos_map->tc; + action_spec.action_color = qos_map->color; + status = + p4_pd_dc_ingress_qos_map_dscp_table_add_with_set_ingress_tc_and_color( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC_AND_COLOR: { + p4_pd_dc_ingress_qos_map_pcp_match_spec_t match_spec; + memset(&match_spec, 0, sizeof(p4_pd_dc_ingress_qos_map_pcp_match_spec_t)); + match_spec.qos_metadata_ingress_qos_group = qos_group_id; + match_spec.qos_metadata_ingress_qos_group_mask = 0xFF; + match_spec.l2_metadata_lkp_pcp = qos_map->pcp; + match_spec.l2_metadata_lkp_pcp_mask = 0xFF; + p4_pd_dc_set_ingress_tc_and_color_action_spec_t action_spec; + memset(&action_spec, + 0, + sizeof(p4_pd_dc_set_ingress_tc_and_color_action_spec_t)); + action_spec.action_tc = qos_map->tc; + action_spec.action_color = qos_map->color; + status = + p4_pd_dc_ingress_qos_map_pcp_table_add_with_set_ingress_tc_and_color( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + entry_hdl); + } break; + + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS: { + p4_pd_dc_traffic_class_match_spec_t match_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + p4_pd_dc_set_icos_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.qos_metadata_tc_qos_group = qos_group_id; + match_spec.qos_metadata_tc_qos_group_mask = 0xFF; + match_spec.qos_metadata_lkp_tc = qos_map->tc; + match_spec.qos_metadata_lkp_tc_mask = 0xFF; + action_spec.action_icos = qos_map->icos; + status = p4_pd_dc_traffic_class_table_add_with_set_icos( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE: { + p4_pd_dc_traffic_class_match_spec_t match_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + p4_pd_dc_set_queue_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.qos_metadata_tc_qos_group = qos_group_id; + match_spec.qos_metadata_tc_qos_group_mask = 0xFF; + match_spec.qos_metadata_lkp_tc = qos_map->tc; + match_spec.qos_metadata_lkp_tc_mask = 0xFF; + action_spec.action_qid = qos_map->qid; + status = p4_pd_dc_traffic_class_table_add_with_set_queue( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS_AND_QUEUE: { + p4_pd_dc_traffic_class_match_spec_t match_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + p4_pd_dc_set_icos_and_queue_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.qos_metadata_tc_qos_group = qos_group_id; + match_spec.qos_metadata_tc_qos_group_mask = 0xFF; + match_spec.qos_metadata_lkp_tc = qos_map->tc; + match_spec.qos_metadata_lkp_tc_mask = 0xFF; + action_spec.action_qid = qos_map->qid; + action_spec.action_icos = qos_map->icos; + status = p4_pd_dc_traffic_class_table_add_with_set_icos_and_queue( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + + default: + return SWITCH_STATUS_FAILURE; + } +#endif /* P4_QOS_DISABLE */ + return status; +} + +p4_pd_status_t switch_pd_qos_map_ingress_entry_delete( + switch_device_t device, + switch_qos_map_ingress_t qos_map_type, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_QOS_DISABLE + switch (qos_map_type) { + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC: + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR: + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC_AND_COLOR: + status = p4_pd_dc_ingress_qos_map_dscp_table_delete( + g_sess_hdl, device, entry_hdl); + break; + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC_AND_COLOR: + status = p4_pd_dc_ingress_qos_map_pcp_table_delete( + g_sess_hdl, device, entry_hdl); + break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS: + case SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE: + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS_AND_QUEUE: + status = + p4_pd_dc_traffic_class_table_delete(g_sess_hdl, device, entry_hdl); + default: + break; + } +#endif /* P4_QOS_DISABLE */ + return status; +} + +p4_pd_status_t switch_pd_qos_map_egress_entry_add( + switch_device_t device, + switch_qos_map_egress_t qos_map_type, + switch_qos_group_t qos_group_id, + switch_qos_map_t *qos_map, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_QOS_DISABLE + p4_pd_dc_egress_qos_map_match_spec_t match_spec; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = PD_DEV_PIPE_ALL; + + memset(&match_spec, 0, sizeof(p4_pd_dc_egress_qos_map_match_spec_t)); + match_spec.qos_metadata_egress_qos_group = qos_group_id; + match_spec.qos_metadata_egress_qos_group_mask = 0xFF; + match_spec.qos_metadata_lkp_tc = qos_map->tc; + match_spec.qos_metadata_lkp_tc_mask = 0xFF; + + switch (qos_map_type) { + case SWITCH_QOS_MAP_EGRESS_TC_TO_DSCP: + case SWITCH_QOS_MAP_EGRESS_COLOR_TO_DSCP: + case SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_DSCP: { + p4_pd_dc_set_ip_dscp_marking_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_set_ip_dscp_marking_action_spec_t)); + action_spec.action_dscp = qos_map->dscp; + status = p4_pd_dc_egress_qos_map_table_add_with_set_ip_dscp_marking( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + case SWITCH_QOS_MAP_EGRESS_TC_TO_PCP: + case SWITCH_QOS_MAP_EGRESS_COLOR_TO_PCP: + case SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_PCP: { + p4_pd_dc_set_vlan_pcp_marking_action_spec_t action_spec; + memset( + &action_spec, 0, sizeof(p4_pd_dc_set_vlan_pcp_marking_action_spec_t)); + action_spec.action_pcp = qos_map->pcp; + status = p4_pd_dc_egress_qos_map_table_add_with_set_vlan_pcp_marking( + g_sess_hdl, p4_pd_device, &match_spec, 1000, &action_spec, entry_hdl); + } break; + default: + return SWITCH_STATUS_FAILURE; + } +#endif /* P4_QOS_DISABLE */ + return status; +} + +p4_pd_status_t switch_pd_qos_map_egress_entry_delete( + switch_device_t device, + switch_qos_map_egress_t qos_map_type, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; +#ifndef P4_QOS_DISABLE + status = p4_pd_dc_egress_qos_map_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_QOS_DISABLE */ + return status; +} diff --git a/switchapi/src/switch_pd_queue.c b/switchapi/src/switch_pd_queue.c new file mode 100644 index 0000000..e98e2fa --- /dev/null +++ b/switchapi/src/switch_pd_queue.c @@ -0,0 +1,130 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "p4features.h" +#include "switch_pd.h" +#include "switch_defines.h" + +extern p4_pd_sess_hdl_t g_sess_hdl; + +p4_pd_status_t switch_pd_queue_pool_usage_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + switch_pd_pool_id_t pool_id, + switch_api_buffer_profile_t *buffer_profile_info, + bool enable) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_color_drop_enable(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool enable) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_color_limit_set(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + switch_color_t color, + uint32_t limit) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_color_hysteresis_set(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + switch_color_t color, + uint32_t limit) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint8_t cos) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_port_mapping(switch_device_t device, + switch_handle_t port_handle, + uint8_t queue_count, + uint8_t *queue_mapping) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_scheduling_enable(switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool enable) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_scheduling_strict_priority_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint32_t priority) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_scheduling_remaining_bw_priority_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint32_t priority) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_scheduling_dwrr_weight_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + uint16_t weight) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_scheduling_guaranteed_shaping_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool pps, + uint32_t burst_size, + uint32_t rate) { + p4_pd_status_t status = 0; + return status; +} + +p4_pd_status_t switch_pd_queue_scheduling_dwrr_shaping_set( + switch_device_t device, + switch_handle_t port_handle, + switch_qid_t queue_id, + bool pps, + uint32_t burst_size, + uint32_t rate) { + p4_pd_status_t status = 0; + return status; +} diff --git a/switchapi/src/switch_pd_types.h b/switchapi/src/switch_pd_types.h new file mode 100644 index 0000000..57e89f0 --- /dev/null +++ b/switchapi/src/switch_pd_types.h @@ -0,0 +1,32 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_pd_types_h_ +#define _switch_pd_types_h_ + +#ifdef BMV2 +#include "pd/pd.h" +#include "pd/pd_pre.h" +#include "pd/pd_mirroring.h" +#else +#include "p4_sim/pd.h" +#include "p4_sim/pd_pre.h" +#include "p4_sim/mirroring.h" +#endif /* BMV2 */ + +typedef uint16_t switch_pd_pool_id_t; +typedef uint16_t switch_tm_ppg_hdl_t; + +#endif /* _switch_pd_types_h_ */ diff --git a/switchapi/src/switch_port.c b/switchapi/src/switch_port.c index dab72a4..b25cdd2 100644 --- a/switchapi/src/switch_port.c +++ b/switchapi/src/switch_port.c @@ -17,212 +17,700 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_port.h" #include "switch_pd.h" +#include "switch_log.h" #include "switch_port_int.h" static switch_port_info_t switch_port_info[SWITCH_API_MAX_PORTS]; static switch_port_info_t null_port_info; static switch_port_info_t dummy_port_info; +static void *switch_ppg_array; -switch_status_t -switch_port_init(switch_device_t device) -{ - switch_port_info_t *port_info = NULL; - int index = 0; +switch_status_t switch_port_init(switch_device_t device) { + switch_port_info_t *port_info = NULL; + int index = 0; - memset(switch_port_info, 0, sizeof(switch_port_info_t) * SWITCH_API_MAX_PORTS); + memset( + switch_port_info, 0, sizeof(switch_port_info_t) * SWITCH_API_MAX_PORTS); - for (index = 0; index < SWITCH_API_MAX_PORTS; index++) { - port_info = &switch_port_info[index]; - SWITCH_PORT_ID(port_info) = index; - port_info->ifindex = index + 1; - port_info->port_type = SWITCH_PORT_TYPE_NORMAL; - if (index == CPU_PORT_ID) { - port_info->port_type = SWITCH_PORT_TYPE_CPU; - } - port_info->lag_handle = 0; + for (index = 0; index < SWITCH_API_MAX_PORTS; index++) { + port_info = &switch_port_info[index]; + SWITCH_PORT_ID(port_info) = index; + port_info->ifindex = index + 1; + port_info->port_type = SWITCH_PORT_TYPE_NORMAL; + port_info->tc = SWITCH_QOS_DEFAULT_TC; + port_info->ingress_qos_group = 0; + port_info->egress_qos_group = 0; + port_info->tc_qos_group = 0; + port_info->trust_dscp = FALSE; + port_info->trust_pcp = FALSE; + 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[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->eg_port_entry = SWITCH_HW_INVALID_HANDLE; - switch_pd_egress_port_mapping_table_add_entry(device, - SWITCH_PORT_ID(port_info), - port_info->ifindex, - port_info->port_type, - &(port_info->eg_port_entry)); - port_info->port_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, index); + 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[0] = SWITCH_HW_INVALID_HANDLE; + port_info->hw_entry[1] = SWITCH_HW_INVALID_HANDLE; + switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + port_info->eg_port_entry = SWITCH_HW_INVALID_HANDLE; + switch_pd_egress_port_mapping_table_add_entry(device, + SWITCH_PORT_ID(port_info), + port_info->ifindex, + port_info->port_type, + port_info->egress_qos_group, + &(port_info->eg_port_entry)); + port_info->port_handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, index); #endif - } - return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_SUCCESS; } -switch_port_info_t * -switch_api_port_get_internal(switch_port_t port) -{ - port = handle_to_id(port); - if(port < SWITCH_API_MAX_PORTS) - return &switch_port_info[port]; - else if(port == NULL_PORT_ID) { - return &null_port_info; - } - else { - return &dummy_port_info; - } +switch_port_info_t *switch_api_port_get_internal(switch_port_t port) { + port = handle_to_id(port); + if (port < SWITCH_API_MAX_PORTS) + return &switch_port_info[port]; + else if (port == NULL_PORT_ID) { + return &null_port_info; + } else { + return &dummy_port_info; + } } -switch_status_t -switch_api_port_set(switch_device_t device, switch_api_port_info_t *api_port_info) -{ - switch_port_info_t *port_info = switch_api_port_get_internal(api_port_info->port_number); - UNUSED(device); - if (port_info) { - // blindly overwrite the values - may need to get a modify later! - memcpy(&(port_info->api_port_info), api_port_info, sizeof(switch_api_port_info_t)); - return SWITCH_STATUS_SUCCESS; - } +switch_status_t switch_api_port_set(switch_device_t device, + switch_api_port_info_t *api_port_info) { + switch_port_info_t *port_info = + switch_api_port_get_internal(api_port_info->port_number); + UNUSED(device); + if (port_info) { + // blindly overwrite the values - may need to get a modify later! + memcpy(&(port_info->api_port_info), + api_port_info, + sizeof(switch_api_port_info_t)); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FAILURE; +} + +switch_status_t switch_api_port_get(switch_device_t device, + switch_api_port_info_t *api_port_info) { + switch_port_info_t *port_info = + switch_api_port_get_internal(api_port_info->port_number); + if (!port_info) { + api_port_info = NULL; return SWITCH_STATUS_FAILURE; + } + memcpy( + api_port_info, &port_info->api_port_info, sizeof(switch_api_port_info_t)); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_port_get(switch_device_t device, switch_api_port_info_t *api_port_info) -{ - switch_port_info_t *port_info = switch_api_port_get_internal(api_port_info->port_number); - if (!port_info) { - api_port_info = NULL; - return SWITCH_STATUS_FAILURE; - } - memcpy(api_port_info, &port_info->api_port_info, sizeof(switch_api_port_info_t)); - return SWITCH_STATUS_SUCCESS; +switch_status_t 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); + 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_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); - 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; +// stubs for linking, fill in when functionality is present in p4 + +switch_status_t switch_api_port_state_get(switch_device_t device, + switch_port_t port, + bool *up) { + *up = TRUE; + return SWITCH_STATUS_SUCCESS; } +switch_status_t switch_api_port_enable_set(switch_device_t device, + switch_port_t port, + bool enable) { + return SWITCH_STATUS_SUCCESS; +} -switch_status_t -switch_api_port_print_entry(switch_port_t port) -{ - switch_port_info_t *port_info = NULL; +switch_status_t switch_api_port_enable_get(switch_device_t device, + switch_port_t port, + bool *enable) { + return SWITCH_STATUS_SUCCESS; +} - port_info = &switch_port_info[port]; - printf("\n\nport number: %d", SWITCH_PORT_ID(port_info)); - printf("\n\tifindex: %x", port_info->ifindex); - printf("\n"); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_port_speed_set(switch_device_t device, + switch_port_t port, + switch_port_speed_t speed) { + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_port_print_all(void) -{ - switch_port_t port = 0; - for (port = 0; port < SWITCH_API_MAX_PORTS; port++) { - switch_api_port_print_entry(port); +switch_status_t switch_api_port_speed_get(switch_device_t device, + switch_port_t port, + switch_port_speed_t *speed) { + return SWITCH_STATUS_SUCCESS; +} + +// end of stubs for linking + +switch_status_t switch_api_port_print_entry(switch_port_t port) { + switch_port_info_t *port_info = NULL; + + port_info = &switch_port_info[port]; + printf("\n\nport number: %d", SWITCH_PORT_ID(port_info)); + printf("\n\tifindex: %x", port_info->ifindex); + printf("\n"); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_port_print_all(void) { + switch_port_t port = 0; + for (port = 0; port < SWITCH_API_MAX_PORTS; port++) { + switch_api_port_print_entry(port); + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_port_storm_control_set( + switch_device_t device, + switch_port_t port, + switch_packet_type_t pkt_type, + switch_handle_t meter_handle) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port = handle_to_id(port); + if (port > SWITCH_API_MAX_PORTS) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + port_info = &switch_port_info[port]; + port_info->meter_handle[pkt_type] = meter_handle; + if (meter_handle) { + status = switch_pd_storm_control_table_add_entry( + device, + port, + 1000, + pkt_type, + handle_to_id(meter_handle), + &port_info->meter_pd_hdl[pkt_type]); + } else { + if (port_info->meter_pd_hdl) { + status = switch_pd_storm_control_table_delete_entry( + device, port_info->meter_pd_hdl[pkt_type]); } - return SWITCH_STATUS_SUCCESS; + } + return status; +} + +switch_status_t switch_api_port_storm_control_get( + switch_device_t device, + switch_port_t port, + switch_packet_type_t pkt_type, + switch_handle_t *meter_handle) { + switch_port_info_t *port_info = NULL; + + port = handle_to_id(port); + if (port > SWITCH_API_MAX_PORTS) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + port_info = &switch_port_info[port]; + *meter_handle = port_info->meter_handle[pkt_type]; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_storm_control_stats_get( + switch_device_t device, + switch_handle_t meter_handle, + uint8_t count, + switch_meter_stats_t *counter_ids, + switch_counter_t *counters) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_meter_info_t *meter_info = NULL; + switch_meter_stats_info_t *stats_info = NULL; + int index = 0; + switch_bd_stats_id_t counter_id = 0; + + meter_info = switch_meter_info_get(meter_handle); + if (!meter_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + stats_info = meter_info->stats_info; + status = switch_pd_storm_control_stats_get(device, meter_info); + for (index = 0; index < count; index++) { + counter_id = counter_ids[index]; + counters[index] = stats_info->counters[counter_id]; + } + return status; +} + +bool switch_port_is_cpu_port(switch_handle_t port_hdl) { + uint32_t port_id = handle_to_id(port_hdl); + return port_id == CPU_PORT_ID; +} + +switch_handle_t switch_ppg_handle_create() { + switch_handle_t ppg_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_PRIORITY_GROUP, + switch_port_priority_group_t, + switch_ppg_array, + NULL, + ppg_handle); + return ppg_handle; +} + +switch_port_priority_group_t *switch_ppg_get(switch_handle_t ppg_handle) { + switch_port_priority_group_t *ppg_info = NULL; + _switch_handle_get( + switch_port_priority_group_t, switch_ppg_array, ppg_handle, ppg_info); + return ppg_info; +} + +switch_status_t switch_ppg_handle_delete(switch_handle_t ppg_handle) { + _switch_handle_delete( + switch_port_priority_group_t, switch_ppg_array, ppg_handle); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_port_storm_control_set( - switch_device_t device, - switch_port_t port, - switch_packet_type_t pkt_type, - switch_handle_t meter_handle) -{ - switch_port_info_t *port_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_ppg_create(switch_device_t device, + switch_handle_t port_handle) { + switch_port_info_t *port_info = NULL; + switch_handle_t ppg_handle = SWITCH_API_INVALID_HANDLE; + switch_port_priority_group_t *ppg_info = NULL; + uint32_t index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return status; + } - port = handle_to_id(port); - if (port > SWITCH_API_MAX_PORTS) { - return SWITCH_STATUS_INVALID_PARAMETER; + for (index = 0; index < port_info->max_ppg; index++) { + ppg_handle = switch_ppg_handle_create(); + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return status; } - port_info = &switch_port_info[port]; - port_info->meter_handle[pkt_type] = meter_handle; - if (meter_handle) { - status = switch_pd_storm_control_table_add_entry( - device, - port, - 1000, - pkt_type, - handle_to_id(meter_handle), - &port_info->meter_pd_hdl[pkt_type]); - } else { - if (port_info->meter_pd_hdl) { - status = switch_pd_storm_control_table_delete_entry( - device, - port_info->meter_pd_hdl[pkt_type]); - } + ppg_info->port_handle = port_handle; + ppg_info->ppg_handle = ppg_handle; + + status = + switch_pd_ppg_create(device, port_handle, &ppg_info->tm_ppg_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return status; } + port_info->ppg_handles[index] = ppg_handle; + } + return status; +} + +switch_status_t switch_api_ppg_delete(switch_device_t device, + switch_handle_t port_handle) { + switch_port_info_t *port_info = NULL; + switch_handle_t ppg_handle = SWITCH_API_INVALID_HANDLE; + switch_port_priority_group_t *ppg_info = NULL; + uint32_t index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); return status; + } + + for (index = 0; index < port_info->max_ppg; index++) { + ppg_handle = port_info->ppg_handles[index]; + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_pd_ppg_delete(device, ppg_handle); + switch_ppg_handle_delete(ppg_handle); + port_info->ppg_handles[index] = 0; + } + + return status; +} + +switch_status_t switch_api_ppg_get(switch_device_t device, + switch_handle_t port_handle, + uint8_t *num_ppg, + switch_handle_t *ppg_handles) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t index = 0; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + for (index = 0; index < port_info->max_ppg; index++) { + ppg_handles[index] = port_info->ppg_handles[index]; + } + *num_ppg = port_info->max_ppg; + + return status; +} + +switch_status_t switch_api_port_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t ppg_handle, + uint8_t cos_bitmap) { + switch_port_priority_group_t *ppg_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_port_ppg_tc_mapping( + device, ppg_info->tm_ppg_handle, cos_bitmap); + return status; +} + +switch_status_t switch_api_ppg_lossless_enable(switch_device_t device, + switch_handle_t ppg_handle, + bool enable) { + switch_port_priority_group_t *ppg_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = + switch_pd_ppg_lossless_enable(device, ppg_info->tm_ppg_handle, enable); + return status; } -switch_status_t -switch_api_port_storm_control_get( - switch_device_t device, - switch_port_t port, - switch_packet_type_t pkt_type, - switch_handle_t *meter_handle) -{ - switch_port_info_t *port_info = NULL; +switch_status_t switch_api_port_qos_group_ingress_set( + switch_device_t device, + switch_handle_t port_handle, + switch_handle_t qos_handle) { + switch_port_info_t *port_info = NULL; + switch_qos_map_list_t *qos_map_list = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + port_info->ingress_qos_group = 0; - port = handle_to_id(port); - if (port > SWITCH_API_MAX_PORTS) { - return SWITCH_STATUS_INVALID_PARAMETER; + if (qos_handle) { + qos_map_list = switch_qos_map_get(qos_handle); + if (!qos_map_list) { + SWITCH_API_ERROR("qos map get failed\n"); + return SWITCH_API_INVALID_HANDLE; } + port_info->ingress_qos_group = qos_map_list->qos_group; + } - port_info = &switch_port_info[port]; - *meter_handle = port_info->meter_handle[pkt_type]; - return SWITCH_STATUS_SUCCESS; + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("port qos group ingress set failed"); + } + return status; } -switch_status_t -switch_api_storm_control_stats_get(switch_device_t device, - switch_handle_t meter_handle, - uint8_t count, - switch_meter_stats_t *counter_ids, - switch_counter_t *counters) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_meter_info_t *meter_info = NULL; - switch_meter_stats_info_t *stats_info = NULL; - int index = 0; - switch_bd_stats_id_t counter_id = 0; - - meter_info = switch_meter_info_get(meter_handle); - if (!meter_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; +switch_status_t switch_api_port_qos_group_tc_set(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t qos_handle) { + switch_port_info_t *port_info = NULL; + switch_qos_map_list_t *qos_map_list = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + port_info->tc_qos_group = 0; + + if (qos_handle) { + qos_map_list = switch_qos_map_get(qos_handle); + if (!qos_map_list) { + SWITCH_API_ERROR("qos map get failed\n"); + return SWITCH_STATUS_INVALID_HANDLE; } + port_info->tc_qos_group = qos_map_list->qos_group; + } - stats_info = meter_info->stats_info; - status = switch_pd_storm_control_stats_get(device, meter_info); - for (index = 0; index < count; index++) { - counter_id = counter_ids[index]; - counters[index] = stats_info->counters[counter_id]; + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("port qos group tc set failed"); + } + return status; +} + +switch_status_t switch_api_port_qos_group_egress_set( + switch_device_t device, + switch_handle_t port_handle, + switch_handle_t qos_handle) { + switch_port_info_t *port_info = NULL; + switch_qos_map_list_t *qos_map_list = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + port_info->egress_qos_group = 0; + + if (qos_handle) { + qos_map_list = switch_qos_map_get(qos_handle); + if (!qos_map_list) { + SWITCH_API_ERROR("qos map get failed\n"); + return SWITCH_STATUS_INVALID_HANDLE; } - return status; + port_info->egress_qos_group = qos_map_list->qos_group; + } + + status = switch_pd_egress_port_mapping_table_add_entry( + device, + SWITCH_PORT_ID(port_info), + port_info->ifindex, + port_info->port_type, + port_info->egress_qos_group, + &(port_info->eg_port_entry)); + return status; +} + +switch_status_t switch_api_port_tc_default_set(switch_device_t device, + switch_handle_t port_handle, + uint16_t tc) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + port_info->tc = tc; + + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("port tc default set failed"); + } + return status; +} + +switch_status_t switch_api_port_color_default_set(switch_device_t device, + switch_handle_t port_handle, + switch_color_t color) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + port_info->color = color; + + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("port color default set failed"); + } + return status; +} + +switch_status_t switch_api_port_trust_dscp_set(switch_device_t device, + switch_handle_t port_handle, + bool trust_dscp) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (port_info->trust_pcp && trust_dscp) { + SWITCH_API_ERROR("dscp trust cannot be enabled when pcp is enabled"); + return SWITCH_STATUS_INVALID_ATTRIBUTE; + } + + port_info->trust_dscp = trust_dscp; + + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("port trust dscp set failed"); + } + return status; +} + +switch_status_t switch_api_port_trust_pcp_set(switch_device_t device, + switch_handle_t port_handle, + bool trust_pcp) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (port_info->trust_dscp && trust_pcp) { + SWITCH_API_ERROR("pcp trust cannot be enabled when dscp is enabled"); + return SWITCH_STATUS_INVALID_ATTRIBUTE; + } + + port_info->trust_pcp = trust_pcp; + + status = switch_pd_ingress_port_mapping_table_add_entry( + device, port_info->ifindex, port_info); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("port trust pcp set failed"); + } + return status; +} + +switch_status_t switch_api_ppg_guaranteed_limit_set(switch_device_t device, + switch_handle_t ppg_handle, + uint32_t num_bytes) { + switch_port_priority_group_t *ppg_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_ppg_guaranteed_limit_set( + device, ppg_info->tm_ppg_handle, num_bytes); + return status; +} + +switch_status_t switch_api_ppg_skid_limit_set(switch_device_t device, + switch_handle_t ppg_handle, + uint32_t num_bytes) { + switch_port_priority_group_t *ppg_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = + switch_pd_ppg_skid_limit_set(device, ppg_info->tm_ppg_handle, num_bytes); + return status; +} + +switch_status_t switch_api_ppg_skid_hysteresis_set(switch_device_t device, + switch_handle_t ppg_handle, + uint32_t num_bytes) { + switch_port_priority_group_t *ppg_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + ppg_info = switch_ppg_get(ppg_handle); + if (!ppg_info) { + SWITCH_API_ERROR("failed to allocate port_priority group"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_ppg_skid_hysteresis_set( + device, ppg_info->tm_ppg_handle, num_bytes); + return status; +} + +switch_status_t switch_api_port_drop_limit_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_port_drop_limit_set(device, port_handle, num_bytes); + + return status; +} + +switch_status_t switch_api_port_drop_hysteresis_set(switch_device_t device, + switch_handle_t port_handle, + uint32_t num_bytes) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_port_drop_hysteresis_set(device, port_handle, num_bytes); + return status; +} + +switch_status_t switch_api_port_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + uint8_t *cos_to_icos) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_port_pfc_cos_mapping(device, port_handle, cos_to_icos); + return status; } -bool -switch_port_is_cpu_port(switch_handle_t port_hdl) -{ - uint32_t port_id = handle_to_id(port_hdl); - return port_id == CPU_PORT_ID; +switch_status_t switch_api_port_flowcontrol_mode_set( + switch_device_t device, + switch_handle_t port_handle, + switch_flowcontrol_type_t flow_control) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = + switch_pd_port_flowcontrol_mode_set(device, port_handle, flow_control); + return status; } diff --git a/switchapi/src/switch_port_int.h b/switchapi/src/switch_port_int.h index 4a9e4fc..9757ebc 100644 --- a/switchapi/src/switch_port_int.h +++ b/switchapi/src/switch_port_int.h @@ -22,48 +22,68 @@ limitations under the License. #include "switchapi/switch_capability.h" #include "switchapi/switch_port.h" -#define NULL_PORT_ID 511 -#define CPU_PORT_ID 64 +#define NULL_PORT_ID 511 +#define CPU_PORT_ID 64 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef enum switch_port_type_ { - SWITCH_PORT_TYPE_NORMAL, - SWITCH_PORT_TYPE_FABRIC, - SWITCH_PORT_TYPE_CPU + SWITCH_PORT_TYPE_NORMAL, + SWITCH_PORT_TYPE_FABRIC, + SWITCH_PORT_TYPE_CPU } switch_port_type_t; /** Port information */ typedef struct switch_port_info_ { - switch_api_port_info_t api_port_info; - switch_ifindex_t ifindex; - void *intf_array; - switch_handle_t port_handle; - switch_port_type_t port_type; - switch_handle_t meter_handle[SWITCH_PACKET_TYPE_MAX]; - switch_handle_t lag_handle; + switch_api_port_info_t api_port_info; + switch_ifindex_t ifindex; + void *intf_array; + switch_handle_t port_handle; + switch_port_type_t port_type; + switch_handle_t meter_handle[SWITCH_PACKET_TYPE_MAX]; + switch_handle_t lag_handle; + bool trust_dscp; + bool trust_pcp; + switch_handle_t ingress_qos_group; + switch_handle_t tc_qos_group; + switch_handle_t egress_qos_group; + uint16_t tc; + switch_color_t color; + uint8_t max_ppg; + switch_handle_t *ppg_handles; + uint8_t max_queues; + switch_handle_t *queue_handles; #ifdef SWITCH_PD - 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 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 */ + 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 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 */ #endif } switch_port_info_t; -#define SWITCH_PORT_LAG_SELECT_ENTRY(info) \ - info->ls_entry +typedef struct switch_port_priority_group_ { + tommy_node node; + switch_handle_t ppg_handle; + switch_handle_t port_handle; + uint16_t priority; + bool lossless; + switch_handle_t buffer_profile_handle; + switch_tm_ppg_hdl_t tm_ppg_handle; +} switch_port_priority_group_t; -#define SWITCH_PORT_ID(info) \ - info->api_port_info.port_number +#define SWITCH_PORT_LAG_SELECT_ENTRY(info) info->ls_entry + +#define SWITCH_PORT_ID(info) info->api_port_info.port_number switch_status_t switch_port_init(switch_device_t device); switch_port_info_t *switch_api_port_get_internal(switch_port_t port); +switch_port_priority_group_t *switch_ppg_get(switch_handle_t ppg_handle); bool switch_port_is_cpu_port(switch_handle_t port_hdl); #ifdef __cplusplus diff --git a/switchapi/src/switch_qos.c b/switchapi/src/switch_qos.c new file mode 100644 index 0000000..aafebf1 --- /dev/null +++ b/switchapi/src/switch_qos.c @@ -0,0 +1,283 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_status.h" +#include "switchapi/switch_utils.h" +#include "switch_qos_int.h" +#include "switch_pd.h" +#include "switch_log_int.h" +#include "switch_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static void *switch_qos_map_array; +switch_api_id_allocator *ingress_qos_map_id = NULL; +switch_api_id_allocator *tc_qos_map_id = NULL; +switch_api_id_allocator *egress_qos_map_id = NULL; + +switch_status_t switch_qos_init(switch_device_t device) { + switch_qos_map_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_QOS_MAP, 128); + ingress_qos_map_id = switch_api_id_allocator_new(32, FALSE); + egress_qos_map_id = switch_api_id_allocator_new(32, FALSE); + tc_qos_map_id = switch_api_id_allocator_new(32, FALSE); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_qos_map_handle_create() { + switch_handle_t qos_map_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_QOS_MAP, + switch_qos_map_list_t, + switch_qos_map_array, + NULL, + qos_map_handle); + return qos_map_handle; +} + +switch_qos_map_list_t *switch_qos_map_get(switch_handle_t qos_map_handle) { + switch_qos_map_list_t *qos_map_list = NULL; + _switch_handle_get(switch_qos_map_list_t, + switch_qos_map_array, + qos_map_handle, + qos_map_list); + return qos_map_list; +} + +switch_status_t switch_qos_map_handle_delete(switch_handle_t qos_map_handle) { + _switch_handle_delete( + switch_qos_map_list_t, switch_qos_map_array, qos_map_handle); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_api_qos_map_ingress_create( + switch_device_t device, + switch_qos_map_ingress_t qos_map_type, + uint8_t num_entries, + switch_qos_map_t *qos_map) { + switch_qos_map_list_t *qos_map_list_info = NULL; + switch_qos_map_info_t *qos_map_info = NULL; + switch_handle_t qos_map_handle = 0; + switch_qos_group_t qos_group = 0; + int index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + qos_map_handle = switch_qos_map_handle_create(); + qos_map_list_info = switch_qos_map_get(qos_map_handle); + if (!qos_map_list_info) { + SWITCH_API_ERROR("qos map create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + tommy_list_init(&qos_map_list_info->qos_map_list); + switch (qos_map_type) { + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC: + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR: + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC_AND_COLOR: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC_AND_COLOR: + qos_group = switch_api_id_allocator_allocate(ingress_qos_map_id); + break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS: + case SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE: + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS_AND_QUEUE: + qos_group = switch_api_id_allocator_allocate(tc_qos_map_id); + break; + default: + return SWITCH_API_INVALID_HANDLE; + } + + for (index = 0; index < num_entries; index++) { + qos_map_info = switch_malloc(sizeof(switch_qos_map_info_t), 1); + if (!qos_map_info) { + SWITCH_API_ERROR("qos map create failed. no memory"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_pd_qos_map_ingress_entry_add(device, + qos_map_type, + qos_group, + &qos_map[index], + &qos_map_info->pd_hdl); + + memcpy(&qos_map_info->qos_map, &qos_map[index], sizeof(switch_qos_map_t)); + + tommy_list_insert_head( + &qos_map_list_info->qos_map_list, &qos_map_info->node, qos_map_info); + } + + qos_map_list_info->qos_group = qos_group; + qos_map_list_info->map_type.ingress_map_type = qos_map_type; + qos_map_list_info->direction = SWITCH_API_DIRECTION_INGRESS; + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("qos map create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + return qos_map_handle; +} + +switch_status_t switch_api_qos_map_ingress_delete( + switch_device_t device, switch_handle_t qos_map_handle) { + switch_qos_map_list_t *qos_map_list_info = NULL; + switch_qos_map_info_t *qos_map_info = NULL; + tommy_node *node = NULL; + tommy_node *next_node = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + qos_map_list_info = switch_qos_map_get(qos_map_handle); + if (!qos_map_list_info) { + SWITCH_API_ERROR("qos map delete failed"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + node = tommy_list_head(&qos_map_list_info->qos_map_list); + while (node) { + qos_map_info = node->data; + status = switch_pd_qos_map_ingress_entry_delete( + device, + qos_map_list_info->map_type.ingress_map_type, + qos_map_info->pd_hdl); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("qos map deleted failed: ingress"); + } + next_node = node->next; + tommy_list_remove_existing(&qos_map_list_info->qos_map_list, node); + switch_free(qos_map_info); + node = next_node; + } + + switch (qos_map_list_info->map_type.ingress_map_type) { + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC: + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR: + case SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC_AND_COLOR: + case SWITCH_QOS_MAP_INGRESS_PCP_TO_TC_AND_COLOR: + switch_api_id_allocator_release(ingress_qos_map_id, + qos_map_list_info->qos_group); + break; + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS: + case SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE: + case SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS_AND_QUEUE: + switch_api_id_allocator_release(tc_qos_map_id, + qos_map_list_info->qos_group); + break; + default: + break; + } + + status = switch_qos_map_handle_delete(qos_map_handle); + return status; +} + +switch_handle_t switch_api_qos_map_egress_create( + switch_device_t device, + switch_qos_map_egress_t qos_map_type, + uint8_t num_entries, + switch_qos_map_t *qos_map) { + switch_qos_map_list_t *qos_map_list_info = NULL; + switch_qos_map_info_t *qos_map_info = NULL; + switch_handle_t qos_map_handle = 0; + switch_qos_group_t qos_group = 0; + int index = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + qos_map_handle = switch_qos_map_handle_create(); + qos_map_list_info = switch_qos_map_get(qos_map_handle); + if (!qos_map_list_info) { + SWITCH_API_ERROR("qos map create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + tommy_list_init(&qos_map_list_info->qos_map_list); + qos_group = switch_api_id_allocator_allocate(egress_qos_map_id); + + for (index = 0; index < num_entries; index++) { + qos_map_info = switch_malloc(sizeof(switch_qos_map_info_t), 1); + if (!qos_map_info) { + SWITCH_API_ERROR("qos map create failed. no memory"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_pd_qos_map_egress_entry_add(device, + qos_map_type, + qos_group, + &qos_map[index], + &qos_map_info->pd_hdl); + + memcpy(&qos_map_info->qos_map, &qos_map[index], sizeof(switch_qos_map_t)); + + tommy_list_insert_head( + &qos_map_list_info->qos_map_list, &qos_map_info->node, qos_map_info); + } + + qos_map_list_info->qos_group = qos_group; + qos_map_list_info->direction = SWITCH_API_DIRECTION_EGRESS; + qos_map_list_info->map_type.egress_map_type = qos_map_type; + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("qos map create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + return qos_map_handle; +} + +switch_status_t switch_api_qos_map_egress_delete( + switch_device_t device, switch_handle_t qos_map_handle) { + switch_qos_map_list_t *qos_map_list_info = NULL; + switch_qos_map_info_t *qos_map_info = NULL; + tommy_node *node = NULL; + tommy_node *next_node = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + qos_map_list_info = switch_qos_map_get(qos_map_handle); + if (!qos_map_list_info) { + SWITCH_API_ERROR("qos map delete failed"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + node = tommy_list_head(&qos_map_list_info->qos_map_list); + while (node) { + qos_map_info = node->data; + status = switch_pd_qos_map_egress_entry_delete( + device, + qos_map_list_info->map_type.egress_map_type, + qos_map_info->pd_hdl); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("qos map deleted failed: egress"); + } + next_node = node->next; + tommy_list_remove_existing(&qos_map_list_info->qos_map_list, node); + switch_free(qos_map_info); + node = next_node; + } + + switch_api_id_allocator_release(egress_qos_map_id, + qos_map_list_info->qos_group); + + status = switch_qos_map_handle_delete(qos_map_handle); + return status; +} + +#ifdef __cplusplus +} +#endif diff --git a/switchapi/src/switch_qos_int.h b/switchapi/src/switch_qos_int.h new file mode 100644 index 0000000..fdf82ce --- /dev/null +++ b/switchapi/src/switch_qos_int.h @@ -0,0 +1,54 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_qos_int_h_ +#define _switch_qos_int_h_ + +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_qos.h" +#include "switch_pd_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SWITCH_QOS_DEFAULT_TC 0 + +typedef struct switch_qos_map_info_ { + tommy_node node; + switch_qos_map_t qos_map; + p4_pd_entry_hdl_t pd_hdl; +} switch_qos_map_info_t; + +typedef struct switch_qos_map_list_ { + tommy_list qos_map_list; + switch_qos_group_t qos_group; + switch_direction_t direction; + union { + switch_qos_map_ingress_t ingress_map_type; + switch_qos_map_egress_t egress_map_type; + } map_type; +} switch_qos_map_list_t; + +switch_status_t switch_qos_init(switch_device_t device); + +switch_qos_map_list_t *switch_qos_map_get(switch_handle_t qos_map_handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/src/switch_queue.c b/switchapi/src/switch_queue.c new file mode 100644 index 0000000..c756404 --- /dev/null +++ b/switchapi/src/switch_queue.c @@ -0,0 +1,219 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_status.h" +#include "switchapi/switch_utils.h" +#include "switch_pd.h" +#include "switch_log_int.h" +#include "switch_defines.h" +#include "switch_queue_int.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static void *switch_queue_array; + +switch_status_t switch_queue_init(switch_device_t device) { + switch_queue_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_QUEUE, 256 * 32); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_queue_handle_create() { + switch_handle_t queue_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_QUEUE, + switch_queue_info_t, + switch_queue_array, + NULL, + queue_handle); + return queue_handle; +} + +switch_queue_info_t *switch_queue_info_get(switch_handle_t queue_handle) { + switch_queue_info_t *queue_info = NULL; + _switch_handle_get( + switch_queue_info_t, switch_queue_array, queue_handle, queue_info); + return queue_info; +} + +switch_status_t switch_queue_handle_delete(switch_handle_t queue_handle) { + _switch_handle_delete(switch_queue_info_t, switch_queue_array, queue_handle); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_queue_allocate(switch_device_t device, + switch_handle_t port_handle, + uint32_t *num_queues, + switch_handle_t *queue_handles) { + switch_port_info_t *port_info = NULL; + switch_queue_info_t *queue_info = NULL; + switch_handle_t queue_handle = 0; + uint32_t index = 0; + uint8_t queue_mapping[SWITCH_MAX_QUEUE]; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + for (index = 0; index < port_info->max_queues; index++) { + queue_handle = switch_queue_handle_create(); + queue_info = switch_queue_info_get(queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("failed to allocate queue"); + return SWITCH_STATUS_NO_MEMORY; + } + queue_info->port_handle = port_handle; + queue_info->queue_id = index; + queue_handles[index] = queue_handle; + port_info->queue_handles[index] = queue_handle; + queue_mapping[index] = queue_info->queue_id; + } + *num_queues = port_info->max_queues; + status = switch_pd_queue_port_mapping( + device, port_handle, *num_queues, queue_mapping); + return status; +} + +switch_status_t switch_api_queue_deallocate(switch_device_t device, + uint32_t num_queues, + switch_handle_t *queue_handles) { + switch_port_info_t *port_info = NULL; + switch_queue_info_t *queue_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t index = 0; + + for (index = 0; index < num_queues; index++) { + queue_info = switch_queue_info_get(queue_handles[index]); + if (!queue_info) { + SWITCH_API_ERROR("invalid handle for queue deallocate"); + return SWITCH_STATUS_INVALID_HANDLE; + } + port_info = switch_api_port_get_internal(queue_info->port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + } + + port_info->queue_handles[index] = 0; + status = switch_queue_handle_delete(queue_handles[index]); + } + return status; +} + +switch_status_t switch_api_queues_get(switch_device_t device, + switch_handle_t port_handle, + uint32_t *num_queues, + switch_handle_t *queue_handles) { + switch_port_info_t *port_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t index = 0; + + port_info = switch_api_port_get_internal(port_handle); + if (!port_info) { + SWITCH_API_ERROR("invalid port handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + for (index = 0; index < port_info->max_queues; index++) { + queue_handles[index] = port_info->queue_handles[index]; + } + *num_queues = port_info->max_queues; + + return status; +} + +switch_status_t switch_api_queue_color_drop_enable(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + bool enable) { + switch_queue_info_t *queue_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + queue_info = switch_queue_info_get(queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("invalid queue handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_queue_color_drop_enable( + device, port_handle, queue_info->queue_id, enable); + return status; +} + +switch_status_t switch_api_queue_color_limit_set(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + switch_color_t color, + uint32_t limit) { + switch_queue_info_t *queue_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + queue_info = switch_queue_info_get(queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("invalid queue handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_queue_color_limit_set( + device, port_handle, queue_info->queue_id, color, limit); + return status; +} + +switch_status_t switch_api_queue_color_hysteresis_set( + switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + switch_color_t color, + uint32_t limit) { + switch_queue_info_t *queue_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + queue_info = switch_queue_info_get(queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("invalid queue handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_queue_color_hysteresis_set( + device, port_handle, queue_info->queue_id, color, limit); + return status; +} + +switch_status_t switch_api_queue_pfc_cos_mapping(switch_device_t device, + switch_handle_t port_handle, + switch_handle_t queue_handle, + uint8_t cos) { + switch_queue_info_t *queue_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + queue_info = switch_queue_info_get(queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("invalid queue handle"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_queue_pfc_cos_mapping( + device, port_handle, queue_info->queue_id, cos); + return status; +} + +#ifdef __cplusplus +} +#endif diff --git a/switchapi/src/switch_queue_int.h b/switchapi/src/switch_queue_int.h new file mode 100644 index 0000000..86ae4d7 --- /dev/null +++ b/switchapi/src/switch_queue_int.h @@ -0,0 +1,47 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_queue_int_h_ +#define _switch_queue_int_h_ + +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_queue.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct switch_queue_info_ { + tommy_node node; + switch_handle_t port_handle; + switch_handle_t buffer_profile_handle; + switch_qid_t queue_id; +} switch_queue_info_t; + +typedef struct switch_port_queue_info_ { + tommy_list queue_handles; + switch_api_id_allocator *queue_id_bmp; +} switch_port_queue_info_t; + +switch_queue_info_t *switch_queue_info_get(switch_handle_t queue_handle); + +switch_status_t switch_queue_init(switch_device_t device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/src/switch_rmac.c b/switchapi/src/switch_rmac.c index 177cce7..29b74f7 100644 --- a/switchapi/src/switch_rmac.c +++ b/switchapi/src/switch_rmac.c @@ -26,7 +26,7 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - + static void *switch_rmac_array; static tommy_hashtable smac_rewrite_table; switch_api_id_allocator *smac_rewrite_index_allocator = NULL; @@ -38,16 +38,18 @@ switch_api_id_allocator *smac_rewrite_index_allocator = NULL; * Creates a RMAC Group * @return: Returns rmac group id if success */ -switch_handle_t -switch_api_router_mac_group_create(switch_device_t device) -{ - switch_rmac_info_t *rmac_info = NULL; - switch_handle_t rmac_handle; - - _switch_handle_create(SWITCH_HANDLE_TYPE_MY_MAC, switch_rmac_info_t, switch_rmac_array, NULL, rmac_handle); - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - tommy_list_init(&(rmac_info->rmac_list)); - return rmac_handle; +switch_handle_t switch_api_router_mac_group_create(switch_device_t device) { + switch_rmac_info_t *rmac_info = NULL; + switch_handle_t rmac_handle; + + _switch_handle_create(SWITCH_HANDLE_TYPE_MY_MAC, + switch_rmac_info_t, + switch_rmac_array, + NULL, + rmac_handle); + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + tommy_list_init(&(rmac_info->rmac_list)); + return rmac_handle; } /* @@ -56,23 +58,22 @@ switch_api_router_mac_group_create(switch_device_t device) * @param - RMAC id that has to be deleted * @return - Returns rmac group id if success */ -switch_status_t -switch_api_router_mac_group_delete(switch_device_t device, switch_handle_t rmac_handle) -{ - switch_rmac_info_t *rmac_info = NULL; - - if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - if (!rmac_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - //TODO: cleanup all the router macs - _switch_handle_delete(switch_rmac_info_t, switch_rmac_array, rmac_handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_router_mac_group_delete( + switch_device_t device, switch_handle_t rmac_handle) { + switch_rmac_info_t *rmac_info = NULL; + + if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + if (!rmac_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + // TODO: cleanup all the router macs + _switch_handle_delete(switch_rmac_info_t, switch_rmac_array, rmac_handle); + return SWITCH_STATUS_SUCCESS; } /* @@ -83,61 +84,60 @@ switch_api_router_mac_group_delete(switch_device_t device, switch_handle_t rmac_ * @param mac - Router mac address to be added to the group * @return: Returns success if mac is added successfully */ -switch_status_t -switch_api_router_mac_add(switch_device_t device, switch_handle_t rmac_handle, switch_mac_addr_t *mac) -{ - switch_rmac_info_t *rmac_info = NULL; - switch_rmac_entry_t *rmac_entry = NULL; - tommy_node *node = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - if (!rmac_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - node = tommy_list_head(&(rmac_info->rmac_list)); - while (node) { - rmac_entry = node->data; - if (memcmp(&(rmac_entry->mac), mac, sizeof(switch_mac_addr_t)) == 0) { - return SWITCH_STATUS_SUCCESS; - } - node = node->next; - } - rmac_entry = switch_malloc(sizeof(switch_rmac_entry_t), 1); - if (!rmac_entry) { - return SWITCH_STATUS_NO_MEMORY; - } - memcpy(&rmac_entry->mac, mac, sizeof(switch_mac_addr_t)); - tommy_list_insert_head(&(rmac_info->rmac_list), &(rmac_entry->node), rmac_entry); - status = switch_smac_rewrite_add_entry(mac); - if (status != SWITCH_STATUS_SUCCESS) { - printf("MAC rewrite table add failed with error code %d\n", status); - return status; +switch_status_t switch_api_router_mac_add(switch_device_t device, + switch_handle_t rmac_handle, + switch_mac_addr_t *mac) { + switch_rmac_info_t *rmac_info = NULL; + switch_rmac_entry_t *rmac_entry = NULL; + tommy_node *node = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + if (!rmac_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + node = tommy_list_head(&(rmac_info->rmac_list)); + while (node) { + rmac_entry = node->data; + if (memcmp(&(rmac_entry->mac), mac, sizeof(switch_mac_addr_t)) == 0) { + return SWITCH_STATUS_SUCCESS; } + node = node->next; + } + rmac_entry = switch_malloc(sizeof(switch_rmac_entry_t), 1); + if (!rmac_entry) { + return SWITCH_STATUS_NO_MEMORY; + } + memcpy(&rmac_entry->mac, mac, sizeof(switch_mac_addr_t)); + tommy_list_insert_head( + &(rmac_info->rmac_list), &(rmac_entry->node), rmac_entry); + status = switch_smac_rewrite_add_entry(mac); + if (status != SWITCH_STATUS_SUCCESS) { + printf("MAC rewrite table add failed with error code %d\n", status); + return status; + } #ifdef SWITCH_PD - - status = switch_pd_inner_rmac_table_add_entry(device, - handle_to_id(rmac_handle), mac, - &rmac_entry->inner_rmac_entry); - if(status != SWITCH_STATUS_SUCCESS) { - printf("Inner RMAC table add failed with error code %d\n", status); - return status; - } - status = switch_pd_outer_rmac_table_add_entry(device, - handle_to_id(rmac_handle), mac, - &rmac_entry->outer_rmac_entry); - if(status != SWITCH_STATUS_SUCCESS) { - printf("Outer RMAC table add failed with error code %d\n", status); - } + status = switch_pd_inner_rmac_table_add_entry( + device, handle_to_id(rmac_handle), mac, &rmac_entry->inner_rmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + printf("Inner RMAC table add failed with error code %d\n", status); + return status; + } + + status = switch_pd_outer_rmac_table_add_entry( + device, handle_to_id(rmac_handle), mac, &rmac_entry->outer_rmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { + printf("Outer RMAC table add failed with error code %d\n", status); + } #endif - return status; + return status; } - + /* * @function: switch_api_router_mac_delete * Add Router mac to rmac group @@ -146,144 +146,144 @@ switch_api_router_mac_add(switch_device_t device, switch_handle_t rmac_handle, s * @param mac - Router mac address to be removed from the group * @return: Returns success if mac is deleted successfully */ -switch_status_t -switch_api_router_mac_delete(switch_device_t device, switch_handle_t rmac_handle, switch_mac_addr_t *mac) -{ - switch_rmac_info_t *rmac_info = NULL; - switch_rmac_entry_t *rmac_entry = NULL; - tommy_node *node = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - if (!rmac_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; +switch_status_t switch_api_router_mac_delete(switch_device_t device, + switch_handle_t rmac_handle, + switch_mac_addr_t *mac) { + switch_rmac_info_t *rmac_info = NULL; + switch_rmac_entry_t *rmac_entry = NULL; + tommy_node *node = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + if (!rmac_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + node = tommy_list_head(&(rmac_info->rmac_list)); + while (node) { + rmac_entry = node->data; + if (memcmp(&(rmac_entry->mac), mac, sizeof(switch_mac_addr_t)) == 0) { + break; } - - node = tommy_list_head(&(rmac_info->rmac_list)); - while (node) { - rmac_entry = node->data; - if (memcmp(&(rmac_entry->mac), mac, sizeof(switch_mac_addr_t)) == 0) { - break; - } - node = node->next; - } - if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - switch_smac_rewrite_delete_entry(mac); - rmac_entry = tommy_list_remove_existing(&(rmac_info->rmac_list), node); + node = node->next; + } + if (!node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + switch_smac_rewrite_delete_entry(mac); + rmac_entry = tommy_list_remove_existing(&(rmac_info->rmac_list), node); #ifdef SWITCH_PD - status = switch_pd_outer_rmac_table_delete_entry(device, rmac_entry->outer_rmac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - status = switch_pd_inner_rmac_table_delete_entry(device, rmac_entry->inner_rmac_entry); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } -#endif - free(rmac_entry); + status = switch_pd_outer_rmac_table_delete_entry( + device, rmac_entry->outer_rmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { return status; -} - -switch_status_t -switch_api_interface_router_mac_handle_set(switch_handle_t intf_handle, uint64_t value) -{ - - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_intf_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_rmac_info_t *rmac_info = NULL; - switch_handle_t rmac_handle = 0; - switch_handle_t bd_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - api_intf_info = &intf_info->api_intf_info; - if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - rmac_handle = (switch_handle_t) value; - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - if (!rmac_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - bd_handle = intf_info->bd_handle; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - api_intf_info->rmac_handle = rmac_handle; - status = switch_bd_router_mac_handle_set(bd_handle, rmac_handle); + } + status = switch_pd_inner_rmac_table_delete_entry( + device, rmac_entry->inner_rmac_entry); + if (status != SWITCH_STATUS_SUCCESS) { return status; + } +#endif + free(rmac_entry); + return status; } -switch_status_t -switch_api_interface_router_mac_handle_get(switch_handle_t intf_handle, uint64_t *value) -{ - switch_interface_info_t *intf_info = NULL; - switch_api_interface_info_t *api_intf_info = NULL; +switch_status_t switch_api_interface_router_mac_handle_set( + switch_handle_t intf_handle, uint64_t value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_intf_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_rmac_info_t *rmac_info = NULL; + switch_handle_t rmac_handle = 0; + switch_handle_t bd_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + api_intf_info = &intf_info->api_intf_info; + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + rmac_handle = (switch_handle_t)value; + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + if (!rmac_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + bd_handle = intf_info->bd_handle; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + api_intf_info->rmac_handle = rmac_handle; + status = switch_bd_router_mac_handle_set(bd_handle, rmac_handle); + return status; +} - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - api_intf_info = &intf_info->api_intf_info; - *value = (uint64_t)(api_intf_info->rmac_handle); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_interface_router_mac_handle_get( + switch_handle_t intf_handle, uint64_t *value) { + switch_interface_info_t *intf_info = NULL; + switch_api_interface_info_t *api_intf_info = NULL; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + api_intf_info = &intf_info->api_intf_info; + *value = (uint64_t)(api_intf_info->rmac_handle); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_router_mac_group_print_entry(switch_handle_t rmac_handle) -{ - switch_rmac_info_t *rmac_info = NULL; - switch_rmac_entry_t *rmac_entry = NULL; - tommy_node *node = NULL; - switch_mac_addr_t *mac = NULL; - - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - if (!rmac_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - printf("\n\nrmac_handle %x", (unsigned int) rmac_handle); - node = tommy_list_head(&(rmac_info->rmac_list)); - while (node) { - rmac_entry = node->data; - mac = &rmac_entry->mac; - printf("\n\t mac %02x:%02x:%02x:%02x:%02x:%02x", - mac->mac_addr[0], mac->mac_addr[1], mac->mac_addr[2], - mac->mac_addr[3], mac->mac_addr[4], mac->mac_addr[5]); - node = node->next; - } - printf("\n"); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_router_mac_group_print_entry( + switch_handle_t rmac_handle) { + switch_rmac_info_t *rmac_info = NULL; + switch_rmac_entry_t *rmac_entry = NULL; + tommy_node *node = NULL; + switch_mac_addr_t *mac = NULL; + + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + if (!rmac_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + printf("\n\nrmac_handle %x", (unsigned int)rmac_handle); + node = tommy_list_head(&(rmac_info->rmac_list)); + while (node) { + rmac_entry = node->data; + mac = &rmac_entry->mac; + printf("\n\t mac %02x:%02x:%02x:%02x:%02x:%02x", + mac->mac_addr[0], + mac->mac_addr[1], + mac->mac_addr[2], + mac->mac_addr[3], + mac->mac_addr[4], + mac->mac_addr[5]); + node = node->next; + } + printf("\n"); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_router_mac_group_print_all(void) -{ - switch_handle_t rmac_handle = 0; - switch_handle_t next_rmac_handle = 0; - - switch_handle_get_first(switch_rmac_array, rmac_handle); - while (rmac_handle) { - switch_api_router_mac_group_print_entry(rmac_handle); - switch_handle_get_next(switch_rmac_array, rmac_handle, next_rmac_handle); - rmac_handle = next_rmac_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_router_mac_group_print_all(void) { + switch_handle_t rmac_handle = 0; + switch_handle_t next_rmac_handle = 0; + + switch_handle_get_first(switch_rmac_array, rmac_handle); + while (rmac_handle) { + switch_api_router_mac_group_print_entry(rmac_handle); + switch_handle_get_next(switch_rmac_array, rmac_handle, next_rmac_handle); + rmac_handle = next_rmac_handle; + } + return SWITCH_STATUS_SUCCESS; } // End of Router MAC API's @@ -293,170 +293,159 @@ switch_api_router_mac_group_print_all(void) * These API's will be used intenrally in SDK to manage * the rmac groups */ -switch_status_t -switch_router_mac_init(switch_device_t device) -{ - p4_pd_entry_hdl_t smac_hdl = 0; - switch_mac_addr_t temp_mac; - - unsigned char mac[ETH_LEN] = {0x00, 0x77, 0x66, 0x55, 0x44, 0x33}; - - switch_rmac_array = NULL; - //switch_pd_mac_rewrite_table_add_entry(device, smac_idx, mac); - tommy_hashtable_init(&smac_rewrite_table, SWITCH_SMAC_REWRITE_HASH_TABLE_SIZE); - smac_rewrite_index_allocator = switch_api_id_allocator_new(SWITCH_SMAC_REWRITE_HASH_TABLE_SIZE, TRUE); - switch_handle_type_init(SWITCH_HANDLE_TYPE_MY_MAC, (512)); - memcpy(&temp_mac.mac_addr, &mac, ETH_LEN); - switch_pd_tunnel_smac_rewrite_table_add_entry(0, 1, &temp_mac, &smac_hdl); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_router_mac_free(switch_device_t device) -{ - tommy_hashtable_done(&smac_rewrite_table); - switch_handle_type_free(SWITCH_HANDLE_TYPE_MY_MAC); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_router_mac_init(switch_device_t device) { + p4_pd_entry_hdl_t smac_hdl = 0; + switch_mac_addr_t temp_mac; + + unsigned char mac[ETH_LEN] = {0x00, 0x77, 0x66, 0x55, 0x44, 0x33}; + + switch_rmac_array = NULL; + // switch_pd_mac_rewrite_table_add_entry(device, smac_idx, mac); + tommy_hashtable_init(&smac_rewrite_table, + SWITCH_SMAC_REWRITE_HASH_TABLE_SIZE); + smac_rewrite_index_allocator = + switch_api_id_allocator_new(SWITCH_SMAC_REWRITE_HASH_TABLE_SIZE, TRUE); + switch_handle_type_init(SWITCH_HANDLE_TYPE_MY_MAC, (512)); + memcpy(&temp_mac.mac_addr, &mac, ETH_LEN); + switch_pd_tunnel_smac_rewrite_table_add_entry(0, 1, &temp_mac, &smac_hdl); + return SWITCH_STATUS_SUCCESS; } -switch_rmac_info_t * -switch_api_rmac_info_get_internal(switch_handle_t rmac_handle) -{ - switch_rmac_info_t *rmac_info = NULL; - _switch_handle_get(switch_rmac_info_t, switch_rmac_array, rmac_handle, rmac_info); - return rmac_info; +switch_status_t switch_router_mac_free(switch_device_t device) { + tommy_hashtable_done(&smac_rewrite_table); + switch_handle_type_free(SWITCH_HANDLE_TYPE_MY_MAC); + return SWITCH_STATUS_SUCCESS; } -static void -switch_smac_rewrite_hash_key_init(uchar *key, switch_mac_addr_t *mac, - uint32_t *len, uint32_t *hash) -{ - *len=0; - memset(key, 0, ETH_LEN); - memcpy(key, mac, ETH_LEN); - *len = ETH_LEN; - *hash = MurmurHash2(key, *len, 0x98761234); +switch_rmac_info_t *switch_api_rmac_info_get_internal( + switch_handle_t rmac_handle) { + switch_rmac_info_t *rmac_info = NULL; + _switch_handle_get( + switch_rmac_info_t, switch_rmac_array, rmac_handle, rmac_info); + return rmac_info; } -static inline int -switch_smac_rewrite_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, ETH_LEN); +static void switch_smac_rewrite_hash_key_init(uchar *key, + switch_mac_addr_t *mac, + uint32_t *len, + uint32_t *hash) { + *len = 0; + memset(key, 0, ETH_LEN); + memcpy(key, mac, ETH_LEN); + *len = ETH_LEN; + *hash = MurmurHash2(key, *len, 0x98761234); } -static void -switch_smac_rewrite_hash_insert(switch_smac_entry_t *smac_entry) -{ - unsigned char key[ETH_LEN]; - unsigned int len = 0; - uint32_t hash; - - switch_smac_rewrite_hash_key_init(key, &smac_entry->mac, &len, &hash); - tommy_hashtable_insert(&smac_rewrite_table, &(smac_entry->node), smac_entry, hash); +static inline int switch_smac_rewrite_hash_cmp(const void *key1, + const void *key2) { + return memcmp(key1, key2, ETH_LEN); } -static void -switch_smac_rewrite_hash_delete(switch_smac_entry_t *smac_entry) -{ - unsigned char key[ETH_LEN]; - uint32_t hash = 0; - unsigned int len = 0; +static void switch_smac_rewrite_hash_insert(switch_smac_entry_t *smac_entry) { + unsigned char key[ETH_LEN]; + unsigned int len = 0; + uint32_t hash; - switch_smac_rewrite_hash_key_init(key, &smac_entry->mac, &len, &hash); - tommy_hashtable_remove(&smac_rewrite_table, switch_smac_rewrite_hash_cmp, key, hash); + switch_smac_rewrite_hash_key_init(key, &smac_entry->mac, &len, &hash); + tommy_hashtable_insert( + &smac_rewrite_table, &(smac_entry->node), smac_entry, hash); } +static void switch_smac_rewrite_hash_delete(switch_smac_entry_t *smac_entry) { + unsigned char key[ETH_LEN]; + uint32_t hash = 0; + unsigned int len = 0; -static switch_smac_entry_t * -switch_smac_rewrite_search_entry(switch_mac_addr_t *mac) -{ - switch_smac_entry_t *smac_entry = NULL; - unsigned char key[ETH_LEN]; - unsigned int len = 0; - uint32_t hash; + switch_smac_rewrite_hash_key_init(key, &smac_entry->mac, &len, &hash); + tommy_hashtable_remove( + &smac_rewrite_table, switch_smac_rewrite_hash_cmp, key, hash); +} - switch_smac_rewrite_hash_key_init(key, mac, &len, &hash); - smac_entry = tommy_hashtable_search(&smac_rewrite_table, switch_smac_rewrite_hash_cmp, key, hash); - return smac_entry; +static switch_smac_entry_t *switch_smac_rewrite_search_entry( + switch_mac_addr_t *mac) { + switch_smac_entry_t *smac_entry = NULL; + unsigned char key[ETH_LEN]; + unsigned int len = 0; + uint32_t hash; + + switch_smac_rewrite_hash_key_init(key, mac, &len, &hash); + smac_entry = tommy_hashtable_search( + &smac_rewrite_table, switch_smac_rewrite_hash_cmp, key, hash); + return smac_entry; } -uint16_t -switch_smac_rewrite_index_from_rmac(switch_handle_t rmac_handle) -{ - switch_rmac_info_t *rmac_info = NULL; - switch_rmac_entry_t *rmac_entry = NULL; - tommy_node *node = NULL; - switch_mac_addr_t *mac = NULL; - uint16_t smac_index = 0; - switch_smac_entry_t *smac_entry = NULL; - - rmac_info = switch_api_rmac_info_get_internal(rmac_handle); - if (!rmac_info) { - return smac_index; - } +uint16_t switch_smac_rewrite_index_from_rmac(switch_handle_t rmac_handle) { + switch_rmac_info_t *rmac_info = NULL; + switch_rmac_entry_t *rmac_entry = NULL; + tommy_node *node = NULL; + switch_mac_addr_t *mac = NULL; + uint16_t smac_index = 0; + switch_smac_entry_t *smac_entry = NULL; - node = tommy_list_head(&(rmac_info->rmac_list)); - while (node) { - rmac_entry = node->data; - mac = &rmac_entry->mac; - smac_entry = switch_smac_rewrite_search_entry(mac); - if (smac_entry) { - smac_index = smac_entry->smac_index; - break; - } - node = node->next; - } + rmac_info = switch_api_rmac_info_get_internal(rmac_handle); + if (!rmac_info) { return smac_index; -} - -switch_status_t -switch_smac_rewrite_add_entry(switch_mac_addr_t *mac) -{ - switch_smac_entry_t *smac_entry = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint16_t smac_index = 0; - switch_device_t device = SWITCH_DEV_ID; + } + node = tommy_list_head(&(rmac_info->rmac_list)); + while (node) { + rmac_entry = node->data; + mac = &rmac_entry->mac; smac_entry = switch_smac_rewrite_search_entry(mac); if (smac_entry) { - smac_entry->ref_count++; - return SWITCH_STATUS_SUCCESS; - } - smac_entry = switch_malloc(sizeof(switch_smac_entry_t), 1); - if (!smac_entry) { - return SWITCH_STATUS_NO_MEMORY; + smac_index = smac_entry->smac_index; + break; } - memset(smac_entry, 0, sizeof(switch_smac_entry_t)); - smac_index = switch_api_id_allocator_allocate(smac_rewrite_index_allocator); - memcpy(&smac_entry->mac, mac, ETH_LEN); - smac_entry->smac_index = smac_index; - smac_entry->ref_count = 1; - switch_smac_rewrite_hash_insert(smac_entry); - status = switch_pd_smac_rewrite_table_add_entry(device, smac_entry); - return status; + node = node->next; + } + return smac_index; } -switch_status_t -switch_smac_rewrite_delete_entry(switch_mac_addr_t *mac) -{ - switch_smac_entry_t *smac_entry = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_smac_rewrite_add_entry(switch_mac_addr_t *mac) { + switch_smac_entry_t *smac_entry = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint16_t smac_index = 0; + switch_device_t device = SWITCH_DEV_ID; - smac_entry = switch_smac_rewrite_search_entry(mac); - if (!smac_entry) { - SWITCH_API_ERROR("%s:%d: unable to find mac!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_ITEM_NOT_FOUND; - } + smac_entry = switch_smac_rewrite_search_entry(mac); + if (smac_entry) { + smac_entry->ref_count++; + return SWITCH_STATUS_SUCCESS; + } + smac_entry = switch_malloc(sizeof(switch_smac_entry_t), 1); + if (!smac_entry) { + return SWITCH_STATUS_NO_MEMORY; + } + memset(smac_entry, 0, sizeof(switch_smac_entry_t)); + smac_index = switch_api_id_allocator_allocate(smac_rewrite_index_allocator); + memcpy(&smac_entry->mac, mac, ETH_LEN); + smac_entry->smac_index = smac_index; + smac_entry->ref_count = 1; + switch_smac_rewrite_hash_insert(smac_entry); + status = switch_pd_smac_rewrite_table_add_entry(device, smac_entry); + return status; +} - smac_entry->ref_count--; - if (smac_entry->ref_count == 0) { - switch_pd_smac_rewrite_table_delete_entry(device, smac_entry); - switch_smac_rewrite_hash_delete(smac_entry); - switch_api_id_allocator_release(smac_rewrite_index_allocator, smac_entry->smac_index); - free(smac_entry); - } - return status; +switch_status_t switch_smac_rewrite_delete_entry(switch_mac_addr_t *mac) { + switch_smac_entry_t *smac_entry = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + smac_entry = switch_smac_rewrite_search_entry(mac); + if (!smac_entry) { + SWITCH_API_ERROR("%s:%d: unable to find mac!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + smac_entry->ref_count--; + if (smac_entry->ref_count == 0) { + switch_pd_smac_rewrite_table_delete_entry(device, smac_entry); + switch_smac_rewrite_hash_delete(smac_entry); + switch_api_id_allocator_release(smac_rewrite_index_allocator, + smac_entry->smac_index); + free(smac_entry); + } + return status; } #ifdef __cplusplus diff --git a/switchapi/src/switch_rmac_int.h b/switchapi/src/switch_rmac_int.h index 4926080..f2016d2 100644 --- a/switchapi/src/switch_rmac_int.h +++ b/switchapi/src/switch_rmac_int.h @@ -15,6 +15,7 @@ limitations under the License. */ #include +#include "switch_pd_types.h" #ifndef _switch_rmac_int_h_ #define _switch_rmac_int_h_ @@ -26,32 +27,31 @@ extern "C" { #define SWITCH_SMAC_REWRITE_HASH_TABLE_SIZE 1024 typedef struct switch_rmac_node_ { - switch_mac_addr_t mac; - tommy_node node; + switch_mac_addr_t mac; + tommy_node node; #ifdef SWITCH_PD - p4_pd_entry_hdl_t outer_rmac_entry; - p4_pd_entry_hdl_t inner_rmac_entry; + p4_pd_entry_hdl_t outer_rmac_entry; + p4_pd_entry_hdl_t inner_rmac_entry; #endif } switch_rmac_entry_t; -typedef struct switch_rmac_info_ { - tommy_list rmac_list; -} switch_rmac_info_t; +typedef struct switch_rmac_info_ { tommy_list rmac_list; } switch_rmac_info_t; typedef struct switch_smac_entry_ { - switch_mac_addr_t mac; - uint16_t smac_index; - uint16_t ref_count; - tommy_hashtable_node node; + switch_mac_addr_t mac; + uint16_t smac_index; + uint16_t ref_count; + tommy_hashtable_node node; #ifdef SWITCH_PD - p4_pd_entry_hdl_t hw_smac_entry; + p4_pd_entry_hdl_t hw_smac_entry; #endif } switch_smac_entry_t; // Internal API Declarations switch_status_t switch_router_mac_init(switch_device_t device); switch_status_t switch_router_mac_free(switch_device_t device); -switch_rmac_info_t * switch_api_rmac_info_get_internal(switch_handle_t rmac_handle); +switch_rmac_info_t *switch_api_rmac_info_get_internal( + switch_handle_t rmac_handle); switch_status_t switch_smac_rewrite_add_entry(switch_mac_addr_t *mac); switch_status_t switch_smac_rewrite_delete_entry(switch_mac_addr_t *mac); diff --git a/switchapi/src/switch_scheduler.c b/switchapi/src/switch_scheduler.c new file mode 100644 index 0000000..945ec16 --- /dev/null +++ b/switchapi/src/switch_scheduler.c @@ -0,0 +1,324 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_status.h" +#include "switchapi/switch_utils.h" +#include "switch_scheduler_int.h" +#include "switch_pd.h" +#include "switch_queue_int.h" +#include "switch_log_int.h" +#include "switch_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +static void *switch_scheduler_array; + +switch_status_t switch_scheduler_init(switch_device_t device) { + switch_scheduler_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_SCHEDULER, 128); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_scheduler_handle_create() { + switch_handle_t scheduler_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_SCHEDULER, + switch_scheduler_info_t, + switch_scheduler_array, + NULL, + scheduler_handle); + return scheduler_handle; +} + +switch_scheduler_info_t *switch_scheduler_info_get( + switch_handle_t scheduler_handle) { + switch_scheduler_info_t *scheduler_info = NULL; + _switch_handle_get(switch_scheduler_info_t, + switch_scheduler_array, + scheduler_handle, + scheduler_info); + return scheduler_info; +} + +switch_status_t switch_scheduler_handle_delete( + switch_handle_t scheduler_handle) { + _switch_handle_delete( + switch_scheduler_info_t, switch_scheduler_array, scheduler_handle); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_api_scheduler_create( + switch_device_t device, switch_scheduler_info_t *scheduler_info) { + switch_handle_t scheduler_handle = 0; + switch_scheduler_info_t *scheduler_info_tmp = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + scheduler_handle = switch_scheduler_handle_create(); + scheduler_info_tmp = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info_tmp) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + memcpy(scheduler_info_tmp, scheduler_info, sizeof(switch_scheduler_info_t)); + + status = switch_api_queue_scheduling_enable(device, scheduler_handle, TRUE); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_api_queue_scheduling_strict_priority_set( + device, scheduler_handle, scheduler_info->priority); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_api_queue_scheduling_remaining_bw_priority_set( + device, scheduler_handle, scheduler_info->rem_bw_priority); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_api_queue_scheduling_dwrr_weight_set( + device, scheduler_handle, scheduler_info->weight); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_api_queue_scheduling_guaranteed_shaping_set( + device, + scheduler_handle, + scheduler_info->shaper_type == SWITCH_METER_TYPE_PACKETS ? TRUE : FALSE, + scheduler_info->min_burst_size, + scheduler_info->min_rate); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_api_queue_scheduling_dwrr_shaping_set( + device, + scheduler_handle, + scheduler_info->shaper_type == SWITCH_METER_TYPE_PACKETS ? TRUE : FALSE, + scheduler_info->max_burst_size, + scheduler_info->max_rate); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + return scheduler_handle; +} + +switch_status_t switch_api_scheduler_update( + switch_device_t device, + switch_handle_t scheduler_handle, + switch_scheduler_info_t *scheduler_info) { + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_scheduler_delete(switch_device_t device, + switch_handle_t scheduler_handle) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("scheduler create failed"); + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_scheduler_handle_delete(scheduler_handle); + return status; +} + +switch_status_t switch_api_queue_scheduling_enable( + switch_device_t device, switch_handle_t scheduler_handle, bool enable) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + switch_queue_info_t *queue_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info = switch_queue_info_get(scheduler_info->queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + status = switch_pd_queue_scheduling_enable( + device, queue_info->port_handle, queue_info->queue_id, enable); + return status; +} + +switch_status_t switch_api_queue_scheduling_strict_priority_set( + switch_device_t device, + switch_handle_t scheduler_handle, + uint32_t priority) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + switch_queue_info_t *queue_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info = switch_queue_info_get(scheduler_info->queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + scheduler_info->priority = priority; + + status = switch_pd_queue_scheduling_strict_priority_set( + device, queue_info->port_handle, queue_info->queue_id, priority); + return status; +} + +switch_status_t switch_api_queue_scheduling_remaining_bw_priority_set( + switch_device_t device, + switch_handle_t scheduler_handle, + uint32_t priority) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + switch_queue_info_t *queue_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info = switch_queue_info_get(scheduler_info->queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + scheduler_info->rem_bw_priority = priority; + + status = switch_pd_queue_scheduling_remaining_bw_priority_set( + device, queue_info->port_handle, queue_info->queue_id, priority); + return status; +} + +switch_status_t switch_api_queue_scheduling_dwrr_weight_set( + switch_device_t device, switch_handle_t scheduler_handle, uint16_t weight) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + switch_queue_info_t *queue_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info = switch_queue_info_get(scheduler_info->queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + scheduler_info->weight = weight; + status = switch_pd_queue_scheduling_dwrr_weight_set( + device, queue_info->port_handle, queue_info->queue_id, weight); + return status; +} + +switch_status_t switch_api_queue_scheduling_guaranteed_shaping_set( + switch_device_t device, + switch_handle_t scheduler_handle, + bool pps, + uint32_t burst_size, + uint32_t rate) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + switch_queue_info_t *queue_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info = switch_queue_info_get(scheduler_info->queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + scheduler_info->min_rate = rate; + scheduler_info->min_burst_size = burst_size; + + status = + switch_pd_queue_scheduling_guaranteed_shaping_set(device, + queue_info->port_handle, + queue_info->queue_id, + pps, + burst_size, + rate); + return status; +} + +switch_status_t switch_api_queue_scheduling_dwrr_shaping_set( + switch_device_t device, + switch_handle_t scheduler_handle, + bool pps, + uint32_t burst_size, + uint32_t rate) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_scheduler_info_t *scheduler_info = NULL; + switch_queue_info_t *queue_info = NULL; + + scheduler_info = switch_scheduler_info_get(scheduler_handle); + if (!scheduler_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + queue_info = switch_queue_info_get(scheduler_info->queue_handle); + if (!queue_info) { + SWITCH_API_ERROR("queue scheduling enable failed"); + return SWITCH_STATUS_INVALID_HANDLE; + } + + scheduler_info->max_rate = rate; + scheduler_info->max_burst_size = burst_size; + + status = switch_pd_queue_scheduling_dwrr_shaping_set(device, + queue_info->port_handle, + queue_info->queue_id, + pps, + burst_size, + rate); + return status; +} +#ifdef __cplusplus +} +#endif diff --git a/switchapi/src/switch_scheduler_int.h b/switchapi/src/switch_scheduler_int.h new file mode 100644 index 0000000..d88fcad --- /dev/null +++ b/switchapi/src/switch_scheduler_int.h @@ -0,0 +1,33 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#ifndef _switch_scheduler_int_h_ +#define _switch_scheduler_int_h_ + +#include "switchapi/switch_base_types.h" +#include "switchapi/switch_handle.h" +#include "switchapi/switch_scheduler.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +switch_status_t switch_scheduler_init(switch_device_t device); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/switchapi/src/switch_sflow.c b/switchapi/src/switch_sflow.c index 46d74ae..c111f8f 100644 --- a/switchapi/src/switch_sflow.c +++ b/switchapi/src/switch_sflow.c @@ -1,5 +1,5 @@ /* -Copyright 2016-present Barefoot Networks, Inc. +Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -12,10 +12,8 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - */ - -#include -#include "tommyds/tommy.h" +*/ +#include "assert.h" #include "switchapi/switch_base_types.h" #include "switchapi/switch_status.h" #include "switchapi/switch_mirror.h" @@ -30,380 +28,415 @@ limitations under the License. static void *switch_sflow_array = NULL; static void *switch_sflow_ace_array = NULL; -#endif //P4_SFLOW_ENABLE +#endif // P4_SFLOW_ENABLE -void -switch_sflow_init(switch_device_t device) -{ +void switch_sflow_init(switch_device_t device) { #ifdef P4_SFLOW_ENABLE - switch_sflow_array = NULL; - switch_handle_type_allocator_init(SWITCH_HANDLE_TYPE_SFLOW, - SWITCH_MAX_SFLOW_SESSIONS, - false/*grow*/, false/*zero_based*/); - - switch_sflow_ace_array = NULL; - switch_handle_type_allocator_init(SWITCH_HANDLE_TYPE_SFLOW_ACE, - SWITCH_MAX_SFLOW_ACES, - false/*grow*/, false/*zero_based*/); - return; + switch_sflow_array = NULL; + switch_handle_type_allocator_init(SWITCH_HANDLE_TYPE_SFLOW, + SWITCH_MAX_SFLOW_SESSIONS, + false /*grow*/, + false /*zero_based*/); + + switch_sflow_ace_array = NULL; + switch_handle_type_allocator_init(SWITCH_HANDLE_TYPE_SFLOW_ACE, + SWITCH_MAX_SFLOW_ACES, + false /*grow*/, + false /*zero_based*/); + return; #else - (void)device; -#endif // P4_SFLOW_ENABLE + (void)device; +#endif // P4_SFLOW_ENABLE } #ifdef P4_SFLOW_ENABLE -static switch_handle_t -switch_sflow_handle_create() -{ - switch_handle_t sflow_handle = SWITCH_API_INVALID_HANDLE; - _switch_handle_create(SWITCH_HANDLE_TYPE_SFLOW, - switch_sflow_info_t, - switch_sflow_array, - NULL, sflow_handle); - return sflow_handle; +static switch_handle_t switch_sflow_handle_create() { + switch_handle_t sflow_handle = SWITCH_API_INVALID_HANDLE; + _switch_handle_create(SWITCH_HANDLE_TYPE_SFLOW, + switch_sflow_info_t, + switch_sflow_array, + NULL, + sflow_handle); + return sflow_handle; } -void -switch_sflow_handle_delete(switch_handle_t sflow_handle) -{ - _switch_handle_delete(switch_sflow_info_t, - switch_sflow_array, - sflow_handle); +void switch_sflow_handle_delete(switch_handle_t sflow_handle) { + _switch_handle_delete(switch_sflow_info_t, switch_sflow_array, sflow_handle); } -switch_sflow_info_t * -switch_sflow_info_get(switch_handle_t sflow_handle) -{ - switch_sflow_info_t *sflow_info = NULL; - _switch_handle_get(switch_sflow_info_t, switch_sflow_array, sflow_handle, - sflow_info); - return sflow_info; +switch_sflow_info_t *switch_sflow_info_get(switch_handle_t sflow_handle) { + switch_sflow_info_t *sflow_info = NULL; + _switch_handle_get( + switch_sflow_info_t, switch_sflow_array, sflow_handle, sflow_info); + return sflow_info; } -static switch_handle_t -switch_sflow_ace_handle_create() -{ - switch_handle_t sflow_ace_handle = SWITCH_API_INVALID_HANDLE; - _switch_handle_create(SWITCH_HANDLE_TYPE_SFLOW_ACE, - switch_sflow_match_entry_t, - switch_sflow_ace_array, - NULL, sflow_ace_handle); - return sflow_ace_handle; +static switch_handle_t switch_sflow_ace_handle_create() { + switch_handle_t sflow_ace_handle = SWITCH_API_INVALID_HANDLE; + _switch_handle_create(SWITCH_HANDLE_TYPE_SFLOW_ACE, + switch_sflow_match_entry_t, + switch_sflow_ace_array, + NULL, + sflow_ace_handle); + return sflow_ace_handle; } -void -switch_sflow_ace_handle_delete(switch_handle_t sflow_ace_handle) -{ - _switch_handle_delete(switch_sflow_match_entry_t, - switch_sflow_ace_array, - sflow_ace_handle); +void switch_sflow_ace_handle_delete(switch_handle_t sflow_ace_handle) { + _switch_handle_delete( + switch_sflow_match_entry_t, switch_sflow_ace_array, sflow_ace_handle); } -switch_sflow_match_entry_t * -switch_sflow_ace_entry_get(switch_handle_t sflow_ace_handle) -{ - switch_sflow_match_entry_t *sflow_ace_info = NULL; - _switch_handle_get(switch_sflow_match_entry_t, switch_sflow_ace_array, - sflow_ace_handle, - sflow_ace_info); - return sflow_ace_info; +switch_sflow_match_entry_t *switch_sflow_ace_entry_get( + switch_handle_t sflow_ace_handle) { + switch_sflow_match_entry_t *sflow_ace_info = NULL; + _switch_handle_get(switch_sflow_match_entry_t, + switch_sflow_ace_array, + sflow_ace_handle, + sflow_ace_info); + return sflow_ace_info; } -#endif // P4_SFLOW_ENABLE +#endif // P4_SFLOW_ENABLE -switch_handle_t -switch_api_sflow_session_create (switch_device_t device, - switch_api_sflow_session_info_t *api_sflow_info) -{ +switch_handle_t switch_api_sflow_session_create( + switch_device_t device, switch_api_sflow_session_info_t *api_sflow_info) { #ifdef P4_SFLOW_ENABLE - switch_handle_t sflow_handle = SWITCH_API_INVALID_HANDLE; - switch_sflow_info_t *sflow_info = NULL; - switch_status_t status = SWITCH_STATUS_FAILURE; - - // Parameter validation - if (api_sflow_info->collector_type != SFLOW_COLLECTOR_TYPE_CPU) { - // Only sflow via cpu is supported at this time - return SWITCH_API_INVALID_HANDLE; - } else if (!switch_port_is_cpu_port(api_sflow_info->egress_port_hdl)) { - return SWITCH_API_INVALID_HANDLE; - } - if (api_sflow_info->sample_mode != SWITCH_SFLOW_SAMPLE_PKT) { - // single packet per notificaiton - other modes are TBD - return SWITCH_API_INVALID_HANDLE; - } - if (api_sflow_info->sample_rate == 0) { - return SWITCH_API_INVALID_HANDLE; - } - sflow_handle = switch_sflow_handle_create(); - if (sflow_handle == SWITCH_API_INVALID_HANDLE) { - return sflow_handle; - } - sflow_info = switch_sflow_info_get(sflow_handle); - if (!sflow_info) { - return SWITCH_API_INVALID_HANDLE; - } - sflow_info->session_id = handle_to_id(sflow_handle); - sflow_info->api_info = *api_sflow_info; - tommy_list_init(&sflow_info->match_list); - - sflow_info->mirror_hdl = SWITCH_API_INVALID_HANDLE; - sflow_info->mirror_table_ent_hdl = SWITCH_API_INVALID_HANDLE; - sflow_info->ing_take_sample_table_ent_hdl = SWITCH_API_INVALID_HANDLE; - - // Create a mirror session to send sampled pkts to CPU. - // SWITCH_CPU_MIRROR_SESSION_ID mirror-session can be used, except - // it does not truncate the packet. sFlow may not need entire packet. - // CPU can perform tuncation as well, but this makes it a bit easier - // for CPU - if (api_sflow_info->collector_type == SFLOW_COLLECTOR_TYPE_CPU) { - switch_api_mirror_info_t api_mirror_info; - - memset(&api_mirror_info, 0, sizeof(switch_api_mirror_info_t)); - api_mirror_info.mirror_type = SWITCH_MIRROR_TYPE_LOCAL; - // mirror session id is allocated by the mirroring api - api_mirror_info.session_type = SWITCH_MIRROR_SESSION_TYPE_SIMPLE; - api_mirror_info.egress_port = CPU_PORT_ID; - api_mirror_info.direction = SWITCH_API_DIRECTION_BOTH; - api_mirror_info.max_pkt_len = api_sflow_info->extract_len; - - sflow_info->mirror_hdl = switch_api_mirror_session_create(device, - &api_mirror_info); - if (sflow_info->mirror_hdl == SWITCH_API_INVALID_HANDLE) { - goto error_return; - } - } else { - assert(0); - } + switch_handle_t sflow_handle = SWITCH_API_INVALID_HANDLE; + switch_sflow_info_t *sflow_info = NULL; + switch_status_t status = SWITCH_STATUS_FAILURE; - status = switch_pd_sflow_session_create(device, sflow_info); - if (status != SWITCH_STATUS_SUCCESS) { - goto error_return; - } - + // Parameter validation + if (api_sflow_info->collector_type != SFLOW_COLLECTOR_TYPE_CPU) { + // Only sflow via cpu is supported at this time + return SWITCH_API_INVALID_HANDLE; + } else if (!switch_port_is_cpu_port(api_sflow_info->egress_port_hdl)) { + return SWITCH_API_INVALID_HANDLE; + } + if (api_sflow_info->sample_mode != SWITCH_SFLOW_SAMPLE_PKT) { + // single packet per notificaiton - other modes are TBD + return SWITCH_API_INVALID_HANDLE; + } + if (api_sflow_info->sample_rate == 0) { + return SWITCH_API_INVALID_HANDLE; + } + sflow_handle = switch_sflow_handle_create(); + if (sflow_handle == SWITCH_API_INVALID_HANDLE) { return sflow_handle; + } + sflow_info = switch_sflow_info_get(sflow_handle); + if (!sflow_info) { + return SWITCH_API_INVALID_HANDLE; + } + sflow_info->session_id = handle_to_id(sflow_handle); + sflow_info->api_info = *api_sflow_info; + tommy_list_init(&sflow_info->match_list); + + sflow_info->mirror_hdl = SWITCH_API_INVALID_HANDLE; + sflow_info->mirror_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + sflow_info->ing_take_sample_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + + // Create a mirror session to send sampled pkts to CPU. + // SWITCH_CPU_MIRROR_SESSION_ID mirror-session can be used, except + // it does not truncate the packet. sFlow may not need entire packet. + // CPU can perform tuncation as well, but this makes it a bit easier + // for CPU + if (api_sflow_info->collector_type == SFLOW_COLLECTOR_TYPE_CPU) { + switch_api_mirror_info_t api_mirror_info; + + memset(&api_mirror_info, 0, sizeof(switch_api_mirror_info_t)); + api_mirror_info.mirror_type = SWITCH_MIRROR_TYPE_LOCAL; + // mirror session id is allocated by the mirroring api + api_mirror_info.session_type = SWITCH_MIRROR_SESSION_TYPE_SIMPLE; + api_mirror_info.egress_port = CPU_PORT_ID; + api_mirror_info.direction = SWITCH_API_DIRECTION_BOTH; + api_mirror_info.max_pkt_len = api_sflow_info->extract_len; + + sflow_info->mirror_hdl = + switch_api_mirror_session_create(device, &api_mirror_info); + if (sflow_info->mirror_hdl == SWITCH_API_INVALID_HANDLE) { + goto error_return; + } + } else { + assert(0); + } + + status = switch_pd_sflow_session_create(device, sflow_info); + if (status != SWITCH_STATUS_SUCCESS) { + goto error_return; + } + + return sflow_handle; error_return: - switch_api_sflow_session_delete(device, sflow_handle, false); - return SWITCH_API_INVALID_HANDLE; + switch_api_sflow_session_delete(device, sflow_handle, false); + return SWITCH_API_INVALID_HANDLE; #else - (void)device; (void)api_sflow_info; - return SWITCH_API_INVALID_HANDLE; + (void)device; + (void)api_sflow_info; + return SWITCH_API_INVALID_HANDLE; #endif } -switch_status_t -switch_api_sflow_session_delete (switch_device_t device, - switch_handle_t sflow_hdl, - bool all_cleanup) -{ +switch_status_t switch_api_sflow_session_delete(switch_device_t device, + switch_handle_t sflow_hdl, + bool all_cleanup) { #ifdef P4_SFLOW_ENABLE - switch_sflow_info_t *sflow_info; - - sflow_info = switch_sflow_info_get(sflow_hdl); - if (!sflow_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if (!tommy_list_empty(&sflow_info->match_list) && !all_cleanup) { - return SWITCH_STATUS_RESOURCE_IN_USE; - } - if (all_cleanup) { - switch_sflow_match_entry_t* entry; - tommy_node* node = NULL; - while (node = tommy_list_head(&sflow_info->match_list)) { - entry = (switch_sflow_match_entry_t *) node->data; - // could be ingress or egress match entry - switch_pd_sflow_match_table_delete(device, entry); - tommy_list_remove_existing(&sflow_info->match_list, node); - switch_sflow_ace_handle_delete(entry->sflow_ace_hdl); - } + switch_sflow_info_t *sflow_info; + + sflow_info = switch_sflow_info_get(sflow_hdl); + if (!sflow_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if (!tommy_list_empty(&sflow_info->match_list) && !all_cleanup) { + return SWITCH_STATUS_RESOURCE_IN_USE; + } + if (all_cleanup) { + switch_sflow_match_entry_t *entry; + tommy_node *node = NULL; + while ((node = tommy_list_head(&sflow_info->match_list)) && node) { + entry = (switch_sflow_match_entry_t *)node->data; + // could be ingress or egress match entry + switch_pd_sflow_match_table_delete(device, entry); + tommy_list_remove_existing(&sflow_info->match_list, node); + switch_sflow_ace_handle_delete(entry->sflow_ace_hdl); } + } - switch_pd_sflow_session_delete(device, sflow_info); + switch_pd_sflow_session_delete(device, sflow_info); - if (sflow_info->mirror_hdl != SWITCH_API_INVALID_HANDLE) { - switch_api_mirror_session_delete(device, sflow_info->mirror_hdl); - } + if (sflow_info->mirror_hdl != SWITCH_API_INVALID_HANDLE) { + switch_api_mirror_session_delete(device, sflow_info->mirror_hdl); + } - switch_sflow_handle_delete(sflow_hdl); + switch_sflow_handle_delete(sflow_hdl); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; #else - (void)device; - (void)sflow_hdl; - (void)all_cleanup; - return SWITCH_STATUS_FAILURE; -#endif //P4_SFLOW_ENABLE + (void)device; + (void)sflow_hdl; + (void)all_cleanup; + return SWITCH_STATUS_FAILURE; +#endif // P4_SFLOW_ENABLE } // TBD - sflow_session_update() #ifdef P4_SFLOW_ENABLE -switch_status_t -switch_sflow_match_key_from_tlv (unsigned int key_value_count, - switch_sflow_match_key_value_pair_t *kvp, - switch_sflow_match_key_t *match_key) -{ - unsigned int k; - bool key_found = false; - for (k=0; kport = kvp[k].value.port; - key_found = true; - break; - case SWITCH_SFLOW_MATCH_VLAN: - match_key->vlan = kvp[k].value.vlan; - // key_found = true; - not supported - break; - case SWITCH_SFLOW_MATCH_SIP: - match_key->sip = kvp[k].value.sip; - // no range mask supported - match_key->sip_mask = (uint32_t)kvp[k].mask.u.mask; - key_found = true; - break; - case SWITCH_SFLOW_MATCH_DIP: - match_key->dip = kvp[k].value.dip; - match_key->dip_mask = (uint32_t)kvp[k].mask.u.mask; - key_found = true; - break; - default: assert(0); break; - } - } - if (!key_found) { - return SWITCH_STATUS_INVALID_PARAMETER; +switch_status_t switch_sflow_match_key_from_tlv( + unsigned int key_value_count, + switch_sflow_match_key_value_pair_t *kvp, + switch_sflow_match_key_t *match_key) { + unsigned int k; + bool key_found = false; + for (k = 0; k < key_value_count; k++) { + switch (kvp[k].field) { + case SWITCH_SFLOW_MATCH_PORT: + match_key->port = kvp[k].value.port; + key_found = true; + break; + case SWITCH_SFLOW_MATCH_VLAN: + match_key->vlan = kvp[k].value.vlan; + // key_found = true; - not supported + break; + case SWITCH_SFLOW_MATCH_SIP: + match_key->sip = kvp[k].value.sip; + // no range mask supported + match_key->sip_mask = (uint32_t)kvp[k].mask.u.mask; + key_found = true; + break; + case SWITCH_SFLOW_MATCH_DIP: + match_key->dip = kvp[k].value.dip; + match_key->dip_mask = (uint32_t)kvp[k].mask.u.mask; + key_found = true; + break; + default: + assert(0); + break; } - return SWITCH_STATUS_SUCCESS; + } + if (!key_found) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_sflow_match_entry_remove(switch_sflow_info_t *sflow_info, - switch_handle_t entry_hdl) -{ - tommy_node* node = tommy_list_head(&sflow_info->match_list); - while (node) { - switch_sflow_match_entry_t* obj = - (switch_sflow_match_entry_t *) node->data; - if (obj->sflow_ace_hdl == entry_hdl) { - break; - } - node = node->next; +switch_status_t switch_sflow_match_entry_remove(switch_sflow_info_t *sflow_info, + switch_handle_t entry_hdl) { + tommy_node *node = tommy_list_head(&sflow_info->match_list); + while (node) { + switch_sflow_match_entry_t *obj = (switch_sflow_match_entry_t *)node->data; + if (obj->sflow_ace_hdl == entry_hdl) { + break; } - if (node) { - tommy_list_remove_existing(&sflow_info->match_list, node); - return SWITCH_STATUS_SUCCESS; - } - return SWITCH_STATUS_ITEM_NOT_FOUND; + node = node->next; + } + if (node) { + tommy_list_remove_existing(&sflow_info->match_list, node); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_ITEM_NOT_FOUND; } #endif -switch_status_t -switch_api_sflow_session_attach (switch_device_t device, - switch_handle_t sflow_hdl, - switch_direction_t direction, - unsigned int priority, - unsigned int sample_rate, /* != 0 can override sampling rate of the session */ - unsigned int key_value_count, - switch_sflow_match_key_value_pair_t *kvp, - switch_handle_t *entry_hdl) -{ +switch_status_t switch_api_sflow_session_attach( + switch_device_t device, + switch_handle_t sflow_hdl, + switch_direction_t direction, + unsigned int priority, + unsigned int + sample_rate, /* != 0 can override sampling rate of the session */ + unsigned int key_value_count, + switch_sflow_match_key_value_pair_t *kvp, + switch_handle_t *entry_hdl) { #ifdef P4_SFLOW_ENABLE - switch_sflow_match_key_t match_key; - switch_sflow_match_entry_t *match_entry = NULL; - switch_status_t status = SWITCH_STATUS_FAILURE; - switch_sflow_info_t *sflow_info; - - sflow_info = switch_sflow_info_get(sflow_hdl); - if (!sflow_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - // key-value pairs are used to specify the match-criteria for enabling sflow - // For ingress sflow, ternary match on ingress port, sip, dip are supported - // TBD - check if the match_spec is already used - callers responsibilty for now - - if (!kvp || key_value_count > SWITCH_SFLOW_MATCH_FIELD_MAX) { - return SWITCH_STATUS_INVALID_PARAMETER; - } - - memset(&match_key, 0, sizeof(switch_sflow_match_key_t)); - match_key.port = SWITCH_API_INVALID_HANDLE; - - status = switch_sflow_match_key_from_tlv(key_value_count, kvp, &match_key); + switch_sflow_match_key_t match_key; + switch_sflow_match_entry_t *match_entry = NULL; + switch_status_t status = SWITCH_STATUS_FAILURE; + switch_sflow_info_t *sflow_info; + + sflow_info = switch_sflow_info_get(sflow_hdl); + if (!sflow_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + // key-value pairs are used to specify the match-criteria for enabling sflow + // For ingress sflow, ternary match on ingress port, sip, dip are supported + // TBD - check if the match_spec is already used - callers responsibilty for + // now + + if (!kvp || key_value_count > SWITCH_SFLOW_MATCH_FIELD_MAX) { + return SWITCH_STATUS_INVALID_PARAMETER; + } + + memset(&match_key, 0, sizeof(switch_sflow_match_key_t)); + match_key.port = SWITCH_API_INVALID_HANDLE; + + status = switch_sflow_match_key_from_tlv(key_value_count, kvp, &match_key); + if (status != SWITCH_STATUS_SUCCESS) { + goto error_return; + } + + // create handle for match entry + *entry_hdl = switch_sflow_ace_handle_create(); + match_entry = switch_sflow_ace_entry_get(*entry_hdl); + match_entry->sflow_ace_hdl = *entry_hdl; + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_sflow_ingress_table_add( + device, &match_key, priority, sample_rate, sflow_info, match_entry); if (status != SWITCH_STATUS_SUCCESS) { - goto error_return; + goto error_return; } - - // create handle for match entry - *entry_hdl = switch_sflow_ace_handle_create(); - match_entry = switch_sflow_ace_entry_get(*entry_hdl); - match_entry->sflow_ace_hdl = *entry_hdl; - - if (direction == SWITCH_API_DIRECTION_INGRESS) { - status = switch_pd_sflow_ingress_table_add(device, &match_key, - priority, sample_rate, - sflow_info, - match_entry); - if (status != SWITCH_STATUS_SUCCESS) { - goto error_return; - } - // add the match entry to the list - tommy_list_insert_tail(&sflow_info->match_list, &match_entry->node, - match_entry); - - } else if (direction == SWITCH_API_DIRECTION_EGRESS) { - status = SWITCH_STATUS_NOT_SUPPORTED; - goto error_return; - } else { - status = SWITCH_STATUS_INVALID_PARAMETER; - goto error_return; - } - return SWITCH_STATUS_SUCCESS; + // add the match entry to the list + tommy_list_insert_tail( + &sflow_info->match_list, &match_entry->node, match_entry); + + } else if (direction == SWITCH_API_DIRECTION_EGRESS) { + status = SWITCH_STATUS_NOT_SUPPORTED; + goto error_return; + } else { + status = SWITCH_STATUS_INVALID_PARAMETER; + goto error_return; + } + return SWITCH_STATUS_SUCCESS; error_return: - *entry_hdl = SWITCH_API_INVALID_HANDLE; - return status; + *entry_hdl = SWITCH_API_INVALID_HANDLE; + return status; #else - (void)device; - (void)sflow_hdl; - (void)direction; - (void)priority; - (void)key_value_count; - (void)kvp; - (void)entry_hdl; + (void)device; + (void)sflow_hdl; + (void)direction; + (void)priority; + (void)key_value_count; + (void)kvp; + (void)entry_hdl; + return SWITCH_STATUS_FAILURE; +#endif // P4_SFLOW_ENABLE +} + +switch_status_t switch_api_sflow_session_detach(switch_device_t device, + switch_handle_t sflow_hdl, + switch_handle_t entry_hdl) { +#ifdef P4_SFLOW_ENABLE + switch_sflow_match_entry_t *match_entry = NULL; + switch_status_t status = SWITCH_STATUS_FAILURE; + switch_sflow_info_t *sflow_info; + + sflow_info = switch_sflow_info_get(sflow_hdl); + if (!sflow_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if ((match_entry = switch_sflow_ace_entry_get(entry_hdl)) == NULL) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if ((status = switch_sflow_match_entry_remove(sflow_info, entry_hdl)) != + SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FAILURE; -#endif //P4_SFLOW_ENABLE + } + status = switch_pd_sflow_match_table_delete(device, match_entry); + switch_sflow_ace_handle_delete(entry_hdl); + return status; +#else + (void)device; + (void)sflow_hdl; + (void)entry_hdl; + return SWITCH_STATUS_FAILURE; +#endif // P4_SFLOW_ENABLE } -switch_status_t -switch_api_sflow_session_detach (switch_device_t device, - switch_handle_t sflow_hdl, - switch_handle_t entry_hdl - ) -{ +switch_status_t switch_api_sflow_session_sample_count_get( + switch_device_t device, + switch_handle_t sflow_hdl, + switch_handle_t entry_hdl, + switch_counter_t *sample_pool) { #ifdef P4_SFLOW_ENABLE - switch_sflow_match_entry_t *match_entry = NULL; - switch_status_t status = SWITCH_STATUS_FAILURE; - switch_sflow_info_t *sflow_info; + switch_sflow_match_entry_t *match_entry = NULL; + switch_status_t status = SWITCH_STATUS_FAILURE; + switch_sflow_info_t *sflow_info; + + sflow_info = switch_sflow_info_get(sflow_hdl); + if (!sflow_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if ((match_entry = switch_sflow_ace_entry_get(entry_hdl)) == NULL) { + return SWITCH_STATUS_INVALID_HANDLE; + } + status = switch_pd_sflow_counter_read(device, match_entry, sample_pool); + return status; - sflow_info = switch_sflow_info_get(sflow_hdl); - if (!sflow_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if ((match_entry = switch_sflow_ace_entry_get(entry_hdl)) == NULL) { - return SWITCH_STATUS_INVALID_HANDLE; - } - if ((status = switch_sflow_match_entry_remove(sflow_info, entry_hdl)) != - SWITCH_STATUS_SUCCESS) - { - return SWITCH_STATUS_FAILURE; - } - status = switch_pd_sflow_match_table_delete(device, match_entry); - switch_sflow_ace_handle_delete(entry_hdl); - return status; #else - (void)device; - (void)sflow_hdl; - (void)entry_hdl; - return SWITCH_STATUS_FAILURE; -#endif //P4_SFLOW_ENABLE + (void)device; + (void)sflow_hdl; + (void)entry_hdl; + return SWITCH_STATUS_FAILURE; +#endif // P4_SFLOW_ENABLE +} + +switch_status_t switch_api_sflow_session_sample_count_reset( + switch_device_t device, + switch_handle_t sflow_hdl, + switch_handle_t entry_hdl) { +#ifdef P4_SFLOW_ENABLE + switch_sflow_match_entry_t *match_entry = NULL; + switch_status_t status = SWITCH_STATUS_FAILURE; + switch_sflow_info_t *sflow_info; + switch_counter_t val; + + sflow_info = switch_sflow_info_get(sflow_hdl); + if (!sflow_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + if ((match_entry = switch_sflow_ace_entry_get(entry_hdl)) == NULL) { + return SWITCH_STATUS_INVALID_HANDLE; + } + memset(&val, 0, sizeof(val)); + status = switch_pd_sflow_counter_write(device, match_entry, val); + return status; +#else + (void)device; + (void)sflow_hdl; + (void)entry_hdl; + return SWITCH_STATUS_FAILURE; +#endif // P4_SFLOW_ENABLE } diff --git a/switchapi/src/switch_sflow_int.h b/switchapi/src/switch_sflow_int.h index 5dcacd3..7bfca41 100644 --- a/switchapi/src/switch_sflow_int.h +++ b/switchapi/src/switch_sflow_int.h @@ -2,37 +2,37 @@ * Copyright 2015-present Barefoot Networks, Inc. */ -#include "tommyds/tommy.h" #include "switchapi/switch_sflow.h" +#include "switch_pd_types.h" #ifndef _SWITCH_SFLOW_INT_H_ #define _SWITCH_SFLOW_INT_H_ typedef struct switch_sflow_match__key_ { - switch_handle_t port; - uint16_t vlan; - uint32_t sip; - uint32_t sip_mask; - uint32_t dip; - uint32_t dip_mask; + switch_handle_t port; + uint16_t vlan; + uint32_t sip; + uint32_t sip_mask; + uint32_t dip; + uint32_t dip_mask; } switch_sflow_match_key_t; typedef struct switch_sflow_match_entry_ { - tommy_node node; - p4_pd_entry_hdl_t ingress_sflow_ent_hdl; - switch_handle_t sflow_ace_hdl; + tommy_node node; + p4_pd_entry_hdl_t ingress_sflow_ent_hdl; + switch_handle_t sflow_ace_hdl; } switch_sflow_match_entry_t; typedef struct switch_sflow_info_ { - switch_api_sflow_session_info_t api_info; - uint8_t session_id; - switch_handle_t mirror_hdl; - p4_pd_entry_hdl_t mirror_table_ent_hdl; - p4_pd_entry_hdl_t ing_take_sample_table_ent_hdl; + switch_api_sflow_session_info_t api_info; + uint8_t session_id; + switch_handle_t mirror_hdl; + p4_pd_entry_hdl_t mirror_table_ent_hdl; + p4_pd_entry_hdl_t ing_take_sample_table_ent_hdl; - // use tommy list to store all the match key_value_pairs - // using this sflow_session - tommy_list match_list; + // use tommy list to store all the match key_value_pairs + // using this sflow_session + tommy_list match_list; } switch_sflow_info_t; void switch_sflow_init(switch_device_t device); diff --git a/switchapi/src/switch_stp.c b/switchapi/src/switch_stp.c index 48a3727..100362f 100644 --- a/switchapi/src/switch_stp.c +++ b/switchapi/src/switch_stp.c @@ -29,543 +29,519 @@ extern "C" { static void *switch_stp_instance_array; -switch_status_t -switch_stp_init(switch_device_t device) -{ - switch_stp_instance_array = NULL; - switch_handle_type_init(SWITCH_HANDLE_TYPE_STP, SWITCH_MAX_STP_INSTANCES); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_stp_init(switch_device_t device) { + switch_stp_instance_array = NULL; + switch_handle_type_init(SWITCH_HANDLE_TYPE_STP, SWITCH_MAX_STP_INSTANCES); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_stp_free(switch_device_t device) -{ - switch_handle_type_free(SWITCH_HANDLE_TYPE_STP); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_stp_free(switch_device_t device) { + switch_handle_type_free(SWITCH_HANDLE_TYPE_STP); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_stg_handle_create() -{ - switch_handle_t stg_handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_STP, switch_stp_info_t, - switch_stp_instance_array, NULL, - stg_handle); - return stg_handle; +switch_handle_t switch_stg_handle_create() { + switch_handle_t stg_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_STP, + switch_stp_info_t, + switch_stp_instance_array, + NULL, + stg_handle); + return stg_handle; } -void -switch_stg_handle_delete(switch_handle_t stg_handle) -{ - _switch_handle_delete(switch_stp_info_t, switch_stp_instance_array, stg_handle); +void switch_stg_handle_delete(switch_handle_t stg_handle) { + _switch_handle_delete( + switch_stp_info_t, switch_stp_instance_array, stg_handle); } -switch_stp_info_t * -switch_api_stp_get_internal(switch_handle_t stg_handle) -{ - switch_stp_info_t *stp_info = NULL; - _switch_handle_get(switch_stp_info_t, switch_stp_instance_array, - stg_handle, stp_info); - return stp_info; +switch_stp_info_t *switch_api_stp_get_internal(switch_handle_t stg_handle) { + switch_stp_info_t *stp_info = NULL; + _switch_handle_get( + switch_stp_info_t, switch_stp_instance_array, stg_handle, stp_info); + return stp_info; } -switch_handle_t -switch_api_stp_group_create(switch_device_t device, - switch_stp_mode_t stp_mode) -{ - switch_handle_t stg_handle; - switch_stp_info_t *stp_info = NULL; - - stg_handle = switch_stg_handle_create(); - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - // No memory - return 0; - } - - tommy_list_init(&(stp_info->vlan_list)); - tommy_list_init(&(stp_info->port_list)); - return stg_handle; -} - -switch_status_t -switch_api_stp_group_delete(switch_device_t device, switch_handle_t stg_handle) -{ - switch_stp_info_t *stp_info = NULL; - tommy_node *node = NULL; - switch_stp_port_entry_t *port_entry = NULL; - switch_stp_vlan_entry_t *vlan_entry = NULL; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - node = tommy_list_head(&(stp_info->port_list)); - while (node) { - port_entry = node->data; - node = node->next; - switch_api_stp_port_state_set(device, stg_handle, - port_entry->intf_handle, - SWITCH_PORT_STP_STATE_NONE); - } - node = tommy_list_head(&(stp_info->vlan_list)); - while (node) { - vlan_entry = node->data; - node = node->next; - switch_api_stp_group_vlans_remove(device, - stg_handle, 1, - &vlan_entry->bd_handle); - } - switch_stg_handle_delete(stg_handle); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_stp_group_vlans_add(switch_device_t device, - switch_handle_t stg_handle, - uint16_t vlan_count, - switch_handle_t *vlan_handle) -{ - switch_stp_info_t *stp_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_stp_vlan_entry_t *vlan_entry = NULL; - switch_handle_t bd_handle; - int count = 0; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - for (count = 0; count < vlan_count; count++) { - bd_handle = vlan_handle[count]; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - vlan_entry = switch_malloc(sizeof(switch_stp_vlan_entry_t), 1); - if (!vlan_entry) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(vlan_entry, 0 , sizeof(switch_stp_vlan_entry_t)); - - 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); - - tommy_list_insert_head(&(stp_info->vlan_list), - &(vlan_entry->node), vlan_entry); - } - return SWITCH_STATUS_SUCCESS; +switch_handle_t switch_api_stp_group_create(switch_device_t device, + switch_stp_mode_t stp_mode) { + switch_handle_t stg_handle; + switch_stp_info_t *stp_info = NULL; + + stg_handle = switch_stg_handle_create(); + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + // No memory + return 0; + } + + tommy_list_init(&(stp_info->vlan_list)); + tommy_list_init(&(stp_info->port_list)); + return stg_handle; } -switch_status_t -switch_api_stp_group_vlans_remove(switch_device_t device, - switch_handle_t stg_handle, - uint16_t vlan_count, - switch_handle_t *vlan_handle) -{ - switch_stp_info_t *stp_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_stp_vlan_entry_t *vlan_entry = NULL; - tommy_node *node = NULL; - switch_handle_t bd_handle; - int count = 0; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - for (count = 0; count < vlan_count; count++) { - bd_handle = vlan_handle[count]; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - node = tommy_list_head(&(stp_info->vlan_list)); - while (node) { - vlan_entry = node->data; - if (vlan_entry->bd_handle == bd_handle) { - break; - } - node = node->next; - } - - if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - bd_info->stp_handle = 0; - 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); - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_stp_group_delete(switch_device_t device, + switch_handle_t stg_handle) { + switch_stp_info_t *stp_info = NULL; + tommy_node *node = NULL; + switch_stp_port_entry_t *port_entry = NULL; + switch_stp_vlan_entry_t *vlan_entry = NULL; + + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + node = tommy_list_head(&(stp_info->port_list)); + while (node) { + port_entry = node->data; + node = node->next; + switch_api_stp_port_state_set(device, + stg_handle, + port_entry->intf_handle, + SWITCH_PORT_STP_STATE_NONE); + } + node = tommy_list_head(&(stp_info->vlan_list)); + while (node) { + vlan_entry = node->data; + node = node->next; + switch_api_stp_group_vlans_remove( + device, stg_handle, 1, &vlan_entry->bd_handle); + } + switch_stg_handle_delete(stg_handle); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_stp_port_state_set(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t handle, switch_stp_state_t state) -{ - switch_stp_info_t *stp_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_stp_port_entry_t *port_entry = NULL; - tommy_node *node = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t intf_handle; - switch_handle_type_t handle_type = 0; - bool new_entry = FALSE; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_api_stp_group_vlans_add(switch_device_t device, + switch_handle_t stg_handle, + uint16_t vlan_count, + switch_handle_t *vlan_handle) { + switch_stp_info_t *stp_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_stp_vlan_entry_t *vlan_entry = NULL; + switch_handle_t bd_handle; + int count = 0; - if ((!SWITCH_PORT_HANDLE_VALID(handle)) && - (!SWITCH_LAG_HANDLE_VALID(handle)) && - (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } - handle_type = switch_handle_get_type(handle); - intf_handle = 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; - } + for (count = 0; count < vlan_count; count++) { + bd_handle = vlan_handle[count]; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; + vlan_entry = switch_malloc(sizeof(switch_stp_vlan_entry_t), 1); + if (!vlan_entry) { + return SWITCH_STATUS_NO_MEMORY; } + memset(vlan_entry, 0, sizeof(switch_stp_vlan_entry_t)); - if (SWITCH_INTF_IS_PORT_L3(intf_info)) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + vlan_entry->bd_handle = bd_handle; + bd_info->stp_handle = stg_handle; - node = tommy_list_head(&stp_info->port_list); - while (node) { - port_entry = node->data; - if (port_entry->intf_handle == intf_handle) { - port_entry->intf_state = state; - break; - } - node = node->next; - } + switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), bd_info); - if (state == SWITCH_PORT_STP_STATE_NONE) { - if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - status = switch_stp_update_flood_list(device, stg_handle, intf_handle, state); - status = switch_pd_spanning_tree_table_delete_entry(device, port_entry->hw_entry); - tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node)); - switch_free(port_entry); - } else { - if (!node) { - new_entry = TRUE; - port_entry = switch_malloc(sizeof(switch_stp_port_entry_t), 1); - if (!port_entry) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(port_entry, 0, sizeof(switch_stp_port_entry_t)); - port_entry->intf_handle = intf_handle; - port_entry->intf_state = state; - tommy_list_insert_head(&(stp_info->port_list), - &(port_entry->node), port_entry); - } - - status = switch_stp_update_flood_list(device, stg_handle, intf_handle, state); - - if (new_entry) { - status = switch_pd_spanning_tree_table_add_entry(device, - handle_to_id(stg_handle), - intf_info->ifindex, - port_entry->intf_state, - &port_entry->hw_entry); - } else { - status = switch_pd_spanning_tree_table_update_entry(device, - handle_to_id(stg_handle), - intf_info->ifindex, - port_entry->intf_state, - port_entry->hw_entry); - } - } - return status; + tommy_list_insert_head( + &(stp_info->vlan_list), &(vlan_entry->node), vlan_entry); + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_stp_port_state_get(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t handle, switch_stp_state_t *state) -{ - switch_stp_info_t *stp_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_stp_port_entry_t *port_entry = NULL; - tommy_node *node = 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; - } - - if ((!SWITCH_PORT_HANDLE_VALID(handle)) && - (!SWITCH_LAG_HANDLE_VALID(handle)) && - (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; +switch_status_t switch_api_stp_group_vlans_remove( + switch_device_t device, + switch_handle_t stg_handle, + uint16_t vlan_count, + switch_handle_t *vlan_handle) { + switch_stp_info_t *stp_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_stp_vlan_entry_t *vlan_entry = NULL; + tommy_node *node = NULL; + switch_handle_t bd_handle; + int count = 0; + + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + for (count = 0; count < vlan_count; count++) { + bd_handle = vlan_handle[count]; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; } - handle_type = switch_handle_get_type(handle); - intf_handle = 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_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; - } - - *state = SWITCH_PORT_STP_STATE_NONE; - node = tommy_list_head(&(stp_info->port_list)); + node = tommy_list_head(&(stp_info->vlan_list)); while (node) { - port_entry = node->data; - if (port_entry->intf_handle == intf_handle) { - *state = port_entry->intf_state; - break; - } - node = node->next; + vlan_entry = node->data; + if (vlan_entry->bd_handle == bd_handle) { + break; + } + node = node->next; } if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + return SWITCH_STATUS_ITEM_NOT_FOUND; } - return SWITCH_STATUS_SUCCESS; -} -switch_status_t -switch_api_stp_port_state_clear(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t handle) -{ - switch_stp_info_t *stp_info = NULL; - switch_interface_info_t *intf_info = NULL; - switch_stp_port_entry_t *port_entry = NULL; - tommy_node *node = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_handle_t intf_handle = 0; - switch_handle_type_t handle_type = 0; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - if ((!SWITCH_PORT_HANDLE_VALID(handle)) && - (!SWITCH_LAG_HANDLE_VALID(handle)) && - (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { - return SWITCH_STATUS_INVALID_HANDLE; - } + bd_info->stp_handle = 0; + switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), bd_info); - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - handle_type = switch_handle_get_type(handle); - intf_handle = 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_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; - } + vlan_entry = tommy_list_remove_existing(&(stp_info->vlan_list), node); + switch_free(vlan_entry); + } + return SWITCH_STATUS_SUCCESS; +} - node = tommy_list_head(&(stp_info->port_list)); - while (node) { - port_entry = node->data; - if (port_entry->intf_handle == intf_handle) { - break; - } - node = node->next; - } +switch_status_t switch_api_stp_port_state_set(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t handle, + switch_stp_state_t state) { + switch_stp_info_t *stp_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_stp_port_entry_t *port_entry = NULL; + tommy_node *node = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t intf_handle; + switch_handle_type_t handle_type = 0; + bool new_entry = FALSE; + + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if ((!SWITCH_PORT_HANDLE_VALID(handle)) && + (!SWITCH_LAG_HANDLE_VALID(handle)) && + (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + handle_type = switch_handle_get_type(handle); + intf_handle = 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_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; + } + + node = tommy_list_head(&stp_info->port_list); + while (node) { + port_entry = node->data; + if (port_entry->intf_handle == intf_handle) { + port_entry->intf_state = state; + break; + } + node = node->next; + } + + if (state == SWITCH_PORT_STP_STATE_NONE) { if (!node) { - return SWITCH_STATUS_ITEM_NOT_FOUND; + return SWITCH_STATUS_ITEM_NOT_FOUND; } - + status = + switch_stp_update_flood_list(device, stg_handle, intf_handle, state); + status = switch_pd_spanning_tree_table_delete_entry(device, + port_entry->hw_entry); tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node)); switch_free(port_entry); - return status; + } else { + if (!node) { + new_entry = TRUE; + port_entry = switch_malloc(sizeof(switch_stp_port_entry_t), 1); + if (!port_entry) { + return SWITCH_STATUS_NO_MEMORY; + } + memset(port_entry, 0, sizeof(switch_stp_port_entry_t)); + port_entry->intf_handle = intf_handle; + port_entry->intf_state = state; + tommy_list_insert_head( + &(stp_info->port_list), &(port_entry->node), port_entry); + } + + status = + switch_stp_update_flood_list(device, stg_handle, intf_handle, state); + + if (new_entry) { + status = switch_pd_spanning_tree_table_add_entry(device, + handle_to_id(stg_handle), + intf_info->ifindex, + port_entry->intf_state, + &port_entry->hw_entry); + } else { + status = + switch_pd_spanning_tree_table_update_entry(device, + handle_to_id(stg_handle), + intf_info->ifindex, + port_entry->intf_state, + port_entry->hw_entry); + } + } + return status; } -switch_status_t -switch_stp_update_flood_list(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t intf_handle, switch_stp_state_t state) -{ - switch_stp_info_t *stp_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_stp_vlan_entry_t *vlan_entry = NULL; - tommy_node *node = NULL; - switch_handle_t bd_handle = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_vlan_interface_t vlan_intf; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - node = tommy_list_head(&(stp_info->vlan_list)); - while (node) { - vlan_entry = node->data; - bd_handle = vlan_entry->bd_handle; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - memset(&vlan_intf, 0, sizeof(vlan_intf)); - vlan_intf.vlan_handle = bd_handle; - vlan_intf.intf_handle = intf_handle; - switch (state) { - case SWITCH_PORT_STP_STATE_FORWARDING: - status = switch_api_multicast_member_add( - device, bd_info->uuc_mc_index, 1, &vlan_intf); - break; - case SWITCH_PORT_STP_STATE_BLOCKING: - case SWITCH_PORT_STP_STATE_NONE: - status = switch_api_multicast_member_delete( - device, bd_info->uuc_mc_index, 1, &vlan_intf); - break; - - default: - break; - } - node = node->next; - } - return status; +switch_status_t switch_api_stp_port_state_get(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t handle, + switch_stp_state_t *state) { + switch_stp_info_t *stp_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_stp_port_entry_t *port_entry = NULL; + tommy_node *node = 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; + } + + if ((!SWITCH_PORT_HANDLE_VALID(handle)) && + (!SWITCH_LAG_HANDLE_VALID(handle)) && + (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + handle_type = switch_handle_get_type(handle); + intf_handle = 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_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; + } + + *state = SWITCH_PORT_STP_STATE_NONE; + node = tommy_list_head(&(stp_info->port_list)); + while (node) { + port_entry = node->data; + if (port_entry->intf_handle == intf_handle) { + *state = port_entry->intf_state; + break; + } + node = node->next; + } + + if (!node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_stp_group_print_entry(switch_handle_t stg_handle) -{ - switch_stp_info_t *stp_info = NULL; - switch_stp_vlan_entry_t *vlan_entry = NULL; - switch_stp_port_entry_t *port_entry = NULL; - tommy_node *node = NULL; - switch_handle_t bd_handle = 0; - switch_handle_t intf_handle = 0; - - if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_api_stp_port_state_clear(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t handle) { + switch_stp_info_t *stp_info = NULL; + switch_interface_info_t *intf_info = NULL; + switch_stp_port_entry_t *port_entry = NULL; + tommy_node *node = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_handle_t intf_handle = 0; + switch_handle_type_t handle_type = 0; + + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if ((!SWITCH_PORT_HANDLE_VALID(handle)) && + (!SWITCH_LAG_HANDLE_VALID(handle)) && + (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + handle_type = switch_handle_get_type(handle); + intf_handle = 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_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; + } + + node = tommy_list_head(&(stp_info->port_list)); + while (node) { + port_entry = node->data; + if (port_entry->intf_handle == intf_handle) { + break; + } + node = node->next; + } + if (!node) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node)); + switch_free(port_entry); + return status; +} - stp_info = switch_api_stp_get_internal(stg_handle); - if (!stp_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } +switch_status_t switch_stp_update_flood_list(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t intf_handle, + switch_stp_state_t state) { + switch_stp_info_t *stp_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_stp_vlan_entry_t *vlan_entry = NULL; + tommy_node *node = NULL; + switch_handle_t bd_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_vlan_interface_t vlan_intf; + + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + node = tommy_list_head(&(stp_info->vlan_list)); + while (node) { + vlan_entry = node->data; + bd_handle = vlan_entry->bd_handle; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + memset(&vlan_intf, 0, sizeof(vlan_intf)); + vlan_intf.vlan_handle = bd_handle; + vlan_intf.intf_handle = intf_handle; + switch (state) { + case SWITCH_PORT_STP_STATE_FORWARDING: + status = switch_api_multicast_member_add( + device, bd_info->uuc_mc_index, 1, &vlan_intf); + break; + case SWITCH_PORT_STP_STATE_BLOCKING: + case SWITCH_PORT_STP_STATE_NONE: + status = switch_api_multicast_member_delete( + device, bd_info->uuc_mc_index, 1, &vlan_intf); + break; + + default: + break; + } + node = node->next; + } + return status; +} - printf("\n\nstp_group_handle: %x", (unsigned int) stg_handle); - node = tommy_list_head(&(stp_info->vlan_list)); - printf("\nlist of vlan handles:"); - while (node) { - vlan_entry = node->data; - bd_handle = vlan_entry->bd_handle; - printf("\n\tvlan_handle: %x", (unsigned int) bd_handle); - node = node->next; - } - printf("\nlist of interface handles:"); - node = tommy_list_head(&(stp_info->port_list)); - while (node) { - port_entry = node->data; - intf_handle = port_entry->intf_handle; - printf("\n\tintf_handle: %x stp_state %x", - (unsigned int) intf_handle, - port_entry->intf_state); - node = node->next; - } - printf("\n"); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_stp_group_print_entry(switch_handle_t stg_handle) { + switch_stp_info_t *stp_info = NULL; + switch_stp_vlan_entry_t *vlan_entry = NULL; + switch_stp_port_entry_t *port_entry = NULL; + tommy_node *node = NULL; + switch_handle_t bd_handle = 0; + switch_handle_t intf_handle = 0; + + if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + stp_info = switch_api_stp_get_internal(stg_handle); + if (!stp_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + printf("\n\nstp_group_handle: %x", (unsigned int)stg_handle); + node = tommy_list_head(&(stp_info->vlan_list)); + printf("\nlist of vlan handles:"); + while (node) { + vlan_entry = node->data; + bd_handle = vlan_entry->bd_handle; + printf("\n\tvlan_handle: %x", (unsigned int)bd_handle); + node = node->next; + } + printf("\nlist of interface handles:"); + node = tommy_list_head(&(stp_info->port_list)); + while (node) { + port_entry = node->data; + intf_handle = port_entry->intf_handle; + printf("\n\tintf_handle: %x stp_state %x", + (unsigned int)intf_handle, + port_entry->intf_state); + node = node->next; + } + printf("\n"); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_stp_group_print_all(void) -{ - switch_handle_t stp_handle = 0; - switch_handle_t next_stp_handle = 0; - - switch_handle_get_first(switch_stp_instance_array, stp_handle); - while (stp_handle) { - switch_api_stp_group_print_entry(stp_handle); - switch_handle_get_next(switch_stp_instance_array, stp_handle, next_stp_handle); - stp_handle = next_stp_handle; - } - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_stp_group_print_all(void) { + switch_handle_t stp_handle = 0; + switch_handle_t next_stp_handle = 0; + + switch_handle_get_first(switch_stp_instance_array, stp_handle); + while (stp_handle) { + switch_api_stp_group_print_entry(stp_handle); + switch_handle_get_next( + switch_stp_instance_array, stp_handle, next_stp_handle); + stp_handle = next_stp_handle; + } + return SWITCH_STATUS_SUCCESS; } #ifdef __cplusplus diff --git a/switchapi/src/switch_stp_int.h b/switchapi/src/switch_stp_int.h index 1258796..11e0d8a 100644 --- a/switchapi/src/switch_stp_int.h +++ b/switchapi/src/switch_stp_int.h @@ -19,36 +19,40 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" +#include "switchapi/switch_stp.h" +#include "switch_pd_types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -#define SWITCH_STP_INVALID_VLAN_HANDLE 0xFF +#define SWITCH_STP_INVALID_VLAN_HANDLE 0xFF typedef struct { - tommy_node node; - switch_handle_t intf_handle; - switch_stp_state_t intf_state; - p4_pd_entry_hdl_t hw_entry; + tommy_node node; + switch_handle_t intf_handle; + switch_stp_state_t intf_state; + p4_pd_entry_hdl_t hw_entry; } switch_stp_port_entry_t; typedef struct { - tommy_node node; - switch_handle_t bd_handle; + tommy_node node; + switch_handle_t bd_handle; } switch_stp_vlan_entry_t; typedef struct switch_stp_info_ { - tommy_list vlan_list; - tommy_list port_list; + tommy_list vlan_list; + tommy_list port_list; } switch_stp_info_t; /* Internal API's */ switch_status_t switch_stp_init(switch_device_t device); switch_status_t switch_stp_free(switch_device_t device); switch_stp_info_t *switch_api_stp_get_internal(switch_handle_t stp_handle); -switch_status_t switch_stp_update_flood_list(switch_device_t device, switch_handle_t stg_handle, - switch_handle_t intf_handle, switch_stp_state_t state); +switch_status_t switch_stp_update_flood_list(switch_device_t device, + switch_handle_t stg_handle, + switch_handle_t intf_handle, + switch_stp_state_t state); #ifdef __cplusplus } diff --git a/switchapi/src/switch_tunnel.c b/switchapi/src/switch_tunnel.c index 2115263..d15bdfa 100644 --- a/switchapi/src/switch_tunnel.c +++ b/switchapi/src/switch_tunnel.c @@ -33,1165 +33,1407 @@ switch_api_id_allocator *src_vtep_index_allocator = NULL; switch_api_id_allocator *dst_vtep_index_allocator = NULL; static void *mpls_transit_array = NULL; -#define UDP_PORT_VXLAN 4789 -#define UDP_PORT_GENEVE 6081 -#define GRE_PROTO_NVGRE 0x6558 - -switch_status_t -switch_tunnel_init(switch_device_t device) -{ - UNUSED(device); - tommy_hashtable_init(&switch_src_vtep_table, SWITCH_SRC_VTEP_HASH_TABLE_SIZE); - tommy_hashtable_init(&switch_dst_vtep_table, SWITCH_DST_VTEP_HASH_TABLE_SIZE); - src_vtep_index_allocator = switch_api_id_allocator_new(SWITCH_SRC_VTEP_HASH_TABLE_SIZE, FALSE); - dst_vtep_index_allocator = switch_api_id_allocator_new(SWITCH_DST_VTEP_HASH_TABLE_SIZE, FALSE); - switch_api_id_allocator_allocate(src_vtep_index_allocator); - switch_api_id_allocator_allocate(dst_vtep_index_allocator); - return SWITCH_STATUS_SUCCESS; +#define UDP_PORT_VXLAN 4789 +#define UDP_PORT_GENEVE 6081 +#define GRE_PROTO_NVGRE 0x6558 + +switch_status_t switch_tunnel_init(switch_device_t device) { + UNUSED(device); + tommy_hashtable_init(&switch_src_vtep_table, SWITCH_SRC_VTEP_HASH_TABLE_SIZE); + tommy_hashtable_init(&switch_dst_vtep_table, SWITCH_DST_VTEP_HASH_TABLE_SIZE); + src_vtep_index_allocator = + switch_api_id_allocator_new(SWITCH_SRC_VTEP_HASH_TABLE_SIZE, FALSE); + dst_vtep_index_allocator = + switch_api_id_allocator_new(SWITCH_DST_VTEP_HASH_TABLE_SIZE, FALSE); + switch_api_id_allocator_allocate(src_vtep_index_allocator); + switch_api_id_allocator_allocate(dst_vtep_index_allocator); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_tunnel_free(switch_device_t device) -{ - UNUSED(device); - tommy_hashtable_done(&switch_src_vtep_table); - tommy_hashtable_done(&switch_dst_vtep_table); - switch_api_id_allocator_destroy(src_vtep_index_allocator); - switch_api_id_allocator_destroy(dst_vtep_index_allocator); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_tunnel_free(switch_device_t device) { + UNUSED(device); + tommy_hashtable_done(&switch_src_vtep_table); + tommy_hashtable_done(&switch_dst_vtep_table); + switch_api_id_allocator_destroy(src_vtep_index_allocator); + switch_api_id_allocator_destroy(dst_vtep_index_allocator); + return SWITCH_STATUS_SUCCESS; } -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) -{ - (*len) = 0; - memset(key, 0, SWITCH_VTEP_HASH_KEY_SIZE); - *(unsigned int *)(&key[(*len)]) = (unsigned int)handle_to_id(vrf); +static void switch_tunnel_vtep_hash_key_init(uchar *key, + switch_handle_t vrf, + switch_ip_addr_t *ip_addr, + switch_encap_type_t encap_type, + uint32_t *len, + uint32_t *hash) { + (*len) = 0; + memset(key, 0, SWITCH_VTEP_HASH_KEY_SIZE); + *(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[(*len)]) = ip_addr->ip.v4addr; (*len) += 4; - key[(*len)] = ip_addr->type; - (*len)++; - if(ip_addr->type == SWITCH_API_IP_ADDR_V4) { - *(unsigned int *)(&key[(*len)]) = ip_addr->ip.v4addr; - (*len) += 4; - } - else { - memcpy(&key[(*len)], ip_addr->ip.v6addr, 4*sizeof(unsigned int)); - (*len) += 16; - } - key[*len] = ip_addr->prefix_len; - (*len)++; - *hash = MurmurHash2(key, *len, 0x98761234); + } else { + memcpy(&key[(*len)], ip_addr->ip.v6addr, 4 * sizeof(unsigned int)); + (*len) += 16; + } + key[*len] = ip_addr->prefix_len; + (*len)++; + key[*len] = encap_type; + (*len)++; + *hash = MurmurHash2(key, *len, 0x98761234); } -static inline int -switch_vtep_hash_cmp(const void *key1, const void *key2) -{ - return memcmp(key1, key2, SWITCH_VTEP_HASH_KEY_SIZE); +static inline int switch_vtep_hash_cmp(const void *key1, const void *key2) { + return memcmp(key1, key2, SWITCH_VTEP_HASH_KEY_SIZE); } -static uint16_t -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]; - unsigned int len = 0; - uint32_t hash = 0; - uint16_t src_vtep_index = 0; - - switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, &len, &hash); - vtep_entry = switch_malloc(sizeof(switch_vtep_entry_t), 1); - 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)); - memcpy(vtep_entry->key, key, SWITCH_VTEP_HASH_KEY_SIZE); - vtep_entry->entry_index = src_vtep_index; - tommy_hashtable_insert(&switch_src_vtep_table, &(vtep_entry->node), vtep_entry, hash); +static uint16_t switch_tunnel_src_vtep_insert_hash( + switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + switch_vtep_entry_t *vtep_entry = NULL; + unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + uint16_t src_vtep_index = 0; + + switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, encap_type, &len, &hash); + vtep_entry = switch_malloc(sizeof(switch_vtep_entry_t), 1); + 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; + vtep_entry->encap_type = encap_type; + memcpy(&vtep_entry->ip_addr, ip_addr, sizeof(switch_ip_addr_t)); + memcpy(vtep_entry->key, key, SWITCH_VTEP_HASH_KEY_SIZE); + vtep_entry->entry_index = src_vtep_index; + tommy_hashtable_insert( + &switch_src_vtep_table, &(vtep_entry->node), vtep_entry, hash); + return src_vtep_index; } -static switch_status_t -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]; - unsigned int len = 0; - uint32_t hash = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, &len, &hash); - vtep_entry = tommy_hashtable_remove(&switch_src_vtep_table, switch_vtep_hash_cmp, key, hash); - if (!vtep_entry) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - switch_api_id_allocator_release(src_vtep_index_allocator, vtep_entry->entry_index); - free(vtep_entry); - return status; +static switch_status_t switch_tunnel_src_vtep_delete_hash( + switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + switch_vtep_entry_t *vtep_entry = NULL; + unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, encap_type, &len, &hash); + vtep_entry = tommy_hashtable_remove( + &switch_src_vtep_table, switch_vtep_hash_cmp, key, hash); + if (!vtep_entry) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + switch_api_id_allocator_release(src_vtep_index_allocator, + vtep_entry->entry_index); + free(vtep_entry); + return status; } -static uint16_t -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]; - unsigned int len = 0; - uint32_t hash; - uint16_t src_vtep_index = 0; - - switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, &len, &hash); - vtep_entry = tommy_hashtable_search(&switch_src_vtep_table, switch_vtep_hash_cmp, key, hash); - - if (vtep_entry) { - src_vtep_index = vtep_entry->entry_index; - } - return src_vtep_index; +static uint16_t switch_tunnel_src_vtep_search_hash( + switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + switch_vtep_entry_t *vtep_entry = NULL; + unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash; + uint16_t src_vtep_index = 0; + + switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, encap_type, &len, &hash); + vtep_entry = tommy_hashtable_search( + &switch_src_vtep_table, switch_vtep_hash_cmp, key, hash); + + if (vtep_entry) { + src_vtep_index = vtep_entry->entry_index; + } + return src_vtep_index; } -static uint16_t -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]; - unsigned int len = 0; - uint32_t hash; - uint16_t dst_vtep_index = 0; - - switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, &len, &hash); - vtep_entry = switch_malloc(sizeof(switch_vtep_entry_t), 1); - 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)); - memcpy(vtep_entry->key, key, SWITCH_VTEP_HASH_KEY_SIZE); - vtep_entry->entry_index = dst_vtep_index; - tommy_hashtable_insert(&switch_dst_vtep_table, &(vtep_entry->node), vtep_entry, hash); +static uint16_t switch_tunnel_dst_vtep_insert_hash( + switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + switch_vtep_entry_t *vtep_entry = NULL; + unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash; + uint16_t dst_vtep_index = 0; + + switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, encap_type, &len, &hash); + vtep_entry = switch_malloc(sizeof(switch_vtep_entry_t), 1); + 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; + vtep_entry->encap_type = encap_type; + memcpy(&vtep_entry->ip_addr, ip_addr, sizeof(switch_ip_addr_t)); + memcpy(vtep_entry->key, key, SWITCH_VTEP_HASH_KEY_SIZE); + vtep_entry->entry_index = dst_vtep_index; + tommy_hashtable_insert( + &switch_dst_vtep_table, &(vtep_entry->node), vtep_entry, hash); + return dst_vtep_index; } -static switch_status_t -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]; - unsigned int len = 0; - uint32_t hash = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, &len, &hash); - vtep_entry = tommy_hashtable_remove(&switch_dst_vtep_table, switch_vtep_hash_cmp, key, hash); - if (!vtep_entry) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - switch_api_id_allocator_release(dst_vtep_index_allocator, vtep_entry->entry_index); - free(vtep_entry); - return status; +static switch_status_t switch_tunnel_dst_vtep_delete_hash( + switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + switch_vtep_entry_t *vtep_entry = NULL; + unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, encap_type, &len, &hash); + vtep_entry = tommy_hashtable_remove( + &switch_dst_vtep_table, switch_vtep_hash_cmp, key, hash); + if (!vtep_entry) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + switch_api_id_allocator_release(dst_vtep_index_allocator, + vtep_entry->entry_index); + free(vtep_entry); + return status; } -static uint16_t -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]; - unsigned int len = 0; - uint32_t hash = 0; - uint16_t dst_vtep_index = 0; - - switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, &len, &hash); - vtep_entry = tommy_hashtable_search(&switch_dst_vtep_table, switch_vtep_hash_cmp, key, hash); - - if (vtep_entry) { - dst_vtep_index = vtep_entry->entry_index; - } - return dst_vtep_index; +static uint16_t switch_tunnel_dst_vtep_search_hash( + switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + switch_vtep_entry_t *vtep_entry = NULL; + unsigned char key[SWITCH_VTEP_HASH_KEY_SIZE]; + unsigned int len = 0; + uint32_t hash = 0; + uint16_t dst_vtep_index = 0; + + switch_tunnel_vtep_hash_key_init(key, vrf, ip_addr, encap_type, &len, &hash); + vtep_entry = tommy_hashtable_search( + &switch_dst_vtep_table, switch_vtep_hash_cmp, key, hash); + + if (vtep_entry) { + dst_vtep_index = vtep_entry->entry_index; + } + return dst_vtep_index; } -uint16_t -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_src_vtep_index_get(switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + return switch_tunnel_src_vtep_search_hash(vrf, encap_type, ip_addr); } -uint16_t -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); +uint16_t switch_tunnel_dst_vtep_index_get(switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr) { + return switch_tunnel_dst_vtep_search_hash(vrf, encap_type, ip_addr); } -static switch_status_t -switch_tunnel_ip_encap_table_add_entries(switch_device_t device, - switch_handle_t intf_handle, - switch_interface_info_t *intf_info) -{ - switch_ip_encap_t *ip_encap = NULL; - switch_ip_encap_pd_hdl_t *ip_encap_hdl = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint16_t src_vtep_index = 0; - uint16_t dst_vtep_index = 0; - - 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); - if (!src_vtep_index) { - src_vtep_index = switch_tunnel_src_vtep_insert_hash( - ip_encap->vrf_handle, &ip_encap->src_ip); +static switch_status_t switch_tunnel_ip_encap_table_add_entries( + switch_device_t device, + switch_handle_t intf_handle, + switch_interface_info_t *intf_info) { + switch_ip_encap_t *ip_encap = NULL; + switch_ip_encap_pd_hdl_t *ip_encap_hdl = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint16_t src_vtep_index = 0; + uint16_t dst_vtep_index = 0; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + + ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); + ip_encap_hdl = &intf_info->ip_encap_hdl; + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + + /* + * Allocate Src Vtep Rewrite Index + */ + src_vtep_index = switch_tunnel_src_vtep_search_hash( + ip_encap->vrf_handle, encap_type, &ip_encap->src_ip); + if (!src_vtep_index) { + src_vtep_index = switch_tunnel_src_vtep_insert_hash( + ip_encap->vrf_handle, encap_type, &ip_encap->src_ip); + } else { + SWITCH_API_ERROR("%s:%d: duplicate src vtep entry interface %lx", + __FUNCTION__, + __LINE__, + intf_handle); + goto cleanup; + } + + dst_vtep_index = switch_tunnel_dst_vtep_search_hash( + ip_encap->vrf_handle, encap_type, &ip_encap->dst_ip); + if (!dst_vtep_index) { + dst_vtep_index = switch_tunnel_dst_vtep_insert_hash( + ip_encap->vrf_handle, encap_type, &ip_encap->dst_ip); + } else { + SWITCH_API_ERROR("%s:%d: duplicate dst vtep entry interface %lx", + __FUNCTION__, + __LINE__, + intf_handle); + goto cleanup; + } + + if (intf_info->direction == SWITCH_API_DIRECTION_INGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { #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 */ + 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; } - /* - * Allocate Dst Vtep Rewrite Index - */ - 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); -#ifdef SWITCH_PD - 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_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; } +#endif /* SWITCH_PD */ + } + if (intf_info->direction == SWITCH_API_DIRECTION_EGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { #ifdef SWITCH_PD - status = switch_pd_src_vtep_table_add_entry( - device, ip_encap, intf_info->ifindex, &ip_encap_hdl->src_hw_entry); + 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 vtep entry for " - "interface %lx", __FUNCTION__, __LINE__, - intf_handle); - goto cleanup; + SWITCH_API_ERROR( + "%s:%d: unable to add src rewrite 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); + 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 dest vtep entry for " - "interface %lx", __FUNCTION__, __LINE__, - intf_handle); - goto cleanup; + SWITCH_API_ERROR( + "%s:%d: unable to add dst rewrite 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; + return status; } -static switch_status_t -switch_tunnel_ip_encap_table_delete_entries(switch_device_t device, - switch_handle_t intf_handle, - switch_interface_info_t *intf_info) -{ - switch_ip_encap_t *ip_encap = NULL; - switch_ip_encap_pd_hdl_t *ip_encap_hdl = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - 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); +static switch_status_t switch_tunnel_ip_encap_table_delete_entries( + switch_device_t device, + switch_handle_t intf_handle, + switch_interface_info_t *intf_info) { + switch_ip_encap_t *ip_encap = NULL; + switch_ip_encap_pd_hdl_t *ip_encap_hdl = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + + ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); + ip_encap_hdl = &intf_info->ip_encap_hdl; + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + + status = switch_tunnel_src_vtep_delete_hash( + ip_encap->vrf_handle, encap_type, &ip_encap->src_ip); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete src hash entry for " + "interface %lx", + __FUNCTION__, + __LINE__, + intf_handle); + goto cleanup; + } + + status = switch_tunnel_dst_vtep_delete_hash( + ip_encap->vrf_handle, encap_type, &ip_encap->dst_ip); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete dst hash entry for " + "interface %lx", + __FUNCTION__, + __LINE__, + intf_handle); + goto cleanup; + } + + if (intf_info->direction == SWITCH_API_DIRECTION_BOTH || + intf_info->direction == SWITCH_API_DIRECTION_EGRESS) { #ifdef SWITCH_PD - 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_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; } -#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_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; } #endif /* SWITCH_PD */ + } + if (intf_info->direction == SWITCH_API_DIRECTION_BOTH || + intf_info->direction == SWITCH_API_DIRECTION_INGRESS) { #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; + SWITCH_API_ERROR( + "%s:%d: unable to delete src vtep 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; + 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; + return status; } -static uint32_t -switch_tunnel_mpls_get_pop_label(switch_mpls_encap_t *mpls_encap) -{ - switch_mpls_pop_t *pop_info = NULL; - pop_info = &mpls_encap->u.pop_info; - return pop_info->tag[0].label; +static uint32_t switch_tunnel_mpls_get_pop_label( + switch_mpls_encap_t *mpls_encap) { + switch_mpls_pop_t *pop_info = NULL; + pop_info = &mpls_encap->u.pop_info; + return pop_info->tag[0].label; } -static switch_status_t -switch_tunnel_mpls_table_add_entries(switch_device_t device, - switch_handle_t bd_handle, - p4_pd_entry_hdl_t *entry_hdl, - switch_mpls_encap_t *mpls_encap) -{ - switch_interface_info_t *eg_intf_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_ifindex_t egress_ifindex = 0; - uint32_t label = 0; - - if (bd_handle) { - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } +static switch_status_t switch_tunnel_mpls_table_add_entries( + switch_device_t device, + switch_handle_t bd_handle, + p4_pd_entry_hdl_t *entry_hdl, + switch_mpls_encap_t *mpls_encap) { + switch_interface_info_t *eg_intf_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_ifindex_t egress_ifindex = 0; + uint32_t label = 0; + + if (bd_handle) { + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; } + } - switch (mpls_encap->mpls_mode) { - case SWITCH_API_MPLS_INITIATE: - break; - case SWITCH_API_MPLS_TRANSIT: - switch(mpls_encap->mpls_action) { - case SWITCH_API_MPLS_ACTION_SWAP: - label = SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap); - break; - case SWITCH_API_MPLS_ACTION_SWAP_PUSH: - label = SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap); - break; - default: - return SWITCH_STATUS_UNSUPPORTED_TYPE; - - } - status = switch_pd_mpls_table_add_entry(device, mpls_encap, - handle_to_id(bd_handle), - label, bd_info, egress_ifindex, - entry_hdl); - break; - case SWITCH_API_MPLS_TERMINATE: - if (mpls_encap->mpls_type == SWITCH_API_MPLS_TYPE_PW) { - eg_intf_info = switch_api_interface_get(mpls_encap->egress_if); - if (!eg_intf_info) { - SWITCH_API_ERROR("%s:%d: invalid egress interface for pw mode!", - __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - egress_ifindex = eg_intf_info->ifindex; - } - label = switch_tunnel_mpls_get_pop_label(mpls_encap); - status = switch_pd_mpls_table_add_entry(device, mpls_encap, - handle_to_id(bd_handle), - label, bd_info, egress_ifindex, - entry_hdl); - - break; + switch (mpls_encap->mpls_mode) { + case SWITCH_API_MPLS_INITIATE: + break; + case SWITCH_API_MPLS_TRANSIT: + switch (mpls_encap->mpls_action) { + case SWITCH_API_MPLS_ACTION_SWAP: + label = SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap); + break; + case SWITCH_API_MPLS_ACTION_SWAP_PUSH: + label = SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap); + break; default: - SWITCH_API_ERROR("%s:%d invalid mpls tunnel mode!", __FUNCTION__, - __LINE__); - status = SWITCH_STATUS_UNSUPPORTED_TYPE; - } - return status; + return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + status = switch_pd_mpls_table_add_entry(device, + mpls_encap, + handle_to_id(bd_handle), + label, + bd_info, + egress_ifindex, + entry_hdl); + break; + case SWITCH_API_MPLS_TERMINATE: + if (mpls_encap->mpls_type == SWITCH_API_MPLS_TYPE_PW) { + eg_intf_info = switch_api_interface_get(mpls_encap->egress_if); + if (!eg_intf_info) { + SWITCH_API_ERROR("%s:%d: invalid egress interface for pw mode!", + __FUNCTION__, + __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + egress_ifindex = eg_intf_info->ifindex; + } + label = switch_tunnel_mpls_get_pop_label(mpls_encap); + status = switch_pd_mpls_table_add_entry(device, + mpls_encap, + handle_to_id(bd_handle), + label, + bd_info, + egress_ifindex, + entry_hdl); + + break; + default: + SWITCH_API_ERROR( + "%s:%d invalid mpls tunnel mode!", __FUNCTION__, __LINE__); + status = SWITCH_STATUS_UNSUPPORTED_TYPE; + } + return status; } -static switch_status_t -switch_tunnel_mpls_table_delete_entries(switch_device_t device, - p4_pd_entry_hdl_t entry_hdl, - switch_mpls_encap_t *mpls_encap) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch (mpls_encap->mpls_mode) { - case SWITCH_API_MPLS_INITIATE: - break; - case SWITCH_API_MPLS_TRANSIT: - status = switch_pd_mpls_table_delete_entry(device, entry_hdl); - break; - case SWITCH_API_MPLS_TERMINATE: - status = switch_pd_mpls_table_delete_entry(device, entry_hdl); - break; - default: - SWITCH_API_ERROR("%s:%d invalid mpls tunnel mode!", __FUNCTION__, - __LINE__); - status = SWITCH_STATUS_UNSUPPORTED_TYPE; - } - return status; +static switch_status_t switch_tunnel_mpls_table_delete_entries( + switch_device_t device, + p4_pd_entry_hdl_t entry_hdl, + switch_mpls_encap_t *mpls_encap) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (mpls_encap->mpls_mode) { + case SWITCH_API_MPLS_INITIATE: + break; + case SWITCH_API_MPLS_TRANSIT: + status = switch_pd_mpls_table_delete_entry(device, entry_hdl); + break; + case SWITCH_API_MPLS_TERMINATE: + status = switch_pd_mpls_table_delete_entry(device, entry_hdl); + break; + default: + SWITCH_API_ERROR( + "%s:%d invalid mpls tunnel mode!", __FUNCTION__, __LINE__); + status = SWITCH_STATUS_UNSUPPORTED_TYPE; + } + return status; } -switch_handle_t -switch_api_tunnel_interface_create(switch_device_t device, - switch_direction_t direction, - switch_tunnel_info_t *tunnel_info) -{ - switch_handle_t intf_handle = 0; - switch_api_interface_info_t info; - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - UNUSED(device); - memset(&info, 0, sizeof(switch_api_interface_info_t)); - info.type = SWITCH_API_INTERFACE_TUNNEL; - info.flags.core_intf = tunnel_info->flags.core_intf; - info.flags.flood_enabled = tunnel_info->flags.flood_enabled; - memcpy(&(info.u.tunnel_info), tunnel_info, sizeof(switch_tunnel_info_t)); - intf_handle = switch_api_interface_create(device, &info); - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: unable to allocate memory!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_NO_MEMORY; - } - - if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { - status = switch_tunnel_ip_encap_table_add_entries(device, intf_handle, intf_info); - } - - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: failed to create tunnel interface!", __FUNCTION__, __LINE__); +switch_handle_t switch_api_tunnel_interface_create( + switch_device_t device, + switch_direction_t direction, + switch_tunnel_info_t *tunnel_info) { + switch_handle_t intf_handle = 0; + switch_api_interface_info_t info; + switch_interface_info_t *intf_info = NULL; + switch_encap_info_t *encap_info = NULL; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + uint32_t tunnel_vni = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + UNUSED(device); + memset(&info, 0, sizeof(switch_api_interface_info_t)); + info.type = SWITCH_API_INTERFACE_TUNNEL; + info.flags.core_intf = tunnel_info->flags.core_intf; + info.flags.flood_enabled = tunnel_info->flags.flood_enabled; + memcpy(&(info.u.tunnel_info), tunnel_info, sizeof(switch_tunnel_info_t)); + intf_handle = switch_api_interface_create(device, &info); + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR( + "%s:%d: unable to allocate memory!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_NO_MEMORY; + } + + intf_info->direction = direction; + + if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + if ((encap_type == SWITCH_API_ENCAP_TYPE_VXLAN) || + (encap_type == SWITCH_API_ENCAP_TYPE_NVGRE) || + (encap_type == SWITCH_API_ENCAP_TYPE_GENEVE)) { + encap_info = &(SWITCH_INTF_TUNNEL_ENCAP_INFO(intf_info)); + tunnel_vni = switch_tunnel_get_tunnel_vni(encap_info); + if (!SWITCH_TUNNEL_VNI_VALID(tunnel_vni)) { + SWITCH_API_ERROR( + "%s:%d: failed to create tunnel interface!" + "invalid tunnel vni", + __FUNCTION__, + __LINE__); + switch_api_interface_delete(device, intf_handle); return SWITCH_API_INVALID_HANDLE; + } } - return intf_handle; + status = switch_tunnel_ip_encap_table_add_entries( + device, intf_handle, intf_info); + } + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: failed to create tunnel interface!", __FUNCTION__, __LINE__); + return SWITCH_API_INVALID_HANDLE; + } + return intf_handle; } -switch_status_t -switch_api_tunnel_interface_delete(switch_device_t device, switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_tunnel_info_t *tunnel_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: invalid interface handle %lx", - __FUNCTION__, __LINE__, intf_handle); - return SWITCH_STATUS_INVALID_INTERFACE; - } - - tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); - if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { - status = switch_tunnel_ip_encap_table_delete_entries(device, intf_handle, intf_info); - } - - status = switch_api_interface_delete(device, intf_handle); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete interface %lx", - __FUNCTION__, __LINE__, intf_handle); - goto cleanup; - } - SWITCH_API_TRACE("%s:%d: Tunnel interface %lx deleted", __FUNCTION__, __LINE__, intf_handle); +switch_status_t switch_api_tunnel_interface_delete( + switch_device_t device, switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_tunnel_info_t *tunnel_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d: invalid interface handle %lx", + __FUNCTION__, + __LINE__, + intf_handle); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); + if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { + status = switch_tunnel_ip_encap_table_delete_entries( + device, intf_handle, intf_info); + } + + status = switch_api_interface_delete(device, intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: unable to delete interface %lx", + __FUNCTION__, + __LINE__, + intf_handle); + goto cleanup; + } + SWITCH_API_TRACE("%s:%d: Tunnel interface %lx deleted", + __FUNCTION__, + __LINE__, + intf_handle); cleanup: - return status; + return status; } -switch_status_t -switch_api_logical_network_member_add(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d invalid interface handle %lx", - __FUNCTION__, __LINE__, intf_handle); - return SWITCH_STATUS_INVALID_INTERFACE; - } - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - SWITCH_API_ERROR("%s:%d invalid logical network handle %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - intf_info->ln_bd_handle = bd_handle; - switch(SWITCH_LN_NETWORK_TYPE(bd_info)) { - case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC: - status = switch_api_logical_network_member_add_basic(device, bd_handle, intf_handle); - break; - case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED: - status = switch_api_logical_network_member_add_enhanced(device, bd_handle, intf_handle); - break; - - default: - status = SWITCH_STATUS_INVALID_LN_TYPE; - } - return status; +switch_status_t switch_api_logical_network_member_add( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d invalid interface handle %lx", + __FUNCTION__, + __LINE__, + intf_handle); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("%s:%d invalid logical network handle %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + intf_info->ln_bd_handle = bd_handle; + switch (SWITCH_LN_NETWORK_TYPE(bd_info)) { + case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC: + status = switch_api_logical_network_member_add_basic( + device, bd_handle, intf_handle); + break; + case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED: + status = switch_api_logical_network_member_add_enhanced( + device, bd_handle, intf_handle); + break; + + default: + status = SWITCH_STATUS_INVALID_LN_TYPE; + } + return status; } -switch_status_t -switch_api_logical_network_member_add_basic(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_ln_member_t *ln_member = NULL; - switch_ip_encap_t *ip_encap = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; - uint16_t tunnel_vni = 0; - uint8_t tunnel_type = 0; - switch_vlan_t vlan_id = 0; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d invalid interface handle %lx", - __FUNCTION__, __LINE__, intf_handle); - return SWITCH_STATUS_INVALID_INTERFACE; +switch_status_t switch_api_logical_network_member_add_basic( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_ln_member_t *ln_member = NULL; + switch_ip_encap_t *ip_encap = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + uint16_t tunnel_vni = 0; + uint8_t tunnel_type = 0; + switch_vlan_t vlan_id = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d invalid interface handle %lx", + __FUNCTION__, + __LINE__, + intf_handle); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("%s:%d invalid logical network handle %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + intf_info->ln_bd_handle = bd_handle; + ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!ln_member) { + ln_member = switch_malloc(sizeof(switch_ln_member_t), 1); + if (!ln_member) { + return SWITCH_STATUS_NO_MEMORY; } - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - SWITCH_API_ERROR("%s:%d invalid logical network handle %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_INVALID_VLAN_ID; + 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); + } + + 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_vni = SWITCH_LN_TUNNEL_VNI(bd_info); + tunnel_type = switch_tunnel_get_egress_tunnel_type(encap_type, ip_encap); +#ifdef SWITCH_PD + if (intf_info->direction == SWITCH_API_DIRECTION_INGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_tunnel_table_add_entry(device, + encap_type, + tunnel_vni, + ln_member->rid, + bd_info, + ip_encap, + handle_to_id(bd_handle), + ln_member->tunnel_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to add tunnel entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; + } } - intf_info->ln_bd_handle = bd_handle; - ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); - if (!ln_member) { - ln_member = switch_malloc(sizeof(switch_ln_member_t), 1); - 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); + if (intf_info->direction == SWITCH_API_DIRECTION_EGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = + switch_pd_egress_vni_table_add_entry(device, + handle_to_id(bd_handle), + tunnel_vni, + tunnel_type, + &ln_member->egress_bd_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to add egress bd map entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; + } } - - 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_vni = SWITCH_LN_TUNNEL_VNI(bd_info); - tunnel_type = switch_tunnel_get_egress_tunnel_type(encap_type, ip_encap); -#ifdef SWITCH_PD - status = switch_pd_tunnel_table_add_entry(device, encap_type, - tunnel_vni, - ln_member->rid, - bd_info, - ip_encap, - handle_to_id(bd_handle), - ln_member->tunnel_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add tunnel entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - status = switch_pd_egress_vni_table_add_entry(device, - handle_to_id(bd_handle), - tunnel_vni, tunnel_type, - &ln_member->egress_bd_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add egress bd map entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } #endif - } else { - switch(SWITCH_INTF_TYPE(intf_info)) { - case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: - vlan_id = 0; - break; - case SWITCH_API_INTERFACE_L2_PORT_VLAN: - vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); - break; - default: - SWITCH_API_ERROR("%s:%d: trying to add unsupported interface type for ln %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_UNSUPPORTED_TYPE; - } - status = switch_pd_port_vlan_mapping_table_add_entry(device, vlan_id, 0, + } else { + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + vlan_id = 0; + break; + case SWITCH_API_INTERFACE_L2_PORT_VLAN: + vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); + break; + default: + SWITCH_API_ERROR( + "%s:%d: trying to add unsupported interface type for ln %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + status = + switch_pd_port_vlan_mapping_table_add_entry(device, + vlan_id, + 0, intf_info, bd_info->bd_entry, &(ln_member->pv_hw_entry)); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add port-vlan entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - status = switch_api_vlan_xlate_add(device, bd_handle, intf_handle, vlan_id); - } - - if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { - switch_vlan_interface_t vlan_intf; - memset(&vlan_intf, 0, sizeof(vlan_intf)); - vlan_intf.vlan_handle = bd_handle; - vlan_intf.intf_handle = intf_handle; - status = switch_api_multicast_member_add(device, - bd_info->uuc_mc_index, - 1, &vlan_intf); - } if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: Unable to add interface %lx to flood list of ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); + SWITCH_API_ERROR( + "%s:%d: unable to add port-vlan entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; } + status = switch_api_vlan_xlate_add(device, bd_handle, intf_handle, vlan_id); + } + + if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { + switch_vlan_interface_t vlan_intf; + memset(&vlan_intf, 0, sizeof(vlan_intf)); + vlan_intf.vlan_handle = bd_handle; + vlan_intf.intf_handle = intf_handle; + status = switch_api_multicast_member_add( + device, bd_info->uuc_mc_index, 1, &vlan_intf); + } + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: Unable to add interface %lx to flood list of ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + } cleanup: - return status; + return status; } -switch_status_t -switch_api_logical_network_member_add_enhanced(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_tunnel_info_t *tunnel_info = NULL; - switch_bd_info_t *bd_info = NULL; - switch_encap_info_t *encap_info = NULL; - switch_ln_member_t *ln_member = NULL; - switch_ip_encap_t *ip_encap = NULL; - switch_mpls_encap_t *mpls_encap = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; - uint16_t tunnel_vni = 0; - uint8_t tunnel_type = 0; - switch_vlan_t vlan_id = 0; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d invalid interface handle %lx", - __FUNCTION__, __LINE__, intf_handle); - return SWITCH_STATUS_INVALID_INTERFACE; - } - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - SWITCH_API_ERROR("%s:%d invalid logical network handle %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - intf_info->ln_bd_handle = bd_handle; - ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); +switch_status_t switch_api_logical_network_member_add_enhanced( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_tunnel_info_t *tunnel_info = NULL; + switch_bd_info_t *bd_info = NULL; + switch_encap_info_t *encap_info = NULL; + switch_ln_member_t *ln_member = NULL; + switch_ip_encap_t *ip_encap = NULL; + switch_mpls_encap_t *mpls_encap = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; + uint16_t tunnel_vni = 0; + uint8_t tunnel_type = 0; + switch_vlan_t vlan_id = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d invalid interface handle %lx", + __FUNCTION__, + __LINE__, + intf_handle); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + SWITCH_API_ERROR("%s:%d invalid logical network handle %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + intf_info->ln_bd_handle = bd_handle; + ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!ln_member) { + ln_member = switch_malloc(sizeof(switch_ln_member_t), 1); if (!ln_member) { - ln_member = switch_malloc(sizeof(switch_ln_member_t), 1); - 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); + 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); + } - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); - if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { - encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); - ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); - encap_info = &(SWITCH_INTF_TUNNEL_ENCAP_INFO(intf_info)); - tunnel_vni = switch_tunnel_get_tunnel_vni(encap_info); - tunnel_type = switch_tunnel_get_egress_tunnel_type(encap_info->encap_type, ip_encap); + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); + if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { + encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); + ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); + encap_info = &(SWITCH_INTF_TUNNEL_ENCAP_INFO(intf_info)); + tunnel_vni = switch_tunnel_get_tunnel_vni(encap_info); + tunnel_type = switch_tunnel_get_egress_tunnel_type(encap_info->encap_type, + ip_encap); #ifdef SWITCH_PD - ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); - status = switch_pd_tunnel_table_add_entry(device, encap_type, - tunnel_vni, - ln_member->rid, - bd_info, - ip_encap, - handle_to_id(bd_handle), - ln_member->tunnel_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add tunnel entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - - status = switch_pd_egress_vni_table_add_entry(device, - handle_to_id(bd_handle), - tunnel_vni, tunnel_type, - &ln_member->egress_bd_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add egress bd map entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { - mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); - status = switch_tunnel_mpls_table_add_entries(device, bd_handle, - ln_member->tunnel_hw_entry, mpls_encap); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d unable to add mpls entry!", __FUNCTION__, __LINE__); - goto cleanup; - } + ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); + if (intf_info->direction == SWITCH_API_DIRECTION_INGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_tunnel_table_add_entry(device, + encap_type, + tunnel_vni, + ln_member->rid, + bd_info, + ip_encap, + handle_to_id(bd_handle), + ln_member->tunnel_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to add tunnel entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; } -#endif - } else { - // access port - switch(SWITCH_INTF_TYPE(intf_info)) { - case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: - vlan_id = 0; - break; - case SWITCH_API_INTERFACE_L2_PORT_VLAN: - vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); - break; - default: - SWITCH_API_ERROR("%s:%d: trying to add unsupported interface type for ln %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + + if (intf_info->direction == SWITCH_API_DIRECTION_EGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_egress_vni_table_add_entry( + device, + handle_to_id(bd_handle), + tunnel_vni, + tunnel_type, + &ln_member->egress_bd_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to add egress bd map entry for interface %lx ln " + "%lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; } + } + } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { + mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); + status = switch_tunnel_mpls_table_add_entries( + device, bd_handle, ln_member->tunnel_hw_entry, mpls_encap); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d unable to add mpls entry!", __FUNCTION__, __LINE__); + goto cleanup; + } + } +#endif + } else { + // access port + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + vlan_id = 0; + break; + case SWITCH_API_INTERFACE_L2_PORT_VLAN: + vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); + break; + default: + SWITCH_API_ERROR( + "%s:%d: trying to add unsupported interface type for ln %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_UNSUPPORTED_TYPE; + } #ifdef SWITCH_PD - status = switch_pd_port_vlan_mapping_table_add_entry(device, vlan_id, 0, + status = + switch_pd_port_vlan_mapping_table_add_entry(device, + vlan_id, + 0, intf_info, bd_info->bd_entry, &(ln_member->pv_hw_entry)); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add port to vlan!.", __FUNCTION__, __LINE__); - return status; - } - status = switch_api_vlan_xlate_add(device, bd_handle, intf_handle, vlan_id); -#endif + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to add port to vlan!.", __FUNCTION__, __LINE__); + return status; } - if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { - switch_vlan_interface_t vlan_intf; - memset(&vlan_intf, 0, sizeof(vlan_intf)); - vlan_intf.vlan_handle = bd_handle; - vlan_intf.intf_handle = intf_handle; - status = switch_api_multicast_member_add(device, - bd_info->uuc_mc_index, - 1, &vlan_intf); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: Unable to add interface %lx to flood list of ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - } + status = switch_api_vlan_xlate_add(device, bd_handle, intf_handle, vlan_id); +#endif + } + if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { + switch_vlan_interface_t vlan_intf; + memset(&vlan_intf, 0, sizeof(vlan_intf)); + vlan_intf.vlan_handle = bd_handle; + vlan_intf.intf_handle = intf_handle; + status = switch_api_multicast_member_add( + device, bd_info->uuc_mc_index, 1, &vlan_intf); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: Unable to add interface %lx to flood list of ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); } + } cleanup: - return status; + return status; } -switch_status_t -switch_api_logical_network_member_remove_basic(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_ln_member_t *ln_member = NULL; - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_vlan_t vlan_id = 0; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; +switch_status_t switch_api_logical_network_member_remove_basic( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_ln_member_t *ln_member = NULL; + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_vlan_t vlan_id = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + intf_info->ln_bd_handle = 0; + ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!ln_member) { + SWITCH_API_ERROR("%s:%d: unable to find member interface %lx for ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; + } + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { +#ifdef SWITCH_PD + if (intf_info->direction == SWITCH_API_DIRECTION_INGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_tunnel_table_delete_entry(device, + ln_member->tunnel_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete tunnel entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; + } } - intf_info->ln_bd_handle = 0; - ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); - if (!ln_member) { - SWITCH_API_ERROR("%s:%d: unable to find member interface %lx for ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); + if (intf_info->direction == SWITCH_API_DIRECTION_EGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_egress_vni_table_delete_entry( + device, ln_member->egress_bd_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete egress bd map entry for interface %lx ln " + "%lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); goto cleanup; + } } - - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { -#ifdef SWITCH_PD - status = switch_pd_tunnel_table_delete_entry(device, ln_member->tunnel_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete tunnel entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - - status = switch_pd_egress_vni_table_delete_entry(device, ln_member->egress_bd_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete egress bd map entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } #endif - } else { - switch(SWITCH_INTF_TYPE(intf_info)) { - case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: - vlan_id = 0; - break; - case SWITCH_API_INTERFACE_L2_PORT_VLAN: - vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); - break; - default: - SWITCH_API_ERROR("%s:%d: trying to add unsupported interface type for ln %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_UNSUPPORTED_TYPE; - } - status = switch_pd_port_vlan_mapping_table_delete_entry(device, ln_member->pv_hw_entry); -#ifdef SWITCH_PD - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete port-vlan entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; -#endif - } - status = switch_api_vlan_xlate_remove(device, bd_handle, intf_handle, vlan_id); - } - if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { - switch_vlan_interface_t vlan_intf; - memset(&vlan_intf, 0, sizeof(vlan_intf)); - vlan_intf.vlan_handle = bd_handle; - vlan_intf.intf_handle = intf_handle; - status = switch_api_multicast_member_delete(device, - bd_info->uuc_mc_index, - 1, &vlan_intf); + } else { + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + vlan_id = 0; + break; + case SWITCH_API_INTERFACE_L2_PORT_VLAN: + vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); + break; + default: + SWITCH_API_ERROR( + "%s:%d: trying to add unsupported interface type for ln %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_UNSUPPORTED_TYPE; } + status = switch_pd_port_vlan_mapping_table_delete_entry( + device, ln_member->pv_hw_entry); +#ifdef SWITCH_PD if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: Unable to add interface %lx to flood list of ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); + SWITCH_API_ERROR( + "%s:%d: unable to delete port-vlan entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; +#endif } - switch_mcast_rid_free(ln_member->rid); - tommy_list_remove_existing(&(bd_info->members), &(ln_member->node)); - switch_free(ln_member); + status = + switch_api_vlan_xlate_remove(device, bd_handle, intf_handle, vlan_id); + } + if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { + switch_vlan_interface_t vlan_intf; + memset(&vlan_intf, 0, sizeof(vlan_intf)); + vlan_intf.vlan_handle = bd_handle; + vlan_intf.intf_handle = intf_handle; + status = switch_api_multicast_member_delete( + device, bd_info->uuc_mc_index, 1, &vlan_intf); + } + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: Unable to add interface %lx to flood list of ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + } + switch_mcast_rid_free(ln_member->rid); + tommy_list_remove_existing(&(bd_info->members), &(ln_member->node)); + switch_free(ln_member); cleanup: - return status; + return status; } -switch_status_t -switch_api_logical_network_member_remove_enhanced(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_ln_member_t *ln_member = NULL; - switch_bd_info_t *bd_info = NULL; - switch_tunnel_info_t *tunnel_info = NULL; - switch_mpls_encap_t *mpls_encap = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_vlan_t vlan_id = 0; - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - intf_info->ln_bd_handle = 0; - ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); - if (!ln_member) { - SWITCH_API_ERROR("%s:%d: unable to find member interface %lx for ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - - if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { - tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); - if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { +switch_status_t switch_api_logical_network_member_remove_enhanced( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_ln_member_t *ln_member = NULL; + switch_bd_info_t *bd_info = NULL; + switch_tunnel_info_t *tunnel_info = NULL; + switch_mpls_encap_t *mpls_encap = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_vlan_t vlan_id = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + intf_info->ln_bd_handle = 0; + ln_member = switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!ln_member) { + SWITCH_API_ERROR("%s:%d: unable to find member interface %lx for ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; + } + + if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { + tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); + if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { #ifdef SWITCH_PD - status = switch_pd_tunnel_table_delete_entry(device, ln_member->tunnel_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete tunnel entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - - status = switch_pd_egress_vni_table_delete_entry(device, ln_member->egress_bd_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete egress bd map entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; - } - } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { - mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); - status = switch_tunnel_mpls_table_delete_entries(device, ln_member->tunnel_hw_entry[0], mpls_encap); + if (intf_info->direction == SWITCH_API_DIRECTION_INGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_tunnel_table_delete_entry( + device, ln_member->tunnel_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete tunnel entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; } -#endif - } else { - switch(SWITCH_INTF_TYPE(intf_info)) { - case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: - vlan_id = 0; - break; - case SWITCH_API_INTERFACE_L2_PORT_VLAN: - vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); - break; - default: - SWITCH_API_ERROR("%s:%d: trying to add unsupported interface type for ln %lx", - __FUNCTION__, __LINE__, bd_handle); - return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + + if (intf_info->direction == SWITCH_API_DIRECTION_EGRESS || + intf_info->direction == SWITCH_API_DIRECTION_BOTH) { + status = switch_pd_egress_vni_table_delete_entry( + device, ln_member->egress_bd_hw_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete egress bd map entry for interface %lx " + "ln " + "%lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; } - status = switch_pd_port_vlan_mapping_table_delete_entry(device, ln_member->pv_hw_entry); + } + } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { + mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); + status = switch_tunnel_mpls_table_delete_entries( + device, ln_member->tunnel_hw_entry[0], mpls_encap); + } +#endif + } else { + switch (SWITCH_INTF_TYPE(intf_info)) { + case SWITCH_API_INTERFACE_L2_VLAN_ACCESS: + vlan_id = 0; + break; + case SWITCH_API_INTERFACE_L2_PORT_VLAN: + vlan_id = SWITCH_INTF_PV_VLAN_ID(intf_info); + break; + default: + SWITCH_API_ERROR( + "%s:%d: trying to add unsupported interface type for ln %lx", + __FUNCTION__, + __LINE__, + bd_handle); + return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + status = switch_pd_port_vlan_mapping_table_delete_entry( + device, ln_member->pv_hw_entry); #ifdef SWITCH_PD - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to delete port-vlan entry for interface %lx ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - goto cleanup; + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: unable to delete port-vlan entry for interface %lx ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); + goto cleanup; #endif - } - status = switch_api_vlan_xlate_remove(device, bd_handle, intf_handle, vlan_id); } - if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { - switch_vlan_interface_t vlan_intf; - memset(&vlan_intf, 0, sizeof(vlan_intf)); - vlan_intf.vlan_handle = bd_handle; - vlan_intf.intf_handle = intf_handle; - status = switch_api_multicast_member_delete(device, - bd_info->uuc_mc_index, - 1, &vlan_intf); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: Unable to remove interface %lx from flood list of ln %lx", - __FUNCTION__, __LINE__, intf_handle, bd_handle); - } + status = + switch_api_vlan_xlate_remove(device, bd_handle, intf_handle, vlan_id); + } + if (SWITCH_INTF_FLOOD_ENABLED(intf_info)) { + switch_vlan_interface_t vlan_intf; + memset(&vlan_intf, 0, sizeof(vlan_intf)); + vlan_intf.vlan_handle = bd_handle; + vlan_intf.intf_handle = intf_handle; + status = switch_api_multicast_member_delete( + device, bd_info->uuc_mc_index, 1, &vlan_intf); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d: Unable to remove interface %lx from flood list of ln %lx", + __FUNCTION__, + __LINE__, + intf_handle, + bd_handle); } - switch_mcast_rid_free(ln_member->rid); - tommy_list_remove_existing(&(bd_info->members), &(ln_member->node)); - switch_free(ln_member); + } + switch_mcast_rid_free(ln_member->rid); + tommy_list_remove_existing(&(bd_info->members), &(ln_member->node)); + switch_free(ln_member); cleanup: - return status; + return status; } -switch_status_t -switch_api_logical_network_member_remove(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - switch_bd_info_t *bd_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; - } - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } +switch_status_t switch_api_logical_network_member_remove( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + switch_bd_info_t *bd_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; + } + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + switch (SWITCH_LN_NETWORK_TYPE(bd_info)) { + case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC: + status = switch_api_logical_network_member_remove_basic( + device, bd_handle, intf_handle); + break; + case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED: + status = switch_api_logical_network_member_remove_enhanced( + device, bd_handle, intf_handle); + break; + default: + status = SWITCH_STATUS_INVALID_LN_TYPE; + } + return status; +} - switch(SWITCH_LN_NETWORK_TYPE(bd_info)) { - case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC: - status = switch_api_logical_network_member_remove_basic(device, bd_handle, intf_handle); - break; - case SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED: - status = switch_api_logical_network_member_remove_enhanced(device, bd_handle, intf_handle); - break; - default: - status = SWITCH_STATUS_INVALID_LN_TYPE; - } - return status; +uint16_t switch_tunnel_get_tunnel_vni(switch_encap_info_t *encap_info) { + uint16_t tunnel_vni = 0; + switch (encap_info->encap_type) { + case SWITCH_API_ENCAP_TYPE_VXLAN: + tunnel_vni = SWITCH_ENCAP_VXLAN_VNI(encap_info); + break; + case SWITCH_API_ENCAP_TYPE_GENEVE: + tunnel_vni = SWITCH_ENCAP_GENEVE_VNI(encap_info); + break; + case SWITCH_API_ENCAP_TYPE_NVGRE: + tunnel_vni = SWITCH_ENCAP_NVGRE_VNI(encap_info); + break; + default: + tunnel_vni = 0; + } + return tunnel_vni; } -uint16_t -switch_tunnel_get_tunnel_vni(switch_encap_info_t *encap_info) -{ - uint16_t tunnel_vni = 0; - switch(encap_info->encap_type) - { - case SWITCH_API_ENCAP_TYPE_VXLAN: - tunnel_vni = SWITCH_ENCAP_VXLAN_VNI(encap_info); - break; - case SWITCH_API_ENCAP_TYPE_GENEVE: - tunnel_vni = SWITCH_ENCAP_GENEVE_VNI(encap_info); - break; - case SWITCH_API_ENCAP_TYPE_NVGRE: - tunnel_vni = SWITCH_ENCAP_NVGRE_VNI(encap_info); - break; +switch_tunnel_type_ingress_t switch_tunnel_get_ingress_tunnel_type( + switch_ip_encap_t *ip_encap) { + switch_tunnel_type_ingress_t tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NONE; + switch (ip_encap->proto) { + case IPPROTO_IPIP: + case IPPROTO_IPV6: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IPIP; + break; + case IPPROTO_GRE: { + switch (ip_encap->u.gre.protocol) { + case GRE_PROTO_NVGRE: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NVGRE; + break; default: - tunnel_vni = 0; + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GRE; + break; + } + break; } - return tunnel_vni; -} - -switch_tunnel_type_ingress_t -switch_tunnel_get_ingress_tunnel_type(switch_ip_encap_t *ip_encap) -{ - switch_tunnel_type_ingress_t tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NONE; - switch (ip_encap->proto) - { - case IPPROTO_IPIP: - case IPPROTO_IPV6: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_IPIP; - break; - case IPPROTO_GRE: { - switch (ip_encap->u.gre.protocol) { - case GRE_PROTO_NVGRE: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_NVGRE; - break; - default : - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GRE; - break; - } - break; - } - case IPPROTO_UDP: { - switch (SWITCH_IP_ENCAP_UDP_DST_PORT(ip_encap)) { - case UDP_PORT_VXLAN: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_VXLAN; - break; - case UDP_PORT_GENEVE: - tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GENEVE; - break; - default : - break; - } - break; - } + case IPPROTO_UDP: { + switch (SWITCH_IP_ENCAP_UDP_DST_PORT(ip_encap)) { + case UDP_PORT_VXLAN: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_VXLAN; + break; + case UDP_PORT_GENEVE: + tunnel_type = SWITCH_INGRESS_TUNNEL_TYPE_GENEVE; + break; default: - break; + break; + } + break; } + default: + break; + } - return tunnel_type; + return tunnel_type; } -switch_tunnel_type_egress_t -switch_tunnel_get_egress_tunnel_type(switch_encap_type_t encap_type, switch_ip_encap_t *ip_encap) -{ - switch_tunnel_type_egress_t tunnel_type = 0; - switch(encap_type) - { - case SWITCH_API_ENCAP_TYPE_VXLAN: - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; - } - break; - case SWITCH_API_ENCAP_TYPE_GENEVE: - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; - } - break; - case SWITCH_API_ENCAP_TYPE_NVGRE: - if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; - } else { - tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE; - } - break; - default: - tunnel_type = 0; - } - return tunnel_type; +switch_tunnel_type_egress_t switch_tunnel_get_egress_tunnel_type( + switch_encap_type_t encap_type, switch_ip_encap_t *ip_encap) { + switch_tunnel_type_egress_t tunnel_type = 0; + switch (encap_type) { + case SWITCH_API_ENCAP_TYPE_VXLAN: + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_VXLAN; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_VXLAN; + } + break; + case SWITCH_API_ENCAP_TYPE_GENEVE: + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_GENEVE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_GENEVE; + } + break; + case SWITCH_API_ENCAP_TYPE_NVGRE: + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_NVGRE; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_NVGRE; + } + break; + case SWITCH_API_ENCAP_TYPE_ERSPAN_T3: + if (SWITCH_IP_ENCAP_SRC_IP_TYPE(ip_encap) == SWITCH_API_IP_ADDR_V4) { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV4_ERSPAN_T3; + } else { + tunnel_type = SWITCH_EGRESS_TUNNEL_TYPE_IPV6_ERSPAN_T3; + } + break; + default: + tunnel_type = 0; + } + return tunnel_type; } -switch_status_t -switch_api_mpls_tunnel_transit_create(switch_device_t device, switch_mpls_encap_t *mpls_encap) -{ - switch_mpls_info_t *mpls_info = NULL; - void *temp = NULL; - uint32_t swap_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch(mpls_encap->mpls_action) { - case SWITCH_API_MPLS_ACTION_SWAP: - swap_label = SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap); - break; - case SWITCH_API_MPLS_ACTION_SWAP_PUSH: - swap_label = SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap); - break; - default: - return SWITCH_STATUS_UNSUPPORTED_TYPE; +switch_status_t switch_api_mpls_tunnel_transit_create( + switch_device_t device, switch_mpls_encap_t *mpls_encap) { + switch_mpls_info_t *mpls_info = NULL; + void *temp = NULL; + uint32_t swap_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (mpls_encap->mpls_action) { + case SWITCH_API_MPLS_ACTION_SWAP: + swap_label = SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap); + break; + case SWITCH_API_MPLS_ACTION_SWAP_PUSH: + swap_label = SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap); + break; + default: + return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + JLG(temp, mpls_transit_array, swap_label); + if (!temp) { + mpls_info = switch_malloc(sizeof(switch_mpls_info_t), 1); + if (!mpls_info) { + SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_NO_MEMORY; } - JLG(temp, mpls_transit_array, swap_label); - if (!temp) { - mpls_info = switch_malloc(sizeof(switch_mpls_info_t), 1); - if (!mpls_info) { - SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_NO_MEMORY; - } - memcpy(&mpls_info->mpls_encap, mpls_encap, sizeof(switch_mpls_encap_t)); - JLI(temp, mpls_transit_array, swap_label); - *(unsigned long *)temp = (unsigned long) mpls_info; - status = switch_tunnel_mpls_table_add_entries(device, 0, &mpls_info->tunnel_hw_entry, mpls_encap); - } else { - //TODO: Update Mpls transit - } - return status; + memcpy(&mpls_info->mpls_encap, mpls_encap, sizeof(switch_mpls_encap_t)); + JLI(temp, mpls_transit_array, swap_label); + *(unsigned long *)temp = (unsigned long)mpls_info; + status = switch_tunnel_mpls_table_add_entries( + device, 0, &mpls_info->tunnel_hw_entry, mpls_encap); + } else { + // TODO: Update Mpls transit + } + return status; } -switch_status_t -switch_api_mpls_tunnel_transit_delete(switch_device_t device, switch_mpls_encap_t *mpls_encap) -{ - switch_mpls_info_t *mpls_info = NULL; - void *temp = NULL; - uint32_t swap_label = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch(mpls_encap->mpls_action) { - case SWITCH_API_MPLS_ACTION_SWAP: - swap_label = SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap); - break; - case SWITCH_API_MPLS_ACTION_SWAP_PUSH: - swap_label = SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap); - break; - default: - return SWITCH_STATUS_UNSUPPORTED_TYPE; - } - JLG(temp, mpls_transit_array, swap_label); - if (!temp) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - - mpls_info = (switch_mpls_info_t *) (*(unsigned long *)temp); - status = switch_tunnel_mpls_table_delete_entries(device, mpls_info->tunnel_hw_entry, mpls_encap); - JLD(status, mpls_transit_array, swap_label); - switch_free(mpls_info); - return status; +switch_status_t switch_api_mpls_tunnel_transit_delete( + switch_device_t device, switch_mpls_encap_t *mpls_encap) { + switch_mpls_info_t *mpls_info = NULL; + void *temp = NULL; + uint32_t swap_label = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (mpls_encap->mpls_action) { + case SWITCH_API_MPLS_ACTION_SWAP: + swap_label = SWITCH_MPLS_SWAP_OLD_LABEL(mpls_encap); + break; + case SWITCH_API_MPLS_ACTION_SWAP_PUSH: + swap_label = SWITCH_MPLS_SWAP_PUSH_OLD_LABEL(mpls_encap); + break; + default: + return SWITCH_STATUS_UNSUPPORTED_TYPE; + } + JLG(temp, mpls_transit_array, swap_label); + if (!temp) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + + mpls_info = (switch_mpls_info_t *)(*(unsigned long *)temp); + status = switch_tunnel_mpls_table_delete_entries( + device, mpls_info->tunnel_hw_entry, mpls_encap); + JLD(status, mpls_transit_array, swap_label); + switch_free(mpls_info); + return status; } diff --git a/switchapi/src/switch_tunnel_int.h b/switchapi/src/switch_tunnel_int.h index b7a5ca6..7ee700d 100644 --- a/switchapi/src/switch_tunnel_int.h +++ b/switchapi/src/switch_tunnel_int.h @@ -17,65 +17,74 @@ limitations under the License. #include "switchapi/switch_base_types.h" #include "switchapi/switch_handle.h" #include "switchapi/switch_neighbor.h" +#include "switch_pd_types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -#define SWITCH_VTEP_HASH_KEY_SIZE 32 +#define SWITCH_VTEP_HASH_KEY_SIZE 40 #define SWITCH_SRC_VTEP_HASH_TABLE_SIZE 4096 #define SWITCH_DST_VTEP_HASH_TABLE_SIZE 4096 +#define SWITCH_TUNNEL_VNI_SIZE 24 + +#define SWITCH_TUNNEL_VNI_VALID(_vni) \ + (_vni < ((1 << SWITCH_TUNNEL_VNI_SIZE) - 1)) + typedef struct switch_vtep_entry_ { - unsigned int key[SWITCH_VTEP_HASH_KEY_SIZE]; - tommy_hashtable_node node; - switch_handle_t vrf; - switch_ip_addr_t ip_addr; - uint16_t entry_index; + unsigned int key[SWITCH_VTEP_HASH_KEY_SIZE]; + tommy_hashtable_node node; + switch_handle_t vrf; + switch_ip_addr_t ip_addr; + switch_encap_type_t encap_type; + uint16_t entry_index; } switch_vtep_entry_t; typedef struct switch_mpls_info_ { - switch_mpls_encap_t mpls_encap; - p4_pd_entry_hdl_t tunnel_hw_entry; + switch_mpls_encap_t mpls_encap; + p4_pd_entry_hdl_t tunnel_hw_entry; } switch_mpls_info_t; 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_src_vtep_index_get(switch_handle_t vrf, + switch_encap_type_t encap_type, + 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_dst_vtep_index_get(switch_handle_t vrf, + switch_encap_type_t encap_type, + switch_ip_addr_t *ip_addr); -switch_status_t -switch_api_logical_network_member_add_basic(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle); +switch_status_t switch_api_logical_network_member_add_basic( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle); -switch_status_t -switch_api_logical_network_member_remove_basic(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle); +switch_status_t switch_api_logical_network_member_remove_basic( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle); -switch_status_t -switch_api_logical_network_member_add_enhanced(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle); +switch_status_t switch_api_logical_network_member_add_enhanced( + switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle); -switch_status_t -switch_api_logical_network_member_remove_enhanced(switch_device_t device, - switch_handle_t bd_handle, - switch_handle_t intf_handle); +switch_status_t 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); -switch_tunnel_type_ingress_t -switch_tunnel_get_ingress_tunnel_type(switch_ip_encap_t *ip_encap); +switch_tunnel_type_ingress_t switch_tunnel_get_ingress_tunnel_type( + switch_ip_encap_t *ip_encap); -switch_tunnel_type_egress_t -switch_tunnel_get_egress_tunnel_type(switch_encap_type_t encap_type, switch_ip_encap_t *ip_encap); +switch_tunnel_type_egress_t switch_tunnel_get_egress_tunnel_type( + switch_encap_type_t encap_type, switch_ip_encap_t *ip_encap); #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_utils.c b/switchapi/src/switch_utils.c index d0f6d1d..05c6173 100644 --- a/switchapi/src/switch_utils.c +++ b/switchapi/src/switch_utils.c @@ -17,72 +17,64 @@ limitations under the License. #include "switchapi/switch_utils.h" #include "switch_ver.h" -#define SWITCH_L3_HASH_TABLE_SIZE (64*1024) +#define SWITCH_L3_HASH_TABLE_SIZE (64 * 1024) #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -uint32_t MurmurHash2 ( const void * key, size_t len, uint32_t seed ) -{ - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. +uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed) { +// 'm' and 'r' are mixing constants generated offline. +// They're not really 'magic', they just happen to work well. #define m 0x5bd1e995 #define r 24 - // Initialize the hash to a 'random' value - uint32_t h = seed ^ (unsigned int)len; + // Initialize the hash to a 'random' value + uint32_t h = seed ^ (unsigned int)len; - // Mix 4 bytes at a time into the hash + // Mix 4 bytes at a time into the hash - const unsigned char * data = (const unsigned char *)key; + const unsigned char *data = (const unsigned char *)key; - while(len >= 4) - { - uint32_t k = *(uint32_t *)data; + while (len >= 4) { + uint32_t k = *(uint32_t *)data; - k *= m; - k ^= k >> r; - k *= m; - h *= m; - h ^= k; + k *= m; + k ^= k >> r; + k *= m; + h *= m; + h ^= k; - data += 4; - len -= 4; - } + data += 4; + len -= 4; + } - // Handle the last few bytes of the input array + // Handle the last few bytes of the input array - switch(len) - { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; - h *= m; - }; + switch (len) { + case 3: + h ^= data[2] << 16; + case 2: + h ^= data[1] << 8; + case 1: + h ^= data[0]; + h *= m; + }; - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. + // Do a few final mixes of the hash to ensure the last few + // bytes are well-incorporated. - h ^= h >> 13; - h *= m; - h ^= h >> 15; + h ^= h >> 13; + h *= m; + h ^= h >> 15; - return h; + return h; } -const char * -switch_get_version(void) -{ - return SWITCH_VER; -} +const char *switch_get_version(void) { return SWITCH_VER; } -const char * -switch_get_internal_version(void) -{ - return SWITCH_INTERNAL_VER; -} +const char *switch_get_internal_version(void) { return SWITCH_INTERNAL_VER; } #ifdef __cplusplus } diff --git a/switchapi/src/switch_vlan.c b/switchapi/src/switch_vlan.c index 1a65bef..7929d0b 100644 --- a/switchapi/src/switch_vlan.c +++ b/switchapi/src/switch_vlan.c @@ -20,6 +20,8 @@ limitations under the License. #include "switchapi/switch_port.h" #include "switchapi/switch_mcast.h" #include "switchapi/switch_utils.h" +#include "switch_tunnel_int.h" +#include "switch_capability_int.h" #include "switch_pd.h" #include "switch_lag_int.h" #include "switch_log_int.h" @@ -27,1613 +29,1593 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - -switch_api_id_allocator *bd_stats_index=NULL; +switch_api_id_allocator *bd_stats_index = NULL; static void *switch_bd_array = NULL; switch_handle_t vlan_handle_list[SWITCH_API_MAX_VLANS]; -static tommy_hashtable switch_vlan_port_hash_table; - -switch_status_t switch_bd_init(switch_device_t device) -{ - bd_stats_index = switch_api_id_allocator_new(16 * 1024, FALSE); - switch_handle_type_init(SWITCH_HANDLE_TYPE_BD, (16 * 1024)); - tommy_hashtable_init(&switch_vlan_port_hash_table, SWITCH_VLAN_PORT_HASH_TABLE_SIZE); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t switch_bd_free(switch_device_t device) -{ - switch_handle_type_free(SWITCH_HANDLE_TYPE_BD); - switch_api_id_allocator_destroy(bd_stats_index); - return SWITCH_STATUS_SUCCESS; -} - -switch_handle_t switch_bd_create() -{ - switch_handle_t handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_BD, - switch_bd_info_t, - switch_bd_array, NULL, handle); - return handle; -} - -switch_bd_info_t *switch_bd_get(switch_handle_t handle) -{ - switch_bd_info_t *bd_info = NULL; - _switch_handle_get(switch_bd_info_t, - switch_bd_array, - handle, bd_info); - return bd_info; -} - -void switch_bd_delete(switch_handle_t handle) -{ - _switch_handle_delete(switch_bd_info_t, switch_bd_array, handle); -} - - -void switch_logical_network_mc_index_allocate(switch_device_t device, switch_bd_info_t *bd_info) -{ - switch_logical_network_t *ln_info = NULL; - - ln_info = &bd_info->ln_info; - //if ((ln_info->flood_type & SWITCH_VLAN_FLOOD_UUC) && - // (bd_info->uuc_mc_index == 0)) { - bd_info->uuc_mc_index = switch_api_mcast_index_allocate(device); - //} - if ((ln_info->flood_type & SWITCH_VLAN_FLOOD_UMC) && - (bd_info->umc_mc_index == 0)) { - bd_info->umc_mc_index = switch_api_mcast_index_allocate(device); - } else { - bd_info->umc_mc_index = bd_info->uuc_mc_index; - } - if ((ln_info->flood_type & SWITCH_VLAN_FLOOD_BCAST) && - (bd_info->bcast_mc_index == 0)) { - bd_info->bcast_mc_index = switch_api_mcast_index_allocate(device); - } else { - bd_info->bcast_mc_index = bd_info->uuc_mc_index; - } -} - -void switch_logical_network_mc_index_free(switch_device_t device, switch_bd_info_t *bd_info) -{ - switch_logical_network_t *ln_info = NULL; - ln_info = &bd_info->ln_info; - //if (ln_info->flood_type & SWITCH_VLAN_FLOOD_UUC) { - switch_api_mcast_index_delete(device, bd_info->uuc_mc_index); - bd_info->uuc_mc_index = 0; - //} - if (ln_info->flood_type & SWITCH_VLAN_FLOOD_UMC) { - switch_api_mcast_index_delete(device, bd_info->umc_mc_index); - } - bd_info->umc_mc_index = 0; - if (ln_info->flood_type & SWITCH_VLAN_FLOOD_BCAST) { - switch_api_mcast_index_delete(device, bd_info->bcast_mc_index); - } - bd_info->bcast_mc_index = 0; -} - -void switch_logical_network_init_default(switch_bd_info_t *bd_info) -{ - switch_logical_network_t *ln_info = NULL; - - ln_info = &bd_info->ln_info; - ln_info->age_interval = SWITCH_API_VLAN_DEFAULT_AGE_INTERVAL; - ln_info->flood_type = SWITCH_VLAN_FLOOD_NONE; - SWITCH_LN_FLOOD_ENABLED(bd_info) = TRUE; - SWITCH_LN_LEARN_ENABLED(bd_info) = TRUE; - bd_info->bd_entry = SWITCH_HW_INVALID_HANDLE; - return; -} - -switch_handle_t -switch_api_logical_network_create(switch_device_t device, switch_logical_network_t *ln_info) -{ - switch_bd_info_t *bd_info = NULL; - switch_handle_t handle; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - handle = switch_bd_create(); - bd_info = switch_bd_get(handle); - if (!bd_info) { - status = SWITCH_STATUS_NO_MEMORY; - SWITCH_API_ERROR("%s:%d unable to create logical network. %s", - __FUNCTION__, __LINE__, - switch_print_error(status)); - return SWITCH_API_INVALID_HANDLE; - } - memset(bd_info, 0, sizeof(switch_bd_info_t)); - memcpy(&bd_info->ln_info, ln_info, sizeof(switch_logical_network_t)); - tommy_list_init(&(bd_info->members)); - switch_logical_network_mc_index_allocate(device, bd_info); - bd_info->rid = switch_mcast_rid_allocate(); - if (ln_info->rmac_handle) { - bd_info->smac_index = - switch_smac_rewrite_index_from_rmac(ln_info->rmac_handle); - } - bd_info->ln_info.mrpf_group = handle; +switch_status_t switch_bd_init(switch_device_t device) { + bd_stats_index = switch_api_id_allocator_new(16 * 1024, FALSE); + switch_handle_type_init(SWITCH_HANDLE_TYPE_BD, (16 * 1024)); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_bd_free(switch_device_t device) { + switch_handle_type_free(SWITCH_HANDLE_TYPE_BD); + switch_api_id_allocator_destroy(bd_stats_index); + return SWITCH_STATUS_SUCCESS; +} + +switch_handle_t switch_bd_create() { + switch_handle_t handle; + _switch_handle_create( + SWITCH_HANDLE_TYPE_BD, switch_bd_info_t, switch_bd_array, NULL, handle); + return handle; +} + +switch_bd_info_t *switch_bd_get(switch_handle_t handle) { + switch_bd_info_t *bd_info = NULL; + _switch_handle_get(switch_bd_info_t, switch_bd_array, handle, bd_info); + return bd_info; +} + +void switch_bd_delete(switch_handle_t handle) { + _switch_handle_delete(switch_bd_info_t, switch_bd_array, handle); +} + +void switch_logical_network_mc_index_allocate(switch_device_t device, + switch_bd_info_t *bd_info) { + switch_logical_network_t *ln_info = NULL; + + ln_info = &bd_info->ln_info; + // if ((ln_info->flood_type & SWITCH_VLAN_FLOOD_UUC) && + // (bd_info->uuc_mc_index == 0)) { + bd_info->uuc_mc_index = switch_api_mcast_index_allocate(device); + //} + if ((ln_info->flood_type & SWITCH_VLAN_FLOOD_UMC) && + (bd_info->umc_mc_index == 0)) { + bd_info->umc_mc_index = switch_api_mcast_index_allocate(device); + } else { + bd_info->umc_mc_index = bd_info->uuc_mc_index; + } + if ((ln_info->flood_type & SWITCH_VLAN_FLOOD_BCAST) && + (bd_info->bcast_mc_index == 0)) { + bd_info->bcast_mc_index = switch_api_mcast_index_allocate(device); + } else { + bd_info->bcast_mc_index = bd_info->uuc_mc_index; + } +} + +void switch_logical_network_mc_index_free(switch_device_t device, + switch_bd_info_t *bd_info) { + switch_logical_network_t *ln_info = NULL; + + ln_info = &bd_info->ln_info; + // if (ln_info->flood_type & SWITCH_VLAN_FLOOD_UUC) { + switch_api_mcast_index_delete(device, bd_info->uuc_mc_index); + bd_info->uuc_mc_index = 0; + //} + if (ln_info->flood_type & SWITCH_VLAN_FLOOD_UMC) { + switch_api_mcast_index_delete(device, bd_info->umc_mc_index); + } + bd_info->umc_mc_index = 0; + if (ln_info->flood_type & SWITCH_VLAN_FLOOD_BCAST) { + switch_api_mcast_index_delete(device, bd_info->bcast_mc_index); + } + bd_info->bcast_mc_index = 0; +} + +void switch_logical_network_init_default(switch_bd_info_t *bd_info) { + switch_logical_network_t *ln_info = NULL; + + ln_info = &bd_info->ln_info; + ln_info->age_interval = SWITCH_API_VLAN_DEFAULT_AGE_INTERVAL; + ln_info->flood_type = SWITCH_VLAN_FLOOD_NONE; + SWITCH_LN_FLOOD_ENABLED(bd_info) = TRUE; + SWITCH_LN_LEARN_ENABLED(bd_info) = TRUE; + bd_info->bd_entry = SWITCH_HW_INVALID_HANDLE; + return; +} + +switch_handle_t switch_api_logical_network_create( + switch_device_t device, switch_logical_network_t *ln_info) { + switch_bd_info_t *bd_info = NULL; + switch_handle_t handle; + switch_status_t status = SWITCH_STATUS_SUCCESS; + uint32_t tunnel_vni = 0; + + handle = switch_bd_create(); + bd_info = switch_bd_get(handle); + if (!bd_info) { + status = SWITCH_STATUS_NO_MEMORY; + SWITCH_API_ERROR("%s:%d unable to create logical network. %s", + __FUNCTION__, + __LINE__, + switch_print_error(status)); + return SWITCH_API_INVALID_HANDLE; + } + + memset(bd_info, 0, sizeof(switch_bd_info_t)); + memcpy(&bd_info->ln_info, ln_info, sizeof(switch_logical_network_t)); + + if (ln_info->type == SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC) { + tunnel_vni = SWITCH_LN_TUNNEL_VNI(bd_info); + if (!SWITCH_TUNNEL_VNI_VALID(tunnel_vni)) { + SWITCH_API_ERROR( + "%s:%d: failed to create tunnel interface!" + "invalid tunnel vni", + __FUNCTION__, + __LINE__); + switch_bd_delete(handle); + return SWITCH_API_INVALID_HANDLE; + } + } + + tommy_list_init(&(bd_info->members)); + switch_logical_network_mc_index_allocate(device, bd_info); + bd_info->rid = switch_mcast_rid_allocate(); + if (ln_info->rmac_handle) { + bd_info->smac_index = + switch_smac_rewrite_index_from_rmac(ln_info->rmac_handle); + } + bd_info->ln_info.mrpf_group = handle; #ifdef SWITCH_PD - status = switch_pd_bd_table_add_entry(device, handle_to_id(handle), - bd_info); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } - - status = switch_pd_egress_bd_map_table_add_entry(device, handle, bd_info); - if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; - } + status = switch_pd_bd_table_add_entry(device, handle_to_id(handle), bd_info); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } + + status = switch_pd_egress_bd_map_table_add_entry(device, handle, bd_info); + if (status != SWITCH_STATUS_SUCCESS) { + return SWITCH_API_INVALID_HANDLE; + } #endif - return handle; + return handle; } -switch_status_t switch_api_logical_network_delete(switch_device_t device, switch_handle_t network_handle) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_logical_network_delete( + switch_device_t device, switch_handle_t network_handle) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - if (!SWITCH_BD_HANDLE_VALID(network_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_BD_HANDLE_VALID(network_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } - bd_info = switch_bd_get(network_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(network_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } #ifdef SWITCH_PD - status = switch_pd_bd_table_delete_entry(device, bd_info); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - status = switch_pd_egress_bd_map_table_delete_entry(device, bd_info); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } -#endif - - switch_mcast_rid_free(bd_info->rid); - switch_logical_network_mc_index_free(device, bd_info); - switch_bd_delete(network_handle); + status = switch_pd_bd_table_delete_entry(device, bd_info); + if (status != SWITCH_STATUS_SUCCESS) { return status; -} - -switch_status_t -switch_api_logical_network_update(switch_device_t device, - switch_handle_t network_handle, - switch_logical_network_t *ln_info) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_BD_HANDLE_VALID(network_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - bd_info = switch_bd_get(network_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - memcpy(&bd_info->ln_info, ln_info, sizeof(switch_logical_network_t)); - - if (ln_info->rmac_handle) { - bd_info->smac_index = - switch_smac_rewrite_index_from_rmac(ln_info->rmac_handle); - } - -#ifdef SWITCH_PD - status = switch_pd_bd_table_update_entry(device, - handle_to_id(network_handle), - bd_info); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - if (bd_info->egress_bd_entry) { - status = switch_pd_egress_bd_map_table_update_entry(device, - network_handle, - bd_info); - } else { - status = switch_pd_egress_bd_map_table_add_entry(device, - network_handle, - bd_info); - } - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } -#endif - + } + status = switch_pd_egress_bd_map_table_delete_entry(device, bd_info); + if (status != SWITCH_STATUS_SUCCESS) { return status; -} - -switch_handle_t switch_api_vlan_create(switch_device_t device, switch_vlan_t vlan_id) -{ - switch_bd_info_t *bd_info = NULL; - switch_bd_info_t info; - switch_handle_t handle; - - bd_info = &info; - memset(&info, 0, sizeof(switch_bd_info_t)); - SWITCH_LN_VLAN_ID(bd_info) = vlan_id; - SWITCH_LN_NETWORK_TYPE(bd_info) = SWITCH_LOGICAL_NETWORK_TYPE_VLAN; - switch_logical_network_init_default(bd_info); - handle = switch_api_logical_network_create(device, &bd_info->ln_info); - if (handle != SWITCH_API_INVALID_HANDLE) { - switch_api_vlan_id_to_handle_set(vlan_id, handle); - switch_api_vlan_stats_enable(device, handle); - } - return handle; -} - -switch_status_t switch_api_vlan_delete(switch_device_t device, switch_handle_t vlan_handle) -{ - switch_bd_info_t *bd_info = NULL; - switch_vlan_t vlan_id = 0; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - vlan_id = SWITCH_LN_VLAN_ID(bd_info); - switch_api_vlan_stats_disable(device, vlan_handle); - status = switch_api_logical_network_delete(device, vlan_handle); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - switch_api_vlan_id_to_handle_set(vlan_id, 0); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_attribute_set(switch_handle_t vlan_handle, - switch_vlan_attr_t attr_type, - uint64_t value) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch(attr_type) { - case SWITCH_VLAN_ATTR_FLOOD_TYPE: - status = switch_api_vlan_flood_type_set(vlan_handle, value); - break; - - case SWITCH_VLAN_ATTR_VRF_ID: - status = switch_api_vlan_vrf_handle_set(vlan_handle, value); - break; - - case SWITCH_VLAN_ATTR_MAC_LEARNING: - status = switch_api_vlan_learning_enabled_set(vlan_handle, value); - break; - - case SWITCH_VLAN_ATTR_AGE_INTERVAL: - status = switch_api_vlan_aging_interval_set(vlan_handle, value); - break; + } +#endif - default: - status = SWITCH_STATUS_INVALID_ATTRIBUTE; - } - return status; + switch_mcast_rid_free(bd_info->rid); + switch_logical_network_mc_index_free(device, bd_info); + switch_bd_delete(network_handle); + return status; } -switch_status_t -switch_api_vlan_attribute_get(switch_handle_t vlan_handle, - switch_vlan_attr_t attr_type, - uint64_t *value) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_logical_network_update( + switch_device_t device, + switch_handle_t network_handle, + switch_logical_network_t *ln_info) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; - switch(attr_type) { - case SWITCH_VLAN_ATTR_FLOOD_TYPE: - status = switch_api_vlan_flood_type_get(vlan_handle, value); - break; + if (!SWITCH_BD_HANDLE_VALID(network_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } - case SWITCH_VLAN_ATTR_VRF_ID: - status = switch_api_vlan_vrf_handle_get(vlan_handle, value); - break; + bd_info = switch_bd_get(network_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + memcpy(&bd_info->ln_info, ln_info, sizeof(switch_logical_network_t)); - case SWITCH_VLAN_ATTR_MAC_LEARNING: - status = switch_api_vlan_learning_enabled_get(vlan_handle, value); - break; - - case SWITCH_VLAN_ATTR_AGE_INTERVAL: - status = switch_api_vlan_aging_interval_get(vlan_handle, value); - break; - - default: - status = SWITCH_STATUS_INVALID_ATTRIBUTE; - } + if (ln_info->rmac_handle) { + bd_info->smac_index = + switch_smac_rewrite_index_from_rmac(ln_info->rmac_handle); + } +#ifdef SWITCH_PD + status = switch_pd_bd_table_update_entry( + device, handle_to_id(network_handle), bd_info); + if (status != SWITCH_STATUS_SUCCESS) { return status; -} - -switch_status_t -switch_api_ln_attribute_set(switch_handle_t ln_handle, - switch_ln_attr_t attr_type, - uint64_t value) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch (attr_type) { - case SWITCH_LN_ATTR_NETWORK_TYPE: - status = switch_api_ln_network_type_set(ln_handle, value); - break; - case SWITCH_LN_ATTR_IPV4_UNICAST: - status = switch_api_ln_ipv4_unicast_enabled_set(ln_handle, value); - break; - case SWITCH_LN_ATTR_IPV6_UNICAST: - status = switch_api_ln_ipv6_unicast_enabled_set(ln_handle, value); - break; - default: - status = SWITCH_STATUS_INVALID_ATTRIBUTE; - } + } + if (bd_info->egress_bd_entry) { + status = switch_pd_egress_bd_map_table_update_entry( + device, network_handle, bd_info); + } else { + status = switch_pd_egress_bd_map_table_add_entry( + device, network_handle, bd_info); + } + if (status != SWITCH_STATUS_SUCCESS) { return status; -} + } +#endif -switch_status_t -switch_api_ln_attribute_get(switch_handle_t ln_handle, - switch_ln_attr_t attr_type, - uint64_t *value) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch(attr_type) { - case SWITCH_LN_ATTR_NETWORK_TYPE: - status = switch_api_ln_network_type_get(ln_handle, value); - break; - case SWITCH_LN_ATTR_IPV4_UNICAST: - status = switch_api_ln_ipv4_unicast_enabled_get(ln_handle, value); - break; - case SWITCH_LN_ATTR_IPV6_UNICAST: - status = switch_api_ln_ipv6_unicast_enabled_get(ln_handle, value); - break; - default: - status = SWITCH_STATUS_INVALID_ATTRIBUTE; - } - return status; + return status; } -switch_status_t -switch_api_vlan_flood_type_set(switch_handle_t vlan_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_handle_t switch_api_vlan_create(switch_device_t device, + switch_vlan_t vlan_id) { + switch_bd_info_t *bd_info = NULL; + switch_bd_info_t info; + switch_handle_t handle; + switch_status_t status = SWITCH_STATUS_SUCCESS; - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - 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); + status = switch_api_vlan_id_to_handle_get(vlan_id, &handle); + if (status == SWITCH_STATUS_SUCCESS && handle) { + SWITCH_API_ERROR("vlan already exists %lx", handle); + return handle; + } + + bd_info = &info; + memset(&info, 0, sizeof(switch_bd_info_t)); + SWITCH_LN_VLAN_ID(bd_info) = vlan_id; + SWITCH_LN_NETWORK_TYPE(bd_info) = SWITCH_LOGICAL_NETWORK_TYPE_VLAN; + switch_logical_network_init_default(bd_info); + handle = switch_api_logical_network_create(device, &bd_info->ln_info); + if (handle != SWITCH_API_INVALID_HANDLE) { + switch_api_vlan_id_to_handle_set(vlan_id, handle); + switch_api_vlan_stats_enable(device, handle); + } + return handle; +} + +switch_status_t switch_api_vlan_delete(switch_device_t device, + switch_handle_t vlan_handle) { + switch_bd_info_t *bd_info = NULL; + switch_vlan_t vlan_id = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + if (switch_api_default_vlan_internal() == vlan_handle) { + SWITCH_API_ERROR("vlan delete failed. cannot delete default vlan"); + return SWITCH_STATUS_NOT_SUPPORTED; + } + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + vlan_id = SWITCH_LN_VLAN_ID(bd_info); + switch_api_vlan_stats_disable(device, vlan_handle); + status = switch_api_logical_network_delete(device, vlan_handle); + if (status != SWITCH_STATUS_SUCCESS) { return status; + } + switch_api_vlan_id_to_handle_set(vlan_id, 0); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_attribute_set(switch_handle_t vlan_handle, + switch_vlan_attr_t attr_type, + uint64_t value) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (attr_type) { + case SWITCH_VLAN_ATTR_FLOOD_TYPE: + status = switch_api_vlan_flood_type_set(vlan_handle, value); + break; + + case SWITCH_VLAN_ATTR_VRF_ID: + status = switch_api_vlan_vrf_handle_set(vlan_handle, value); + break; + + case SWITCH_VLAN_ATTR_MAC_LEARNING: + status = switch_api_vlan_learning_enabled_set(vlan_handle, value); + break; + + case SWITCH_VLAN_ATTR_AGE_INTERVAL: + status = switch_api_vlan_aging_interval_set(vlan_handle, value); + break; + + default: + status = SWITCH_STATUS_INVALID_ATTRIBUTE; + } + return status; +} + +switch_status_t switch_api_vlan_attribute_get(switch_handle_t vlan_handle, + switch_vlan_attr_t attr_type, + uint64_t *value) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (attr_type) { + case SWITCH_VLAN_ATTR_FLOOD_TYPE: + status = switch_api_vlan_flood_type_get(vlan_handle, value); + break; + + case SWITCH_VLAN_ATTR_VRF_ID: + status = switch_api_vlan_vrf_handle_get(vlan_handle, value); + break; + + case SWITCH_VLAN_ATTR_MAC_LEARNING: + status = switch_api_vlan_learning_enabled_get(vlan_handle, value); + break; + + case SWITCH_VLAN_ATTR_AGE_INTERVAL: + status = switch_api_vlan_aging_interval_get(vlan_handle, value); + break; + + default: + status = SWITCH_STATUS_INVALID_ATTRIBUTE; + } + + return status; +} + +switch_status_t switch_api_ln_attribute_set(switch_handle_t ln_handle, + switch_ln_attr_t attr_type, + uint64_t value) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (attr_type) { + case SWITCH_LN_ATTR_NETWORK_TYPE: + status = switch_api_ln_network_type_set(ln_handle, value); + break; + case SWITCH_LN_ATTR_IPV4_UNICAST: + status = switch_api_ln_ipv4_unicast_enabled_set(ln_handle, value); + break; + case SWITCH_LN_ATTR_IPV6_UNICAST: + status = switch_api_ln_ipv6_unicast_enabled_set(ln_handle, value); + break; + default: + status = SWITCH_STATUS_INVALID_ATTRIBUTE; + } + return status; +} + +switch_status_t switch_api_ln_attribute_get(switch_handle_t ln_handle, + switch_ln_attr_t attr_type, + uint64_t *value) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (attr_type) { + case SWITCH_LN_ATTR_NETWORK_TYPE: + status = switch_api_ln_network_type_get(ln_handle, value); + break; + case SWITCH_LN_ATTR_IPV4_UNICAST: + status = switch_api_ln_ipv4_unicast_enabled_get(ln_handle, value); + break; + case SWITCH_LN_ATTR_IPV6_UNICAST: + status = switch_api_ln_ipv6_unicast_enabled_get(ln_handle, value); + break; + default: + status = SWITCH_STATUS_INVALID_ATTRIBUTE; + } + return status; +} + +switch_status_t switch_api_vlan_flood_type_set(switch_handle_t vlan_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + 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); + return status; +} + +switch_status_t switch_api_vlan_flood_type_get(switch_handle_t vlan_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + ln_info = &bd_info->ln_info; + *value = (uint64_t)(ln_info->flood_type); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_aging_interval_set(switch_handle_t vlan_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + ln_info = &bd_info->ln_info; + ln_info->age_interval = (uint32_t)value; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_aging_interval_get(switch_handle_t vlan_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + ln_info = &bd_info->ln_info; + *value = (uint64_t)ln_info->age_interval; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_vrf_handle_set(switch_handle_t vlan_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + 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); + return status; +} + +switch_status_t switch_api_vlan_vrf_handle_get(switch_handle_t vlan_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + ln_info = &bd_info->ln_info; + *value = (uint64_t)ln_info->vrf_handle; + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_ln_network_type_set(switch_handle_t ln_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(ln_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + 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); + return status; +} + +switch_status_t switch_api_ln_network_type_get(switch_handle_t ln_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; + + bd_info = switch_bd_get(ln_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_NETWORK_TYPE(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_vlan_flood_type_get(switch_handle_t vlan_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - ln_info = &bd_info->ln_info; - *value = (uint64_t) (ln_info->flood_type); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_aging_interval_set(switch_handle_t vlan_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - ln_info = &bd_info->ln_info; - ln_info->age_interval = (uint32_t) value; - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_aging_interval_get(switch_handle_t vlan_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; +switch_status_t switch_bd_ipv4_unicast_enabled_set(switch_handle_t bd_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - ln_info = &bd_info->ln_info; - *value = (uint64_t) ln_info->age_interval; - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_vrf_handle_set(switch_handle_t vlan_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - 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); - return status; + 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); + return status; } -switch_status_t -switch_api_vlan_vrf_handle_get(switch_handle_t vlan_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - ln_info = &bd_info->ln_info; - *value = (uint64_t) ln_info->vrf_handle; - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_ln_ipv4_unicast_enabled_set( + switch_handle_t ln_handle, uint64_t value) { + return switch_bd_ipv4_unicast_enabled_set(ln_handle, value); } -switch_status_t -switch_api_ln_network_type_set(switch_handle_t ln_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_ipv4_unicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(ln_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - 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); - return status; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_ln_network_type_get(switch_handle_t ln_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - - bd_info = switch_bd_get(ln_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_NETWORK_TYPE(bd_info); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_api_ln_ipv4_unicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value) { + return switch_bd_ipv4_unicast_enabled_get(ln_handle, value); } -switch_status_t -switch_bd_ipv4_unicast_enabled_set(switch_handle_t bd_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_ipv6_unicast_enabled_set(switch_handle_t bd_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - 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); - return status; + 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); + return status; } -switch_status_t -switch_api_ln_ipv4_unicast_enabled_set(switch_handle_t ln_handle, uint64_t value) -{ - return switch_bd_ipv4_unicast_enabled_set(ln_handle, value); +switch_status_t switch_api_ln_ipv6_unicast_enabled_set( + switch_handle_t ln_handle, uint64_t value) { + return switch_bd_ipv6_unicast_enabled_set(ln_handle, value); } -switch_status_t -switch_bd_ipv4_unicast_enabled_get(switch_handle_t bd_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; +switch_status_t switch_bd_ipv6_unicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_IPV4_UNICAST_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_ln_ipv4_unicast_enabled_get(switch_handle_t ln_handle, uint64_t *value) -{ - return switch_bd_ipv4_unicast_enabled_get(ln_handle, value); +switch_status_t switch_api_ln_ipv6_unicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value) { + return switch_bd_ipv6_unicast_enabled_get(ln_handle, value); } -switch_status_t -switch_bd_ipv6_unicast_enabled_set(switch_handle_t bd_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_ipv4_multicast_enabled_set(switch_handle_t bd_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - 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); - return status; + 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); + return status; } -switch_status_t -switch_api_ln_ipv6_unicast_enabled_set(switch_handle_t ln_handle, uint64_t value) -{ - return switch_bd_ipv6_unicast_enabled_set(ln_handle, value); +switch_status_t switch_api_ln_ipv4_multicast_enabled_set( + switch_handle_t ln_handle, uint64_t value) { + return switch_bd_ipv4_multicast_enabled_set(ln_handle, value); } -switch_status_t -switch_bd_ipv6_unicast_enabled_get(switch_handle_t bd_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; +switch_status_t switch_bd_ipv4_multicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_IPV6_UNICAST_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_ln_ipv6_unicast_enabled_get(switch_handle_t ln_handle, uint64_t *value) -{ - return switch_bd_ipv6_unicast_enabled_get(ln_handle, value); +switch_status_t switch_api_ln_ipv4_multicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value) { + return switch_bd_ipv4_multicast_enabled_get(ln_handle, value); } -switch_status_t -switch_bd_ipv4_multicast_enabled_set(switch_handle_t bd_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_ipv6_multicast_enabled_set(switch_handle_t bd_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - 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); - return status; + 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); + return status; } -switch_status_t -switch_api_ln_ipv4_multicast_enabled_set(switch_handle_t ln_handle, - uint64_t value) -{ - return switch_bd_ipv4_multicast_enabled_set(ln_handle, value); +switch_status_t switch_api_ln_ipv6_multicast_enabled_set( + switch_handle_t ln_handle, uint64_t value) { + return switch_bd_ipv6_multicast_enabled_set(ln_handle, value); } -switch_status_t -switch_bd_ipv4_multicast_enabled_get(switch_handle_t bd_handle, - uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; +switch_status_t switch_bd_ipv6_multicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_IPV4_MULTICAST_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_ln_ipv4_multicast_enabled_get(switch_handle_t ln_handle, - uint64_t *value) -{ - return switch_bd_ipv4_multicast_enabled_get(ln_handle, value); +switch_status_t switch_api_ln_ipv6_multicast_enabled_get( + switch_handle_t ln_handle, uint64_t *value) { + return switch_bd_ipv6_multicast_enabled_get(ln_handle, value); } -switch_status_t -switch_bd_ipv6_multicast_enabled_set(switch_handle_t bd_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_ipv4_urpf_mode_set(switch_handle_t bd_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - 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); - return status; + bd_info->ipv4_urpf_mode = (uint8_t)value; + status = + switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), bd_info); + return status; } -switch_status_t -switch_api_ln_ipv6_multicast_enabled_set(switch_handle_t ln_handle, - uint64_t value) -{ - return switch_bd_ipv6_multicast_enabled_set(ln_handle, value); -} +switch_status_t switch_bd_ipv4_urpf_mode_get(switch_handle_t bd_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; -switch_status_t -switch_bd_ipv6_multicast_enabled_get(switch_handle_t bd_handle, - uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_IPV6_MULTICAST_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)bd_info->ipv4_urpf_mode; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_ln_ipv6_multicast_enabled_get(switch_handle_t ln_handle, - uint64_t *value) -{ - return switch_bd_ipv6_multicast_enabled_get(ln_handle, value); -} - -switch_status_t -switch_bd_ipv4_urpf_mode_set(switch_handle_t bd_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_ipv6_urpf_mode_set(switch_handle_t bd_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - bd_info->ipv4_urpf_mode = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), - bd_info); - return status; + bd_info->ipv6_urpf_mode = (uint8_t)value; + status = + switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), bd_info); + return status; } -switch_status_t -switch_bd_ipv4_urpf_mode_get(switch_handle_t bd_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; +switch_status_t switch_bd_ipv6_urpf_mode_get(switch_handle_t bd_handle, + uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) bd_info->ipv4_urpf_mode; - return SWITCH_STATUS_SUCCESS; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)bd_info->ipv6_urpf_mode; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_bd_ipv6_urpf_mode_set(switch_handle_t bd_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - bd_info->ipv6_urpf_mode = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), - bd_info); - return status; -} +switch_status_t switch_bd_nat_mode_set(switch_handle_t bd_handle, + uint8_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; -switch_status_t -switch_bd_ipv6_urpf_mode_get(switch_handle_t bd_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) bd_info->ipv6_urpf_mode; - return SWITCH_STATUS_SUCCESS; + SWITCH_LN_NAT_MODE(bd_info) = value; + status = + switch_pd_egress_bd_map_table_update_entry(device, bd_handle, bd_info); + return status; } -switch_status_t -switch_api_vlan_learning_enabled_set(switch_handle_t vlan_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_bd_nat_mode_get(switch_handle_t bd_handle, + uint8_t *value) { + switch_bd_info_t *bd_info = NULL; + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = SWITCH_LN_NAT_MODE(bd_info); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_learning_enabled_set( + switch_handle_t vlan_handle, uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - SWITCH_LN_LEARN_ENABLED(bd_info) = (uint8_t) value; - status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), - bd_info); - return status; + SWITCH_LN_LEARN_ENABLED(bd_info) = (uint8_t)value; + status = switch_pd_bd_table_update_entry( + device, handle_to_id(vlan_handle), bd_info); + return status; +} + +switch_status_t switch_api_vlan_learning_enabled_get( + switch_handle_t vlan_handle, uint64_t *value) { + switch_bd_info_t *bd_info = NULL; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_LEARN_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_vlan_learning_enabled_get(switch_handle_t vlan_handle, uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_LEARN_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; -} +switch_status_t switch_api_vlan_igmp_snooping_enabled_set( + switch_handle_t vlan_handle, uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } -switch_status_t -switch_api_vlan_igmp_snooping_enabled_set(switch_handle_t vlan_handle, - uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; + 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); + return status; +} - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } +switch_status_t switch_api_vlan_igmp_snooping_enabled_get( + switch_handle_t vlan_handle, uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - 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); - return status; + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_vlan_igmp_snooping_enabled_get(switch_handle_t vlan_handle, - uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; +switch_status_t switch_api_vlan_mld_snooping_enabled_set( + switch_handle_t vlan_handle, uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_IGMP_SNOOPING_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; + 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); + return status; } -switch_status_t -switch_api_vlan_mld_snooping_enabled_set(switch_handle_t vlan_handle, - uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; +switch_status_t switch_api_vlan_mld_snooping_enabled_get( + switch_handle_t vlan_handle, uint64_t *value) { + switch_bd_info_t *bd_info = NULL; - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - 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); - return status; + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *value = (uint64_t)SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_vlan_mld_snooping_enabled_get(switch_handle_t vlan_handle, - uint64_t *value) -{ - switch_bd_info_t *bd_info = NULL; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *value = (uint64_t) SWITCH_LN_MLD_SNOOPING_ENABLED(bd_info); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_mrpf_group_set(switch_handle_t vlan_handle, uint64_t value) -{ - switch_bd_info_t *bd_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } +switch_status_t switch_api_vlan_mrpf_group_set(switch_handle_t vlan_handle, + uint64_t value) { + switch_bd_info_t *bd_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } - bd_info->ln_info.mrpf_group = value; - status = switch_pd_bd_table_update_entry(device, handle_to_id(vlan_handle), - bd_info); - return status; + bd_info->ln_info.mrpf_group = value; + status = switch_pd_bd_table_update_entry( + device, handle_to_id(vlan_handle), bd_info); + return status; } switch_status_t switch_api_vlan_id_to_handle_set(switch_vlan_t vlan_id, - switch_handle_t vlan_handle) -{ - if (vlan_id > SWITCH_API_MAX_VLANS) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - vlan_handle_list[vlan_id] = vlan_handle; - return SWITCH_STATUS_SUCCESS; + switch_handle_t vlan_handle) { + if (vlan_id > SWITCH_API_MAX_VLANS) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + vlan_handle_list[vlan_id] = vlan_handle; + return SWITCH_STATUS_SUCCESS; } switch_status_t switch_api_vlan_id_to_handle_get(switch_vlan_t vlan_id, - switch_handle_t *vlan_handle) -{ - if (vlan_id > SWITCH_API_MAX_VLANS) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - *vlan_handle = vlan_handle_list[vlan_id]; - return SWITCH_STATUS_SUCCESS; + switch_handle_t *vlan_handle) { + if (vlan_id > SWITCH_API_MAX_VLANS) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + *vlan_handle = vlan_handle_list[vlan_id]; + return SWITCH_STATUS_SUCCESS; } switch_status_t switch_api_vlan_handle_to_id_get(switch_handle_t vlan_handle, switch_vlan_t *vlan_id) { - if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + switch_bd_info_t *info = NULL; + info = switch_bd_get(vlan_handle); + if (!info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + *vlan_id = SWITCH_LN_VLAN_ID(info); + return SWITCH_STATUS_SUCCESS; +} + +bool switch_vlan_interface_check(switch_handle_t vlan_handle, + switch_handle_t intf_handle) { + switch_interface_info_t *intf_info = NULL; + void *temp = NULL; + switch_handle_t tmp_vlan_handle = 0; + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return FALSE; + } + + 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; + } + + 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; + } + + JLN(temp, intf_info->vlan_array, tmp_vlan_handle); + } + return TRUE; +} + +switch_status_t switch_api_vlan_ports_add(switch_device_t device, + switch_handle_t vlan_handle, + uint16_t port_count, + switch_vlan_port_t *vlan_port) { + switch_bd_info_t *info = NULL; + switch_ln_member_t *vlan_member = NULL; + switch_handle_t intf_handle = 0; + switch_interface_info_t *intf_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_vlan_t vlan_id = 0; + switch_handle_type_t handle_type = 0; + switch_api_interface_info_t api_intf_info; + 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)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + info = switch_bd_get(vlan_handle); + if (!info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + for (count = 0; count < port_count; count++) { + handle = vlan_port[count].handle; + intf_handle = vlan_port[count].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; + } + + handle_type = switch_handle_get_type(handle); + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + 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; + } - switch_bd_info_t *info = NULL; - info = switch_bd_get(vlan_handle); - if (!info) { - 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_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_id = SWITCH_LN_VLAN_ID(info); - return SWITCH_STATUS_SUCCESS; -} - -bool -switch_vlan_interface_check( - switch_handle_t vlan_handle, - switch_handle_t intf_handle) -{ - switch_interface_info_t *intf_info = NULL; - void *temp = NULL; - switch_handle_t tmp_vlan_handle = 0; - intf_info = switch_api_interface_get(intf_handle); if (!intf_info) { - return FALSE; + return SWITCH_STATUS_INVALID_INTERFACE; } - 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; - } + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + intf_info->vlan_count++; + } - 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; - } + 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; + } - JLN(temp, intf_info->vlan_array, tmp_vlan_handle); + 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; + } else if ((SWITCH_INTF_IS_PORT_L2_TRUNK(intf_info)) && + (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) == vlan_handle) && + (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) != 0)) { + vlan_id = 0; + } else { + vlan_id = SWITCH_LN_VLAN_ID(info); + } } - return TRUE; -} - -switch_status_t -switch_api_vlan_ports_add(switch_device_t device, - switch_handle_t vlan_handle, - uint16_t port_count, - switch_vlan_port_t *vlan_port) -{ - switch_bd_info_t *info = NULL; - switch_ln_member_t *vlan_member = NULL; - switch_handle_t intf_handle = 0; - switch_interface_info_t *intf_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_vlan_t vlan_id = 0; - switch_handle_type_t handle_type = 0; - switch_api_interface_info_t api_intf_info; - 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)) { - return SWITCH_STATUS_INVALID_HANDLE; + vlan_member = switch_malloc(sizeof(switch_ln_member_t), 1); + if (!vlan_member) { + return SWITCH_STATUS_NO_MEMORY; } - info = switch_bd_get(vlan_handle); - if (!info) { - return SWITCH_STATUS_INVALID_VLAN_ID; + memset(vlan_member, 0, sizeof(switch_ln_member_t)); + vlan_member->member = intf_handle; + tommy_list_insert_tail(&(info->members), &(vlan_member->node), vlan_member); +#ifdef SWITCH_PD + status = switch_pd_port_vlan_mapping_table_add_entry( + device, + vlan_id, + 0, + intf_info, + info->bd_entry, + &(vlan_member->pv_hw_entry)); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d: unable to add to port vlan entry for vlan %d", + __FUNCTION__, + __LINE__, + vlan_id); + return SWITCH_STATUS_PD_FAILURE; + } + status = + switch_api_vlan_xlate_add(device, vlan_handle, intf_handle, vlan_id); + if (status != SWITCH_STATUS_SUCCESS) { + return status; } - for (count = 0; count < port_count; count++) { - handle = vlan_port[count].handle; - intf_handle = vlan_port[count].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; + switch_vlan_interface_t vlan_intf; + memset(&vlan_intf, 0, sizeof(vlan_intf)); + vlan_intf.vlan_handle = vlan_handle; + vlan_intf.intf_handle = intf_handle; + status = switch_api_multicast_member_add( + device, info->uuc_mc_index, 1, &vlan_intf); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } +#endif + } + + return status; +} + +switch_status_t switch_api_vlan_ports_remove(switch_device_t device, + switch_handle_t vlan_handle, + uint16_t port_count, + switch_vlan_port_t *vlan_port) { + switch_bd_info_t *info = NULL; + switch_interface_info_t *intf_info = NULL; + 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_handle_t handle = 0; + switch_port_info_t *port_info = NULL; + + if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + info = switch_bd_get(vlan_handle); + if (!info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + 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))) { + return SWITCH_STATUS_INVALID_HANDLE; + } + handle_type = switch_handle_get_type(vlan_port[count].handle); + if (handle_type == SWITCH_HANDLE_TYPE_PORT || + handle_type == SWITCH_HANDLE_TYPE_LAG) { + 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; } - handle_type = switch_handle_get_type(handle); - if (handle_type == SWITCH_HANDLE_TYPE_PORT || - handle_type == SWITCH_HANDLE_TYPE_LAG) { - - 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; - } - } - - 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; - } - } + if (port_info->lag_handle) { + port_lag_handle = port_info->lag_handle; } + } - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } + status = switch_interface_handle_get(port_lag_handle, 0x0, &intf_handle); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "vlan ports delete failed. " + "interface handle get failed\n"); + continue; + } - if (handle_type == SWITCH_HANDLE_TYPE_PORT || - handle_type == SWITCH_HANDLE_TYPE_LAG) { - intf_info->vlan_count++; - } + vlan_member = + switch_api_logical_network_search_member(vlan_handle, intf_handle); + if (!vlan_member) { + continue; + } + } - 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; - } + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } - 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; - } else if ((SWITCH_INTF_IS_PORT_L2_TRUNK(intf_info)) && - (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) == vlan_handle) && - (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) != 0)) { - vlan_id = 0; - } else { - vlan_id = SWITCH_LN_VLAN_ID(info); - } - } - vlan_member = switch_malloc(sizeof(switch_ln_member_t), 1); - if (!vlan_member) { - return SWITCH_STATUS_NO_MEMORY; - } + JLD(status, intf_info->vlan_array, vlan_handle); - memset(vlan_member, 0, sizeof(switch_ln_member_t)); - vlan_member->member = intf_handle; - tommy_list_insert_tail(&(info->members), &(vlan_member->node), vlan_member); + if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { + if (SWITCH_INTF_IS_PORT_L2_ACCESS(intf_info)) { + vlan_id = 0; + } else if ((SWITCH_INTF_IS_PORT_L2_TRUNK(intf_info)) && + (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) == vlan_handle) && + (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) != 0)) { + vlan_id = 0; + } else { + vlan_id = SWITCH_LN_VLAN_ID(info); + } + } + node = tommy_list_head(&(info->members)); + while (node) { + vlan_member = (switch_ln_member_t *)node->data; + node = node->next; + if (vlan_member->member == intf_handle) { #ifdef SWITCH_PD - status = switch_pd_port_vlan_mapping_table_add_entry(device, - vlan_id, 0, - intf_info, - info->bd_entry, - &(vlan_member->pv_hw_entry)); + status = switch_api_vlan_xlate_remove( + device, vlan_handle, intf_handle, vlan_id); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to add to port vlan entry for vlan %d", - __FUNCTION__, __LINE__, vlan_id); - return SWITCH_STATUS_PD_FAILURE; + return status; } - status = switch_api_vlan_xlate_add(device, vlan_handle, intf_handle, vlan_id); + status = switch_pd_port_vlan_mapping_table_delete_entry( + device, vlan_member->pv_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - return status; + SWITCH_API_ERROR( + "%s:%d: unable to remove port vlan entry for vlan %d!", + __FUNCTION__, + __LINE__, + vlan_id); + return SWITCH_STATUS_PD_FAILURE; } switch_vlan_interface_t vlan_intf; memset(&vlan_intf, 0, sizeof(vlan_intf)); vlan_intf.vlan_handle = vlan_handle; vlan_intf.intf_handle = intf_handle; - status = switch_api_multicast_member_add(device, info->uuc_mc_index, - 1, &vlan_intf); - if (status != SWITCH_STATUS_SUCCESS) { - return status; + status = switch_api_multicast_member_delete( + device, info->uuc_mc_index, 1, &vlan_intf); + // item not found is ok since stp removes the + // member when clearing the stp state + if (status != SWITCH_STATUS_ITEM_NOT_FOUND && + status != SWITCH_STATUS_SUCCESS) { + return status; } #endif - } - - return status; -} - -switch_status_t -switch_api_vlan_ports_remove(switch_device_t device, - switch_handle_t vlan_handle, - uint16_t port_count, - switch_vlan_port_t *vlan_port) -{ - switch_bd_info_t *info = NULL; - switch_interface_info_t *intf_info = NULL; - 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_handle_t handle = 0; - switch_port_info_t *port_info = NULL; - - if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - info = switch_bd_get(vlan_handle); - if (!info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } + status = SWITCH_STATUS_SUCCESS; + tommy_list_remove_existing(&(info->members), &(vlan_member->node)); + switch_free(vlan_member); - 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))) { - return SWITCH_STATUS_INVALID_HANDLE; - } - handle_type = switch_handle_get_type(vlan_port[count].handle); if (handle_type == SWITCH_HANDLE_TYPE_PORT || handle_type == SWITCH_HANDLE_TYPE_LAG) { - 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); + intf_info->vlan_count--; + if (intf_info->vlan_count == 0) { + status = switch_api_interface_delete(device, intf_handle); if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("vlan ports delete failed. " - "interface handle get failed\n"); - continue; + return status; } - - vlan_member = switch_api_logical_network_search_member(vlan_handle, intf_handle); - if (!vlan_member) { - continue; - } - } - - intf_info = switch_api_interface_get(intf_handle); - 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; - } else if ((SWITCH_INTF_IS_PORT_L2_TRUNK(intf_info)) && - (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) == vlan_handle) && - (SWITCH_INTF_NATIVE_VLAN_HANDLE(intf_info) != 0)) { - vlan_id = 0; - } else { - vlan_id = SWITCH_LN_VLAN_ID(info); - } - } - node = tommy_list_head(&(info->members)); - while (node) { - vlan_member = (switch_ln_member_t *) node->data; - node = node->next; - if (vlan_member->member == intf_handle) { -#ifdef SWITCH_PD - status = switch_api_vlan_xlate_remove(device, vlan_handle, intf_handle, vlan_id); - if (status != SWITCH_STATUS_SUCCESS) { - return status; - } - status = switch_pd_port_vlan_mapping_table_delete_entry(device, - vlan_member->pv_hw_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d: unable to remove port vlan entry for vlan %d!", - __FUNCTION__, __LINE__, vlan_id); - return SWITCH_STATUS_PD_FAILURE; - } - - switch_vlan_interface_t vlan_intf; - memset(&vlan_intf, 0, sizeof(vlan_intf)); - vlan_intf.vlan_handle = vlan_handle; - vlan_intf.intf_handle = intf_handle; - status = switch_api_multicast_member_delete(device, - info->uuc_mc_index, - 1, &vlan_intf); - // item not found is ok since stp removes the - // member when clearing the stp state - if (status != SWITCH_STATUS_ITEM_NOT_FOUND && - status != SWITCH_STATUS_SUCCESS) { - return status; - } -#endif - status = SWITCH_STATUS_SUCCESS; - tommy_list_remove_existing(&(info->members), &(vlan_member->node)); - switch_free(vlan_member); - - if (handle_type == SWITCH_HANDLE_TYPE_PORT|| - handle_type == SWITCH_HANDLE_TYPE_LAG) { - 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; - } - } - } - } - } - } - return status; -} - -switch_status_t -switch_api_vlan_interfaces_get(switch_device_t device, - switch_handle_t vlan_handle, - uint16_t *mbr_count, - switch_vlan_interface_t **mbrs) -{ - switch_bd_info_t *info = NULL; - tommy_node *node = NULL; - uint16_t mbr_count_max = 0; - - if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - info = switch_bd_get(vlan_handle); - if (!info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - *mbrs = NULL; - *mbr_count = 0; - - node = tommy_list_head(&(info->members)); - while (node) { - switch_ln_member_t *vlan_member = NULL; - vlan_member = (switch_ln_member_t *) node->data; - node = node->next; - - if (mbr_count_max == *mbr_count) { - mbr_count_max += 16; - *mbrs = switch_realloc(*mbrs, (sizeof(switch_vlan_interface_t) * - mbr_count_max)); - } - (*mbrs)[*mbr_count].vlan_handle = vlan_handle; - (*mbrs)[*mbr_count].intf_handle = vlan_member->member; - (*mbr_count)++; - } - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_bd_router_mac_handle_set(switch_handle_t bd_handle, switch_handle_t rmac_handle) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_device_t device = SWITCH_DEV_ID; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - 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); - return status; -} - -switch_status_t -switch_api_vlan_xlate_add(switch_device_t device, switch_handle_t bd_handle, - switch_handle_t intf_handle, switch_vlan_t vlan_id) -{ - switch_interface_info_t *intf_info = NULL; - switch_ln_member_t *bd_member = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: invalid interface!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - - bd_member = switch_api_logical_network_search_member(bd_handle, intf_handle); - if (!bd_member) { - SWITCH_API_ERROR("%s:%d interface is not port of vlan!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - status = switch_pd_egress_vlan_xlate_table_add_entry( - device, - intf_info->ifindex, - handle_to_id(bd_handle), - vlan_id, - &bd_member->xlate_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d unable to add xlate entry for vlan %d", - __FUNCTION__, __LINE__, vlan_id); - return SWITCH_STATUS_PD_FAILURE; - } - return status; -} - -switch_status_t -switch_api_vlan_xlate_remove(switch_device_t device, switch_handle_t bd_handle, - switch_handle_t intf_handle, switch_vlan_t vlan_id) -{ - switch_interface_info_t *intf_info = NULL; - switch_ln_member_t *bd_member = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - - if (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } - - intf_info = switch_api_interface_get(intf_handle); - if (!intf_info) { - SWITCH_API_ERROR("%s:%d: invalid interface!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - - bd_member = switch_api_logical_network_search_member(bd_handle, intf_handle); - if (!bd_member) { - SWITCH_API_ERROR("%s:%d interface is not port of vlan!", __FUNCTION__, __LINE__); - return SWITCH_STATUS_INVALID_INTERFACE; - } - status = switch_pd_egress_vlan_xlate_table_delete_entry(device, bd_member->xlate_entry); - if (status != SWITCH_STATUS_SUCCESS) { - SWITCH_API_ERROR("%s:%d unable to remove xlate entry", __FUNCTION__, __LINE__); - return SWITCH_STATUS_PD_FAILURE; - } - return SWITCH_STATUS_SUCCESS; -} - -switch_ln_member_t * -switch_api_logical_network_search_member(switch_handle_t bd_handle, switch_handle_t intf_handle) -{ - switch_ln_member_t *ln_member = NULL; - tommy_node *node = NULL; - switch_bd_info_t *bd_info = NULL; - - bd_info = switch_bd_get(bd_handle); - node = tommy_list_head(&bd_info->members); - while (node) { - ln_member = node->data; - if (ln_member->member == intf_handle) { - return ln_member; - } - node = node->next; - } - return NULL; -} - -switch_status_t -switch_bd_get_entry(switch_handle_t bd_handle, char *entry, int entry_length) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - int bytes_output = 0; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - ln_info = &bd_info->ln_info; - bytes_output += sprintf(entry + bytes_output, "\nvlan_handle: %x", (unsigned int) bd_handle); - bytes_output += sprintf(entry + bytes_output, "\nvrf_handle: %x", (unsigned int) ln_info->vrf_handle); - bytes_output += sprintf(entry + bytes_output, "rmac_handle: %x", (unsigned int) ln_info->rmac_handle); - bytes_output += sprintf(entry + bytes_output, "type: %d", SWITCH_LN_NETWORK_TYPE(bd_info)); - bytes_output += sprintf(entry + bytes_output, "\nucast mc %x", bd_info->uuc_mc_index); - bytes_output += sprintf(entry + bytes_output, "mcast mc %x", bd_info->umc_mc_index); - bytes_output += sprintf(entry + bytes_output, "bcast mc %x", bd_info->bcast_mc_index); - bytes_output += sprintf(entry + bytes_output, "\nv4_urpf %d", bd_info->ipv4_urpf_mode); - bytes_output += sprintf(entry + bytes_output, "v6_urpf %d", bd_info->ipv6_urpf_mode); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_get_entry(switch_handle_t vlan_handle, char *entry, int entry_length) -{ - return switch_bd_get_entry(vlan_handle, entry, entry_length); -} - -switch_status_t -switch_api_vlan_print_entry(switch_handle_t vlan_handle) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - - bd_info = switch_bd_get(vlan_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_HANDLE; - } - ln_info = &bd_info->ln_info; - printf("\n\n vlan handle %x", (unsigned int) vlan_handle); - printf("\n vrf_handle %x rmac_handle %x", - (unsigned int) ln_info->vrf_handle, - (unsigned int) ln_info->rmac_handle); - printf("\n bd type %d", SWITCH_LN_NETWORK_TYPE(bd_info)); - printf("\n flood uuc %x umc %x bcast %x", - bd_info->uuc_mc_index, bd_info->umc_mc_index, bd_info->bcast_mc_index); - printf("\n v4 urpf %d v6 urpf %d", bd_info->ipv4_urpf_mode, bd_info->ipv6_urpf_mode); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -switch_api_vlan_print_all(void) -{ - switch_handle_t vlan_handle; - switch_handle_t next_vlan_handle; - - switch_handle_get_first(switch_bd_array, vlan_handle); - while (vlan_handle) { - switch_api_vlan_print_entry(vlan_handle); - switch_handle_get_next(switch_bd_array, vlan_handle, next_vlan_handle); - vlan_handle = next_vlan_handle; - } - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t -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; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_bd_stats_t *ingress_bd_stats = NULL; - switch_bd_stats_t *egress_bd_stats = NULL; - int index = 0; - uint16_t bd_stats_start_idx = 0; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - ln_info = &bd_info->ln_info; - if (!ln_info->flags.stats_enabled) { - ln_info->flags.stats_enabled = TRUE; - bd_info->ingress_bd_stats = (switch_bd_stats_t *) switch_malloc(sizeof(switch_bd_stats_t), 1); - if (!bd_info->ingress_bd_stats) { - return SWITCH_STATUS_NO_MEMORY; - } - memset(bd_info->ingress_bd_stats, 0, sizeof(switch_bd_stats_t)); - bd_info->egress_bd_stats = (switch_bd_stats_t *) switch_malloc(sizeof(switch_bd_stats_t), 1); - if (!bd_info->egress_bd_stats) { - return SWITCH_STATUS_NO_MEMORY; - } - 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_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(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(bd_handle), egress_bd_stats->stats_hw_entry); + } + } + } + return status; +} + +switch_status_t switch_api_vlan_interfaces_get(switch_device_t device, + switch_handle_t vlan_handle, + uint16_t *mbr_count, + switch_vlan_interface_t **mbrs) { + switch_bd_info_t *info = NULL; + tommy_node *node = NULL; + uint16_t mbr_count_max = 0; + + if (!SWITCH_BD_HANDLE_VALID(vlan_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + info = switch_bd_get(vlan_handle); + if (!info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + *mbrs = NULL; + *mbr_count = 0; + + node = tommy_list_head(&(info->members)); + while (node) { + switch_ln_member_t *vlan_member = NULL; + vlan_member = (switch_ln_member_t *)node->data; + node = node->next; + + if (mbr_count_max == *mbr_count) { + mbr_count_max += 16; + *mbrs = switch_realloc(*mbrs, + (sizeof(switch_vlan_interface_t) * mbr_count_max)); + } + (*mbrs)[*mbr_count].vlan_handle = vlan_handle; + (*mbrs)[*mbr_count].intf_handle = vlan_member->member; + (*mbr_count)++; + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_bd_router_mac_handle_set(switch_handle_t bd_handle, + switch_handle_t rmac_handle) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_device_t device = SWITCH_DEV_ID; + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + 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); + return status; +} + +switch_status_t switch_api_vlan_xlate_add(switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle, + switch_vlan_t vlan_id) { + switch_interface_info_t *intf_info = NULL; + switch_ln_member_t *bd_member = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d: invalid interface!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_member = switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!bd_member) { + SWITCH_API_ERROR( + "%s:%d interface is not port of vlan!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + status = switch_pd_egress_vlan_xlate_table_add_entry(device, + intf_info->ifindex, + handle_to_id(bd_handle), + vlan_id, + &bd_member->xlate_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("%s:%d unable to add xlate entry for vlan %d", + __FUNCTION__, + __LINE__, + vlan_id); + return SWITCH_STATUS_PD_FAILURE; + } + return status; +} + +switch_status_t switch_api_vlan_xlate_remove(switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle, + switch_vlan_t vlan_id) { + switch_interface_info_t *intf_info = NULL; + switch_ln_member_t *bd_member = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_INTERFACE_HANDLE_VALID(intf_handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } + + intf_info = switch_api_interface_get(intf_handle); + if (!intf_info) { + SWITCH_API_ERROR("%s:%d: invalid interface!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + + bd_member = switch_api_logical_network_search_member(bd_handle, intf_handle); + if (!bd_member) { + SWITCH_API_ERROR( + "%s:%d interface is not port of vlan!", __FUNCTION__, __LINE__); + return SWITCH_STATUS_INVALID_INTERFACE; + } + status = switch_pd_egress_vlan_xlate_table_delete_entry( + device, bd_member->xlate_entry); + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR( + "%s:%d unable to remove xlate entry", __FUNCTION__, __LINE__); + return SWITCH_STATUS_PD_FAILURE; + } + return SWITCH_STATUS_SUCCESS; +} + +switch_ln_member_t *switch_api_logical_network_search_member( + switch_handle_t bd_handle, switch_handle_t intf_handle) { + switch_ln_member_t *ln_member = NULL; + tommy_node *node = NULL; + switch_bd_info_t *bd_info = NULL; + + bd_info = switch_bd_get(bd_handle); + node = tommy_list_head(&bd_info->members); + while (node) { + ln_member = node->data; + if (ln_member->member == intf_handle) { + return ln_member; + } + node = node->next; + } + return NULL; +} + +switch_status_t switch_bd_get_entry(switch_handle_t bd_handle, + char *entry, + int entry_length) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + int bytes_output = 0; + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + ln_info = &bd_info->ln_info; + bytes_output += sprintf( + entry + bytes_output, "\nvlan_handle: %x", (unsigned int)bd_handle); + bytes_output += sprintf(entry + bytes_output, + "\nvrf_handle: %x", + (unsigned int)ln_info->vrf_handle); + bytes_output += sprintf(entry + bytes_output, + "rmac_handle: %x", + (unsigned int)ln_info->rmac_handle); + bytes_output += sprintf( + entry + bytes_output, "type: %d", SWITCH_LN_NETWORK_TYPE(bd_info)); + bytes_output += + sprintf(entry + bytes_output, "\nucast mc %x", bd_info->uuc_mc_index); + bytes_output += + sprintf(entry + bytes_output, "mcast mc %x", bd_info->umc_mc_index); + bytes_output += + sprintf(entry + bytes_output, "bcast mc %x", bd_info->bcast_mc_index); + bytes_output += + sprintf(entry + bytes_output, "\nv4_urpf %d", bd_info->ipv4_urpf_mode); + bytes_output += + sprintf(entry + bytes_output, "v6_urpf %d", bd_info->ipv6_urpf_mode); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_get_entry(switch_handle_t vlan_handle, + char *entry, + int entry_length) { + return switch_bd_get_entry(vlan_handle, entry, entry_length); +} + +switch_status_t switch_api_vlan_print_entry(switch_handle_t vlan_handle) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + + bd_info = switch_bd_get(vlan_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_HANDLE; + } + ln_info = &bd_info->ln_info; + printf("\n\n vlan handle %x", (unsigned int)vlan_handle); + printf("\n vrf_handle %x rmac_handle %x", + (unsigned int)ln_info->vrf_handle, + (unsigned int)ln_info->rmac_handle); + printf("\n bd type %d", SWITCH_LN_NETWORK_TYPE(bd_info)); + printf("\n flood uuc %x umc %x bcast %x", + bd_info->uuc_mc_index, + bd_info->umc_mc_index, + bd_info->bcast_mc_index); + printf("\n v4 urpf %d v6 urpf %d", + bd_info->ipv4_urpf_mode, + bd_info->ipv6_urpf_mode); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_vlan_print_all(void) { + switch_handle_t vlan_handle; + switch_handle_t next_vlan_handle; + + switch_handle_get_first(switch_bd_array, vlan_handle); + while (vlan_handle) { + switch_api_vlan_print_entry(vlan_handle); + switch_handle_get_next(switch_bd_array, vlan_handle, next_vlan_handle); + vlan_handle = next_vlan_handle; + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t 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; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_bd_stats_t *ingress_bd_stats = NULL; + switch_bd_stats_t *egress_bd_stats = NULL; + int index = 0; + uint16_t bd_stats_start_idx = 0; + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + ln_info = &bd_info->ln_info; + if (!ln_info->flags.stats_enabled) { + ln_info->flags.stats_enabled = TRUE; + bd_info->ingress_bd_stats = + (switch_bd_stats_t *)switch_malloc(sizeof(switch_bd_stats_t), 1); + if (!bd_info->ingress_bd_stats) { + return SWITCH_STATUS_NO_MEMORY; + } + memset(bd_info->ingress_bd_stats, 0, sizeof(switch_bd_stats_t)); + bd_info->egress_bd_stats = + (switch_bd_stats_t *)switch_malloc(sizeof(switch_bd_stats_t), 1); + if (!bd_info->egress_bd_stats) { + return SWITCH_STATUS_NO_MEMORY; + } + 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_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(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(bd_handle), egress_bd_stats->stats_hw_entry); + } + return status; +} + +switch_status_t 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; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_bd_stats_t *ingress_bd_stats = NULL; + switch_bd_stats_t *egress_bd_stats = NULL; + int index = 0; + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + ln_info = &bd_info->ln_info; + 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_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(bd_handle), bd_info); + } + switch_free(bd_info->ingress_bd_stats); + egress_bd_stats = bd_info->egress_bd_stats; + status = switch_pd_egress_bd_stats_table_delete_entry( + device, egress_bd_stats->stats_hw_entry); + switch_free(bd_info->egress_bd_stats); + } + return status; +} + +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) { + switch_bd_info_t *bd_info = NULL; + switch_logical_network_t *ln_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_bd_stats_t *ingress_bd_stats = NULL; + switch_bd_stats_t *egress_bd_stats = NULL; + int index = 0; + switch_bd_stats_id_t counter_id = 0; + + bd_info = switch_bd_get(bd_handle); + if (!bd_info) { + return SWITCH_STATUS_INVALID_VLAN_ID; + } + + ln_info = &bd_info->ln_info; + 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_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_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_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: + break; + } } - return status; + } + return status; } -switch_status_t -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; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_bd_stats_t *ingress_bd_stats = NULL; - switch_bd_stats_t *egress_bd_stats = NULL; - int index = 0; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - ln_info = &bd_info->ln_info; - 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_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(bd_handle), - bd_info); - } - switch_free(bd_info->ingress_bd_stats); - egress_bd_stats = bd_info->egress_bd_stats; - status = switch_pd_egress_bd_stats_table_delete_entry( - device, - egress_bd_stats->stats_hw_entry); - switch_free(bd_info->egress_bd_stats); - } - 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_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) -{ - switch_bd_info_t *bd_info = NULL; - switch_logical_network_t *ln_info = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_bd_stats_t *ingress_bd_stats = NULL; - switch_bd_stats_t *egress_bd_stats = NULL; - int index = 0; - switch_bd_stats_id_t counter_id = 0; - - bd_info = switch_bd_get(bd_handle); - if (!bd_info) { - return SWITCH_STATUS_INVALID_VLAN_ID; - } - - ln_info = &bd_info->ln_info; - 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_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_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_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: - break; - } - } - } - return status; +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_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); +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 diff --git a/switchapi/src/switch_vlan_int.h b/switchapi/src/switch_vlan_int.h index c26f0b3..35b81d7 100644 --- a/switchapi/src/switch_vlan_int.h +++ b/switchapi/src/switch_vlan_int.h @@ -33,102 +33,100 @@ extern "C" { /** member of logcal network */ typedef struct { - tommy_node node; /**< linked list node */ - switch_handle_t member; /**< handle of member that belongs to bd */ - switch_handle_t stp_handle; - switch_rid_t rid; + tommy_node node; /**< linked list node */ + switch_handle_t member; /**< handle of member that belongs to bd */ + switch_handle_t stp_handle; + switch_rid_t rid; #ifdef SWITCH_PD - p4_pd_entry_hdl_t pv_hw_entry; - p4_pd_entry_hdl_t xlate_entry; - p4_pd_entry_hdl_t tunnel_hw_entry[3]; - p4_pd_entry_hdl_t egress_bd_hw_entry; + p4_pd_entry_hdl_t pv_hw_entry; + p4_pd_entry_hdl_t xlate_entry; + p4_pd_entry_hdl_t tunnel_hw_entry[3]; + p4_pd_entry_hdl_t egress_bd_hw_entry; #endif -} switch_ln_member_t; +} switch_ln_member_t; typedef struct switch_bd_stats_ { - uint16_t stats_idx[SWITCH_BD_STATS_MAX]; - switch_counter_t counters[SWITCH_BD_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_BD_STATS_MAX]; + p4_pd_entry_hdl_t stats_hw_entry[SWITCH_BD_STATS_MAX]; #endif } switch_bd_stats_t; /** Logical Network information */ typedef struct switch_bd_info_ { - switch_logical_network_t ln_info; - uint32_t uuc_mc_index; - uint32_t umc_mc_index; - uint32_t bcast_mc_index; - switch_rid_t rid; - uint16_t smac_index; - switch_handle_t stp_handle; - tommy_list members; /**< members of VLAN */ - - switch_urpf_mode_t ipv4_urpf_mode; - switch_urpf_mode_t ipv6_urpf_mode; - uint16_t bd_label; - switch_bd_stats_t *ingress_bd_stats; - switch_bd_stats_t *egress_bd_stats; - - switch_handle_t l3_intf_handle; + switch_logical_network_t ln_info; + uint32_t uuc_mc_index; + uint32_t umc_mc_index; + uint32_t bcast_mc_index; + switch_rid_t rid; + uint16_t smac_index; + switch_handle_t stp_handle; + tommy_list members; /**< members of VLAN */ + + switch_urpf_mode_t ipv4_urpf_mode; + switch_urpf_mode_t ipv6_urpf_mode; + uint8_t nat_mode; + 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 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; + 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; typedef struct switch_vlan_port_key_ { - switch_handle_t vlan_handle; - switch_handle_t port_lag_handle; + switch_handle_t vlan_handle; + switch_handle_t port_lag_handle; } switch_vlan_port_key_t; typedef struct switch_vlan_port_info_ { - switch_vlan_port_key_t vlan_port_key; - tommy_hashtable_node node; - switch_handle_t intf_handle; + switch_vlan_port_key_t vlan_port_key; + tommy_hashtable_node node; + switch_handle_t intf_handle; } switch_vlan_port_info_t; #define SWITCH_LN_IPV4_UNICAST_ENABLED(ln) \ - ln->ln_info.flags.ipv4_unicast_enabled + ln->ln_info.flags.ipv4_unicast_enabled #define SWITCH_LN_IPV4_MULTICAST_ENABLED(ln) \ - ln->ln_info.flags.ipv4_multicast_enabled + ln->ln_info.flags.ipv4_multicast_enabled #define SWITCH_LN_IPV6_UNICAST_ENABLED(ln) \ - ln->ln_info.flags.ipv6_unicast_enabled + ln->ln_info.flags.ipv6_unicast_enabled #define SWITCH_LN_IPV6_MULTICAST_ENABLED(ln) \ - ln->ln_info.flags.ipv6_multicast_enabled + ln->ln_info.flags.ipv6_multicast_enabled #define SWITCH_LN_IGMP_SNOOPING_ENABLED(ln) \ - ln->ln_info.flags.igmp_snooping_enabled + ln->ln_info.flags.igmp_snooping_enabled #define SWITCH_LN_MLD_SNOOPING_ENABLED(ln) \ - ln->ln_info.flags.mld_snooping_enabled + ln->ln_info.flags.mld_snooping_enabled -#define SWITCH_LN_VLAN_ID(ln) \ - ln->ln_info.encap_info.u.vlan_id +#define SWITCH_LN_NAT_MODE(ln) ln->nat_mode -#define SWITCH_LN_LEARN_ENABLED(ln) \ - ln->ln_info.flags.learn_enabled +#define SWITCH_LN_VLAN_ID(ln) ln->ln_info.encap_info.u.vlan_id -#define SWITCH_LN_FLOOD_ENABLED(ln) \ - ln->ln_info.flags.flood_enabled +#define SWITCH_LN_LEARN_ENABLED(ln) ln->ln_info.flags.learn_enabled -#define SWITCH_LN_NETWORK_TYPE(ln) \ - ln->ln_info.type +#define SWITCH_LN_FLOOD_ENABLED(ln) ln->ln_info.flags.flood_enabled -#define SWITCH_BD_IS_CORE(ln) \ - ln->ln_info.flags.core_bd +#define SWITCH_LN_NETWORK_TYPE(ln) ln->ln_info.type + +#define SWITCH_BD_IS_CORE(ln) ln->ln_info.flags.core_bd #define SWITCH_BD_STATS_START_INDEX(ln) \ - (ln->ingress_bd_stats != NULL) ? ln->ingress_bd_stats->stats_idx[0] : 0 + (ln->ingress_bd_stats != NULL) ? ln->ingress_bd_stats->stats_idx[0] : 0 // Internal API Declarations switch_handle_t switch_bd_create(); @@ -138,43 +136,58 @@ void switch_bd_delete(switch_handle_t handle); switch_status_t switch_bd_init(switch_device_t device); switch_status_t switch_bd_free(switch_device_t device); -switch_status_t switch_bd_ipv4_unicast_enabled_set(switch_handle_t bd_handle, uint64_t value); -switch_status_t switch_bd_ipv4_unicast_enabled_get(switch_handle_t bd_handle, uint64_t *value); -switch_status_t switch_bd_ipv6_unicast_enabled_set(switch_handle_t bd_handle, uint64_t value); -switch_status_t switch_bd_ipv6_unicast_enabled_get(switch_handle_t bd_handle, uint64_t *value); -switch_status_t switch_bd_ipv4_multicast_enabled_set(switch_handle_t bd_handle, uint64_t value); -switch_status_t switch_bd_ipv4_multicast_enabled_get(switch_handle_t bd_handle, uint64_t *value); -switch_status_t switch_bd_ipv6_multicast_enabled_set(switch_handle_t bd_handle, uint64_t value); -switch_status_t switch_bd_ipv6_multicast_enabled_get(switch_handle_t bd_handle, uint64_t *value); -switch_status_t switch_bd_ipv4_urpf_mode_set(switch_handle_t bd_handle, uint64_t value); -switch_status_t switch_bd_ipv4_urpf_mode_get(switch_handle_t bd_handle, uint64_t *value); -switch_status_t switch_bd_ipv6_urpf_mode_set(switch_handle_t bd_handle, uint64_t value); -switch_status_t switch_bd_ipv6_urpf_mode_get(switch_handle_t bd_handle, uint64_t *value); -switch_status_t switch_bd_router_mac_handle_set(switch_handle_t bd_handle, switch_handle_t rmac_handle); -switch_status_t switch_api_vlan_xlate_add(switch_device_t device, switch_handle_t bd_handle, - switch_handle_t intf_handle, switch_vlan_t vlan_id); -switch_status_t switch_api_vlan_xlate_remove(switch_device_t device, switch_handle_t bd_handle, - 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_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); +switch_status_t switch_bd_ipv4_unicast_enabled_set(switch_handle_t bd_handle, + uint64_t value); +switch_status_t switch_bd_ipv4_unicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value); +switch_status_t switch_bd_ipv6_unicast_enabled_set(switch_handle_t bd_handle, + uint64_t value); +switch_status_t switch_bd_ipv6_unicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value); +switch_status_t switch_bd_ipv4_multicast_enabled_set(switch_handle_t bd_handle, + uint64_t value); +switch_status_t switch_bd_ipv4_multicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value); +switch_status_t switch_bd_ipv6_multicast_enabled_set(switch_handle_t bd_handle, + uint64_t value); +switch_status_t switch_bd_ipv6_multicast_enabled_get(switch_handle_t bd_handle, + uint64_t *value); +switch_status_t switch_bd_ipv4_urpf_mode_set(switch_handle_t bd_handle, + uint64_t value); +switch_status_t switch_bd_ipv4_urpf_mode_get(switch_handle_t bd_handle, + uint64_t *value); +switch_status_t switch_bd_ipv6_urpf_mode_set(switch_handle_t bd_handle, + uint64_t value); +switch_status_t switch_bd_ipv6_urpf_mode_get(switch_handle_t bd_handle, + uint64_t *value); +switch_status_t switch_bd_nat_mode_set(switch_handle_t bd_handle, + uint8_t value); +switch_status_t switch_bd_nat_mode_get(switch_handle_t bd_handle, + uint8_t *value); +switch_status_t switch_bd_router_mac_handle_set(switch_handle_t bd_handle, + switch_handle_t rmac_handle); +switch_status_t switch_api_vlan_xlate_add(switch_device_t device, + switch_handle_t bd_handle, + switch_handle_t intf_handle, + switch_vlan_t vlan_id); +switch_status_t switch_api_vlan_xlate_remove(switch_device_t device, + switch_handle_t bd_handle, + 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_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/switch_vrf.c b/switchapi/src/switch_vrf.c index d926c3b..e876058 100644 --- a/switchapi/src/switch_vrf.c +++ b/switchapi/src/switch_vrf.c @@ -28,136 +28,124 @@ extern "C" { static void *switch_vrf_array; -switch_status_t -switch_vrf_init(switch_device_t device) -{ - UNUSED(device); - switch_vrf_array = NULL; - return switch_handle_type_init(SWITCH_HANDLE_TYPE_VRF, (16*1024)); +switch_status_t switch_vrf_init(switch_device_t device) { + UNUSED(device); + switch_vrf_array = NULL; + return switch_handle_type_init(SWITCH_HANDLE_TYPE_VRF, (16 * 1024)); } -switch_status_t -switch_vrf_free(switch_device_t device) -{ - UNUSED(device); - switch_handle_type_free(SWITCH_HANDLE_TYPE_VRF); - return SWITCH_STATUS_SUCCESS; +switch_status_t switch_vrf_free(switch_device_t device) { + UNUSED(device); + switch_handle_type_free(SWITCH_HANDLE_TYPE_VRF); + return SWITCH_STATUS_SUCCESS; } -switch_handle_t -switch_vrf_create() -{ - switch_handle_t handle; - _switch_handle_create(SWITCH_HANDLE_TYPE_VRF, switch_vrf_info_t, switch_vrf_array, NULL, handle); - return handle; +switch_handle_t switch_vrf_create() { + switch_handle_t handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_VRF, + switch_vrf_info_t, + switch_vrf_array, + NULL, + handle); + return handle; } -switch_vrf_info_t * -switch_vrf_get(switch_handle_t handle) -{ - switch_vrf_info_t *vrf_info = NULL; - _switch_handle_get(switch_vrf_info_t, switch_vrf_array, handle, vrf_info); - return vrf_info; +switch_vrf_info_t *switch_vrf_get(switch_handle_t handle) { + switch_vrf_info_t *vrf_info = NULL; + _switch_handle_get(switch_vrf_info_t, switch_vrf_array, handle, vrf_info); + return vrf_info; } -switch_handle_t -switch_api_vrf_create(switch_device_t device, switch_vrf_id_t vrf_id) -{ - switch_vrf_info_t *vrf_info = NULL; - switch_handle_t handle; - - if ((vrf_id == SWITCH_API_DEFAULT_VRF) && - (switch_api_default_vrf_internal() != 0)) { - handle = switch_api_default_vrf_internal(); - } else { - handle = switch_vrf_create(); - vrf_info = switch_vrf_get(handle); - vrf_info->vrf_id = vrf_id; - } - switch_api_init_default_route_entries(device, handle); - - return handle; +switch_handle_t switch_api_vrf_create(switch_device_t device, + switch_vrf_id_t vrf_id) { + switch_vrf_info_t *vrf_info = NULL; + switch_handle_t handle; + + if ((vrf_id == SWITCH_API_DEFAULT_VRF) && + (switch_api_default_vrf_internal() != 0)) { + handle = switch_api_default_vrf_internal(); + } else { + handle = switch_vrf_create(); + vrf_info = switch_vrf_get(handle); + vrf_info->vrf_id = vrf_id; + } + switch_api_init_default_route_entries(device, handle); + + return handle; } -switch_status_t -switch_api_vrf_delete(switch_device_t device, switch_handle_t handle) -{ - switch_vrf_info_t *vrf_info = NULL; +switch_status_t switch_api_vrf_delete(switch_device_t device, + switch_handle_t handle) { + switch_vrf_info_t *vrf_info = NULL; - if (!SWITCH_VRF_HANDLE_VALID(handle)) { - return SWITCH_STATUS_INVALID_HANDLE; - } + if (!SWITCH_VRF_HANDLE_VALID(handle)) { + return SWITCH_STATUS_INVALID_HANDLE; + } - UNUSED(device); - vrf_info = switch_vrf_get(handle); - if (!vrf_info) { - return SWITCH_STATUS_ITEM_NOT_FOUND; - } - if (vrf_info->vrf_id == SWITCH_API_DEFAULT_VRF) { - return SWITCH_STATUS_SUCCESS; - } - _switch_handle_delete(switch_vrf_info_t, switch_vrf_array, handle); + UNUSED(device); + vrf_info = switch_vrf_get(handle); + if (!vrf_info) { + return SWITCH_STATUS_ITEM_NOT_FOUND; + } + if (vrf_info->vrf_id == SWITCH_API_DEFAULT_VRF) { return SWITCH_STATUS_SUCCESS; + } + _switch_handle_delete(switch_vrf_info_t, switch_vrf_array, handle); + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_vrf_attribute_set(switch_handle_t vrf_handle, - switch_vrf_attr_t type, - uint64_t value) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch(type) { - case SWITCH_VRF_ATTR_VRF_TYPE: - status = switch_api_vrf_type_set(vrf_handle, value); - break; - default: - status = SWITCH_STATUS_INVALID_VRID; - } - return status; +switch_status_t switch_api_vrf_attribute_set(switch_handle_t vrf_handle, + switch_vrf_attr_t type, + uint64_t value) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (type) { + case SWITCH_VRF_ATTR_VRF_TYPE: + status = switch_api_vrf_type_set(vrf_handle, value); + break; + default: + status = SWITCH_STATUS_INVALID_VRID; + } + return status; } -switch_status_t -switch_api_vrf_attribute_get(switch_handle_t vrf_handle, - switch_vrf_attr_t type, - uint64_t *value) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - - switch(type) { - case SWITCH_VRF_ATTR_VRF_TYPE: - status = switch_api_vrf_type_get(vrf_handle, value); - break; - default: - status = SWITCH_STATUS_INVALID_VRID; - } - return status; +switch_status_t switch_api_vrf_attribute_get(switch_handle_t vrf_handle, + switch_vrf_attr_t type, + uint64_t *value) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch (type) { + case SWITCH_VRF_ATTR_VRF_TYPE: + status = switch_api_vrf_type_get(vrf_handle, value); + break; + default: + status = SWITCH_STATUS_INVALID_VRID; + } + return status; } -switch_status_t -switch_api_vrf_type_set(switch_handle_t vrf_handle, uint64_t value) -{ - switch_vrf_info_t *vrf_info = NULL; +switch_status_t switch_api_vrf_type_set(switch_handle_t vrf_handle, + uint64_t value) { + switch_vrf_info_t *vrf_info = NULL; - vrf_info = switch_vrf_get(vrf_handle); - if (!vrf_info) { - return SWITCH_STATUS_INVALID_VRID; - } + vrf_info = switch_vrf_get(vrf_handle); + if (!vrf_info) { + return SWITCH_STATUS_INVALID_VRID; + } - SWITCH_VRF_TYPE(vrf_info) = (uint8_t) value; - return SWITCH_STATUS_SUCCESS; + SWITCH_VRF_TYPE(vrf_info) = (uint8_t)value; + return SWITCH_STATUS_SUCCESS; } -switch_status_t -switch_api_vrf_type_get(switch_handle_t vrf_handle, uint64_t *value) -{ - switch_vrf_info_t *vrf_info = NULL; +switch_status_t switch_api_vrf_type_get(switch_handle_t vrf_handle, + uint64_t *value) { + switch_vrf_info_t *vrf_info = NULL; - vrf_info = switch_vrf_get(vrf_handle); - if (!vrf_info) { - return SWITCH_STATUS_INVALID_VRID; - } + vrf_info = switch_vrf_get(vrf_handle); + if (!vrf_info) { + return SWITCH_STATUS_INVALID_VRID; + } - *value = SWITCH_VRF_TYPE(vrf_info); - return SWITCH_STATUS_SUCCESS; + *value = SWITCH_VRF_TYPE(vrf_info); + return SWITCH_STATUS_SUCCESS; } diff --git a/switchapi/src/switch_vrf_int.h b/switchapi/src/switch_vrf_int.h index 1707800..6aac7a0 100644 --- a/switchapi/src/switch_vrf_int.h +++ b/switchapi/src/switch_vrf_int.h @@ -23,22 +23,18 @@ limitations under the License. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - -#define SWITCH_VRF_V4_ENABLED(info) \ - info->flags.v4_enabled -#define SWITCH_VRF_V6_ENABLED(info) \ - info->flags.v6_enabled +#define SWITCH_VRF_V4_ENABLED(info) info->flags.v4_enabled -#define SWITCH_VRF_TYPE(info) \ - info->flags.vrf_type +#define SWITCH_VRF_V6_ENABLED(info) info->flags.v6_enabled -#define SWITCH_VRF_IS_CORE(info) \ - SWITCH_VRF_TYPE(info) == SWITCH_VRF_TYPE_CORE +#define SWITCH_VRF_TYPE(info) info->flags.vrf_type + +#define SWITCH_VRF_IS_CORE(info) SWITCH_VRF_TYPE(info) == SWITCH_VRF_TYPE_CORE switch_status_t switch_vrf_init(switch_device_t device); switch_status_t switch_vrf_free(switch_device_t device); -switch_vrf_info_t * switch_vrf_get(switch_handle_t vrf_handle); +switch_vrf_info_t *switch_vrf_get(switch_handle_t vrf_handle); #ifdef __cplusplus } diff --git a/switchapi/src/thrift_cache.h b/switchapi/src/thrift_cache.h index 42def3d..3161cb7 100644 --- a/switchapi/src/thrift_cache.h +++ b/switchapi/src/thrift_cache.h @@ -32,4 +32,4 @@ namespace thrift_provider = p4::thrift; #include namespace thrift_provider = apache::thrift; -#endif // P4THRIFT +#endif // P4THRIFT diff --git a/switchlink/src/switchlink.h b/switchlink/src/switchlink.h index 04b96ce..1f1e5df 100644 --- a/switchlink/src/switchlink.h +++ b/switchlink/src/switchlink.h @@ -17,28 +17,33 @@ limitations under the License. #ifndef __SWITCHLINK_H__ #define __SWITCHLINK_H__ -#define switchlink_malloc(x, c) malloc(x * c) +#include +#define switchlink_malloc(x, c) malloc(x *c) #define switchlink_free(x) free(x) -#define SWITCHLINK_LOG_ERR 1 -#define SWITCHLINK_LOG_WARN 2 -#define SWITCHLINK_LOG_INFO 3 +#define SWITCHLINK_LOG_ERR 1 +#define SWITCHLINK_LOG_WARN 2 +#define SWITCHLINK_LOG_INFO 3 #define SWITCHLINK_LOG_DEBUG 4 -#define NL_LOG_DEBUG(_x) if (g_log_level >= SWITCHLINK_LOG_DEBUG) printf _x -#define NL_LOG_INFO(_x) if (g_log_level >= SWITCHLINK_LOG_INFO) printf _x -#define NL_LOG_WARN(_x) if (g_log_level >= SWITCHLINK_LOG_WARN) printf _x -#define NL_LOG_ERROR(_x) if (g_log_level >= SWITCHLINK_LOG_ERR) printf _x +#define NL_LOG_DEBUG(_x) \ + if (g_log_level >= SWITCHLINK_LOG_DEBUG) printf _x +#define NL_LOG_INFO(_x) \ + if (g_log_level >= SWITCHLINK_LOG_INFO) printf _x +#define NL_LOG_WARN(_x) \ + if (g_log_level >= SWITCHLINK_LOG_WARN) printf _x +#define NL_LOG_ERROR(_x) \ + if (g_log_level >= SWITCHLINK_LOG_ERR) printf _x typedef uint64_t switchlink_handle_t; typedef uint8_t switchlink_mac_addr_t[6]; typedef struct switchlink_ip_addr_ { - uint8_t family; - uint8_t prefix_len; - union { - struct in_addr v4addr; - struct in6_addr v6addr; - } ip; + uint8_t family; + uint8_t prefix_len; + union { + struct in_addr v4addr; + struct in6_addr v6addr; + } ip; } switchlink_ip_addr_t; extern uint8_t g_log_level; @@ -47,7 +52,7 @@ extern switchlink_handle_t g_default_bridge_h; extern switchlink_handle_t g_default_stp_h; extern switchlink_handle_t g_cpu_rx_nhop_h; -extern struct nl_sock * switchlink_get_nl_sock(); +extern struct nl_sock *switchlink_get_nl_sock(); #define SWITCHLINK_DEFAULT_VRF_ID 1 diff --git a/switchlink/src/switchlink_address.c b/switchlink/src/switchlink_address.c index a3fbc23..b4c287f 100644 --- a/switchlink/src/switchlink_address.c +++ b/switchlink/src/switchlink_address.c @@ -26,120 +26,122 @@ limitations under the License. #include "switchlink_db.h" #include "switchlink_sai.h" -void -process_address_msg(struct nlmsghdr *nlmsg, int type) { - int hdrlen, attrlen; - struct nlattr *attr; - struct ifaddrmsg *addrmsg; - bool addr_valid = false; - switchlink_ip_addr_t addr; +void process_address_msg(struct nlmsghdr *nlmsg, int type) { + int hdrlen, attrlen; + struct nlattr *attr; + struct ifaddrmsg *addrmsg; + bool addr_valid = false; + switchlink_ip_addr_t addr; - assert((type == RTM_NEWADDR) || (type == RTM_DELADDR)); - addrmsg = nlmsg_data(nlmsg); - hdrlen = sizeof(struct ifaddrmsg); - NL_LOG_DEBUG(("%saddr: family = %d, prefixlen = %d, flags = 0x%x, " - "scope = 0x%x ifindex = %d\n", - ((type == RTM_NEWADDR) ? "new" : "del"), addrmsg->ifa_family, - addrmsg->ifa_prefixlen, addrmsg->ifa_flags, - addrmsg->ifa_scope, addrmsg->ifa_index)); + assert((type == RTM_NEWADDR) || (type == RTM_DELADDR)); + addrmsg = nlmsg_data(nlmsg); + hdrlen = sizeof(struct ifaddrmsg); + NL_LOG_DEBUG( + ("%saddr: family = %d, prefixlen = %d, flags = 0x%x, " + "scope = 0x%x ifindex = %d\n", + ((type == RTM_NEWADDR) ? "new" : "del"), + addrmsg->ifa_family, + addrmsg->ifa_prefixlen, + addrmsg->ifa_flags, + addrmsg->ifa_scope, + addrmsg->ifa_index)); - if ((addrmsg->ifa_family != AF_INET) && (addrmsg->ifa_family != AF_INET6)) { - // an address family that we are not interested in, skip - return; - } + if ((addrmsg->ifa_family != AF_INET) && (addrmsg->ifa_family != AF_INET6)) { + // an address family that we are not interested in, skip + return; + } - switchlink_db_status_t status; - switchlink_intf_type_t intf_type = SWITCHLINK_INTF_TYPE_NONE; - switchlink_handle_t intf_h = 0; - bool create_l3vi = false; + switchlink_db_status_t status; + switchlink_intf_type_t intf_type = SWITCHLINK_INTF_TYPE_NONE; + switchlink_handle_t intf_h = 0; + bool create_l3vi = false; - switchlink_db_interface_info_t ifinfo; - status = switchlink_db_interface_get_info(addrmsg->ifa_index, &ifinfo); + switchlink_db_interface_info_t ifinfo; + status = switchlink_db_interface_get_info(addrmsg->ifa_index, &ifinfo); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + intf_type = ifinfo.intf_type; + intf_h = ifinfo.intf_h; + } else { + switchlink_db_bridge_info_t brinfo; + status = switchlink_db_bridge_get_info(addrmsg->ifa_index, &brinfo); if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - intf_type = ifinfo.intf_type; - intf_h = ifinfo.intf_h; + create_l3vi = true; } else { - switchlink_db_bridge_info_t brinfo; - status = switchlink_db_bridge_get_info(addrmsg->ifa_index, &brinfo); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - create_l3vi = true; - } else { - // an interface that we are not interested in, skip - return; - } - } - if (strcmp(ifinfo.ifname, SWITCHLINK_CPU_INTERFACE_NAME) == 0) { - // address on CPU interface, skip - return; + // an interface that we are not interested in, skip + return; } + } + if (strcmp(ifinfo.ifname, SWITCHLINK_CPU_INTERFACE_NAME) == 0) { + // address on CPU interface, skip + return; + } - attrlen = nlmsg_attrlen(nlmsg, hdrlen); - attr = nlmsg_attrdata(nlmsg, hdrlen); - while (nla_ok(attr, attrlen)) { - int attr_type = nla_type(attr); - switch (attr_type) { - case IFA_ADDRESS: - addr_valid = true; - memset(&addr, 0, sizeof(switchlink_ip_addr_t)); - addr.family = addrmsg->ifa_family; - addr.prefix_len = addrmsg->ifa_prefixlen; - if (addrmsg->ifa_family == AF_INET) { - addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); - } else { - memcpy(&(addr.ip.v6addr), nla_data(attr), nla_len(attr)); - } - break; - default: - NL_LOG_DEBUG(("addr: skipping attr(%d)\n", attr_type)); - break; + attrlen = nlmsg_attrlen(nlmsg, hdrlen); + attr = nlmsg_attrdata(nlmsg, hdrlen); + while (nla_ok(attr, attrlen)) { + int attr_type = nla_type(attr); + switch (attr_type) { + case IFA_ADDRESS: + addr_valid = true; + memset(&addr, 0, sizeof(switchlink_ip_addr_t)); + addr.family = addrmsg->ifa_family; + addr.prefix_len = addrmsg->ifa_prefixlen; + if (addrmsg->ifa_family == AF_INET) { + addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); + } else { + memcpy(&(addr.ip.v6addr), nla_data(attr), nla_len(attr)); } - attr = nla_next(attr, &attrlen); + break; + default: + NL_LOG_DEBUG(("addr: skipping attr(%d)\n", attr_type)); + break; } + attr = nla_next(attr, &attrlen); + } - if (type == RTM_NEWADDR) { - if ((addrmsg->ifa_family == AF_INET) || - ((addrmsg->ifa_family == AF_INET6) && - !IN6_IS_ADDR_LINKLOCAL(&(addr.ip.v6addr)))) { - if (create_l3vi) { - interface_create_l3vi(addrmsg->ifa_index); - status = switchlink_db_interface_get_info(addrmsg->ifa_index, &ifinfo); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - intf_h = ifinfo.intf_h; - } else { - if (intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { - interface_change_type(addrmsg->ifa_index, - SWITCHLINK_INTF_TYPE_L3); - } - } + if (type == RTM_NEWADDR) { + if ((addrmsg->ifa_family == AF_INET) || + ((addrmsg->ifa_family == AF_INET6) && + !IN6_IS_ADDR_LINKLOCAL(&(addr.ip.v6addr)))) { + if (create_l3vi) { + interface_create_l3vi(addrmsg->ifa_index); + status = switchlink_db_interface_get_info(addrmsg->ifa_index, &ifinfo); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + intf_h = ifinfo.intf_h; + } else { + if (intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { + interface_change_type(addrmsg->ifa_index, SWITCHLINK_INTF_TYPE_L3); } - if (addr_valid) { - switchlink_ip_addr_t null_gateway; - memset(&null_gateway, 0, sizeof(null_gateway)); - null_gateway.family = addr.family; + } + } + if (addr_valid) { + switchlink_ip_addr_t null_gateway; + memset(&null_gateway, 0, sizeof(null_gateway)); + null_gateway.family = addr.family; - // add the subnet route - route_create(g_default_vrf_h, &addr, &null_gateway, 0, intf_h); + // add the subnet route + route_create(g_default_vrf_h, &addr, &null_gateway, 0, intf_h); - // add the interface route - if (addrmsg->ifa_family == AF_INET) { - addr.prefix_len = 32; - } else { - addr.prefix_len = 128; - } - route_create(g_default_vrf_h, &addr, &null_gateway, 0, intf_h); - } - } else { - if (addr_valid) { - // remove the subnet route - route_delete(g_default_vrf_h, &addr); + // add the interface route + if (addrmsg->ifa_family == AF_INET) { + addr.prefix_len = 32; + } else { + addr.prefix_len = 128; + } + route_create(g_default_vrf_h, &addr, &null_gateway, 0, intf_h); + } + } else { + if (addr_valid) { + // remove the subnet route + route_delete(g_default_vrf_h, &addr); - // remove the interface route - if (addrmsg->ifa_family == AF_INET) { - addr.prefix_len = 32; - } else { - addr.prefix_len = 128; - } - route_delete(g_default_vrf_h, &addr); - } + // remove the interface route + if (addrmsg->ifa_family == AF_INET) { + addr.prefix_len = 32; + } else { + addr.prefix_len = 128; + } + route_delete(g_default_vrf_h, &addr); } + } } diff --git a/switchlink/src/switchlink_db.c b/switchlink/src/switchlink_db.c index 5652d76..68872f4 100644 --- a/switchlink/src/switchlink_db.c +++ b/switchlink/src/switchlink_db.c @@ -32,26 +32,26 @@ limitations under the License. #define SWITCHLINK_MAC_KEY_LEN 14 -#define SWITCHLINK_HANDLE_TYPE_OIFL 0xF800000000 +#define SWITCHLINK_HANDLE_TYPE_OIFL 0xF800000000 static switchlink_db_port_obj_t switchlink_db_port_map[] = { - {"swp1", 0}, - {"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}, + {"swp1", 0}, + {"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}, }; static tommy_trie_inplace switchlink_db_handle_obj_map; @@ -66,753 +66,739 @@ static tommy_list switchlink_db_route_obj_list; static tommy_list switchlink_db_mroute_obj_list; static tommy_list switchlink_db_mdb_obj_list; -static void * -switchlink_db_handle_get_obj(switchlink_handle_t h) { - void * obj; - obj = tommy_trie_inplace_search(&switchlink_db_handle_obj_map, h); - return obj; -} - -switchlink_db_status_t -switchlink_db_port_get_all_ports(uint16_t *num_ports, - switchlink_db_port_obj_t **port_map) { - *num_ports = - sizeof(switchlink_db_port_map)/sizeof(switchlink_db_port_obj_t); - *port_map = switchlink_malloc(sizeof(switchlink_db_port_obj_t), *num_ports); - memcpy(*port_map, switchlink_db_port_map, sizeof(switchlink_db_port_map)); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_port_get(char *name, uint16_t *port_id) { - uint16_t i; - for(i = 0; - i < sizeof(switchlink_db_port_map)/sizeof(switchlink_db_port_obj_t); - i++) { - switchlink_db_port_obj_t *obj = &switchlink_db_port_map[i]; - if (strcmp(obj->name, name) == 0) { - *port_id = obj->port_id; - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +static void *switchlink_db_handle_get_obj(switchlink_handle_t h) { + void *obj; + obj = tommy_trie_inplace_search(&switchlink_db_handle_obj_map, h); + return obj; +} + +switchlink_db_status_t switchlink_db_port_get_all_ports( + uint16_t *num_ports, switchlink_db_port_obj_t **port_map) { + *num_ports = + sizeof(switchlink_db_port_map) / sizeof(switchlink_db_port_obj_t); + *port_map = switchlink_malloc(sizeof(switchlink_db_port_obj_t), *num_ports); + memcpy(*port_map, switchlink_db_port_map, sizeof(switchlink_db_port_map)); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_port_get(char *name, uint16_t *port_id) { + uint16_t i; + for (i = 0; + i < sizeof(switchlink_db_port_map) / sizeof(switchlink_db_port_obj_t); + i++) { + switchlink_db_port_obj_t *obj = &switchlink_db_port_map[i]; + if (strcmp(obj->name, name) == 0) { + *port_id = obj->port_id; + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_interface_add( + uint32_t ifindex, switchlink_db_interface_info_t *intf_info) { + switchlink_db_intf_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_intf_obj_t), 1); + obj->ifindex = ifindex; + memcpy(&(obj->intf_info), intf_info, sizeof(switchlink_db_interface_info_t)); + tommy_trie_inplace_insert( + &switchlink_db_interface_obj_map, &obj->ifindex_node, obj, obj->ifindex); + tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, + &obj->handle_node, + obj, + obj->intf_info.intf_h); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_interface_get_info( + uint32_t ifindex, switchlink_db_interface_info_t *intf_info) { + assert(intf_info); + switchlink_db_intf_obj_t *obj; + obj = tommy_trie_inplace_search(&switchlink_db_interface_obj_map, ifindex); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; -} - -switchlink_db_status_t -switchlink_db_interface_add(uint32_t ifindex, - switchlink_db_interface_info_t *intf_info) { - switchlink_db_intf_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_intf_obj_t), 1); - obj->ifindex = ifindex; - memcpy(&(obj->intf_info), intf_info, - sizeof(switchlink_db_interface_info_t)); - tommy_trie_inplace_insert(&switchlink_db_interface_obj_map, - &obj->ifindex_node, obj, obj->ifindex); - tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, - &obj->handle_node, obj, obj->intf_info.intf_h); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_interface_get_info(uint32_t ifindex, - switchlink_db_interface_info_t *intf_info) { - assert(intf_info); - switchlink_db_intf_obj_t * obj; - obj = tommy_trie_inplace_search(&switchlink_db_interface_obj_map, ifindex); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - if (intf_info) { - memcpy(intf_info, &(obj->intf_info), - sizeof(switchlink_db_interface_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_interface_get_ifindex(switchlink_handle_t intf_h, - uint32_t *ifindex) { - switchlink_db_intf_obj_t * obj; - obj = switchlink_db_handle_get_obj(intf_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } + } + if (intf_info) { + memcpy( + intf_info, &(obj->intf_info), sizeof(switchlink_db_interface_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_interface_get_ifindex( + switchlink_handle_t intf_h, uint32_t *ifindex) { + switchlink_db_intf_obj_t *obj; + obj = switchlink_db_handle_get_obj(intf_h); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } - *ifindex = obj->ifindex; - return SWITCHLINK_DB_STATUS_SUCCESS; + *ifindex = obj->ifindex; + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_interface_update(uint32_t ifindex, - switchlink_db_interface_info_t *intf_info) { - switchlink_db_intf_obj_t * obj; - obj = tommy_trie_inplace_search(&switchlink_db_interface_obj_map, ifindex); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - memcpy(&(obj->intf_info), intf_info, - sizeof(switchlink_db_interface_info_t)); - return SWITCHLINK_DB_STATUS_SUCCESS; +switchlink_db_status_t switchlink_db_interface_update( + uint32_t ifindex, switchlink_db_interface_info_t *intf_info) { + switchlink_db_intf_obj_t *obj; + obj = tommy_trie_inplace_search(&switchlink_db_interface_obj_map, ifindex); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + memcpy(&(obj->intf_info), intf_info, sizeof(switchlink_db_interface_info_t)); + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_interface_delete(uint32_t ifindex) { - switchlink_db_intf_obj_t * obj; - obj = tommy_trie_inplace_remove(&switchlink_db_interface_obj_map, ifindex); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, - &obj->handle_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_bridge_add(uint32_t ifindex, - switchlink_db_bridge_info_t *bridge) { - switchlink_db_bridge_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_bridge_obj_t), 1); - obj->ifindex = ifindex; +switchlink_db_status_t switchlink_db_interface_delete(uint32_t ifindex) { + switchlink_db_intf_obj_t *obj; + obj = tommy_trie_inplace_remove(&switchlink_db_interface_obj_map, ifindex); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, + &obj->handle_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_bridge_add( + uint32_t ifindex, switchlink_db_bridge_info_t *bridge) { + switchlink_db_bridge_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_bridge_obj_t), 1); + obj->ifindex = ifindex; + memcpy(&(obj->bridge), bridge, sizeof(switchlink_db_bridge_info_t)); + tommy_trie_inplace_insert( + &switchlink_db_bridge_obj_map, &obj->ifindex_node, obj, obj->ifindex); + tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, + &obj->handle_node, + obj, + obj->bridge.bridge_h); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_bridge_update( + uint32_t ifindex, switchlink_db_bridge_info_t *bridge) { + switchlink_db_bridge_obj_t *obj; + obj = tommy_trie_inplace_search(&switchlink_db_bridge_obj_map, ifindex); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } else { memcpy(&(obj->bridge), bridge, sizeof(switchlink_db_bridge_info_t)); - tommy_trie_inplace_insert(&switchlink_db_bridge_obj_map, &obj->ifindex_node, - obj, obj->ifindex); - tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, - &obj->handle_node, obj, obj->bridge.bridge_h); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_bridge_update(uint32_t ifindex, - switchlink_db_bridge_info_t *bridge) { - switchlink_db_bridge_obj_t * obj; - obj = tommy_trie_inplace_search(&switchlink_db_bridge_obj_map, ifindex); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } else { - memcpy(&(obj->bridge), bridge, sizeof(switchlink_db_bridge_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_bridge_get_info(uint32_t ifindex, - switchlink_db_bridge_info_t *bridge) { - switchlink_db_bridge_obj_t * obj; - obj = tommy_trie_inplace_search(&switchlink_db_bridge_obj_map, ifindex); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } else { - if (bridge) { - memcpy(bridge, &(obj->bridge), sizeof(switchlink_db_bridge_info_t)); - } - } - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_bridge_get_ifindex(switchlink_handle_t bridge_h, - uint32_t *ifindex) { - switchlink_db_bridge_obj_t * obj; - obj = switchlink_db_handle_get_obj(bridge_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - - *ifindex = obj->ifindex; - return SWITCHLINK_DB_STATUS_SUCCESS; + } + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_bridge_handle_get_info(switchlink_handle_t bridge_h, - switchlink_db_bridge_info_t *bridge) { - switchlink_db_bridge_obj_t * obj; - obj = switchlink_db_handle_get_obj(bridge_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - +switchlink_db_status_t switchlink_db_bridge_get_info( + uint32_t ifindex, switchlink_db_bridge_info_t *bridge) { + switchlink_db_bridge_obj_t *obj; + obj = tommy_trie_inplace_search(&switchlink_db_bridge_obj_map, ifindex); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } else { if (bridge) { - memcpy(bridge, &(obj->bridge), sizeof(switchlink_db_bridge_info_t)); + memcpy(bridge, &(obj->bridge), sizeof(switchlink_db_bridge_info_t)); } - return SWITCHLINK_DB_STATUS_SUCCESS; + } + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_bridge_delete(uint32_t ifindex) { - switchlink_db_bridge_obj_t * obj; - obj = tommy_trie_inplace_remove(&switchlink_db_bridge_obj_map, ifindex); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, - &obj->handle_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -static inline void -switchlink_db_mac_key_hash(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - uint8_t *key, uint32_t *hash) { - memset(key, 0, SWITCHLINK_MAC_KEY_LEN); - memcpy(&key[0], &bridge_h, min(sizeof(bridge_h), (uint32_t)8)); - memcpy(&key[8], mac_addr, 6); - if (hash) { - *hash = XXH32(key, SWITCHLINK_MAC_KEY_LEN, 0x98761234); - } -} - -static inline int -switchlink_db_mac_cmp(const void *key1, const void *arg) { - switchlink_db_mac_obj_t * obj = (switchlink_db_mac_obj_t *)arg; - uint8_t key2[SWITCHLINK_MAC_KEY_LEN]; - - switchlink_db_mac_key_hash(obj->addr, obj->bridge_h, key2, NULL); - return (memcmp(key1, key2, SWITCHLINK_MAC_KEY_LEN)); -} - -switchlink_db_status_t -switchlink_db_mac_add(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h) { - switchlink_db_mac_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_mac_obj_t), 1); - memcpy(obj->addr, mac_addr, sizeof(switchlink_mac_addr_t)); - obj->bridge_h = bridge_h; - obj->intf_h = intf_h; - - uint32_t hash; - uint8_t key[SWITCHLINK_MAC_KEY_LEN]; - switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); - tommy_hashlin_insert(&switchlink_db_mac_obj_hash, &obj->hash_node, obj, - hash); - tommy_list_insert_tail(&switchlink_db_mac_obj_list, &obj->list_node, obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_mac_get_intf(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t *intf_h) { - switchlink_db_mac_obj_t * obj; - uint32_t hash; - uint8_t key[SWITCHLINK_MAC_KEY_LEN]; - switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); - - obj = tommy_hashlin_search(&switchlink_db_mac_obj_hash, - switchlink_db_mac_cmp, key, hash); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - *intf_h = obj->intf_h; - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_mac_set_intf(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h) { - switchlink_db_mac_obj_t * obj; - uint32_t hash; - uint8_t key[SWITCHLINK_MAC_KEY_LEN]; - switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); - - obj = tommy_hashlin_search(&switchlink_db_mac_obj_hash, - switchlink_db_mac_cmp, key, hash); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - obj->intf_h = intf_h; - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_mac_delete(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h) { - switchlink_db_mac_obj_t * obj; - uint32_t hash; - uint8_t key[SWITCHLINK_MAC_KEY_LEN]; - switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); - - obj = tommy_hashlin_search(&switchlink_db_mac_obj_hash, - switchlink_db_mac_cmp, key, hash); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - tommy_hashlin_remove_existing(&switchlink_db_mac_obj_hash, &obj->hash_node); - tommy_list_remove_existing(&switchlink_db_mac_obj_list, &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_mac_intf_delete(switchlink_handle_t intf_h) { - tommy_node * node = tommy_list_head(&switchlink_db_mac_obj_list); - while (node) { - switchlink_db_mac_obj_t * obj = node->data; - node = node->next; - if (obj->intf_h == intf_h) { - tommy_hashlin_remove_existing(&switchlink_db_mac_obj_hash, - &obj->hash_node); - tommy_list_remove_existing(&switchlink_db_mac_obj_list, - &obj->list_node); - switchlink_free(obj); - } - } - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_neighbor_add(switchlink_db_neigh_info_t *neigh_info) { - switchlink_db_neigh_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_neigh_obj_t), 1); - memcpy(&(obj->neigh_info), neigh_info, sizeof(switchlink_db_neigh_info_t)); - tommy_list_insert_tail(&switchlink_db_neigh_obj_list, &obj->list_node, obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_neighbor_get_info(switchlink_db_neigh_info_t *neigh_info) { - tommy_node * node = tommy_list_head(&switchlink_db_neigh_obj_list); - while (node) { - switchlink_db_neigh_obj_t * obj = node->data; - node = node->next; - if ((memcmp(&(neigh_info->ip_addr), &(obj->neigh_info.ip_addr), - sizeof(switchlink_ip_addr_t)) == 0) && - (neigh_info->vrf_h == obj->neigh_info.vrf_h) && - (neigh_info->intf_h == obj->neigh_info.intf_h)) { - if (neigh_info) { - memcpy(neigh_info, &(obj->neigh_info), - sizeof(switchlink_db_neigh_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_bridge_get_ifindex( + switchlink_handle_t bridge_h, uint32_t *ifindex) { + switchlink_db_bridge_obj_t *obj; + obj = switchlink_db_handle_get_obj(bridge_h); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; -} + } -switchlink_db_status_t -switchlink_db_neighbor_delete(switchlink_db_neigh_info_t *neigh_info) { - tommy_node * node = tommy_list_head(&switchlink_db_neigh_obj_list); - while (node) { - switchlink_db_neigh_obj_t * obj = node->data; - node = node->next; - if ((memcmp(&(neigh_info->ip_addr), &(obj->neigh_info.ip_addr), - sizeof(switchlink_ip_addr_t)) == 0) && - (neigh_info->intf_h == obj->neigh_info.intf_h)) { - tommy_list_remove_existing(&switchlink_db_neigh_obj_list, - &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + *ifindex = obj->ifindex; + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_ecmp_add(switchlink_db_ecmp_info_t *ecmp_info) { - assert(ecmp_info->num_nhops < SWITCHLINK_ECMP_NUM_MEMBERS_MAX); - switchlink_db_ecmp_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_ecmp_obj_t), 1); - memcpy(&(obj->ecmp_info), ecmp_info, sizeof(switchlink_db_ecmp_info_t)); - obj->ref_count = 0; - tommy_list_insert_tail(&switchlink_db_ecmp_obj_list, &obj->list_node, obj); - tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, - &obj->handle_node, obj, obj->ecmp_info.ecmp_h); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_ecmp_get_info(switchlink_db_ecmp_info_t *ecmp_info) { - tommy_node * node = tommy_list_head(&switchlink_db_ecmp_obj_list); - while (node) { - switchlink_db_ecmp_obj_t * obj = node->data; - node = node->next; - if (obj->ecmp_info.num_nhops == ecmp_info->num_nhops) { - int i, j; - for (i = 0; i < ecmp_info->num_nhops; i++) { - bool match_found = false; - for (j = 0; j < ecmp_info->num_nhops; j++) { - if (obj->ecmp_info.nhops[i] == ecmp_info->nhops[j]) { - match_found = true; - break; - } - } - if (!match_found) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - } - if (ecmp_info) { - memcpy(ecmp_info, &(obj->ecmp_info), - sizeof(switchlink_db_ecmp_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_bridge_handle_get_info( + switchlink_handle_t bridge_h, switchlink_db_bridge_info_t *bridge) { + switchlink_db_bridge_obj_t *obj; + obj = switchlink_db_handle_get_obj(bridge_h); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; -} + } -switchlink_db_status_t -switchlink_db_ecmp_handle_get_info(switchlink_handle_t ecmp_h, - switchlink_db_ecmp_info_t *ecmp_info) { - switchlink_db_ecmp_obj_t * obj; - obj = switchlink_db_handle_get_obj(ecmp_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - if (ecmp_info) { - memcpy(ecmp_info, &(obj->ecmp_info), sizeof(switchlink_db_ecmp_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_ecmp_ref_inc(switchlink_handle_t ecmp_h) { - switchlink_db_ecmp_obj_t * obj; - obj = switchlink_db_handle_get_obj(ecmp_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - assert(obj->ref_count >= 0); - obj->ref_count++; - return SWITCHLINK_DB_STATUS_SUCCESS; + if (bridge) { + memcpy(bridge, &(obj->bridge), sizeof(switchlink_db_bridge_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_ecmp_ref_dec(switchlink_handle_t ecmp_h, int *ref_count) { - switchlink_db_ecmp_obj_t * obj; - obj = switchlink_db_handle_get_obj(ecmp_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - assert(obj->ref_count >= 0); - if (obj->ref_count != 0) { - obj->ref_count--; - } - *ref_count = obj->ref_count; - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_ecmp_delete(switchlink_handle_t ecmp_h) { - switchlink_db_ecmp_obj_t * obj; - obj = switchlink_db_handle_get_obj(ecmp_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - assert(obj->ref_count == 0); - tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, - &obj->handle_node); - tommy_list_remove_existing(&switchlink_db_ecmp_obj_list, &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_oifl_add(switchlink_db_oifl_info_t *oifl_info) { - static switchlink_handle_t s_oifl_h = 1; - assert(oifl_info->num_intfs < SWITCHLINK_OIFL_NUM_MEMBERS_MAX); - switchlink_db_oifl_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_oifl_obj_t), 1); - oifl_info->oifl_h = (s_oifl_h++ & ~SWITCHLINK_HANDLE_TYPE_OIFL) | - SWITCHLINK_HANDLE_TYPE_OIFL; - memcpy(&(obj->oifl_info), oifl_info, sizeof(switchlink_db_oifl_info_t)); - obj->ref_count = 0; - tommy_list_insert_tail(&switchlink_db_oifl_obj_list, &obj->list_node, obj); - tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, - &obj->handle_node, obj, obj->oifl_info.oifl_h); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_oifl_get_info(switchlink_db_oifl_info_t *oifl_info) { - tommy_node * node = tommy_list_head(&switchlink_db_oifl_obj_list); - while (node) { - switchlink_db_oifl_obj_t * obj = node->data; - node = node->next; - if (obj->oifl_info.num_intfs == oifl_info->num_intfs) { - int i, j; - for (i = 0; i < oifl_info->num_intfs; i++) { - bool match_found = false; - for (j = 0; j < oifl_info->num_intfs; j++) { - if (obj->oifl_info.intfs[i] == oifl_info->intfs[j]) { - match_found = true; - break; - } - } - if (!match_found) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - } - if (oifl_info) { - memcpy(oifl_info, &(obj->oifl_info), - sizeof(switchlink_db_oifl_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_bridge_delete(uint32_t ifindex) { + switchlink_db_bridge_obj_t *obj; + obj = tommy_trie_inplace_remove(&switchlink_db_bridge_obj_map, ifindex); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, + &obj->handle_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +static inline void switchlink_db_mac_key_hash(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + uint8_t *key, + uint32_t *hash) { + memset(key, 0, SWITCHLINK_MAC_KEY_LEN); + memcpy(&key[0], &bridge_h, min(sizeof(bridge_h), (uint32_t)8)); + memcpy(&key[8], mac_addr, 6); + if (hash) { + *hash = XXH32(key, SWITCHLINK_MAC_KEY_LEN, 0x98761234); + } +} + +static inline int switchlink_db_mac_cmp(const void *key1, const void *arg) { + switchlink_db_mac_obj_t *obj = (switchlink_db_mac_obj_t *)arg; + uint8_t key2[SWITCHLINK_MAC_KEY_LEN]; + + switchlink_db_mac_key_hash(obj->addr, obj->bridge_h, key2, NULL); + return (memcmp(key1, key2, SWITCHLINK_MAC_KEY_LEN)); +} + +switchlink_db_status_t switchlink_db_mac_add(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h) { + switchlink_db_mac_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_mac_obj_t), 1); + memcpy(obj->addr, mac_addr, sizeof(switchlink_mac_addr_t)); + obj->bridge_h = bridge_h; + obj->intf_h = intf_h; + + uint32_t hash; + uint8_t key[SWITCHLINK_MAC_KEY_LEN]; + switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); + tommy_hashlin_insert(&switchlink_db_mac_obj_hash, &obj->hash_node, obj, hash); + tommy_list_insert_tail(&switchlink_db_mac_obj_list, &obj->list_node, obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_mac_get_intf( + switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t *intf_h) { + switchlink_db_mac_obj_t *obj; + uint32_t hash; + uint8_t key[SWITCHLINK_MAC_KEY_LEN]; + switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); + + obj = tommy_hashlin_search( + &switchlink_db_mac_obj_hash, switchlink_db_mac_cmp, key, hash); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + *intf_h = obj->intf_h; + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_mac_set_intf( + switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h) { + switchlink_db_mac_obj_t *obj; + uint32_t hash; + uint8_t key[SWITCHLINK_MAC_KEY_LEN]; + switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); + + obj = tommy_hashlin_search( + &switchlink_db_mac_obj_hash, switchlink_db_mac_cmp, key, hash); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + obj->intf_h = intf_h; + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_oifl_handle_get_info(switchlink_handle_t oifl_h, - switchlink_db_oifl_info_t *oifl_info) { - switchlink_db_oifl_obj_t * obj; - obj = switchlink_db_handle_get_obj(oifl_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - if (oifl_info) { - memcpy(oifl_info, &(obj->oifl_info), sizeof(switchlink_db_oifl_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_oifl_ref_inc(switchlink_handle_t oifl_h) { - switchlink_db_oifl_obj_t * obj; - obj = switchlink_db_handle_get_obj(oifl_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - assert(obj->ref_count >= 0); - obj->ref_count++; - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_oifl_ref_dec(switchlink_handle_t oifl_h, int *ref_count) { - switchlink_db_oifl_obj_t * obj; - obj = switchlink_db_handle_get_obj(oifl_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - assert(obj->ref_count >= 0); - if (obj->ref_count != 0) { - obj->ref_count--; - } - *ref_count = obj->ref_count; - return SWITCHLINK_DB_STATUS_SUCCESS; -} +switchlink_db_status_t switchlink_db_mac_delete(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h) { + switchlink_db_mac_obj_t *obj; + uint32_t hash; + uint8_t key[SWITCHLINK_MAC_KEY_LEN]; + switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); -switchlink_db_status_t -switchlink_db_oifl_delete(switchlink_handle_t oifl_h) { - switchlink_db_oifl_obj_t * obj; - obj = switchlink_db_handle_get_obj(oifl_h); - if (!obj) { - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; - } - assert(obj->ref_count == 0); - tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, - &obj->handle_node); - tommy_list_remove_existing(&switchlink_db_oifl_obj_list, &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_route_add(switchlink_db_route_info_t *route_info) { - switchlink_db_route_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_route_obj_t), 1); - memcpy(&(obj->route_info), route_info, sizeof(switchlink_db_route_info_t)); - tommy_list_insert_tail(&switchlink_db_route_obj_list, &obj->list_node, obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_route_delete(switchlink_db_route_info_t *route_info) { - tommy_node * node = tommy_list_head(&switchlink_db_route_obj_list); - while (node) { - switchlink_db_route_obj_t * obj = node->data; - node = node->next; - if ((obj->route_info.vrf_h == route_info->vrf_h) && - (memcmp(&(obj->route_info.ip_addr), &(route_info->ip_addr), - sizeof(switchlink_ip_addr_t)) == 0)) { - tommy_list_remove_existing(&switchlink_db_route_obj_list, - &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } + obj = tommy_hashlin_search( + &switchlink_db_mac_obj_hash, switchlink_db_mac_cmp, key, hash); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; -} - -switchlink_db_status_t -switchlink_db_route_get_info(switchlink_db_route_info_t *route_info) { - tommy_node * node = tommy_list_head(&switchlink_db_route_obj_list); - while (node) { - switchlink_db_route_obj_t * obj = node->data; - node = node->next; - if ((obj->route_info.vrf_h == route_info->vrf_h) && - (memcmp(&(obj->route_info.ip_addr), &(route_info->ip_addr), - sizeof(switchlink_ip_addr_t)) == 0)) { - if (route_info) { - memcpy(route_info, &(obj->route_info), - sizeof(switchlink_db_route_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; + } + tommy_hashlin_remove_existing(&switchlink_db_mac_obj_hash, &obj->hash_node); + tommy_list_remove_existing(&switchlink_db_mac_obj_list, &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_mac_intf_delete( + switchlink_handle_t intf_h) { + tommy_node *node = tommy_list_head(&switchlink_db_mac_obj_list); + while (node) { + switchlink_db_mac_obj_t *obj = node->data; + node = node->next; + if (obj->intf_h == intf_h) { + tommy_hashlin_remove_existing(&switchlink_db_mac_obj_hash, + &obj->hash_node); + tommy_list_remove_existing(&switchlink_db_mac_obj_list, &obj->list_node); + switchlink_free(obj); + } + } + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_neighbor_add( + switchlink_db_neigh_info_t *neigh_info) { + switchlink_db_neigh_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_neigh_obj_t), 1); + memcpy(&(obj->neigh_info), neigh_info, sizeof(switchlink_db_neigh_info_t)); + tommy_list_insert_tail(&switchlink_db_neigh_obj_list, &obj->list_node, obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_neighbor_get_info( + switchlink_db_neigh_info_t *neigh_info) { + tommy_node *node = tommy_list_head(&switchlink_db_neigh_obj_list); + while (node) { + switchlink_db_neigh_obj_t *obj = node->data; + node = node->next; + if ((memcmp(&(neigh_info->ip_addr), + &(obj->neigh_info.ip_addr), + sizeof(switchlink_ip_addr_t)) == 0) && + (neigh_info->vrf_h == obj->neigh_info.vrf_h) && + (neigh_info->intf_h == obj->neigh_info.intf_h)) { + if (neigh_info) { + memcpy( + neigh_info, &(obj->neigh_info), sizeof(switchlink_db_neigh_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_neighbor_delete( + switchlink_db_neigh_info_t *neigh_info) { + tommy_node *node = tommy_list_head(&switchlink_db_neigh_obj_list); + while (node) { + switchlink_db_neigh_obj_t *obj = node->data; + node = node->next; + if ((memcmp(&(neigh_info->ip_addr), + &(obj->neigh_info.ip_addr), + sizeof(switchlink_ip_addr_t)) == 0) && + (neigh_info->intf_h == obj->neigh_info.intf_h)) { + tommy_list_remove_existing(&switchlink_db_neigh_obj_list, + &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_ecmp_add( + switchlink_db_ecmp_info_t *ecmp_info) { + assert(ecmp_info->num_nhops < SWITCHLINK_ECMP_NUM_MEMBERS_MAX); + switchlink_db_ecmp_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_ecmp_obj_t), 1); + memcpy(&(obj->ecmp_info), ecmp_info, sizeof(switchlink_db_ecmp_info_t)); + obj->ref_count = 0; + tommy_list_insert_tail(&switchlink_db_ecmp_obj_list, &obj->list_node, obj); + tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, + &obj->handle_node, + obj, + obj->ecmp_info.ecmp_h); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_ecmp_get_info( + switchlink_db_ecmp_info_t *ecmp_info) { + tommy_node *node = tommy_list_head(&switchlink_db_ecmp_obj_list); + while (node) { + switchlink_db_ecmp_obj_t *obj = node->data; + node = node->next; + if (obj->ecmp_info.num_nhops == ecmp_info->num_nhops) { + int i, j; + for (i = 0; i < ecmp_info->num_nhops; i++) { + bool match_found = false; + for (j = 0; j < ecmp_info->num_nhops; j++) { + if (obj->ecmp_info.nhops[i] == ecmp_info->nhops[j]) { + match_found = true; + break; + } + } + if (!match_found) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; } + } + if (ecmp_info) { + memcpy(ecmp_info, &(obj->ecmp_info), sizeof(switchlink_db_ecmp_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; } - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; } -switchlink_db_status_t -switchlink_db_mroute_add(switchlink_db_mroute_info_t *mroute_info) { - switchlink_db_mroute_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_mroute_obj_t), 1); - memcpy(&(obj->mroute_info), mroute_info, - sizeof(switchlink_db_mroute_info_t)); - tommy_list_insert_tail(&switchlink_db_mroute_obj_list, - &obj->list_node, obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_mroute_delete(switchlink_db_mroute_info_t *mroute_info) { - tommy_node * node = tommy_list_head(&switchlink_db_mroute_obj_list); - while (node) { - switchlink_db_mroute_obj_t * obj = node->data; - node = node->next; - if ((obj->mroute_info.vrf_h == mroute_info->vrf_h) && - (memcmp(&(obj->mroute_info.src_ip), &(mroute_info->src_ip), - sizeof(switchlink_ip_addr_t)) == 0) && - (memcmp(&(obj->mroute_info.dst_ip), &(mroute_info->dst_ip), - sizeof(switchlink_ip_addr_t)) == 0)) { - tommy_list_remove_existing(&switchlink_db_mroute_obj_list, - &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_ecmp_handle_get_info( + switchlink_handle_t ecmp_h, switchlink_db_ecmp_info_t *ecmp_info) { + switchlink_db_ecmp_obj_t *obj; + obj = switchlink_db_handle_get_obj(ecmp_h); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + if (ecmp_info) { + memcpy(ecmp_info, &(obj->ecmp_info), sizeof(switchlink_db_ecmp_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_mroute_get_info(switchlink_db_mroute_info_t *mroute_info) { - tommy_node * node = tommy_list_head(&switchlink_db_mroute_obj_list); - while (node) { - switchlink_db_mroute_obj_t * obj = node->data; - node = node->next; - if ((obj->mroute_info.vrf_h == mroute_info->vrf_h) && - (memcmp(&(obj->mroute_info.src_ip), &(mroute_info->src_ip), - sizeof(switchlink_ip_addr_t)) == 0) && - (memcmp(&(obj->mroute_info.dst_ip), &(mroute_info->dst_ip), - sizeof(switchlink_ip_addr_t)) == 0)) { - if (mroute_info) { - memcpy(mroute_info, &(obj->mroute_info), - sizeof(switchlink_db_mroute_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_ecmp_ref_inc(switchlink_handle_t ecmp_h) { + switchlink_db_ecmp_obj_t *obj; + obj = switchlink_db_handle_get_obj(ecmp_h); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + assert(obj->ref_count >= 0); + obj->ref_count++; + return SWITCHLINK_DB_STATUS_SUCCESS; } -void -switchlink_db_mroute_mdb_walk(switchlink_db_mdb_info_t *mdb_info, - switchlink_db_mroute_walk_fn notify) { - if (!mdb_info || !notify) { - return; - } - - switchlink_handle_t mdb_vrf_h; - switchlink_db_bridge_info_t bridge_info; - if (switchlink_db_bridge_handle_get_info( - mdb_info->bridge_h, &bridge_info) != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } - mdb_vrf_h = bridge_info.vrf_h; - - tommy_node * node = tommy_list_head(&switchlink_db_mroute_obj_list); - while (node) { - switchlink_db_mroute_obj_t * obj = node->data; - node = node->next; - if ((obj->mroute_info.vrf_h == mdb_vrf_h) && - (memcmp(&(obj->mroute_info.dst_ip), &(mdb_info->grp_ip), - sizeof(switchlink_ip_addr_t)) == 0)) { - switchlink_db_mroute_info_t mroute_info; - memcpy(&mroute_info, &(obj->mroute_info), - sizeof(switchlink_db_mroute_info_t)); - (*notify)(&mroute_info); +switchlink_db_status_t switchlink_db_ecmp_ref_dec(switchlink_handle_t ecmp_h, + int *ref_count) { + switchlink_db_ecmp_obj_t *obj; + obj = switchlink_db_handle_get_obj(ecmp_h); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + assert(obj->ref_count >= 0); + if (obj->ref_count != 0) { + obj->ref_count--; + } + *ref_count = obj->ref_count; + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_ecmp_delete(switchlink_handle_t ecmp_h) { + switchlink_db_ecmp_obj_t *obj; + obj = switchlink_db_handle_get_obj(ecmp_h); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + assert(obj->ref_count == 0); + tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, + &obj->handle_node); + tommy_list_remove_existing(&switchlink_db_ecmp_obj_list, &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_oifl_add( + switchlink_db_oifl_info_t *oifl_info) { + static switchlink_handle_t s_oifl_h = 1; + assert(oifl_info->num_intfs < SWITCHLINK_OIFL_NUM_MEMBERS_MAX); + switchlink_db_oifl_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_oifl_obj_t), 1); + oifl_info->oifl_h = + (s_oifl_h++ & ~SWITCHLINK_HANDLE_TYPE_OIFL) | SWITCHLINK_HANDLE_TYPE_OIFL; + memcpy(&(obj->oifl_info), oifl_info, sizeof(switchlink_db_oifl_info_t)); + obj->ref_count = 0; + tommy_list_insert_tail(&switchlink_db_oifl_obj_list, &obj->list_node, obj); + tommy_trie_inplace_insert(&switchlink_db_handle_obj_map, + &obj->handle_node, + obj, + obj->oifl_info.oifl_h); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_oifl_get_info( + switchlink_db_oifl_info_t *oifl_info) { + tommy_node *node = tommy_list_head(&switchlink_db_oifl_obj_list); + while (node) { + switchlink_db_oifl_obj_t *obj = node->data; + node = node->next; + if (obj->oifl_info.num_intfs == oifl_info->num_intfs) { + int i, j; + for (i = 0; i < oifl_info->num_intfs; i++) { + bool match_found = false; + for (j = 0; j < oifl_info->num_intfs; j++) { + if (obj->oifl_info.intfs[i] == oifl_info->intfs[j]) { + match_found = true; + break; + } } - } -} - -switchlink_db_status_t -switchlink_db_mdb_add(switchlink_db_mdb_info_t *mdb_info) { - switchlink_db_mdb_obj_t * obj = - switchlink_malloc(sizeof(switchlink_db_mdb_obj_t), 1); - memcpy(&(obj->mdb_info), mdb_info, sizeof(switchlink_db_mdb_info_t)); - tommy_list_insert_tail(&switchlink_db_mdb_obj_list, &obj->list_node, obj); - return SWITCHLINK_DB_STATUS_SUCCESS; -} - -switchlink_db_status_t -switchlink_db_mdb_delete(switchlink_db_mdb_info_t *mdb_info) { - tommy_node * node = tommy_list_head(&switchlink_db_mdb_obj_list); - while (node) { - switchlink_db_mdb_obj_t * obj = node->data; - node = node->next; - if ((obj->mdb_info.bridge_h == mdb_info->bridge_h) && - (memcmp(&(obj->mdb_info.grp_ip), &(mdb_info->grp_ip), - sizeof(switchlink_ip_addr_t)) == 0)) { - tommy_list_remove_existing(&switchlink_db_mdb_obj_list, - &obj->list_node); - switchlink_free(obj); - return SWITCHLINK_DB_STATUS_SUCCESS; + if (!match_found) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; } + } + if (oifl_info) { + memcpy(oifl_info, &(obj->oifl_info), sizeof(switchlink_db_oifl_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; } - return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; } -switchlink_db_status_t -switchlink_db_mdb_update(switchlink_db_mdb_info_t *mdb_info) { - tommy_node * node = tommy_list_head(&switchlink_db_mdb_obj_list); - while (node) { - switchlink_db_mdb_obj_t * obj = node->data; - node = node->next; - if ((obj->mdb_info.bridge_h == mdb_info->bridge_h) && - (memcmp(&(obj->mdb_info.grp_ip), &(mdb_info->grp_ip), - sizeof(switchlink_ip_addr_t)) == 0)) { - memcpy(&(obj->mdb_info), mdb_info, - sizeof(switchlink_db_mdb_info_t)); - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_oifl_handle_get_info( + switchlink_handle_t oifl_h, switchlink_db_oifl_info_t *oifl_info) { + switchlink_db_oifl_obj_t *obj; + obj = switchlink_db_handle_get_obj(oifl_h); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + if (oifl_info) { + memcpy(oifl_info, &(obj->oifl_info), sizeof(switchlink_db_oifl_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; } -switchlink_db_status_t -switchlink_db_mdb_get_info(switchlink_db_mdb_info_t *mdb_info) { - tommy_node * node = tommy_list_head(&switchlink_db_mdb_obj_list); - while (node) { - switchlink_db_mdb_obj_t * obj = node->data; - node = node->next; - if ((obj->mdb_info.bridge_h == mdb_info->bridge_h) && - (memcmp(&(obj->mdb_info.grp_ip), &(mdb_info->grp_ip), - sizeof(switchlink_ip_addr_t)) == 0)) { - if (mdb_info) { - memcpy(mdb_info, &(obj->mdb_info), - sizeof(switchlink_db_mdb_info_t)); - } - return SWITCHLINK_DB_STATUS_SUCCESS; - } - } +switchlink_db_status_t switchlink_db_oifl_ref_inc(switchlink_handle_t oifl_h) { + switchlink_db_oifl_obj_t *obj; + obj = switchlink_db_handle_get_obj(oifl_h); + if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + assert(obj->ref_count >= 0); + obj->ref_count++; + return SWITCHLINK_DB_STATUS_SUCCESS; } -void -switchlink_db_init() { - tommy_trie_inplace_init(&switchlink_db_handle_obj_map); - tommy_trie_inplace_init(&switchlink_db_interface_obj_map); - tommy_trie_inplace_init(&switchlink_db_bridge_obj_map); - tommy_hashlin_init(&switchlink_db_mac_obj_hash); - tommy_list_init(&switchlink_db_mac_obj_list); - tommy_list_init(&switchlink_db_neigh_obj_list); - tommy_list_init(&switchlink_db_ecmp_obj_list); - tommy_list_init(&switchlink_db_oifl_obj_list); - tommy_list_init(&switchlink_db_route_obj_list); - tommy_list_init(&switchlink_db_mroute_obj_list); - tommy_list_init(&switchlink_db_mdb_obj_list); +switchlink_db_status_t switchlink_db_oifl_ref_dec(switchlink_handle_t oifl_h, + int *ref_count) { + switchlink_db_oifl_obj_t *obj; + obj = switchlink_db_handle_get_obj(oifl_h); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + assert(obj->ref_count >= 0); + if (obj->ref_count != 0) { + obj->ref_count--; + } + *ref_count = obj->ref_count; + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_oifl_delete(switchlink_handle_t oifl_h) { + switchlink_db_oifl_obj_t *obj; + obj = switchlink_db_handle_get_obj(oifl_h); + if (!obj) { + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; + } + assert(obj->ref_count == 0); + tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, + &obj->handle_node); + tommy_list_remove_existing(&switchlink_db_oifl_obj_list, &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_route_add( + switchlink_db_route_info_t *route_info) { + switchlink_db_route_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_route_obj_t), 1); + memcpy(&(obj->route_info), route_info, sizeof(switchlink_db_route_info_t)); + tommy_list_insert_tail(&switchlink_db_route_obj_list, &obj->list_node, obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_route_delete( + switchlink_db_route_info_t *route_info) { + tommy_node *node = tommy_list_head(&switchlink_db_route_obj_list); + while (node) { + switchlink_db_route_obj_t *obj = node->data; + node = node->next; + if ((obj->route_info.vrf_h == route_info->vrf_h) && + (memcmp(&(obj->route_info.ip_addr), + &(route_info->ip_addr), + sizeof(switchlink_ip_addr_t)) == 0)) { + tommy_list_remove_existing(&switchlink_db_route_obj_list, + &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_route_get_info( + switchlink_db_route_info_t *route_info) { + tommy_node *node = tommy_list_head(&switchlink_db_route_obj_list); + while (node) { + switchlink_db_route_obj_t *obj = node->data; + node = node->next; + if ((obj->route_info.vrf_h == route_info->vrf_h) && + (memcmp(&(obj->route_info.ip_addr), + &(route_info->ip_addr), + sizeof(switchlink_ip_addr_t)) == 0)) { + if (route_info) { + memcpy( + route_info, &(obj->route_info), sizeof(switchlink_db_route_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_mroute_add( + switchlink_db_mroute_info_t *mroute_info) { + switchlink_db_mroute_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_mroute_obj_t), 1); + memcpy(&(obj->mroute_info), mroute_info, sizeof(switchlink_db_mroute_info_t)); + tommy_list_insert_tail(&switchlink_db_mroute_obj_list, &obj->list_node, obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_mroute_delete( + switchlink_db_mroute_info_t *mroute_info) { + tommy_node *node = tommy_list_head(&switchlink_db_mroute_obj_list); + while (node) { + switchlink_db_mroute_obj_t *obj = node->data; + node = node->next; + if ((obj->mroute_info.vrf_h == mroute_info->vrf_h) && + (memcmp(&(obj->mroute_info.src_ip), + &(mroute_info->src_ip), + sizeof(switchlink_ip_addr_t)) == 0) && + (memcmp(&(obj->mroute_info.dst_ip), + &(mroute_info->dst_ip), + sizeof(switchlink_ip_addr_t)) == 0)) { + tommy_list_remove_existing(&switchlink_db_mroute_obj_list, + &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_mroute_get_info( + switchlink_db_mroute_info_t *mroute_info) { + tommy_node *node = tommy_list_head(&switchlink_db_mroute_obj_list); + while (node) { + switchlink_db_mroute_obj_t *obj = node->data; + node = node->next; + if ((obj->mroute_info.vrf_h == mroute_info->vrf_h) && + (memcmp(&(obj->mroute_info.src_ip), + &(mroute_info->src_ip), + sizeof(switchlink_ip_addr_t)) == 0) && + (memcmp(&(obj->mroute_info.dst_ip), + &(mroute_info->dst_ip), + sizeof(switchlink_ip_addr_t)) == 0)) { + if (mroute_info) { + memcpy(mroute_info, + &(obj->mroute_info), + sizeof(switchlink_db_mroute_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +void switchlink_db_mroute_mdb_walk(switchlink_db_mdb_info_t *mdb_info, + switchlink_db_mroute_walk_fn notify) { + if (!mdb_info || !notify) { + return; + } + + switchlink_handle_t mdb_vrf_h; + switchlink_db_bridge_info_t bridge_info; + if (switchlink_db_bridge_handle_get_info(mdb_info->bridge_h, &bridge_info) != + SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } + mdb_vrf_h = bridge_info.vrf_h; + + tommy_node *node = tommy_list_head(&switchlink_db_mroute_obj_list); + while (node) { + switchlink_db_mroute_obj_t *obj = node->data; + node = node->next; + if ((obj->mroute_info.vrf_h == mdb_vrf_h) && + (memcmp(&(obj->mroute_info.dst_ip), + &(mdb_info->grp_ip), + sizeof(switchlink_ip_addr_t)) == 0)) { + switchlink_db_mroute_info_t mroute_info; + memcpy(&mroute_info, + &(obj->mroute_info), + sizeof(switchlink_db_mroute_info_t)); + (*notify)(&mroute_info); + } + } +} + +switchlink_db_status_t switchlink_db_mdb_add( + switchlink_db_mdb_info_t *mdb_info) { + switchlink_db_mdb_obj_t *obj = + switchlink_malloc(sizeof(switchlink_db_mdb_obj_t), 1); + memcpy(&(obj->mdb_info), mdb_info, sizeof(switchlink_db_mdb_info_t)); + tommy_list_insert_tail(&switchlink_db_mdb_obj_list, &obj->list_node, obj); + return SWITCHLINK_DB_STATUS_SUCCESS; +} + +switchlink_db_status_t switchlink_db_mdb_delete( + switchlink_db_mdb_info_t *mdb_info) { + tommy_node *node = tommy_list_head(&switchlink_db_mdb_obj_list); + while (node) { + switchlink_db_mdb_obj_t *obj = node->data; + node = node->next; + if ((obj->mdb_info.bridge_h == mdb_info->bridge_h) && + (memcmp(&(obj->mdb_info.grp_ip), + &(mdb_info->grp_ip), + sizeof(switchlink_ip_addr_t)) == 0)) { + tommy_list_remove_existing(&switchlink_db_mdb_obj_list, &obj->list_node); + switchlink_free(obj); + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_mdb_update( + switchlink_db_mdb_info_t *mdb_info) { + tommy_node *node = tommy_list_head(&switchlink_db_mdb_obj_list); + while (node) { + switchlink_db_mdb_obj_t *obj = node->data; + node = node->next; + if ((obj->mdb_info.bridge_h == mdb_info->bridge_h) && + (memcmp(&(obj->mdb_info.grp_ip), + &(mdb_info->grp_ip), + sizeof(switchlink_ip_addr_t)) == 0)) { + memcpy(&(obj->mdb_info), mdb_info, sizeof(switchlink_db_mdb_info_t)); + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +switchlink_db_status_t switchlink_db_mdb_get_info( + switchlink_db_mdb_info_t *mdb_info) { + tommy_node *node = tommy_list_head(&switchlink_db_mdb_obj_list); + while (node) { + switchlink_db_mdb_obj_t *obj = node->data; + node = node->next; + if ((obj->mdb_info.bridge_h == mdb_info->bridge_h) && + (memcmp(&(obj->mdb_info.grp_ip), + &(mdb_info->grp_ip), + sizeof(switchlink_ip_addr_t)) == 0)) { + if (mdb_info) { + memcpy(mdb_info, &(obj->mdb_info), sizeof(switchlink_db_mdb_info_t)); + } + return SWITCHLINK_DB_STATUS_SUCCESS; + } + } + return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; +} + +void switchlink_db_init() { + tommy_trie_inplace_init(&switchlink_db_handle_obj_map); + tommy_trie_inplace_init(&switchlink_db_interface_obj_map); + tommy_trie_inplace_init(&switchlink_db_bridge_obj_map); + tommy_hashlin_init(&switchlink_db_mac_obj_hash); + tommy_list_init(&switchlink_db_mac_obj_list); + tommy_list_init(&switchlink_db_neigh_obj_list); + tommy_list_init(&switchlink_db_ecmp_obj_list); + tommy_list_init(&switchlink_db_oifl_obj_list); + tommy_list_init(&switchlink_db_route_obj_list); + tommy_list_init(&switchlink_db_mroute_obj_list); + tommy_list_init(&switchlink_db_mdb_obj_list); } diff --git a/switchlink/src/switchlink_db.h b/switchlink/src/switchlink_db.h index 6451d26..4dcb0d8 100644 --- a/switchlink/src/switchlink_db.h +++ b/switchlink/src/switchlink_db.h @@ -17,256 +17,241 @@ limitations under the License. #ifndef __SWITCHLINK_DB_H__ #define __SWITCHLINK_DB_H__ -#define SWITCHLINK_INTERFACE_NAME_LEN_MAX 32 -#define SWITCHLINK_ECMP_NUM_MEMBERS_MAX 16 -#define SWITCHLINK_OIFL_NUM_MEMBERS_MAX 16 -#define SWITCHLINK_CPU_INTERFACE_NAME "veth251" +#define SWITCHLINK_INTERFACE_NAME_LEN_MAX 32 +#define SWITCHLINK_ECMP_NUM_MEMBERS_MAX 16 +#define SWITCHLINK_OIFL_NUM_MEMBERS_MAX 16 +#define SWITCHLINK_CPU_INTERFACE_NAME "veth251" typedef enum { - SWITCHLINK_DB_STATUS_SUCCESS, - SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND, + SWITCHLINK_DB_STATUS_SUCCESS, + SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND, } switchlink_db_status_t; typedef struct switchlink_db_port_obj_ { - char * name; - uint16_t port_id; + char *name; + uint16_t port_id; } switchlink_db_port_obj_t; typedef struct switchlink_db_interface_info_ { - char ifname[SWITCHLINK_INTERFACE_NAME_LEN_MAX]; - uint32_t ifindex; - uint16_t port_id; - switchlink_handle_t intf_h; - switchlink_intf_type_t intf_type; - switchlink_link_type_t link_type; - switchlink_handle_t vrf_h; - switchlink_handle_t bridge_h; - switchlink_handle_t stp_h; - switchlink_handle_t lag_h; - switchlink_stp_state_t stp_state; - switchlink_mac_addr_t mac_addr; - struct interface_flags { - bool ipv4_unicast_enabled; - bool ipv6_unicast_enabled; - bool ipv4_multicast_enabled; - bool ipv6_multicast_enabled; - uint8_t ipv4_urpf_mode; - uint8_t ipv6_urpf_mode; - } flags; + char ifname[SWITCHLINK_INTERFACE_NAME_LEN_MAX]; + uint32_t ifindex; + uint16_t port_id; + switchlink_handle_t intf_h; + switchlink_intf_type_t intf_type; + switchlink_link_type_t link_type; + switchlink_handle_t vrf_h; + switchlink_handle_t bridge_h; + switchlink_handle_t stp_h; + switchlink_handle_t lag_h; + switchlink_handle_t vlan_member_h; + switchlink_stp_state_t stp_state; + switchlink_mac_addr_t mac_addr; + struct interface_flags { + bool ipv4_unicast_enabled; + bool ipv6_unicast_enabled; + bool ipv4_multicast_enabled; + bool ipv6_multicast_enabled; + uint8_t ipv4_urpf_mode; + uint8_t ipv6_urpf_mode; + } flags; } switchlink_db_interface_info_t; typedef struct switchlink_db_bridge_info_ { - switchlink_handle_t bridge_h; - switchlink_handle_t vrf_h; - switchlink_handle_t stp_h; - switchlink_mac_addr_t mac_addr; + switchlink_handle_t bridge_h; + switchlink_handle_t vrf_h; + switchlink_handle_t stp_h; + switchlink_mac_addr_t mac_addr; } switchlink_db_bridge_info_t; typedef struct switchlink_db_neigh_info_ { - switchlink_handle_t vrf_h; - switchlink_handle_t nhop_h; - switchlink_handle_t intf_h; - switchlink_ip_addr_t ip_addr; - switchlink_mac_addr_t mac_addr; + switchlink_handle_t vrf_h; + switchlink_handle_t nhop_h; + switchlink_handle_t intf_h; + switchlink_ip_addr_t ip_addr; + switchlink_mac_addr_t mac_addr; } switchlink_db_neigh_info_t; typedef struct switchlink_db_ecmp_info_ { - switchlink_handle_t ecmp_h; - uint8_t num_nhops; - switchlink_handle_t nhops[SWITCHLINK_ECMP_NUM_MEMBERS_MAX]; + switchlink_handle_t ecmp_h; + uint8_t num_nhops; + switchlink_handle_t nhops[SWITCHLINK_ECMP_NUM_MEMBERS_MAX]; } switchlink_db_ecmp_info_t; typedef struct switchlink_db_route_info_ { - switchlink_handle_t vrf_h; - switchlink_ip_addr_t ip_addr; - bool ecmp; - switchlink_handle_t nhop_h; + switchlink_handle_t vrf_h; + switchlink_ip_addr_t ip_addr; + bool ecmp; + switchlink_handle_t nhop_h; } switchlink_db_route_info_t; typedef struct switchlink_db_oifl_info_ { - switchlink_handle_t oifl_h; - uint8_t num_intfs; - switchlink_handle_t intfs[SWITCHLINK_OIFL_NUM_MEMBERS_MAX]; - switchlink_handle_t nhops[SWITCHLINK_OIFL_NUM_MEMBERS_MAX]; + switchlink_handle_t oifl_h; + uint8_t num_intfs; + switchlink_handle_t intfs[SWITCHLINK_OIFL_NUM_MEMBERS_MAX]; + switchlink_handle_t nhops[SWITCHLINK_OIFL_NUM_MEMBERS_MAX]; } switchlink_db_oifl_info_t; typedef struct switchlink_db_mroute_info_ { - switchlink_handle_t vrf_h; - switchlink_ip_addr_t src_ip; - switchlink_ip_addr_t dst_ip; - switchlink_handle_t iif_h; - switchlink_handle_t oifl_h; + switchlink_handle_t vrf_h; + switchlink_ip_addr_t src_ip; + switchlink_ip_addr_t dst_ip; + switchlink_handle_t iif_h; + switchlink_handle_t oifl_h; } switchlink_db_mroute_info_t; typedef struct switchlink_db_mdb_info_ { - switchlink_handle_t bridge_h; - switchlink_ip_addr_t grp_ip; - uint8_t num_intfs; - switchlink_handle_t intfs[SWITCHLINK_OIFL_NUM_MEMBERS_MAX]; + switchlink_handle_t bridge_h; + switchlink_ip_addr_t grp_ip; + uint8_t num_intfs; + switchlink_handle_t intfs[SWITCHLINK_OIFL_NUM_MEMBERS_MAX]; } switchlink_db_mdb_info_t; /*** port ***/ -extern switchlink_db_status_t -switchlink_db_port_get(char *name, uint16_t *port_id); +extern switchlink_db_status_t switchlink_db_port_get(char *name, + uint16_t *port_id); -extern switchlink_db_status_t -switchlink_db_port_get_all_ports(uint16_t *num_ports, - switchlink_db_port_obj_t **port_map); +extern switchlink_db_status_t switchlink_db_port_get_all_ports( + uint16_t *num_ports, switchlink_db_port_obj_t **port_map); /*** interface ***/ -extern switchlink_db_status_t -switchlink_db_interface_add(uint32_t ifindex, - switchlink_db_interface_info_t *intf_info); +extern switchlink_db_status_t switchlink_db_interface_add( + uint32_t ifindex, switchlink_db_interface_info_t *intf_info); -extern switchlink_db_status_t -switchlink_db_interface_get_info(uint32_t ifindex, - switchlink_db_interface_info_t *intf_info); +extern switchlink_db_status_t switchlink_db_interface_get_info( + uint32_t ifindex, switchlink_db_interface_info_t *intf_info); -extern switchlink_db_status_t -switchlink_db_interface_get_ifindex(switchlink_handle_t intf_h, - uint32_t *ifindex); +extern switchlink_db_status_t switchlink_db_interface_get_ifindex( + switchlink_handle_t intf_h, uint32_t *ifindex); -extern switchlink_db_status_t -switchlink_db_interface_update(uint32_t ifindex, - switchlink_db_interface_info_t *intf_info); +extern switchlink_db_status_t switchlink_db_interface_update( + uint32_t ifindex, switchlink_db_interface_info_t *intf_info); -extern switchlink_db_status_t -switchlink_db_interface_delete(uint32_t ifindex); +extern switchlink_db_status_t switchlink_db_interface_delete(uint32_t ifindex); /*** bridge/vlan ***/ -extern switchlink_db_status_t -switchlink_db_bridge_add(uint32_t ifindex, - switchlink_db_bridge_info_t *bridge_info); +extern switchlink_db_status_t switchlink_db_bridge_add( + uint32_t ifindex, switchlink_db_bridge_info_t *bridge_info); -extern switchlink_db_status_t -switchlink_db_bridge_update(uint32_t ifindex, - switchlink_db_bridge_info_t *bridge_info); +extern switchlink_db_status_t switchlink_db_bridge_update( + uint32_t ifindex, switchlink_db_bridge_info_t *bridge_info); -extern switchlink_db_status_t -switchlink_db_bridge_get_info(uint32_t ifindex, - switchlink_db_bridge_info_t *bridge_info); +extern switchlink_db_status_t switchlink_db_bridge_get_info( + uint32_t ifindex, switchlink_db_bridge_info_t *bridge_info); -extern switchlink_db_status_t -switchlink_db_bridge_handle_get_info(switchlink_handle_t bridge_h, - switchlink_db_bridge_info_t *bridge_info); +extern switchlink_db_status_t switchlink_db_bridge_handle_get_info( + switchlink_handle_t bridge_h, switchlink_db_bridge_info_t *bridge_info); -extern switchlink_db_status_t -switchlink_db_bridge_get_ifindex(switchlink_handle_t bridge_h, - uint32_t *ifindex); +extern switchlink_db_status_t switchlink_db_bridge_get_ifindex( + switchlink_handle_t bridge_h, uint32_t *ifindex); -extern switchlink_db_status_t -switchlink_db_bridge_delete(uint32_t ifindex); +extern switchlink_db_status_t switchlink_db_bridge_delete(uint32_t ifindex); /*** mac ***/ -extern switchlink_db_status_t -switchlink_db_mac_add(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h); +extern switchlink_db_status_t switchlink_db_mac_add( + switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h); -extern switchlink_db_status_t -switchlink_db_mac_get_intf(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t *int_h); +extern switchlink_db_status_t switchlink_db_mac_get_intf( + switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t *int_h); -extern switchlink_db_status_t -switchlink_db_mac_set_intf(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t int_h); +extern switchlink_db_status_t switchlink_db_mac_set_intf( + switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t int_h); -extern switchlink_db_status_t -switchlink_db_mac_delete(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h); +extern switchlink_db_status_t switchlink_db_mac_delete( + switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h); -extern switchlink_db_status_t -switchlink_db_mac_intf_delete(switchlink_handle_t intf_h); +extern switchlink_db_status_t switchlink_db_mac_intf_delete( + switchlink_handle_t intf_h); /*** neighbor ***/ -extern switchlink_db_status_t -switchlink_db_neighbor_add(switchlink_db_neigh_info_t *neigh_info); +extern switchlink_db_status_t switchlink_db_neighbor_add( + switchlink_db_neigh_info_t *neigh_info); -extern switchlink_db_status_t -switchlink_db_neighbor_delete(switchlink_db_neigh_info_t *neigh_info); +extern switchlink_db_status_t switchlink_db_neighbor_delete( + switchlink_db_neigh_info_t *neigh_info); -extern switchlink_db_status_t -switchlink_db_neighbor_get_info(switchlink_db_neigh_info_t *neigh_info); +extern switchlink_db_status_t switchlink_db_neighbor_get_info( + switchlink_db_neigh_info_t *neigh_info); /*** ecmp ***/ -extern switchlink_db_status_t -switchlink_db_ecmp_add(switchlink_db_ecmp_info_t *ecmp_info); +extern switchlink_db_status_t switchlink_db_ecmp_add( + switchlink_db_ecmp_info_t *ecmp_info); -extern switchlink_db_status_t -switchlink_db_ecmp_get_info(switchlink_db_ecmp_info_t *ecmp_info); +extern switchlink_db_status_t switchlink_db_ecmp_get_info( + switchlink_db_ecmp_info_t *ecmp_info); -extern switchlink_db_status_t -switchlink_db_ecmp_handle_get_info(switchlink_handle_t ecmp_h, - switchlink_db_ecmp_info_t *ecmp_info); +extern switchlink_db_status_t switchlink_db_ecmp_handle_get_info( + switchlink_handle_t ecmp_h, switchlink_db_ecmp_info_t *ecmp_info); -extern switchlink_db_status_t -switchlink_db_ecmp_ref_inc(switchlink_handle_t ecmp_h); +extern switchlink_db_status_t switchlink_db_ecmp_ref_inc( + switchlink_handle_t ecmp_h); -extern switchlink_db_status_t -switchlink_db_ecmp_ref_dec(switchlink_handle_t ecmp_h, int *ref_count); +extern switchlink_db_status_t switchlink_db_ecmp_ref_dec( + switchlink_handle_t ecmp_h, int *ref_count); -extern switchlink_db_status_t -switchlink_db_ecmp_delete(switchlink_handle_t ecmp_h); +extern switchlink_db_status_t switchlink_db_ecmp_delete( + switchlink_handle_t ecmp_h); /*** oifl ***/ -extern switchlink_db_status_t -switchlink_db_oifl_add(switchlink_db_oifl_info_t *oifl_info); +extern switchlink_db_status_t switchlink_db_oifl_add( + switchlink_db_oifl_info_t *oifl_info); -extern switchlink_db_status_t -switchlink_db_oifl_get_info(switchlink_db_oifl_info_t *oifl_info); +extern switchlink_db_status_t switchlink_db_oifl_get_info( + switchlink_db_oifl_info_t *oifl_info); -extern switchlink_db_status_t -switchlink_db_oifl_handle_get_info(switchlink_handle_t oifl_h, - switchlink_db_oifl_info_t *oifl_info); +extern switchlink_db_status_t switchlink_db_oifl_handle_get_info( + switchlink_handle_t oifl_h, switchlink_db_oifl_info_t *oifl_info); -extern switchlink_db_status_t -switchlink_db_oifl_ref_inc(switchlink_handle_t oifl_h); +extern switchlink_db_status_t switchlink_db_oifl_ref_inc( + switchlink_handle_t oifl_h); -extern switchlink_db_status_t -switchlink_db_oifl_ref_dec(switchlink_handle_t oifl_h, int *ref_count); +extern switchlink_db_status_t switchlink_db_oifl_ref_dec( + switchlink_handle_t oifl_h, int *ref_count); -extern switchlink_db_status_t -switchlink_db_oifl_delete(switchlink_handle_t oifl_h); +extern switchlink_db_status_t switchlink_db_oifl_delete( + switchlink_handle_t oifl_h); /*** route ***/ -extern switchlink_db_status_t -switchlink_db_route_add(switchlink_db_route_info_t *route_info); +extern switchlink_db_status_t switchlink_db_route_add( + switchlink_db_route_info_t *route_info); -extern switchlink_db_status_t -switchlink_db_route_delete(switchlink_db_route_info_t *route_info); +extern switchlink_db_status_t switchlink_db_route_delete( + switchlink_db_route_info_t *route_info); -extern switchlink_db_status_t -switchlink_db_route_get_info(switchlink_db_route_info_t *route_info); +extern switchlink_db_status_t switchlink_db_route_get_info( + switchlink_db_route_info_t *route_info); /*** multicast route ***/ typedef void (*switchlink_db_mroute_walk_fn)(switchlink_db_mroute_info_t *); -extern switchlink_db_status_t -switchlink_db_mroute_add(switchlink_db_mroute_info_t *mroute_info); +extern switchlink_db_status_t switchlink_db_mroute_add( + switchlink_db_mroute_info_t *mroute_info); -extern switchlink_db_status_t -switchlink_db_mroute_delete(switchlink_db_mroute_info_t *mroute_info); +extern switchlink_db_status_t switchlink_db_mroute_delete( + switchlink_db_mroute_info_t *mroute_info); -extern switchlink_db_status_t -switchlink_db_mroute_get_info(switchlink_db_mroute_info_t *mroute_info); +extern switchlink_db_status_t switchlink_db_mroute_get_info( + switchlink_db_mroute_info_t *mroute_info); -extern void -switchlink_db_mroute_mdb_walk(switchlink_db_mdb_info_t *mdb_info, - switchlink_db_mroute_walk_fn notify); +extern void switchlink_db_mroute_mdb_walk(switchlink_db_mdb_info_t *mdb_info, + switchlink_db_mroute_walk_fn notify); /*** bridge multicast entry ***/ -extern switchlink_db_status_t -switchlink_db_mdb_add(switchlink_db_mdb_info_t *mdb_info); +extern switchlink_db_status_t switchlink_db_mdb_add( + switchlink_db_mdb_info_t *mdb_info); -extern switchlink_db_status_t -switchlink_db_mdb_update(switchlink_db_mdb_info_t *mdb_info); +extern switchlink_db_status_t switchlink_db_mdb_update( + switchlink_db_mdb_info_t *mdb_info); -extern switchlink_db_status_t -switchlink_db_mdb_delete(switchlink_db_mdb_info_t *mdb_info); +extern switchlink_db_status_t switchlink_db_mdb_delete( + switchlink_db_mdb_info_t *mdb_info); -extern switchlink_db_status_t -switchlink_db_mdb_get_info(switchlink_db_mdb_info_t *mdb_info); +extern switchlink_db_status_t switchlink_db_mdb_get_info( + switchlink_db_mdb_info_t *mdb_info); #endif /* __SWITCHLINK_DB_H__ */ diff --git a/switchlink/src/switchlink_db_int.h b/switchlink/src/switchlink_db_int.h index 9c4a7de..7955580 100644 --- a/switchlink/src/switchlink_db_int.h +++ b/switchlink/src/switchlink_db_int.h @@ -17,64 +17,67 @@ limitations under the License. #ifndef __SWITCHLINK_DB_INT_H__ #define __SWITCHLINK_DB_INT_H__ -#define min(a,b) \ - ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; }) +#define min(a, b) \ + ({ \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a > _b ? _a : _b; \ + }) typedef struct switchlink_db_intf_obj_ { - tommy_trie_inplace_node ifindex_node; - tommy_trie_inplace_node handle_node; - uint32_t ifindex; - switchlink_db_interface_info_t intf_info; + tommy_trie_inplace_node ifindex_node; + tommy_trie_inplace_node handle_node; + uint32_t ifindex; + switchlink_db_interface_info_t intf_info; } switchlink_db_intf_obj_t; typedef struct switchlink_db_bridge_obj_ { - tommy_trie_inplace_node ifindex_node; - tommy_trie_inplace_node handle_node; - uint32_t ifindex; - switchlink_db_bridge_info_t bridge; + tommy_trie_inplace_node ifindex_node; + tommy_trie_inplace_node handle_node; + uint32_t ifindex; + switchlink_db_bridge_info_t bridge; } switchlink_db_bridge_obj_t; typedef struct switchlink_db_mac_obj_ { - tommy_node hash_node; - tommy_node list_node; - switchlink_mac_addr_t addr; - switchlink_handle_t bridge_h; - switchlink_handle_t intf_h; + tommy_node hash_node; + tommy_node list_node; + switchlink_mac_addr_t addr; + switchlink_handle_t bridge_h; + switchlink_handle_t intf_h; } switchlink_db_mac_obj_t; typedef struct switchlink_db_neigh_obj_ { - tommy_node list_node; - switchlink_db_neigh_info_t neigh_info; + tommy_node list_node; + switchlink_db_neigh_info_t neigh_info; } switchlink_db_neigh_obj_t; typedef struct switchlink_db_ecmp_obj_ { - tommy_node list_node; - int32_t ref_count; - tommy_trie_inplace_node handle_node; - switchlink_db_ecmp_info_t ecmp_info; + tommy_node list_node; + int32_t ref_count; + tommy_trie_inplace_node handle_node; + switchlink_db_ecmp_info_t ecmp_info; } switchlink_db_ecmp_obj_t; typedef struct switchlink_db_oifl_obj_ { - tommy_node list_node; - int32_t ref_count; - tommy_trie_inplace_node handle_node; - switchlink_db_oifl_info_t oifl_info; + tommy_node list_node; + int32_t ref_count; + tommy_trie_inplace_node handle_node; + switchlink_db_oifl_info_t oifl_info; } switchlink_db_oifl_obj_t; typedef struct switchlink_db_route_obj_ { - tommy_node list_node; - switchlink_db_route_info_t route_info; + tommy_node list_node; + switchlink_db_route_info_t route_info; } switchlink_db_route_obj_t; typedef struct switchlink_db_mroute_obj_ { - tommy_node list_node; - switchlink_db_mroute_info_t mroute_info; + tommy_node list_node; + switchlink_db_mroute_info_t mroute_info; } switchlink_db_mroute_obj_t; typedef struct switchlink_db_mdb_obj_ { - tommy_node list_node; - switchlink_db_mdb_info_t mdb_info; + tommy_node list_node; + switchlink_db_mdb_info_t mdb_info; } switchlink_db_mdb_obj_t; #endif /* __SWITCHLINK_DB_INT_H__ */ diff --git a/switchlink/src/switchlink_link.c b/switchlink/src/switchlink_link.c index e7b1476..7ded263 100644 --- a/switchlink/src/switchlink_link.c +++ b/switchlink/src/switchlink_link.c @@ -36,440 +36,438 @@ switchlink_handle_t g_default_bridge_h = 0; switchlink_handle_t g_default_stp_h = 0; switchlink_handle_t g_cpu_rx_nhop_h = 0; -static void -create_cpu_interface(switchlink_handle_t intf_h) { - switchlink_ip_addr_t null_ip_addr; - switchlink_mac_addr_t null_mac_addr; - switchlink_db_status_t status; - - memset(&null_ip_addr, 0, sizeof(switchlink_ip_addr_t)); - null_ip_addr.family = AF_INET; - memset(null_mac_addr, 0, sizeof(switchlink_mac_addr_t)); - - neigh_create(g_default_vrf_h, &null_ip_addr, null_mac_addr, intf_h); - switchlink_db_neigh_info_t neigh_info; - memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); - neigh_info.ip_addr.family = AF_INET; - neigh_info.vrf_h = g_default_vrf_h; - neigh_info.intf_h = intf_h; - status = switchlink_db_neighbor_get_info(&neigh_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - g_cpu_rx_nhop_h = neigh_info.nhop_h; +static void create_cpu_interface(switchlink_handle_t intf_h) { + switchlink_ip_addr_t null_ip_addr; + switchlink_mac_addr_t null_mac_addr; + switchlink_db_status_t status; + + memset(&null_ip_addr, 0, sizeof(switchlink_ip_addr_t)); + null_ip_addr.family = AF_INET; + memset(null_mac_addr, 0, sizeof(switchlink_mac_addr_t)); + + neigh_create(g_default_vrf_h, &null_ip_addr, null_mac_addr, intf_h); + switchlink_db_neigh_info_t neigh_info; + memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); + neigh_info.ip_addr.family = AF_INET; + neigh_info.vrf_h = g_default_vrf_h; + neigh_info.intf_h = intf_h; + status = switchlink_db_neighbor_get_info(&neigh_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + g_cpu_rx_nhop_h = neigh_info.nhop_h; } -static void -interface_create(switchlink_db_interface_info_t *intf) -{ - switchlink_db_status_t status; - switchlink_db_interface_info_t ifinfo; - switchlink_handle_t old_bridge_h = 0; +static void interface_create(switchlink_db_interface_info_t *intf) { + switchlink_db_status_t status; + switchlink_db_interface_info_t ifinfo; + switchlink_handle_t old_bridge_h = 0; - status = switchlink_db_interface_get_info(intf->ifindex, &ifinfo); - if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { - // create the interface + status = switchlink_db_interface_get_info(intf->ifindex, &ifinfo); + if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { + // create the interface - if (intf->link_type == SWITCHLINK_LINK_TYPE_BOND) { - switchlink_lag_create(&(intf->lag_h)); - } else { - status = switchlink_db_port_get(intf->ifname, &(intf->port_id)); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - // a port that we are not interested in - return; - } - } - - status = switchlink_interface_create(intf, &(intf->intf_h)); - if (status != 0) { - NL_LOG_ERROR(("newlink: switchlink_interface_create failed\n")); - return; - } - - // add the mapping to the db - switchlink_db_interface_add(intf->ifindex, intf); - memcpy(&ifinfo, intf, sizeof(switchlink_db_interface_info_t)); + if (intf->link_type == SWITCHLINK_LINK_TYPE_BOND) { + switchlink_lag_create(&(intf->lag_h)); } else { - // interface has already been created - // update mac address if it has changed - if (memcmp(&(ifinfo.mac_addr), &(intf->mac_addr), - sizeof(switchlink_mac_addr_t))) { - switchlink_db_interface_update(intf->ifindex, &ifinfo); - } - old_bridge_h = ifinfo.bridge_h; - intf->intf_h = ifinfo.intf_h; - } - - if (strcmp(intf->ifname, SWITCHLINK_CPU_INTERFACE_NAME) == 0) { - create_cpu_interface(ifinfo.intf_h); + status = switchlink_db_port_get(intf->ifname, &(intf->port_id)); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + // a port that we are not interested in return; + } } - // update bridge domain for the interface - if (old_bridge_h && (old_bridge_h != intf->bridge_h)) { - int ret = switchlink_del_interface_from_bridge(intf, old_bridge_h); - assert(ret == 0); - ifinfo.bridge_h = 0; - switchlink_db_interface_update(intf->ifindex, &ifinfo); - } - - if ((intf->intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) && - intf->bridge_h && (old_bridge_h != intf->bridge_h)) { - int ret = switchlink_add_interface_to_bridge(intf); - if (ret != 0) { - NL_LOG_ERROR(("newlink(%s): switchlink_add_interface_to_bridge " - "failed\n", intf->ifname)); - return; - } - ifinfo.bridge_h = intf->bridge_h; - switchlink_db_interface_update(intf->ifindex, &ifinfo); - } - - if (intf->intf_type != SWITCHLINK_INTF_TYPE_L3) { - switchlink_stp_state_update(intf); + status = switchlink_interface_create(intf, &(intf->intf_h)); + if (status != 0) { + NL_LOG_ERROR(("newlink: switchlink_interface_create failed\n")); + return; } -} -static void -interface_delete(switchlink_db_interface_info_t *intf) { - switchlink_db_interface_info_t ifinfo; - if (switchlink_db_interface_get_info(intf->ifindex, &ifinfo) == - SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { - return; + // add the mapping to the db + switchlink_db_interface_add(intf->ifindex, intf); + memcpy(&ifinfo, intf, sizeof(switchlink_db_interface_info_t)); + } else { + // interface has already been created + // update mac address if it has changed + if (memcmp(&(ifinfo.mac_addr), + &(intf->mac_addr), + sizeof(switchlink_mac_addr_t))) { + switchlink_db_interface_update(intf->ifindex, &ifinfo); } + old_bridge_h = ifinfo.bridge_h; intf->intf_h = ifinfo.intf_h; - - // remove the interface from bridge - if (ifinfo.bridge_h) { - switchlink_del_interface_from_bridge(intf, ifinfo.bridge_h); - } - - if (ifinfo.intf_type != SWITCHLINK_INTF_TYPE_L3) { - // clear stp state on interface - intf->stp_state = SWITCHLINK_STP_STATE_BLOCKING; - switchlink_stp_state_update(intf); + } + + if (strcmp(intf->ifname, SWITCHLINK_CPU_INTERFACE_NAME) == 0) { + create_cpu_interface(ifinfo.intf_h); + return; + } + + // update bridge domain for the interface + if (old_bridge_h && (old_bridge_h != intf->bridge_h)) { + int ret = switchlink_del_interface_from_bridge(intf, old_bridge_h); + assert(ret == 0); + ifinfo.bridge_h = 0; + switchlink_db_interface_update(intf->ifindex, &ifinfo); + } + + if ((intf->intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) && intf->bridge_h && + (old_bridge_h != intf->bridge_h)) { + int ret = switchlink_add_interface_to_bridge(intf); + if (ret != 0) { + NL_LOG_ERROR( + ("newlink(%s): switchlink_add_interface_to_bridge " + "failed\n", + intf->ifname)); + return; } - - // delete the interface - switchlink_interface_delete(intf, ifinfo.intf_h); - - switchlink_db_mac_intf_delete(ifinfo.intf_h); - switchlink_db_interface_delete(intf->ifindex); + ifinfo.bridge_h = intf->bridge_h; + ifinfo.vlan_member_h = intf->vlan_member_h; + switchlink_db_interface_update(intf->ifindex, &ifinfo); + } + + if (intf->intf_type != SWITCHLINK_INTF_TYPE_L3) { + switchlink_stp_state_update(intf); + } } -void -interface_change_type(uint32_t ifindex, switchlink_intf_type_t type) { - switchlink_db_interface_info_t ifinfo; - switchlink_db_interface_info_t intf; - if (switchlink_db_interface_get_info(ifindex, &ifinfo) == - SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { - return; - } - - if (type == ifinfo.intf_type) { - return; - } +static void interface_delete(switchlink_db_interface_info_t *intf) { + switchlink_db_interface_info_t ifinfo; + if (switchlink_db_interface_get_info(intf->ifindex, &ifinfo) == + SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { + return; + } + intf->intf_h = ifinfo.intf_h; + + // remove the interface from bridge + if (ifinfo.bridge_h) { + switchlink_del_interface_from_bridge(intf, ifinfo.bridge_h); + } + + if (ifinfo.intf_type != SWITCHLINK_INTF_TYPE_L3) { + // clear stp state on interface + intf->stp_state = SWITCHLINK_STP_STATE_BLOCKING; + switchlink_stp_state_update(intf); + } + + // delete the interface + switchlink_interface_delete(intf, ifinfo.intf_h); + + switchlink_db_mac_intf_delete(ifinfo.intf_h); + switchlink_db_interface_delete(intf->ifindex); +} - interface_delete(&ifinfo); - if (type == SWITCHLINK_INTF_TYPE_L3) { - memset(&intf, 0, sizeof(switchlink_db_interface_info_t)); - strncpy(intf.ifname, ifinfo.ifname, SWITCHLINK_INTERFACE_NAME_LEN_MAX); - intf.ifindex = ifinfo.ifindex; - intf.intf_type = SWITCHLINK_INTF_TYPE_L3; - intf.vrf_h = ifinfo.vrf_h; - intf.flags.ipv4_unicast_enabled = true; - intf.flags.ipv6_unicast_enabled = true; - intf.flags.ipv4_multicast_enabled = false; - intf.flags.ipv6_multicast_enabled = false; - intf.flags.ipv4_urpf_mode = SWITCHLINK_URPF_MODE_NONE; - intf.flags.ipv6_urpf_mode = SWITCHLINK_URPF_MODE_NONE; - memcpy(&(intf.mac_addr), &ifinfo.mac_addr, - sizeof(switchlink_mac_addr_t)); - interface_create(&intf); - } +void interface_change_type(uint32_t ifindex, switchlink_intf_type_t type) { + switchlink_db_interface_info_t ifinfo; + switchlink_db_interface_info_t intf; + if (switchlink_db_interface_get_info(ifindex, &ifinfo) == + SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { + return; + } + + if (type == ifinfo.intf_type) { + return; + } + + interface_delete(&ifinfo); + if (type == SWITCHLINK_INTF_TYPE_L3) { + memset(&intf, 0, sizeof(switchlink_db_interface_info_t)); + strncpy(intf.ifname, ifinfo.ifname, SWITCHLINK_INTERFACE_NAME_LEN_MAX); + intf.ifindex = ifinfo.ifindex; + intf.intf_type = SWITCHLINK_INTF_TYPE_L3; + intf.vrf_h = ifinfo.vrf_h; + intf.flags.ipv4_unicast_enabled = true; + intf.flags.ipv6_unicast_enabled = true; + intf.flags.ipv4_multicast_enabled = false; + intf.flags.ipv6_multicast_enabled = false; + intf.flags.ipv4_urpf_mode = SWITCHLINK_URPF_MODE_NONE; + intf.flags.ipv6_urpf_mode = SWITCHLINK_URPF_MODE_NONE; + memcpy(&(intf.mac_addr), &ifinfo.mac_addr, sizeof(switchlink_mac_addr_t)); + interface_create(&intf); + } } -void -interface_create_l3vi(uint32_t ifindex) { - switchlink_db_bridge_info_t bridge_db_info; - switchlink_db_interface_info_t intf_info; - switchlink_db_status_t status; - - status = switchlink_db_bridge_get_info(ifindex, &bridge_db_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - - memset(&intf_info, 0, sizeof(intf_info)); - intf_info.ifindex = ifindex; - intf_info.stp_h = bridge_db_info.stp_h; - intf_info.stp_state = SWITCHLINK_STP_STATE_NONE; - intf_info.bridge_h = bridge_db_info.bridge_h; - intf_info.vrf_h = g_default_vrf_h; - intf_info.intf_type = SWITCHLINK_INTF_TYPE_L3VI; - intf_info.link_type = SWITCHLINK_LINK_TYPE_BRIDGE; - intf_info.flags.ipv4_unicast_enabled = true; - intf_info.flags.ipv6_unicast_enabled = true; - intf_info.flags.ipv4_multicast_enabled = false; - intf_info.flags.ipv6_multicast_enabled = false; - intf_info.flags.ipv4_urpf_mode = SWITCHLINK_URPF_MODE_NONE; - intf_info.flags.ipv6_urpf_mode = SWITCHLINK_URPF_MODE_NONE; - memcpy(&(intf_info.mac_addr), &(bridge_db_info.mac_addr), - sizeof(switchlink_mac_addr_t)); - - status = switchlink_interface_create(&intf_info, &(intf_info.intf_h)); - if (status != 0) { - NL_LOG_ERROR(("newlink: switchlink_interface_create failed\n")); - return; - } - // add the mapping to the db - switchlink_db_interface_add(intf_info.ifindex, &intf_info); +void interface_create_l3vi(uint32_t ifindex) { + switchlink_db_bridge_info_t bridge_db_info; + switchlink_db_interface_info_t intf_info; + switchlink_db_status_t status; + + status = switchlink_db_bridge_get_info(ifindex, &bridge_db_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + + memset(&intf_info, 0, sizeof(intf_info)); + intf_info.ifindex = ifindex; + intf_info.stp_h = bridge_db_info.stp_h; + intf_info.stp_state = SWITCHLINK_STP_STATE_NONE; + intf_info.bridge_h = bridge_db_info.bridge_h; + intf_info.vrf_h = g_default_vrf_h; + intf_info.intf_type = SWITCHLINK_INTF_TYPE_L3VI; + intf_info.link_type = SWITCHLINK_LINK_TYPE_BRIDGE; + intf_info.flags.ipv4_unicast_enabled = true; + intf_info.flags.ipv6_unicast_enabled = true; + intf_info.flags.ipv4_multicast_enabled = false; + intf_info.flags.ipv6_multicast_enabled = false; + intf_info.flags.ipv4_urpf_mode = SWITCHLINK_URPF_MODE_NONE; + intf_info.flags.ipv6_urpf_mode = SWITCHLINK_URPF_MODE_NONE; + memcpy(&(intf_info.mac_addr), + &(bridge_db_info.mac_addr), + sizeof(switchlink_mac_addr_t)); + + status = switchlink_interface_create(&intf_info, &(intf_info.intf_h)); + if (status != 0) { + NL_LOG_ERROR(("newlink: switchlink_interface_create failed\n")); + return; + } + // add the mapping to the db + switchlink_db_interface_add(intf_info.ifindex, &intf_info); } -static switchlink_handle_t -bridge_create(uint32_t ifindex, switchlink_mac_addr_t *mac_addr) { - switchlink_db_bridge_info_t bridge_db_info; - switchlink_db_status_t status; - - status = switchlink_db_bridge_get_info(ifindex, &bridge_db_info); - if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { - memset(&bridge_db_info, 0, sizeof(switchlink_db_bridge_info_t)); - bridge_db_info.vrf_h = g_default_vrf_h; - switchlink_bridge_create(&bridge_db_info); - switchlink_db_bridge_add(ifindex, &bridge_db_info); - } else { - if (mac_addr) { - memcpy(&(bridge_db_info.mac_addr), mac_addr, - sizeof(switchlink_mac_addr_t)); - switchlink_bridge_update(&bridge_db_info); - } - switchlink_db_bridge_update(ifindex, &bridge_db_info); +static switchlink_handle_t bridge_create(uint32_t ifindex, + switchlink_mac_addr_t *mac_addr) { + switchlink_db_bridge_info_t bridge_db_info; + switchlink_db_status_t status; + + status = switchlink_db_bridge_get_info(ifindex, &bridge_db_info); + if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { + memset(&bridge_db_info, 0, sizeof(switchlink_db_bridge_info_t)); + bridge_db_info.vrf_h = g_default_vrf_h; + switchlink_bridge_create(&bridge_db_info); + switchlink_db_bridge_add(ifindex, &bridge_db_info); + } else { + if (mac_addr) { + memcpy( + &(bridge_db_info.mac_addr), mac_addr, sizeof(switchlink_mac_addr_t)); + switchlink_bridge_update(&bridge_db_info); } - return bridge_db_info.bridge_h; + switchlink_db_bridge_update(ifindex, &bridge_db_info); + } + return bridge_db_info.bridge_h; } -static void -bridge_delete(uint32_t ifindex, switchlink_db_bridge_info_t *bridge_info) { - switchlink_bridge_delete(bridge_info); - switchlink_db_bridge_delete(ifindex); +static void bridge_delete(uint32_t ifindex, + switchlink_db_bridge_info_t *bridge_info) { + switchlink_bridge_delete(bridge_info); + switchlink_db_bridge_delete(ifindex); } -static inline switchlink_stp_state_t -convert_stp_state(uint8_t linux_stp_state) { - switchlink_stp_state_t stp_state = SWITCHLINK_STP_STATE_NONE; - switch(linux_stp_state) { - case BR_STATE_DISABLED: - stp_state = SWITCHLINK_STP_STATE_DISABLED; - break; - case BR_STATE_LEARNING: - stp_state = SWITCHLINK_STP_STATE_LEARNING; - break; - case BR_STATE_FORWARDING: - stp_state = SWITCHLINK_STP_STATE_FORWARDING; - break; - case BR_STATE_BLOCKING: - stp_state = SWITCHLINK_STP_STATE_BLOCKING; - break; - default: - stp_state = SWITCHLINK_STP_STATE_NONE; - break; - } - return stp_state; +static inline switchlink_stp_state_t convert_stp_state( + uint8_t linux_stp_state) { + switchlink_stp_state_t stp_state = SWITCHLINK_STP_STATE_NONE; + switch (linux_stp_state) { + case BR_STATE_DISABLED: + stp_state = SWITCHLINK_STP_STATE_DISABLED; + break; + case BR_STATE_LEARNING: + stp_state = SWITCHLINK_STP_STATE_LEARNING; + break; + case BR_STATE_FORWARDING: + stp_state = SWITCHLINK_STP_STATE_FORWARDING; + break; + case BR_STATE_BLOCKING: + stp_state = SWITCHLINK_STP_STATE_BLOCKING; + break; + default: + stp_state = SWITCHLINK_STP_STATE_NONE; + break; + } + return stp_state; } -static switchlink_stp_state_t -get_stp_state(char *link_name) { - switchlink_stp_state_t stp_state = SWITCHLINK_STP_STATE_NONE; - char path[128]; - int fd; - uint8_t linux_stp_state; +static switchlink_stp_state_t get_stp_state(char *link_name) { + switchlink_stp_state_t stp_state = SWITCHLINK_STP_STATE_NONE; + char path[128]; + int fd; + uint8_t linux_stp_state; - snprintf(path, 128, "/sys/devices/virtual/net/%s/brport/state", link_name); - if ((fd = open(path, O_RDONLY)) < 0) { - return stp_state; - } - - if (read(fd, &linux_stp_state, sizeof(linux_stp_state)) < - (int)sizeof(linux_stp_state)) { - close(fd); - return stp_state; - } + snprintf(path, 128, "/sys/devices/virtual/net/%s/brport/state", link_name); + if ((fd = open(path, O_RDONLY)) < 0) { + return stp_state; + } + if (read(fd, &linux_stp_state, sizeof(linux_stp_state)) < + (int)sizeof(linux_stp_state)) { close(fd); - stp_state = convert_stp_state(linux_stp_state - '0'); return stp_state; + } + + close(fd); + stp_state = convert_stp_state(linux_stp_state - '0'); + return stp_state; } -static switchlink_link_type_t -get_link_type(char *info_kind) { - switchlink_link_type_t link_type = SWITCHLINK_LINK_TYPE_ETH; +static switchlink_link_type_t get_link_type(char *info_kind) { + switchlink_link_type_t link_type = SWITCHLINK_LINK_TYPE_ETH; - if(!strcmp(info_kind, "bridge")) { - link_type = SWITCHLINK_LINK_TYPE_BRIDGE; - } else if (!strcmp(info_kind, "vxlan")) { - link_type = SWITCHLINK_LINK_TYPE_VXLAN; - } else if (!strcmp(info_kind, "bond")) { - link_type = SWITCHLINK_LINK_TYPE_BOND; - } + if (!strcmp(info_kind, "bridge")) { + link_type = SWITCHLINK_LINK_TYPE_BRIDGE; + } else if (!strcmp(info_kind, "vxlan")) { + link_type = SWITCHLINK_LINK_TYPE_VXLAN; + } else if (!strcmp(info_kind, "bond")) { + link_type = SWITCHLINK_LINK_TYPE_BOND; + } - return link_type; + return link_type; } -void -process_link_msg(struct nlmsghdr *nlmsg, int type) { - int hdrlen, attrlen; - struct nlattr *attr, *nest_attr; - struct ifinfomsg *ifmsg; - uint32_t master = 0; - bool mac_addr_valid = false; - bool prot_info_valid = false; - int nest_attr_type; - switchlink_db_interface_info_t intf_info; - switchlink_link_type_t link_type = SWITCHLINK_LINK_TYPE_NONE; - switchlink_stp_state_t stp_state; - switchlink_handle_t bridge_h; - switchlink_handle_t stp_h; - - assert((type == RTM_NEWLINK) || (type == RTM_DELLINK)); - ifmsg = nlmsg_data(nlmsg); - hdrlen = sizeof(struct ifinfomsg); - NL_LOG_DEBUG(("%slink: family = %d, type = %d, ifindex = %d, flags = 0x%x, " - "change = 0x%x\n", ((type == RTM_NEWLINK) ? "new" : "del"), - ifmsg->ifi_family, ifmsg->ifi_type, ifmsg->ifi_index, - ifmsg->ifi_flags, ifmsg->ifi_change)); - - memset(&intf_info, 0, sizeof(switchlink_db_interface_info_t)); - attrlen = nlmsg_attrlen(nlmsg, hdrlen); - attr = nlmsg_attrdata(nlmsg, hdrlen); - while (nla_ok(attr, attrlen)) { - int attr_type = nla_type(attr); - switch (attr_type) { - case IFLA_IFNAME: - strncpy(intf_info.ifname, nla_get_string(attr), - SWITCHLINK_INTERFACE_NAME_LEN_MAX); - break; - case IFLA_LINKINFO: - nla_for_each_nested(nest_attr, attr, attrlen) { - nest_attr_type = nla_type(nest_attr); - switch (nest_attr_type) { - case IFLA_INFO_KIND: - link_type = get_link_type( - nla_get_string(nest_attr)); - break; - default: - break; - } - } - break; - case IFLA_ADDRESS: { - uint64_t lladdr; - mac_addr_valid = true; - lladdr = nla_get_u64(attr); - memcpy(&(intf_info.mac_addr), &lladdr, 6); - break; - } - case IFLA_MASTER: - master = nla_get_u32(attr); - break; - case IFLA_PROTINFO: - prot_info_valid = true; - link_type = SWITCHLINK_LINK_TYPE_ETH; - nla_for_each_nested(nest_attr, attr, attrlen) { - switch(nla_type(nest_attr)) { - case IFLA_BRPORT_STATE: - stp_state = - convert_stp_state(nla_get_u8(nest_attr)); - break; - default: - break; - } - } - break; - case IFLA_AF_SPEC: - break; +void process_link_msg(struct nlmsghdr *nlmsg, int type) { + int hdrlen, attrlen; + struct nlattr *attr, *nest_attr; + struct ifinfomsg *ifmsg; + uint32_t master = 0; + bool mac_addr_valid = false; + bool prot_info_valid = false; + int nest_attr_type; + switchlink_db_interface_info_t intf_info; + switchlink_link_type_t link_type = SWITCHLINK_LINK_TYPE_NONE; + switchlink_stp_state_t stp_state = SWITCHLINK_STP_STATE_NONE; + switchlink_handle_t bridge_h = 0; + switchlink_handle_t stp_h = 0; + + assert((type == RTM_NEWLINK) || (type == RTM_DELLINK)); + ifmsg = nlmsg_data(nlmsg); + hdrlen = sizeof(struct ifinfomsg); + NL_LOG_DEBUG( + ("%slink: family = %d, type = %d, ifindex = %d, flags = 0x%x, " + "change = 0x%x\n", + ((type == RTM_NEWLINK) ? "new" : "del"), + ifmsg->ifi_family, + ifmsg->ifi_type, + ifmsg->ifi_index, + ifmsg->ifi_flags, + ifmsg->ifi_change)); + + memset(&intf_info, 0, sizeof(switchlink_db_interface_info_t)); + attrlen = nlmsg_attrlen(nlmsg, hdrlen); + attr = nlmsg_attrdata(nlmsg, hdrlen); + while (nla_ok(attr, attrlen)) { + int attr_type = nla_type(attr); + switch (attr_type) { + case IFLA_IFNAME: + strncpy(intf_info.ifname, + nla_get_string(attr), + SWITCHLINK_INTERFACE_NAME_LEN_MAX); + break; + case IFLA_LINKINFO: + nla_for_each_nested(nest_attr, attr, attrlen) { + nest_attr_type = nla_type(nest_attr); + switch (nest_attr_type) { + case IFLA_INFO_KIND: + link_type = get_link_type(nla_get_string(nest_attr)); + break; default: - NL_LOG_DEBUG(("link: skipping attr(%d)\n", attr_type)); - break; + break; + } } - attr = nla_next(attr, &attrlen); - } - - if (type == RTM_NEWLINK) { - switch (link_type) { - case SWITCHLINK_LINK_TYPE_BRIDGE: - bridge_create(ifmsg->ifi_index, - (mac_addr_valid ? &(intf_info.mac_addr) : NULL)); - break; - case SWITCHLINK_LINK_TYPE_ETH: - case SWITCHLINK_LINK_TYPE_BOND: - if (master) { - if (!prot_info_valid) { - stp_state = get_stp_state(intf_info.ifname); - } - if (ifmsg->ifi_flags & IFF_SLAVE) { - } else { - switchlink_db_bridge_info_t bridge_info; - bridge_h = bridge_create(master, NULL); - switchlink_db_bridge_get_info(master, &bridge_info); - stp_h = bridge_info.stp_h; - } - } else { - bridge_h = g_default_bridge_h; - stp_h = g_default_stp_h; - } - intf_info.ifindex = ifmsg->ifi_index; - intf_info.stp_h = stp_h; - intf_info.stp_state = stp_state; - intf_info.bridge_h = bridge_h; - intf_info.vrf_h = g_default_vrf_h; - if (!strcmp(intf_info.ifname, SWITCHLINK_CPU_INTERFACE_NAME)) { - intf_info.intf_type = SWITCHLINK_INTF_TYPE_L3; - } else { - intf_info.intf_type = SWITCHLINK_INTF_TYPE_L2_ACCESS; - } - intf_info.link_type = link_type; - assert(bridge_h != 0); - interface_create(&intf_info); - if (mac_addr_valid) { - // update packet driver - } - break; - case SWITCHLINK_LINK_TYPE_VXLAN: - break; + break; + case IFLA_ADDRESS: { + uint64_t lladdr; + mac_addr_valid = true; + lladdr = nla_get_u64(attr); + memcpy(&(intf_info.mac_addr), &lladdr, 6); + break; + } + case IFLA_MASTER: + master = nla_get_u32(attr); + break; + case IFLA_PROTINFO: + prot_info_valid = true; + link_type = SWITCHLINK_LINK_TYPE_ETH; + nla_for_each_nested(nest_attr, attr, attrlen) { + switch (nla_type(nest_attr)) { + case IFLA_BRPORT_STATE: + stp_state = convert_stp_state(nla_get_u8(nest_attr)); + break; default: - break; + break; + } } - } else { - assert(type == RTM_DELLINK); - - switchlink_db_bridge_info_t bridge_db_info; - switchlink_handle_t bridge_h = 0; - switchlink_handle_t stp_h = 0; - int ret; - ret = switchlink_db_bridge_get_info(ifmsg->ifi_index, &bridge_db_info); - if (ret == 0) { - bridge_h = bridge_db_info.bridge_h; - stp_h = bridge_db_info.stp_h; + break; + case IFLA_AF_SPEC: + break; + default: + NL_LOG_DEBUG(("link: skipping attr(%d)\n", attr_type)); + break; + } + attr = nla_next(attr, &attrlen); + } + + if (type == RTM_NEWLINK) { + switch (link_type) { + case SWITCHLINK_LINK_TYPE_BRIDGE: + bridge_create(ifmsg->ifi_index, + (mac_addr_valid ? &(intf_info.mac_addr) : NULL)); + break; + case SWITCHLINK_LINK_TYPE_ETH: + case SWITCHLINK_LINK_TYPE_BOND: + if (master) { + if (!prot_info_valid) { + stp_state = get_stp_state(intf_info.ifname); + } + if (ifmsg->ifi_flags & IFF_SLAVE) { + } else { + switchlink_db_bridge_info_t bridge_info; + bridge_h = bridge_create(master, NULL); + switchlink_db_bridge_get_info(master, &bridge_info); + stp_h = bridge_info.stp_h; + } + } else { + bridge_h = g_default_bridge_h; + stp_h = g_default_stp_h; } - - if (link_type == SWITCHLINK_LINK_TYPE_BRIDGE) { - assert(bridge_h != 0); - bridge_delete(ifmsg->ifi_index, &bridge_db_info); + intf_info.ifindex = ifmsg->ifi_index; + intf_info.stp_h = stp_h; + intf_info.stp_state = stp_state; + intf_info.bridge_h = bridge_h; + intf_info.vrf_h = g_default_vrf_h; + if (!strcmp(intf_info.ifname, SWITCHLINK_CPU_INTERFACE_NAME)) { + intf_info.intf_type = SWITCHLINK_INTF_TYPE_L3; } else { - intf_info.bridge_h = bridge_h; - intf_info.stp_h = stp_h; - intf_info.ifindex = ifmsg->ifi_index; - interface_delete(&intf_info); + intf_info.intf_type = SWITCHLINK_INTF_TYPE_L2_ACCESS; } + intf_info.link_type = link_type; + assert(bridge_h != 0); + interface_create(&intf_info); + if (mac_addr_valid) { + // update packet driver + } + break; + case SWITCHLINK_LINK_TYPE_VXLAN: + break; + default: + break; } -} + } else { + assert(type == RTM_DELLINK); -void -switchlink_link_init() { - // create default vrf - switchlink_vrf_create(SWITCHLINK_DEFAULT_VRF_ID, &g_default_vrf_h); - - // create default bridge switchlink_db_bridge_info_t bridge_db_info; - memset(&bridge_db_info, 0, sizeof(switchlink_db_bridge_info_t)); - bridge_db_info.vrf_h = g_default_vrf_h; - switchlink_bridge_create(&bridge_db_info); - g_default_bridge_h = bridge_db_info.bridge_h; - g_default_stp_h = bridge_db_info.stp_h; + switchlink_handle_t bridge_h = 0; + switchlink_handle_t stp_h = 0; + int ret; + ret = switchlink_db_bridge_get_info(ifmsg->ifi_index, &bridge_db_info); + if (ret == 0) { + bridge_h = bridge_db_info.bridge_h; + stp_h = bridge_db_info.stp_h; + } + + if (link_type == SWITCHLINK_LINK_TYPE_BRIDGE) { + assert(bridge_h != 0); + bridge_delete(ifmsg->ifi_index, &bridge_db_info); + } else { + intf_info.bridge_h = bridge_h; + intf_info.stp_h = stp_h; + intf_info.ifindex = ifmsg->ifi_index; + interface_delete(&intf_info); + } + } +} + +void switchlink_link_init() { + // create default vrf + switchlink_vrf_create(SWITCHLINK_DEFAULT_VRF_ID, &g_default_vrf_h); + + // create default bridge + switchlink_db_bridge_info_t bridge_db_info; + memset(&bridge_db_info, 0, sizeof(switchlink_db_bridge_info_t)); + bridge_db_info.vrf_h = g_default_vrf_h; + switchlink_bridge_create(&bridge_db_info); + g_default_bridge_h = bridge_db_info.bridge_h; + g_default_stp_h = bridge_db_info.stp_h; } diff --git a/switchlink/src/switchlink_link.h b/switchlink/src/switchlink_link.h index 057d69e..ab46ac4 100644 --- a/switchlink/src/switchlink_link.h +++ b/switchlink/src/switchlink_link.h @@ -18,36 +18,36 @@ limitations under the License. #define __SWITCHLINK_LINK_H__ typedef enum { - SWITCHLINK_INTF_TYPE_NONE, - SWITCHLINK_INTF_TYPE_L2_ACCESS, - SWITCHLINK_INTF_TYPE_L3, - SWITCHLINK_INTF_TYPE_L3VI, + SWITCHLINK_INTF_TYPE_NONE, + SWITCHLINK_INTF_TYPE_L2_ACCESS, + SWITCHLINK_INTF_TYPE_L3, + SWITCHLINK_INTF_TYPE_L3VI, } switchlink_intf_type_t; typedef enum { - SWITCHLINK_LINK_TYPE_NONE, - SWITCHLINK_LINK_TYPE_ETH, - SWITCHLINK_LINK_TYPE_BRIDGE, - SWITCHLINK_LINK_TYPE_VXLAN, - SWITCHLINK_LINK_TYPE_BOND, + SWITCHLINK_LINK_TYPE_NONE, + SWITCHLINK_LINK_TYPE_ETH, + SWITCHLINK_LINK_TYPE_BRIDGE, + SWITCHLINK_LINK_TYPE_VXLAN, + SWITCHLINK_LINK_TYPE_BOND, } switchlink_link_type_t; typedef enum { - SWITCHLINK_STP_STATE_NONE, - SWITCHLINK_STP_STATE_DISABLED, - SWITCHLINK_STP_STATE_LEARNING, - SWITCHLINK_STP_STATE_FORWARDING, - SWITCHLINK_STP_STATE_BLOCKING, + SWITCHLINK_STP_STATE_NONE, + SWITCHLINK_STP_STATE_DISABLED, + SWITCHLINK_STP_STATE_LEARNING, + SWITCHLINK_STP_STATE_FORWARDING, + SWITCHLINK_STP_STATE_BLOCKING, } switchlink_stp_state_t; typedef enum { - SWITCHLINK_URPF_MODE_NONE, - SWITCHLINK_URPF_MODE_STRICT, - SWITCHLINK_URPF_MODE_LOOSE, + SWITCHLINK_URPF_MODE_NONE, + SWITCHLINK_URPF_MODE_STRICT, + SWITCHLINK_URPF_MODE_LOOSE, } switchlink_urpf_mode_t; -extern void -interface_change_type(uint32_t ifindex, switchlink_intf_type_t type); +extern void interface_change_type(uint32_t ifindex, + switchlink_intf_type_t type); extern void interface_create_l3vi(uint32_t ifindex); #endif /* __SWITCHLINK_LINK_H__ */ diff --git a/switchlink/src/switchlink_main.c b/switchlink/src/switchlink_main.c index 4edd8ac..3c10410 100644 --- a/switchlink/src/switchlink_main.c +++ b/switchlink/src/switchlink_main.c @@ -30,265 +30,256 @@ static pthread_t switchlink_thread; uint8_t g_log_level = SWITCHLINK_LOG_ERR; enum { - SWITCHLINK_MSG_LINK, - SWITCHLINK_MSG_ADDR, - SWITCHLINK_MSG_NETCONF, - SWITCHLINK_MSG_NETCONF6, - SWITCHLINK_MSG_NEIGH_MAC, - SWITCHLINK_MSG_NEIGH_IP, - SWITCHLINK_MSG_NEIGH_IP6, - SWITCHLINK_MSG_MDB, - SWITCHLINK_MSG_UNICAST_ROUTE, - SWITCHLINK_MSG_UNICAST_ROUTE6, - SWITCHLINK_MSG_MULTICAST_ROUTE, - SWITCHLINK_MSG_MULTICAST_ROUTE6, - SWITCHLINK_MSG_MAX, + SWITCHLINK_MSG_LINK, + SWITCHLINK_MSG_ADDR, + SWITCHLINK_MSG_NETCONF, + SWITCHLINK_MSG_NETCONF6, + SWITCHLINK_MSG_NEIGH_MAC, + SWITCHLINK_MSG_NEIGH_IP, + SWITCHLINK_MSG_NEIGH_IP6, + SWITCHLINK_MSG_MDB, + SWITCHLINK_MSG_UNICAST_ROUTE, + SWITCHLINK_MSG_UNICAST_ROUTE6, + SWITCHLINK_MSG_MULTICAST_ROUTE, + SWITCHLINK_MSG_MULTICAST_ROUTE6, + SWITCHLINK_MSG_MAX, } switchlink_msg_t; -static void -nl_sync_state() { - static uint8_t msg_idx = SWITCHLINK_MSG_LINK; - if (msg_idx == SWITCHLINK_MSG_MAX) { - return; - } - - struct rtgenmsg rt_hdr = { - .rtgen_family = AF_UNSPEC, - }; - - int msg_type; - switch (msg_idx) { - case SWITCHLINK_MSG_LINK: - msg_type = RTM_GETLINK; - break; - - case SWITCHLINK_MSG_ADDR: - msg_type = RTM_GETADDR; - break; - - case SWITCHLINK_MSG_NETCONF: - msg_type = RTM_GETNETCONF; - rt_hdr.rtgen_family = AF_INET; - break; - - case SWITCHLINK_MSG_NETCONF6: - msg_type = RTM_GETNETCONF; - rt_hdr.rtgen_family = AF_INET6; - break; - - case SWITCHLINK_MSG_NEIGH_MAC: - msg_type = RTM_GETNEIGH; - rt_hdr.rtgen_family = AF_BRIDGE; - break; - - case SWITCHLINK_MSG_NEIGH_IP: - msg_type = RTM_GETNEIGH; - rt_hdr.rtgen_family = AF_INET; - break; - - case SWITCHLINK_MSG_NEIGH_IP6: - msg_type = RTM_GETNEIGH; - rt_hdr.rtgen_family = AF_INET6; - break; - - case SWITCHLINK_MSG_MDB: - msg_type = RTM_GETMDB; - rt_hdr.rtgen_family = AF_BRIDGE; - break; - - case SWITCHLINK_MSG_UNICAST_ROUTE: - msg_type = RTM_GETROUTE; - rt_hdr.rtgen_family = AF_INET; - break; - - case SWITCHLINK_MSG_UNICAST_ROUTE6: - msg_type = RTM_GETROUTE; - rt_hdr.rtgen_family = AF_INET6; - break; - - case SWITCHLINK_MSG_MULTICAST_ROUTE: - msg_type = RTM_GETROUTE; - rt_hdr.rtgen_family = RTNL_FAMILY_IPMR; - break; - - case SWITCHLINK_MSG_MULTICAST_ROUTE6: - msg_type = RTM_GETROUTE; - rt_hdr.rtgen_family = RTNL_FAMILY_IP6MR; - break; - } - +static void nl_sync_state() { + static uint8_t msg_idx = SWITCHLINK_MSG_LINK; + if (msg_idx == SWITCHLINK_MSG_MAX) { + return; + } + + struct rtgenmsg rt_hdr = { + .rtgen_family = AF_UNSPEC, + }; + + int msg_type = -1; + switch (msg_idx) { + case SWITCHLINK_MSG_LINK: + msg_type = RTM_GETLINK; + break; + + case SWITCHLINK_MSG_ADDR: + msg_type = RTM_GETADDR; + break; + + case SWITCHLINK_MSG_NETCONF: + msg_type = RTM_GETNETCONF; + rt_hdr.rtgen_family = AF_INET; + break; + + case SWITCHLINK_MSG_NETCONF6: + msg_type = RTM_GETNETCONF; + rt_hdr.rtgen_family = AF_INET6; + break; + + case SWITCHLINK_MSG_NEIGH_MAC: + msg_type = RTM_GETNEIGH; + rt_hdr.rtgen_family = AF_BRIDGE; + break; + + case SWITCHLINK_MSG_NEIGH_IP: + msg_type = RTM_GETNEIGH; + rt_hdr.rtgen_family = AF_INET; + break; + + case SWITCHLINK_MSG_NEIGH_IP6: + msg_type = RTM_GETNEIGH; + rt_hdr.rtgen_family = AF_INET6; + break; + + case SWITCHLINK_MSG_MDB: + msg_type = RTM_GETMDB; + rt_hdr.rtgen_family = AF_BRIDGE; + break; + + case SWITCHLINK_MSG_UNICAST_ROUTE: + msg_type = RTM_GETROUTE; + rt_hdr.rtgen_family = AF_INET; + break; + + case SWITCHLINK_MSG_UNICAST_ROUTE6: + msg_type = RTM_GETROUTE; + rt_hdr.rtgen_family = AF_INET6; + break; + + case SWITCHLINK_MSG_MULTICAST_ROUTE: + msg_type = RTM_GETROUTE; + rt_hdr.rtgen_family = RTNL_FAMILY_IPMR; + break; + + case SWITCHLINK_MSG_MULTICAST_ROUTE6: + msg_type = RTM_GETROUTE; + rt_hdr.rtgen_family = RTNL_FAMILY_IP6MR; + break; + } + + if (msg_type != -1) { nl_send_simple(g_nlsk, msg_type, NLM_F_DUMP, &rt_hdr, sizeof(rt_hdr)); msg_idx++; + } } -static void -process_nl_message(struct nlmsghdr *nlmsg) { - switch(nlmsg->nlmsg_type) { - case RTM_NEWLINK: - case RTM_DELLINK: - process_link_msg(nlmsg, nlmsg->nlmsg_type); - break; - case RTM_NEWADDR: - case RTM_DELADDR: - process_address_msg(nlmsg, nlmsg->nlmsg_type); - break; - case RTM_NEWROUTE: - case RTM_DELROUTE: - process_route_msg(nlmsg, nlmsg->nlmsg_type); - break; - case RTM_NEWNEIGH: - case RTM_DELNEIGH: - process_neigh_msg(nlmsg, nlmsg->nlmsg_type); - break; - case RTM_NEWNETCONF: - process_netconf_msg(nlmsg, nlmsg->nlmsg_type); - break; - case RTM_GETMDB: - case RTM_NEWMDB: - case RTM_DELMDB: - process_mdb_msg(nlmsg, nlmsg->nlmsg_type); - break; - case NLMSG_DONE: - nl_sync_state(); - break; - default: - printf("Unknown netlink message(%d). Ignoring\n", - nlmsg->nlmsg_type); - break; - } +static void process_nl_message(struct nlmsghdr *nlmsg) { + switch (nlmsg->nlmsg_type) { + case RTM_NEWLINK: + case RTM_DELLINK: + process_link_msg(nlmsg, nlmsg->nlmsg_type); + break; + case RTM_NEWADDR: + case RTM_DELADDR: + process_address_msg(nlmsg, nlmsg->nlmsg_type); + break; + case RTM_NEWROUTE: + case RTM_DELROUTE: + process_route_msg(nlmsg, nlmsg->nlmsg_type); + break; + case RTM_NEWNEIGH: + case RTM_DELNEIGH: + process_neigh_msg(nlmsg, nlmsg->nlmsg_type); + break; + case RTM_NEWNETCONF: + process_netconf_msg(nlmsg, nlmsg->nlmsg_type); + break; + case RTM_GETMDB: + case RTM_NEWMDB: + case RTM_DELMDB: + process_mdb_msg(nlmsg, nlmsg->nlmsg_type); + break; + case NLMSG_DONE: + nl_sync_state(); + break; + default: + printf("Unknown netlink message(%d). Ignoring\n", nlmsg->nlmsg_type); + break; + } } -static int -nl_sock_recv_msg(struct nl_msg *msg, void *arg) { - struct nlmsghdr *nl_msg = nlmsg_hdr(msg); - int nl_msg_sz = nlmsg_get_max_size(msg); - while (nlmsg_ok(nl_msg, nl_msg_sz)) { - process_nl_message(nl_msg); - nl_msg = nlmsg_next(nl_msg, &nl_msg_sz); - } +static int nl_sock_recv_msg(struct nl_msg *msg, void *arg) { + struct nlmsghdr *nl_msg = nlmsg_hdr(msg); + int nl_msg_sz = nlmsg_get_max_size(msg); + while (nlmsg_ok(nl_msg, nl_msg_sz)) { + process_nl_message(nl_msg); + nl_msg = nlmsg_next(nl_msg, &nl_msg_sz); + } - return 0; + return 0; } -static void -cleanup_nl_sock() { - // free the socket - nl_socket_free(g_nlsk); - g_nlsk = NULL; +static void cleanup_nl_sock() { + // free the socket + nl_socket_free(g_nlsk); + g_nlsk = NULL; } -static void -switchlink_nl_sock_intf_init() { - int nlsk_fd, sock_flags; - - // allocate a new socket - g_nlsk = nl_socket_alloc(); - if (g_nlsk == NULL) { - perror("nl_socket_alloc"); - return; - } - - nl_socket_set_local_port(g_nlsk, 0); - - // disable sequence number checking - nl_socket_disable_seq_check(g_nlsk); - - // set the callback function - nl_socket_modify_cb(g_nlsk, NL_CB_VALID, NL_CB_CUSTOM, nl_sock_recv_msg, - NULL); - nl_socket_modify_cb(g_nlsk, NL_CB_FINISH, NL_CB_CUSTOM, nl_sock_recv_msg, - NULL); - - // connect to the netlink route socket - if (nl_connect(g_nlsk, NETLINK_ROUTE) < 0) { - perror("nl_connect:NETLINK_ROUTE"); - cleanup_nl_sock(); - return; - } - - // register for the following messages - nl_socket_add_memberships(g_nlsk, RTNLGRP_LINK, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_NOTIFY, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_NEIGH, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_IFADDR, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_MROUTE, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_ROUTE, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_RULE, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_NETCONF, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_IFADDR, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_MROUTE, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_ROUTE, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_RULE, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_NETCONF, 0); - nl_socket_add_memberships(g_nlsk, RTNLGRP_MDB, 0); - - // set socket to be non-blocking - nlsk_fd = nl_socket_get_fd(g_nlsk); - if (nlsk_fd < 0) { - perror("nl_socket_get_fd"); - cleanup_nl_sock(); - return; - } - sock_flags = fcntl(nlsk_fd, F_GETFL, 0); - if (fcntl(nlsk_fd, F_SETFL, sock_flags | O_NONBLOCK) < 0) { - perror("fcntl"); - cleanup_nl_sock(); - return; - } - - // start building state from the kernel - nl_sync_state(); +static void switchlink_nl_sock_intf_init() { + int nlsk_fd, sock_flags; + + // allocate a new socket + g_nlsk = nl_socket_alloc(); + if (g_nlsk == NULL) { + perror("nl_socket_alloc"); + return; + } + + nl_socket_set_local_port(g_nlsk, 0); + + // disable sequence number checking + nl_socket_disable_seq_check(g_nlsk); + + // set the callback function + nl_socket_modify_cb( + g_nlsk, NL_CB_VALID, NL_CB_CUSTOM, nl_sock_recv_msg, NULL); + nl_socket_modify_cb( + g_nlsk, NL_CB_FINISH, NL_CB_CUSTOM, nl_sock_recv_msg, NULL); + + // connect to the netlink route socket + if (nl_connect(g_nlsk, NETLINK_ROUTE) < 0) { + perror("nl_connect:NETLINK_ROUTE"); + cleanup_nl_sock(); + return; + } + + // register for the following messages + nl_socket_add_memberships(g_nlsk, RTNLGRP_LINK, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_NOTIFY, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_NEIGH, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_IFADDR, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_MROUTE, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_ROUTE, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_RULE, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV4_NETCONF, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_IFADDR, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_MROUTE, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_ROUTE, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_RULE, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_IPV6_NETCONF, 0); + nl_socket_add_memberships(g_nlsk, RTNLGRP_MDB, 0); + + // set socket to be non-blocking + nlsk_fd = nl_socket_get_fd(g_nlsk); + if (nlsk_fd < 0) { + perror("nl_socket_get_fd"); + cleanup_nl_sock(); + return; + } + sock_flags = fcntl(nlsk_fd, F_GETFL, 0); + if (fcntl(nlsk_fd, F_SETFL, sock_flags | O_NONBLOCK) < 0) { + perror("fcntl"); + cleanup_nl_sock(); + return; + } + + // start building state from the kernel + nl_sync_state(); } -static void -process_nl_event_loop() { - int nlsk_fd; - nlsk_fd = nl_socket_get_fd(g_nlsk); - assert(nlsk_fd > 0); - - while(1) { - int ret, num_fds; - fd_set read_fds; - FD_ZERO(&read_fds); - FD_SET(nlsk_fd, &read_fds); - num_fds = nlsk_fd + 1; - - ret = select(num_fds, &read_fds, NULL, NULL, NULL); - if (ret == -1) { - perror("pselect"); - return; - } else if (ret == 0) { - } else { - if (FD_ISSET(nlsk_fd, &read_fds)) { - nl_recvmsgs_default(g_nlsk); - } - } +static void process_nl_event_loop() { + int nlsk_fd; + nlsk_fd = nl_socket_get_fd(g_nlsk); + assert(nlsk_fd > 0); + + while (1) { + int ret, num_fds; + fd_set read_fds; + FD_ZERO(&read_fds); + FD_SET(nlsk_fd, &read_fds); + num_fds = nlsk_fd + 1; + + ret = select(num_fds, &read_fds, NULL, NULL, NULL); + if (ret == -1) { + perror("pselect"); + return; + } else if (ret == 0) { + } else { + if (FD_ISSET(nlsk_fd, &read_fds)) { + nl_recvmsgs_default(g_nlsk); + } } + } } - -struct nl_sock * -switchlink_get_nl_sock() { - return g_nlsk; +struct nl_sock *switchlink_get_nl_sock() { + return g_nlsk; } -static void * -switchlink_main(void *args) { - switchlink_db_init(); - switchlink_api_init(); - switchlink_link_init(); - switchlink_packet_driver_init(); - switchlink_nl_sock_intf_init(); - - if (g_nlsk) { - process_nl_event_loop(); - cleanup_nl_sock(); - } +static void *switchlink_main(void *args) { + switchlink_db_init(); + switchlink_api_init(); + switchlink_link_init(); + switchlink_packet_driver_init(); + switchlink_nl_sock_intf_init(); + + if (g_nlsk) { + process_nl_event_loop(); + cleanup_nl_sock(); + } - return NULL; + return NULL; } -int -switchlink_init() { - return pthread_create(&switchlink_thread, NULL, switchlink_main, NULL); +int switchlink_init() { + return pthread_create(&switchlink_thread, NULL, switchlink_main, NULL); } diff --git a/switchlink/src/switchlink_mdb.c b/switchlink/src/switchlink_mdb.c index 6f47b8f..a4188b7 100644 --- a/switchlink/src/switchlink_mdb.c +++ b/switchlink/src/switchlink_mdb.c @@ -26,160 +26,158 @@ limitations under the License. #include "switchlink_db.h" #include "switchlink_sai.h" -static void -switchlink_mdb_mroute_notify(switchlink_db_mroute_info_t *mroute_info) { - switchlink_mroute_delete(mroute_info); - switchlink_mroute_create(mroute_info); +static void switchlink_mdb_mroute_notify( + switchlink_db_mroute_info_t *mroute_info) { + switchlink_mroute_delete(mroute_info); + switchlink_mroute_create(mroute_info); } -static void -process_mdb_entry(int type, int ifindex, struct br_mdb_entry *bre) { - switchlink_db_mdb_info_t mdb_info; - switchlink_db_bridge_info_t bridge_info; - switchlink_db_interface_info_t intf_info; - switchlink_db_status_t status; - bool notify = false; +static void process_mdb_entry(int type, int ifindex, struct br_mdb_entry *bre) { + switchlink_db_mdb_info_t mdb_info; + switchlink_db_bridge_info_t bridge_info; + switchlink_db_interface_info_t intf_info; + switchlink_db_status_t status; + bool notify = false; - memset(&bridge_info, 0, sizeof(bridge_info)); - status = switchlink_db_bridge_get_info(ifindex, &bridge_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } + memset(&bridge_info, 0, sizeof(bridge_info)); + status = switchlink_db_bridge_get_info(ifindex, &bridge_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } - memset(&intf_info, 0, sizeof(intf_info)); - status = switchlink_db_interface_get_info(bre->ifindex, &intf_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } + memset(&intf_info, 0, sizeof(intf_info)); + status = switchlink_db_interface_get_info(bre->ifindex, &intf_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } - memset(&mdb_info, 0, sizeof(mdb_info)); - mdb_info.bridge_h = bridge_info.bridge_h; - if (ntohs(bre->addr.proto) == ETH_P_IP) { - mdb_info.grp_ip.family = AF_INET; - mdb_info.grp_ip.prefix_len = 32; - mdb_info.grp_ip.ip.v4addr.s_addr = ntohl(bre->addr.u.ip4); - } else if (ntohs(bre->addr.proto) == ETH_P_IPV6) { - mdb_info.grp_ip.family = AF_INET6; - mdb_info.grp_ip.prefix_len = 128; - memcpy(&(mdb_info.grp_ip.ip.v6addr), &(bre->addr.u.ip6), - sizeof(struct in6_addr)); - } else { - return; - } + memset(&mdb_info, 0, sizeof(mdb_info)); + mdb_info.bridge_h = bridge_info.bridge_h; + if (ntohs(bre->addr.proto) == ETH_P_IP) { + mdb_info.grp_ip.family = AF_INET; + mdb_info.grp_ip.prefix_len = 32; + mdb_info.grp_ip.ip.v4addr.s_addr = ntohl(bre->addr.u.ip4); + } else if (ntohs(bre->addr.proto) == ETH_P_IPV6) { + mdb_info.grp_ip.family = AF_INET6; + mdb_info.grp_ip.prefix_len = 128; + memcpy(&(mdb_info.grp_ip.ip.v6addr), + &(bre->addr.u.ip6), + sizeof(struct in6_addr)); + } else { + return; + } - if (type == RTM_NEWMDB) { - status = switchlink_db_mdb_get_info(&mdb_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - mdb_info.intfs[mdb_info.num_intfs] = intf_info.intf_h; - mdb_info.num_intfs++; - status = switchlink_db_mdb_add(&mdb_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - switchlink_mdb_create(&mdb_info); - notify = true; - } else { - bool found = false; - for(int i = 0; i < mdb_info.num_intfs; i++) { - if (mdb_info.intfs[i] == intf_info.intf_h) { - found = true; - break; - } - } - if (!found) { - mdb_info.intfs[mdb_info.num_intfs] = intf_info.intf_h; - mdb_info.num_intfs++; - switchlink_mdb_delete(&mdb_info); - switchlink_mdb_create(&mdb_info); - status = switchlink_db_mdb_update(&mdb_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - notify = true; - } - } + if (type == RTM_NEWMDB) { + status = switchlink_db_mdb_get_info(&mdb_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + mdb_info.intfs[mdb_info.num_intfs] = intf_info.intf_h; + mdb_info.num_intfs++; + status = switchlink_db_mdb_add(&mdb_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + switchlink_mdb_create(&mdb_info); + notify = true; } else { - status = switchlink_db_mdb_get_info(&mdb_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } - bool found = false; - int entry_index = -1; - for(int i = 0; i < mdb_info.num_intfs; i++) { - if (mdb_info.intfs[i] == intf_info.intf_h) { - found = true; - entry_index = i; - break; - } - } - if (!found) { - return; - } - mdb_info.intfs[entry_index] = mdb_info.intfs[mdb_info.num_intfs - 1]; - mdb_info.intfs[mdb_info.num_intfs - 1] = 0; - mdb_info.num_intfs--; - if (mdb_info.num_intfs == 0) { - switchlink_mdb_delete(&mdb_info); - status = switchlink_db_mdb_delete(&mdb_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - } else { - switchlink_mdb_delete(&mdb_info); - switchlink_mdb_create(&mdb_info); - status = switchlink_db_mdb_update(&mdb_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + bool found = false; + for (int i = 0; i < mdb_info.num_intfs; i++) { + if (mdb_info.intfs[i] == intf_info.intf_h) { + found = true; + break; } + } + if (!found) { + mdb_info.intfs[mdb_info.num_intfs] = intf_info.intf_h; + mdb_info.num_intfs++; + switchlink_mdb_delete(&mdb_info); + switchlink_mdb_create(&mdb_info); + status = switchlink_db_mdb_update(&mdb_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); notify = true; + } } - - if (notify) { - switchlink_db_mroute_mdb_walk(&mdb_info, switchlink_mdb_mroute_notify); + } else { + status = switchlink_db_mdb_get_info(&mdb_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } + bool found = false; + int entry_index = -1; + for (int i = 0; i < mdb_info.num_intfs; i++) { + if (mdb_info.intfs[i] == intf_info.intf_h) { + found = true; + entry_index = i; + break; + } + } + if (!found) { + return; } + mdb_info.intfs[entry_index] = mdb_info.intfs[mdb_info.num_intfs - 1]; + mdb_info.intfs[mdb_info.num_intfs - 1] = 0; + mdb_info.num_intfs--; + if (mdb_info.num_intfs == 0) { + switchlink_mdb_delete(&mdb_info); + status = switchlink_db_mdb_delete(&mdb_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + } else { + switchlink_mdb_delete(&mdb_info); + switchlink_mdb_create(&mdb_info); + status = switchlink_db_mdb_update(&mdb_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + } + notify = true; + } + + if (notify) { + switchlink_db_mroute_mdb_walk(&mdb_info, switchlink_mdb_mroute_notify); + } } -void -process_mdb_msg(struct nlmsghdr *nlmsg, int type) { - int hdrlen, attrlen; - struct nlattr *attr, *nest_attr, *info_attr; - struct br_port_msg *brp_msg; - struct br_mdb_entry *bre; +void process_mdb_msg(struct nlmsghdr *nlmsg, int type) { + int hdrlen, attrlen; + struct nlattr *attr, *nest_attr, *info_attr; + struct br_port_msg *brp_msg; + struct br_mdb_entry *bre; - assert((type == RTM_GETMDB) || (type == RTM_NEWMDB) || - (type == RTM_DELMDB)); - if (type == RTM_GETMDB) { - type = RTM_NEWMDB; - } + assert((type == RTM_GETMDB) || (type == RTM_NEWMDB) || (type == RTM_DELMDB)); + if (type == RTM_GETMDB) { + type = RTM_NEWMDB; + } - brp_msg = nlmsg_data(nlmsg); - hdrlen = sizeof(struct br_port_msg); - NL_LOG_DEBUG(("%smdb: family = %d, ifindex = %d\n", - ((type == RTM_NEWMDB) ? "new" : "del"), - brp_msg->family, brp_msg->ifindex)); + brp_msg = nlmsg_data(nlmsg); + hdrlen = sizeof(struct br_port_msg); + NL_LOG_DEBUG(("%smdb: family = %d, ifindex = %d\n", + ((type == RTM_NEWMDB) ? "new" : "del"), + brp_msg->family, + brp_msg->ifindex)); - attrlen = nlmsg_attrlen(nlmsg, hdrlen); - attr = nlmsg_attrdata(nlmsg, hdrlen); - while (nla_ok(attr, attrlen)) { - int attr_type = nla_type(attr); - switch (attr_type) { - case MDBA_MDB: - nla_for_each_nested(nest_attr, attr, attrlen) { - int nest_attr_type; - nest_attr_type = nla_type(nest_attr); - switch (nest_attr_type) { - case MDBA_MDB_ENTRY: - info_attr = nla_data(nest_attr); - if (nla_type(info_attr) == MDBA_MDB_ENTRY_INFO) { - bre = - (struct br_mdb_entry *)nla_data(info_attr); - process_mdb_entry(type, brp_msg->ifindex, bre); - } - break; - default: - break; - } - } - break; - case MDBA_ROUTER: - break; + attrlen = nlmsg_attrlen(nlmsg, hdrlen); + attr = nlmsg_attrdata(nlmsg, hdrlen); + while (nla_ok(attr, attrlen)) { + int attr_type = nla_type(attr); + switch (attr_type) { + case MDBA_MDB: + nla_for_each_nested(nest_attr, attr, attrlen) { + int nest_attr_type; + nest_attr_type = nla_type(nest_attr); + switch (nest_attr_type) { + case MDBA_MDB_ENTRY: + info_attr = nla_data(nest_attr); + if (nla_type(info_attr) == MDBA_MDB_ENTRY_INFO) { + bre = (struct br_mdb_entry *)nla_data(info_attr); + process_mdb_entry(type, brp_msg->ifindex, bre); + } + break; default: - NL_LOG_DEBUG(("mdb: skipping attr(%d)\n", attr_type)); - break; + break; + } } - attr = nla_next(attr, &attrlen); + break; + case MDBA_ROUTER: + break; + default: + NL_LOG_DEBUG(("mdb: skipping attr(%d)\n", attr_type)); + break; } + attr = nla_next(attr, &attrlen); + } } diff --git a/switchlink/src/switchlink_neigh.c b/switchlink/src/switchlink_neigh.c index 0bc6d8f..88677f3 100644 --- a/switchlink/src/switchlink_neigh.c +++ b/switchlink/src/switchlink_neigh.c @@ -28,235 +28,239 @@ limitations under the License. #include "switchlink_db.h" #include "switchlink_sai.h" -static void -mac_delete(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h) { - switchlink_handle_t intf_h; - switchlink_db_status_t status; - status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &intf_h); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } - switchlink_mac_delete(mac_addr, bridge_h); - switchlink_db_mac_delete(mac_addr, bridge_h); +static void mac_delete(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h) { + switchlink_handle_t intf_h; + switchlink_db_status_t status; + status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &intf_h); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } + switchlink_mac_delete(mac_addr, bridge_h); + switchlink_db_mac_delete(mac_addr, bridge_h); } -static void -mac_create(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h, - switchlink_handle_t intf_h) { - switchlink_handle_t old_intf_h; - switchlink_db_status_t status; - status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &old_intf_h); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - if (old_intf_h != intf_h) { - switchlink_mac_update(mac_addr, bridge_h, intf_h); - switchlink_db_mac_set_intf(mac_addr, bridge_h, intf_h); - return; - } +static void mac_create(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h) { + switchlink_handle_t old_intf_h; + switchlink_db_status_t status; + status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &old_intf_h); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + if (old_intf_h != intf_h) { + switchlink_mac_update(mac_addr, bridge_h, intf_h); + switchlink_db_mac_set_intf(mac_addr, bridge_h, intf_h); + return; } + } - switchlink_mac_create(mac_addr, bridge_h, intf_h); - switchlink_db_mac_add(mac_addr, bridge_h, intf_h); + switchlink_mac_create(mac_addr, bridge_h, intf_h); + switchlink_db_mac_add(mac_addr, bridge_h, intf_h); } -static void -neigh_delete(switchlink_handle_t vrf_h, switchlink_ip_addr_t *ipaddr, - switchlink_handle_t intf_h) { - switchlink_db_neigh_info_t neigh_info; - switchlink_db_status_t status; +static void neigh_delete(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *ipaddr, + switchlink_handle_t intf_h) { + switchlink_db_neigh_info_t neigh_info; + switchlink_db_status_t status; - memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); - neigh_info.vrf_h = vrf_h; - neigh_info.intf_h = intf_h; - memcpy(&(neigh_info.ip_addr), ipaddr, sizeof(switchlink_ip_addr_t)); - status = switchlink_db_neighbor_get_info(&neigh_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } + memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); + neigh_info.vrf_h = vrf_h; + neigh_info.intf_h = intf_h; + memcpy(&(neigh_info.ip_addr), ipaddr, sizeof(switchlink_ip_addr_t)); + status = switchlink_db_neighbor_get_info(&neigh_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } - switchlink_neighbor_delete(&neigh_info); - switchlink_nexthop_delete(&neigh_info); - switchlink_db_neighbor_delete(&neigh_info); + switchlink_neighbor_delete(&neigh_info); + switchlink_nexthop_delete(&neigh_info); + switchlink_db_neighbor_delete(&neigh_info); - // delete the host route - route_delete(g_default_vrf_h, ipaddr); + // delete the host route + route_delete(g_default_vrf_h, ipaddr); } -void -neigh_create(switchlink_handle_t vrf_h, switchlink_ip_addr_t *ipaddr, - switchlink_mac_addr_t mac_addr, switchlink_handle_t intf_h) { - switchlink_db_status_t status; - switchlink_db_neigh_info_t neigh_info; +void neigh_create(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *ipaddr, + switchlink_mac_addr_t mac_addr, + switchlink_handle_t intf_h) { + switchlink_db_status_t status; + switchlink_db_neigh_info_t neigh_info; - if ((ipaddr->family == AF_INET6) && - IN6_IS_ADDR_MULTICAST(&(ipaddr->ip.v6addr))) { - return; - } + if ((ipaddr->family == AF_INET6) && + IN6_IS_ADDR_MULTICAST(&(ipaddr->ip.v6addr))) { + return; + } - memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); - neigh_info.vrf_h = vrf_h; - neigh_info.intf_h = intf_h; - memcpy(&(neigh_info.ip_addr), ipaddr, sizeof(switchlink_ip_addr_t)); + memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); + neigh_info.vrf_h = vrf_h; + neigh_info.intf_h = intf_h; + memcpy(&(neigh_info.ip_addr), ipaddr, sizeof(switchlink_ip_addr_t)); - status = switchlink_db_neighbor_get_info(&neigh_info); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - if (memcmp(neigh_info.mac_addr, mac_addr, - sizeof(switchlink_mac_addr_t)) == 0) { - // no change - return; - } - - // update, currently handled as a delete followed by add - neigh_delete(vrf_h, ipaddr, intf_h); + status = switchlink_db_neighbor_get_info(&neigh_info); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + if (memcmp(neigh_info.mac_addr, mac_addr, sizeof(switchlink_mac_addr_t)) == + 0) { + // no change + return; } - memcpy(neigh_info.mac_addr, mac_addr, sizeof(switchlink_mac_addr_t)); - if (switchlink_nexthop_create(&neigh_info) == -1) { - return; - } - if (switchlink_neighbor_create(&neigh_info) == -1) { - switchlink_nexthop_delete(&neigh_info); - return; - } - switchlink_db_neighbor_add(&neigh_info); + // update, currently handled as a delete followed by add + neigh_delete(vrf_h, ipaddr, intf_h); + } - // add a host route - route_create(g_default_vrf_h, ipaddr, ipaddr, 0, intf_h); + memcpy(neigh_info.mac_addr, mac_addr, sizeof(switchlink_mac_addr_t)); + if (switchlink_nexthop_create(&neigh_info) == -1) { + return; + } + if (switchlink_neighbor_create(&neigh_info) == -1) { + switchlink_nexthop_delete(&neigh_info); + return; + } + switchlink_db_neighbor_add(&neigh_info); + + // add a host route + route_create(g_default_vrf_h, ipaddr, ipaddr, 0, intf_h); } -void -process_neigh_msg(struct nlmsghdr *nlmsg, int type) { - int hdrlen, attrlen; - struct nlattr *attr; - struct ndmsg *nbh; - switchlink_mac_addr_t mac_addr; - bool mac_addr_valid = false; - bool ipaddr_valid = false; - switchlink_ip_addr_t ipaddr; +void process_neigh_msg(struct nlmsghdr *nlmsg, int type) { + int hdrlen, attrlen; + struct nlattr *attr; + struct ndmsg *nbh; + switchlink_mac_addr_t mac_addr; + bool mac_addr_valid = false; + bool ipaddr_valid = false; + switchlink_ip_addr_t ipaddr; - assert((type == RTM_NEWNEIGH) || (type == RTM_DELNEIGH)); - nbh = nlmsg_data(nlmsg); - hdrlen = sizeof(struct ndmsg); - NL_LOG_DEBUG(("%sneigh: family = %d, ifindex = %d, state = 0x%x, " - "flags = 0x%x, type = %d\n", - ((type == RTM_NEWNEIGH) ? "new" : "del"), - nbh->ndm_family, nbh->ndm_ifindex, nbh->ndm_state, - nbh->ndm_flags, nbh->ndm_type)); + assert((type == RTM_NEWNEIGH) || (type == RTM_DELNEIGH)); + nbh = nlmsg_data(nlmsg); + hdrlen = sizeof(struct ndmsg); + NL_LOG_DEBUG( + ("%sneigh: family = %d, ifindex = %d, state = 0x%x, " + "flags = 0x%x, type = %d\n", + ((type == RTM_NEWNEIGH) ? "new" : "del"), + nbh->ndm_family, + nbh->ndm_ifindex, + nbh->ndm_state, + nbh->ndm_flags, + nbh->ndm_type)); - switchlink_db_interface_info_t ifinfo; - if (switchlink_db_interface_get_info(nbh->ndm_ifindex, &ifinfo) != - SWITCHLINK_DB_STATUS_SUCCESS) { - NL_LOG_DEBUG(("neigh: switchlink_db_interface_get_info failed\n")); - return; - } + switchlink_db_interface_info_t ifinfo; + if (switchlink_db_interface_get_info(nbh->ndm_ifindex, &ifinfo) != + SWITCHLINK_DB_STATUS_SUCCESS) { + NL_LOG_DEBUG(("neigh: switchlink_db_interface_get_info failed\n")); + return; + } - if (strncmp(ifinfo.ifname, SWITCHLINK_CPU_INTERFACE_NAME, - SWITCHLINK_INTERFACE_NAME_LEN_MAX) == 0) { - NL_LOG_DEBUG(("neigh: skipping neighbor on CPU interface\n")); - return; - } + if (strncmp(ifinfo.ifname, + SWITCHLINK_CPU_INTERFACE_NAME, + SWITCHLINK_INTERFACE_NAME_LEN_MAX) == 0) { + NL_LOG_DEBUG(("neigh: skipping neighbor on CPU interface\n")); + return; + } - memset(&ipaddr, 0, sizeof(switchlink_ip_addr_t)); - attrlen = nlmsg_attrlen(nlmsg, hdrlen); - attr = nlmsg_attrdata(nlmsg, hdrlen); - while (nla_ok(attr, attrlen)) { - int attr_type = nla_type(attr); - switch (attr_type) { - case NDA_DST: - ipaddr_valid = true; - ipaddr.family = nbh->ndm_family; - if (nbh->ndm_family == AF_INET) { - ipaddr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); - ipaddr.prefix_len = 32; - } else { - memcpy(&(ipaddr.ip.v6addr), nla_data(attr), nla_len(attr)); - ipaddr.prefix_len = 128; - } - break; - case NDA_LLADDR: { - uint64_t lladdr; - mac_addr_valid = true; - lladdr = nla_get_u64(attr); - memcpy(mac_addr, &lladdr, 6); - break; - } - default: - NL_LOG_DEBUG(("neigh: skipping attr(%d)\n", attr_type)); - break; + memset(&ipaddr, 0, sizeof(switchlink_ip_addr_t)); + attrlen = nlmsg_attrlen(nlmsg, hdrlen); + attr = nlmsg_attrdata(nlmsg, hdrlen); + while (nla_ok(attr, attrlen)) { + int attr_type = nla_type(attr); + switch (attr_type) { + case NDA_DST: + ipaddr_valid = true; + ipaddr.family = nbh->ndm_family; + if (nbh->ndm_family == AF_INET) { + ipaddr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); + ipaddr.prefix_len = 32; + } else { + memcpy(&(ipaddr.ip.v6addr), nla_data(attr), nla_len(attr)); + ipaddr.prefix_len = 128; } - attr = nla_next(attr, &attrlen); + break; + case NDA_LLADDR: { + uint64_t lladdr; + mac_addr_valid = true; + lladdr = nla_get_u64(attr); + memcpy(mac_addr, &lladdr, 6); + break; + } + default: + NL_LOG_DEBUG(("neigh: skipping attr(%d)\n", attr_type)); + break; } + attr = nla_next(attr, &attrlen); + } - switchlink_handle_t intf_h = ifinfo.intf_h; - switchlink_handle_t bridge_h = 0; - if (ifinfo.intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { - bridge_h = ifinfo.bridge_h; - assert(bridge_h); - } + switchlink_handle_t intf_h = ifinfo.intf_h; + switchlink_handle_t bridge_h = 0; + if (ifinfo.intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { + bridge_h = ifinfo.bridge_h; + assert(bridge_h); + } - if (type == RTM_NEWNEIGH) { - if (bridge_h && mac_addr_valid) { - mac_create(mac_addr, bridge_h, intf_h); - } - if (ipaddr_valid) { - if (mac_addr_valid) { - neigh_create(g_default_vrf_h, &ipaddr, mac_addr, intf_h); - } else { - // mac address is not valid, remove the neighbor entry - neigh_delete(g_default_vrf_h, &ipaddr, intf_h); - } - } - } else { - if (bridge_h && mac_addr_valid) { - mac_delete(mac_addr, bridge_h); - } - if (ipaddr_valid) { - neigh_delete(g_default_vrf_h, &ipaddr, intf_h); - } + if (type == RTM_NEWNEIGH) { + if (bridge_h && mac_addr_valid) { + mac_create(mac_addr, bridge_h, intf_h); + } + if (ipaddr_valid) { + if (mac_addr_valid) { + neigh_create(g_default_vrf_h, &ipaddr, mac_addr, intf_h); + } else { + // mac address is not valid, remove the neighbor entry + neigh_delete(g_default_vrf_h, &ipaddr, intf_h); + } + } + } else { + if (bridge_h && mac_addr_valid) { + mac_delete(mac_addr, bridge_h); + } + if (ipaddr_valid) { + neigh_delete(g_default_vrf_h, &ipaddr, intf_h); } + } } -void -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 ifindex; +void 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 ifindex; - if (!create) { - status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &intf_h); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - assert(false); - return; - } - } - - status = switchlink_db_interface_get_ifindex(intf_h, &ifindex); + if (!create) { + status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &intf_h); if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - assert(false); - return; + assert(false); + return; } + } - struct nl_sock *nlsk = switchlink_get_nl_sock(); - if (!nlsk) { - return; - } + status = switchlink_db_interface_get_ifindex(intf_h, &ifindex); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } - struct nl_addr *nl_addr = nl_addr_build(AF_LLC, mac_addr, ETH_ALEN); - struct rtnl_neigh *rtnl_neigh = rtnl_neigh_alloc(); - rtnl_neigh_set_ifindex(rtnl_neigh, ifindex); - rtnl_neigh_set_lladdr(rtnl_neigh, nl_addr); - rtnl_neigh_set_state(rtnl_neigh, rtnl_neigh_str2state("permanent")); - rtnl_neigh_set_family(rtnl_neigh, AF_BRIDGE); + struct nl_sock *nlsk = switchlink_get_nl_sock(); + if (!nlsk) { + return; + } - if (create) { - status = switchlink_db_mac_add(mac_addr, bridge_h, intf_h); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - rtnl_neigh_add(nlsk, rtnl_neigh, NLM_F_CREATE|NLM_F_REPLACE); - } else { - status = switchlink_db_mac_delete(mac_addr, bridge_h); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - rtnl_neigh_delete(nlsk, rtnl_neigh, 0); - } - rtnl_neigh_put(rtnl_neigh); - nl_addr_put(nl_addr); + struct nl_addr *nl_addr = nl_addr_build(AF_LLC, mac_addr, ETH_ALEN); + struct rtnl_neigh *rtnl_neigh = rtnl_neigh_alloc(); + rtnl_neigh_set_ifindex(rtnl_neigh, ifindex); + rtnl_neigh_set_lladdr(rtnl_neigh, nl_addr); + rtnl_neigh_set_state(rtnl_neigh, rtnl_neigh_str2state("permanent")); + rtnl_neigh_set_family(rtnl_neigh, AF_BRIDGE); + + if (create) { + status = switchlink_db_mac_add(mac_addr, bridge_h, intf_h); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + rtnl_neigh_add(nlsk, rtnl_neigh, NLM_F_CREATE | NLM_F_REPLACE); + } else { + status = switchlink_db_mac_delete(mac_addr, bridge_h); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + rtnl_neigh_delete(nlsk, rtnl_neigh, 0); + } + rtnl_neigh_put(rtnl_neigh); + nl_addr_put(nl_addr); } diff --git a/switchlink/src/switchlink_neigh.h b/switchlink/src/switchlink_neigh.h index 4ffc098..f2eb32f 100644 --- a/switchlink/src/switchlink_neigh.h +++ b/switchlink/src/switchlink_neigh.h @@ -17,13 +17,14 @@ limitations under the License. #ifndef __SWITCHLINK_NEIGH_H__ #define __SWITCHLINK_NEIGH_H__ -extern void -neigh_create(switchlink_handle_t vrf_h, switchlink_ip_addr_t *ipaddr, - switchlink_mac_addr_t mac_addr, switchlink_handle_t intf_h); +extern void neigh_create(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *ipaddr, + switchlink_mac_addr_t mac_addr, + switchlink_handle_t intf_h); -extern void -switchlink_linux_mac_update(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h, bool create); +extern void switchlink_linux_mac_update(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h, + bool create); #endif /* __SWITCHLINK_NEIGH_H__ */ diff --git a/switchlink/src/switchlink_netconf.c b/switchlink/src/switchlink_netconf.c index db8c3b3..2585279 100644 --- a/switchlink/src/switchlink_netconf.c +++ b/switchlink/src/switchlink_netconf.c @@ -25,146 +25,138 @@ limitations under the License. #include "switchlink_db.h" #include "switchlink_sai.h" -static bool g_forwarding[2] = {true, true}; +static bool g_forwarding[2] = {true, true}; static uint8_t g_rp_filter[2] = {1, 1}; -static bool g_mc_forwarding[2] = {true, true}; +static bool g_mc_forwarding[2] = {true, true}; -void -process_netconf_msg(struct nlmsghdr *nlmsg, int type) { - struct netconfmsg *ncmsg; - struct nlattr *attr; - int hdrlen, attrlen; - uint32_t ifindex = 0; - bool forwarding = false; - uint8_t rp_filter = 0; - bool mc_forwarding = false; - bool forwarding_valid = false; - bool rp_filter_valid = false; - bool mc_forwarding_valid = false; +void process_netconf_msg(struct nlmsghdr *nlmsg, int type) { + struct netconfmsg *ncmsg; + struct nlattr *attr; + int hdrlen, attrlen; + uint32_t ifindex = 0; + bool forwarding = false; + uint8_t rp_filter = 0; + bool mc_forwarding = false; + bool forwarding_valid = false; + bool rp_filter_valid = false; + bool mc_forwarding_valid = false; - assert(type == RTM_NEWNETCONF); - ncmsg = nlmsg_data(nlmsg); + assert(type == RTM_NEWNETCONF); + ncmsg = nlmsg_data(nlmsg); - if ((ncmsg->ncm_family != AF_INET) && (ncmsg->ncm_family != AF_INET6)) { - NL_LOG_DEBUG(("netconf: skipping unknown address family\n")); - return; - } + if ((ncmsg->ncm_family != AF_INET) && (ncmsg->ncm_family != AF_INET6)) { + NL_LOG_DEBUG(("netconf: skipping unknown address family\n")); + return; + } - hdrlen = sizeof(struct netconfmsg); - attrlen = nlmsg_attrlen(nlmsg, hdrlen); - attr = nlmsg_attrdata(nlmsg, hdrlen); - while (nla_ok(attr, attrlen)) { - int attr_type = nla_type(attr); - switch (attr_type) { - case NETCONFA_IFINDEX: - ifindex = nla_get_u32(attr); - break; - case NETCONFA_FORWARDING: - forwarding = nla_get_u32(attr); - forwarding_valid = true; - break; - case NETCONFA_RP_FILTER: - rp_filter = nla_get_u32(attr); - rp_filter_valid = true; - break; - case NETCONFA_MC_FORWARDING: - mc_forwarding = nla_get_u32(attr); - mc_forwarding_valid = true; - break; - default: - break; - } - attr = nla_next(attr, &attrlen); + hdrlen = sizeof(struct netconfmsg); + attrlen = nlmsg_attrlen(nlmsg, hdrlen); + attr = nlmsg_attrdata(nlmsg, hdrlen); + while (nla_ok(attr, attrlen)) { + int attr_type = nla_type(attr); + switch (attr_type) { + case NETCONFA_IFINDEX: + ifindex = nla_get_u32(attr); + break; + case NETCONFA_FORWARDING: + forwarding = nla_get_u32(attr); + forwarding_valid = true; + break; + case NETCONFA_RP_FILTER: + rp_filter = nla_get_u32(attr); + rp_filter_valid = true; + break; + case NETCONFA_MC_FORWARDING: + mc_forwarding = nla_get_u32(attr); + mc_forwarding_valid = true; + break; + default: + break; } + attr = nla_next(attr, &attrlen); + } - if (ifindex == (uint32_t) -1) { - int af = (ncmsg->ncm_family == AF_INET) ? 0 : 1; - if (forwarding_valid && (g_forwarding[af] != forwarding)) { - g_forwarding[af] = forwarding; - } - if (mc_forwarding_valid && (g_mc_forwarding[af] != mc_forwarding)) { - g_mc_forwarding[af] = mc_forwarding; - } - if (rp_filter_valid && (g_rp_filter[af] != rp_filter)) { - g_rp_filter[af] = rp_filter; - } - return; + if (ifindex == (uint32_t)-1) { + int af = (ncmsg->ncm_family == AF_INET) ? 0 : 1; + if (forwarding_valid && (g_forwarding[af] != forwarding)) { + g_forwarding[af] = forwarding; + } + if (mc_forwarding_valid && (g_mc_forwarding[af] != mc_forwarding)) { + g_mc_forwarding[af] = mc_forwarding; } + if (rp_filter_valid && (g_rp_filter[af] != rp_filter)) { + g_rp_filter[af] = rp_filter; + } + return; + } + + bool update_intf = false; + switchlink_db_status_t status; + switchlink_db_interface_info_t ifinfo; + + status = switchlink_db_interface_get_info(ifindex, &ifinfo); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + NL_LOG_DEBUG( + ("netconf: switchlink_db_interface_get_info " + "failed\n")); + return; + } + if (ifinfo.intf_type != SWITCHLINK_INTF_TYPE_L3) { + return; + } - bool update_intf = false; - switchlink_db_status_t status; - switchlink_db_interface_info_t ifinfo; + // merge global forwarding disable configuration + int af = (ncmsg->ncm_family == AF_INET) ? 0 : 1; + if (forwarding_valid && !g_forwarding[af]) { + forwarding = false; + } + if (mc_forwarding_valid && !g_mc_forwarding[af]) { + mc_forwarding = false; + } - status = switchlink_db_interface_get_info(ifindex, &ifinfo); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - NL_LOG_DEBUG(("netconf: switchlink_db_interface_get_info " - "failed\n")); - return; + if (ncmsg->ncm_family == AF_INET) { + if (forwarding_valid && (ifinfo.flags.ipv4_unicast_enabled != forwarding)) { + switchlink_interface_forwarding_update( + ifinfo.intf_h, ncmsg->ncm_family, forwarding); + ifinfo.flags.ipv4_unicast_enabled = forwarding; + update_intf = true; } - if (ifinfo.intf_type != SWITCHLINK_INTF_TYPE_L3) { - return; + if (mc_forwarding_valid && + (ifinfo.flags.ipv4_multicast_enabled != mc_forwarding)) { + switchlink_interface_mc_forwarding_update( + ifinfo.intf_h, ncmsg->ncm_family, mc_forwarding); + ifinfo.flags.ipv4_multicast_enabled = mc_forwarding; + update_intf = true; } - - // merge global forwarding disable configuration - int af = (ncmsg->ncm_family == AF_INET) ? 0 : 1; - if (forwarding_valid && !g_forwarding[af]) { - forwarding = false; + if (rp_filter_valid && (ifinfo.flags.ipv4_urpf_mode != rp_filter)) { + switchlink_interface_urpf_mode_update( + ifinfo.intf_h, ncmsg->ncm_family, rp_filter); + ifinfo.flags.ipv4_urpf_mode = rp_filter; + update_intf = true; } - if (mc_forwarding_valid && !g_mc_forwarding[af]) { - mc_forwarding = false; + } else { + if (forwarding_valid && (ifinfo.flags.ipv6_unicast_enabled != forwarding)) { + switchlink_interface_forwarding_update( + ifinfo.intf_h, ncmsg->ncm_family, forwarding); + ifinfo.flags.ipv6_unicast_enabled = forwarding; + update_intf = true; } - - if (ncmsg->ncm_family == AF_INET) { - if (forwarding_valid && - (ifinfo.flags.ipv4_unicast_enabled != forwarding)) { - switchlink_interface_forwarding_update(ifinfo.intf_h, - ncmsg->ncm_family, - forwarding); - ifinfo.flags.ipv4_unicast_enabled = forwarding; - update_intf = true; - } - if (mc_forwarding_valid && - (ifinfo.flags.ipv4_multicast_enabled != mc_forwarding)) { - switchlink_interface_mc_forwarding_update(ifinfo.intf_h, - ncmsg->ncm_family, - mc_forwarding); - ifinfo.flags.ipv4_multicast_enabled = mc_forwarding; - update_intf = true; - } - if (rp_filter_valid && (ifinfo.flags.ipv4_urpf_mode != rp_filter)) { - switchlink_interface_urpf_mode_update(ifinfo.intf_h, - ncmsg->ncm_family, - rp_filter); - ifinfo.flags.ipv4_urpf_mode = rp_filter; - update_intf = true; - } - } else { - if (forwarding_valid && - (ifinfo.flags.ipv6_unicast_enabled != forwarding)) { - switchlink_interface_forwarding_update(ifinfo.intf_h, - ncmsg->ncm_family, - forwarding); - ifinfo.flags.ipv6_unicast_enabled = forwarding; - update_intf = true; - } - if (mc_forwarding_valid && - (ifinfo.flags.ipv6_multicast_enabled != mc_forwarding)) { - switchlink_interface_mc_forwarding_update(ifinfo.intf_h, - ncmsg->ncm_family, - mc_forwarding); - ifinfo.flags.ipv6_multicast_enabled = mc_forwarding; - update_intf = true; - } - if (rp_filter_valid && (ifinfo.flags.ipv6_urpf_mode != rp_filter)) { - switchlink_interface_urpf_mode_update(ifinfo.intf_h, - ncmsg->ncm_family, - rp_filter); - ifinfo.flags.ipv6_urpf_mode = rp_filter; - update_intf = true; - } + if (mc_forwarding_valid && + (ifinfo.flags.ipv6_multicast_enabled != mc_forwarding)) { + switchlink_interface_mc_forwarding_update( + ifinfo.intf_h, ncmsg->ncm_family, mc_forwarding); + ifinfo.flags.ipv6_multicast_enabled = mc_forwarding; + update_intf = true; } - - if (update_intf) { - switchlink_db_interface_update(ifindex, &ifinfo); + if (rp_filter_valid && (ifinfo.flags.ipv6_urpf_mode != rp_filter)) { + switchlink_interface_urpf_mode_update( + ifinfo.intf_h, ncmsg->ncm_family, rp_filter); + ifinfo.flags.ipv6_urpf_mode = rp_filter; + update_intf = true; } + } + + if (update_intf) { + switchlink_db_interface_update(ifindex, &ifinfo); + } } diff --git a/switchlink/src/switchlink_packet.c b/switchlink/src/switchlink_packet.c index 5cfbc94..c213d36 100644 --- a/switchlink/src/switchlink_packet.c +++ b/switchlink/src/switchlink_packet.c @@ -38,176 +38,172 @@ limitations under the License. static pthread_t switchlink_packet_driver_thread; typedef struct switchlink_packet_intf_ { - char name[128]; - uint16_t port_id; - int fd; - char mac_addr[6]; + char name[128]; + uint16_t port_id; + int fd; + char mac_addr[6]; } switchlink_packet_intf_t; uint16_t g_num_intfs; static switchlink_packet_intf_t *g_intf; -static void -process_packet_from_user(int intf) { - int ret, fd, i; - char buf[2000]; - - // read packet from switch port - fd = g_intf[intf].fd; - while((ret = read(fd, buf, sizeof(buf))) > 0) { - - // ignore the packet if it is not sourced from one of the - // device's interface - char *src_mac_addr = buf + 6; - bool src_found = false; - for (i = 0; i < g_num_intfs; i++) { - if (memcmp(src_mac_addr, g_intf[i].mac_addr, 6) == 0) { - src_found = true; - break; - } - } - if (!src_found) { - NL_LOG_DEBUG(("Tx: Dropped %d bytes from %s\n", - ret, g_intf[intf].name)); - continue; - } - - // transmit the packet - if (switchlink_send_packet(buf, ret, g_intf[intf].port_id) != 0) { - NL_LOG_ERROR(("Tx: Sending %d bytes from %s failed\n", - ret, g_intf[intf].name)); - continue; - } - } -} - -static int -tunnel_alloc(int intf) { - int fd; - char *dev = g_intf[intf].name; - - if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { - return -1; +static void process_packet_from_user(int intf) { + int ret, fd, i; + char buf[2000]; + + // read packet from switch port + fd = g_intf[intf].fd; + while ((ret = read(fd, buf, sizeof(buf))) > 0) { + // ignore the packet if it is not sourced from one of the + // device's interface + char *src_mac_addr = buf + 6; + bool src_found = false; + for (i = 0; i < g_num_intfs; i++) { + if (memcmp(src_mac_addr, g_intf[i].mac_addr, 6) == 0) { + src_found = true; + break; + } } - - // open the tap interface - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { - perror("tunsetiff"); - close(fd); - return -1; + if (!src_found) { + NL_LOG_DEBUG(("Tx: Dropped %d bytes from %s\n", ret, g_intf[intf].name)); + continue; } - // set connection to be non-blocking - int sock_flags = fcntl(fd, F_GETFL, 0); - if (fcntl(fd, F_SETFL, sock_flags | O_NONBLOCK) < 0) { - perror("f_setfl"); - close(fd); - return -1; + // transmit the packet + if (switchlink_send_packet(buf, ret, g_intf[intf].port_id) != 0) { + NL_LOG_ERROR( + ("Tx: Sending %d bytes from %s failed\n", ret, g_intf[intf].name)); + continue; } + } +} - // fetch the mac address - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if (ioctl(fd, SIOCGIFHWADDR, (void *)&ifr) < 0) { - perror("ioctl:mac"); - close(fd); - return -1; - } - memcpy(g_intf[intf].mac_addr, ifr.ifr_addr.sa_data, 6); - g_intf[intf].fd = fd; - - return 0; +static int tunnel_alloc(int intf) { + int fd; + char *dev = g_intf[intf].name; + + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + return -1; + } + + // open the tap interface + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) { + perror("tunsetiff"); + close(fd); + return -1; + } + + // set connection to be non-blocking + int sock_flags = fcntl(fd, F_GETFL, 0); + if (fcntl(fd, F_SETFL, sock_flags | O_NONBLOCK) < 0) { + perror("f_setfl"); + close(fd); + return -1; + } + + // fetch the mac address + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + if (ioctl(fd, SIOCGIFHWADDR, (void *)&ifr) < 0) { + perror("ioctl:mac"); + close(fd); + return -1; + } + memcpy(g_intf[intf].mac_addr, ifr.ifr_addr.sa_data, 6); + g_intf[intf].fd = fd; + + return 0; } -static void -packet_driver_init() { - int i, ret; +static void packet_driver_init() { + int i, ret; - switchlink_db_port_obj_t *port_map; - uint16_t num_ports; - switchlink_db_port_get_all_ports(&num_ports, &port_map); - g_intf = switchlink_malloc(sizeof(switchlink_packet_intf_t), num_ports); + switchlink_db_port_obj_t *port_map; + uint16_t num_ports; + switchlink_db_port_get_all_ports(&num_ports, &port_map); + g_intf = switchlink_malloc(sizeof(switchlink_packet_intf_t), num_ports); - // initialize switch ports - for (i = 0; i < num_ports; i++) { - if (strncmp(port_map[i].name, SWITCHLINK_CPU_INTERFACE_NAME, - SWITCHLINK_INTERFACE_NAME_LEN_MAX) == 0) { - continue; - } - strncpy(g_intf[g_num_intfs].name, port_map[i].name, - SWITCHLINK_INTERFACE_NAME_LEN_MAX); - g_intf[g_num_intfs].port_id = port_map[i].port_id; - ret = tunnel_alloc(g_num_intfs); - assert(ret == 0); - g_num_intfs++; + // initialize switch ports + for (i = 0; i < num_ports; i++) { + if (strncmp(port_map[i].name, + SWITCHLINK_CPU_INTERFACE_NAME, + SWITCHLINK_INTERFACE_NAME_LEN_MAX) == 0) { + continue; } - switchlink_free(port_map); + strncpy(g_intf[g_num_intfs].name, + port_map[i].name, + SWITCHLINK_INTERFACE_NAME_LEN_MAX); + g_intf[g_num_intfs].port_id = port_map[i].port_id; + ret = tunnel_alloc(g_num_intfs); + assert(ret == 0); + g_num_intfs++; + } + switchlink_free(port_map); } -static void * -switchlink_packet_driver_main(void *args) { - int i; +static void *switchlink_packet_driver_main(void *args) { + int i; - packet_driver_init(); + packet_driver_init(); - while (true) { - int ret, nfds = -1; - fd_set read_fds; - FD_ZERO(&read_fds); - for (i = 0; i < g_num_intfs; i++) { - FD_SET(g_intf[i].fd, &read_fds); - nfds = (g_intf[i].fd > nfds) ? g_intf[i].fd : nfds; - } - nfds++; - - ret = select(nfds, &read_fds, NULL, NULL, NULL); - if (ret == -1) { - perror("select"); - break; - } else if (ret == 0) { - } else { - for (i = 0; i < g_num_intfs; i++) { - if (FD_ISSET(g_intf[i].fd, &read_fds)) { - process_packet_from_user(i); - } - } + while (true) { + int ret, nfds = -1; + fd_set read_fds; + FD_ZERO(&read_fds); + for (i = 0; i < g_num_intfs; i++) { + FD_SET(g_intf[i].fd, &read_fds); + nfds = (g_intf[i].fd > nfds) ? g_intf[i].fd : nfds; + } + nfds++; + + ret = select(nfds, &read_fds, NULL, NULL, NULL); + if (ret == -1) { + perror("select"); + break; + } else if (ret == 0) { + } else { + for (i = 0; i < g_num_intfs; i++) { + if (FD_ISSET(g_intf[i].fd, &read_fds)) { + process_packet_from_user(i); } + } } - return NULL; + } + return NULL; } -void -switchlink_packet_driver_update_mac(char *link_name, uint8_t *lladdr) { - int i; - for (i = 0; i < g_num_intfs; i++) { - if (strncmp(g_intf[i].name, link_name, - SWITCHLINK_INTERFACE_NAME_LEN_MAX) == 0) { - memcpy(g_intf[i].mac_addr, lladdr, 6); - } +void switchlink_packet_driver_update_mac(char *link_name, uint8_t *lladdr) { + int i; + for (i = 0; i < g_num_intfs; i++) { + if (strncmp(g_intf[i].name, link_name, SWITCHLINK_INTERFACE_NAME_LEN_MAX) == + 0) { + memcpy(g_intf[i].mac_addr, lladdr, 6); } + } } -void -switchlink_packet_from_hardware(const void *buf, uint32_t buf_size, - uint16_t port_id) { - int i; - for (i = 0; i < g_num_intfs; i++) { - if (g_intf[i].port_id == port_id) { - if (write(g_intf[i].fd, buf, buf_size) < 0) { - NL_LOG_ERROR(("Rx: Sending %d bytes to %s failed\n", - buf_size, g_intf[i].name)); - } - break; - } +void switchlink_packet_from_hardware(const void *buf, + uint32_t buf_size, + uint16_t port_id) { + int i; + for (i = 0; i < g_num_intfs; i++) { + if (g_intf[i].port_id == port_id) { + if (write(g_intf[i].fd, buf, buf_size) < 0) { + NL_LOG_ERROR( + ("Rx: Sending %d bytes to %s failed\n", buf_size, g_intf[i].name)); + } + break; } + } } -int -switchlink_packet_driver_init() { - return pthread_create(&switchlink_packet_driver_thread, NULL, - switchlink_packet_driver_main, NULL); +int switchlink_packet_driver_init() { + return pthread_create(&switchlink_packet_driver_thread, + NULL, + switchlink_packet_driver_main, + NULL); } diff --git a/switchlink/src/switchlink_packet.h b/switchlink/src/switchlink_packet.h index 0f176c2..c7733d3 100644 --- a/switchlink/src/switchlink_packet.h +++ b/switchlink/src/switchlink_packet.h @@ -17,8 +17,8 @@ limitations under the License. #ifndef __SWITCHLINK_PACKET_H__ #define __SWITCHLINK_PACKET_H__ -extern void -switchlink_packet_from_hardware(const void *buf, uint32_t buf_size, - uint16_t port_id); +extern void switchlink_packet_from_hardware(const void *buf, + uint32_t buf_size, + uint16_t port_id); #endif /* __SWITCH_PACKET_H__ */ diff --git a/switchlink/src/switchlink_route.c b/switchlink/src/switchlink_route.c index 7477b6f..9560796 100644 --- a/switchlink/src/switchlink_route.c +++ b/switchlink/src/switchlink_route.c @@ -26,469 +26,476 @@ limitations under the License. #include "switchlink_db.h" #include "switchlink_sai.h" -static void -ecmp_delete(switchlink_handle_t ecmp_h) { - int32_t ref_count; - switchlink_db_status_t status; - status = switchlink_db_ecmp_ref_dec(ecmp_h, &ref_count); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - - if (ref_count == 0) { - switchlink_db_ecmp_info_t ecmp_info; - memset(&ecmp_info, 0, sizeof(switchlink_db_ecmp_info_t)); - status = switchlink_db_ecmp_handle_get_info(ecmp_h, &ecmp_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - switchlink_ecmp_delete(&ecmp_info); - switchlink_db_ecmp_delete(ecmp_h); - } -} +static void ecmp_delete(switchlink_handle_t ecmp_h) { + int32_t ref_count; + switchlink_db_status_t status; + status = switchlink_db_ecmp_ref_dec(ecmp_h, &ref_count); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); -static void -oifl_delete(switchlink_handle_t oifl_h) { - int32_t ref_count; - switchlink_db_status_t status; - status = switchlink_db_oifl_ref_dec(oifl_h, &ref_count); + if (ref_count == 0) { + switchlink_db_ecmp_info_t ecmp_info; + memset(&ecmp_info, 0, sizeof(switchlink_db_ecmp_info_t)); + status = switchlink_db_ecmp_handle_get_info(ecmp_h, &ecmp_info); assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - - if (ref_count == 0) { - switchlink_db_oifl_info_t oifl_info; - memset(&oifl_info, 0, sizeof(switchlink_db_oifl_info_t)); - status = switchlink_db_oifl_handle_get_info(oifl_h, &oifl_info); - assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - switchlink_db_oifl_delete(oifl_h); - } + switchlink_ecmp_delete(&ecmp_info); + switchlink_db_ecmp_delete(ecmp_h); + } } -void -route_create(switchlink_handle_t vrf_h, switchlink_ip_addr_t *dst, - switchlink_ip_addr_t *gateway, switchlink_handle_t ecmp_h, - switchlink_handle_t intf_h) { - if (!dst || (!gateway && !ecmp_h)) { - if (ecmp_h) { - ecmp_delete(ecmp_h); - } - return; - } - - bool ecmp_valid = false; - switchlink_handle_t nhop_h = 0; - if (!ecmp_h) { - switchlink_db_neigh_info_t neigh_info; - memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); - memcpy(&(neigh_info.ip_addr), gateway, sizeof(switchlink_ip_addr_t)); - neigh_info.intf_h = intf_h; - neigh_info.vrf_h = vrf_h; - switchlink_db_status_t status; - status = switchlink_db_neighbor_get_info(&neigh_info); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - nhop_h = neigh_info.nhop_h; - } else { - nhop_h = g_cpu_rx_nhop_h; - } - ecmp_valid = false; - } else { - ecmp_valid = true; - nhop_h = ecmp_h; - } - - // get the route from the db (if it already exists) - switchlink_db_route_info_t route_info; - memset(&route_info, 0, sizeof(switchlink_db_route_info_t)); - route_info.vrf_h = vrf_h; - memcpy(&(route_info.ip_addr), dst, sizeof(switchlink_ip_addr_t)); - switchlink_db_status_t status = switchlink_db_route_get_info(&route_info); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - if ((route_info.ecmp == ecmp_valid) && (route_info.nhop_h == nhop_h)) { - // no change - return; - } - // nexthop has change, delete the current route - route_delete(vrf_h, dst); - } - - memset(&route_info, 0, sizeof(switchlink_db_route_info_t)); - route_info.vrf_h = vrf_h; - memcpy(&(route_info.ip_addr), dst, sizeof(switchlink_ip_addr_t)); - route_info.ecmp = ecmp_valid; - route_info.nhop_h = nhop_h; - - // add the route - if (switchlink_route_create(&route_info) == -1) { - if (route_info.ecmp) { - ecmp_delete(route_info.nhop_h); - } - return; - } +static void oifl_delete(switchlink_handle_t oifl_h) { + int32_t ref_count; + switchlink_db_status_t status; + status = switchlink_db_oifl_ref_dec(oifl_h, &ref_count); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); - // add the route to the db - if (switchlink_db_route_add(&route_info) == SWITCHLINK_DB_STATUS_SUCCESS) { - if (route_info.ecmp) { - switchlink_db_ecmp_ref_inc(route_info.nhop_h); - } - } + if (ref_count == 0) { + switchlink_db_oifl_info_t oifl_info; + memset(&oifl_info, 0, sizeof(switchlink_db_oifl_info_t)); + status = switchlink_db_oifl_handle_get_info(oifl_h, &oifl_info); + assert(status == SWITCHLINK_DB_STATUS_SUCCESS); + switchlink_db_oifl_delete(oifl_h); + } } -void -route_delete(switchlink_handle_t vrf_h, switchlink_ip_addr_t *dst) { - if (!dst) { - return; +void route_create(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *dst, + switchlink_ip_addr_t *gateway, + switchlink_handle_t ecmp_h, + switchlink_handle_t intf_h) { + if (!dst || (!gateway && !ecmp_h)) { + if (ecmp_h) { + ecmp_delete(ecmp_h); } - + return; + } + + bool ecmp_valid = false; + switchlink_handle_t nhop_h = 0; + if (!ecmp_h) { + switchlink_db_neigh_info_t neigh_info; + memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); + memcpy(&(neigh_info.ip_addr), gateway, sizeof(switchlink_ip_addr_t)); + neigh_info.intf_h = intf_h; + neigh_info.vrf_h = vrf_h; switchlink_db_status_t status; - switchlink_db_route_info_t route_info; - memset(&route_info, 0, sizeof(switchlink_db_route_info_t)); - route_info.vrf_h = vrf_h; - memcpy(&(route_info.ip_addr), dst, sizeof(switchlink_ip_addr_t)); - status = switchlink_db_route_get_info(&route_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; - } - - if (switchlink_route_delete(&route_info) == -1) { - return; - } - - status = switchlink_db_route_delete(&route_info); + status = switchlink_db_neighbor_get_info(&neigh_info); if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - if (route_info.ecmp) { - ecmp_delete(route_info.nhop_h); - } + nhop_h = neigh_info.nhop_h; + } else { + nhop_h = g_cpu_rx_nhop_h; } -} - -void -mroute_delete(switchlink_handle_t vrf_h, - switchlink_ip_addr_t *src, switchlink_ip_addr_t *dst) { - if (!src || !dst) { - return; + ecmp_valid = false; + } else { + ecmp_valid = true; + nhop_h = ecmp_h; + } + + // get the route from the db (if it already exists) + switchlink_db_route_info_t route_info; + memset(&route_info, 0, sizeof(switchlink_db_route_info_t)); + route_info.vrf_h = vrf_h; + memcpy(&(route_info.ip_addr), dst, sizeof(switchlink_ip_addr_t)); + switchlink_db_status_t status = switchlink_db_route_get_info(&route_info); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + if ((route_info.ecmp == ecmp_valid) && (route_info.nhop_h == nhop_h)) { + // no change + return; } - - switchlink_db_status_t status; - switchlink_db_mroute_info_t mroute_info; - memset(&mroute_info, 0, sizeof(switchlink_db_mroute_info_t)); - mroute_info.vrf_h = vrf_h; - memcpy(&(mroute_info.src_ip), src, sizeof(switchlink_ip_addr_t)); - memcpy(&(mroute_info.dst_ip), dst, sizeof(switchlink_ip_addr_t)); - status = switchlink_db_mroute_get_info(&mroute_info); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - return; + // nexthop has change, delete the current route + route_delete(vrf_h, dst); + } + + memset(&route_info, 0, sizeof(switchlink_db_route_info_t)); + route_info.vrf_h = vrf_h; + memcpy(&(route_info.ip_addr), dst, sizeof(switchlink_ip_addr_t)); + route_info.ecmp = ecmp_valid; + route_info.nhop_h = nhop_h; + + // add the route + if (switchlink_route_create(&route_info) == -1) { + if (route_info.ecmp) { + ecmp_delete(route_info.nhop_h); } + return; + } - if (switchlink_mroute_delete(&mroute_info) == -1) { - return; - } - - status = switchlink_db_mroute_delete(&mroute_info); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - oifl_delete(mroute_info.oifl_h); + // add the route to the db + if (switchlink_db_route_add(&route_info) == SWITCHLINK_DB_STATUS_SUCCESS) { + if (route_info.ecmp) { + switchlink_db_ecmp_ref_inc(route_info.nhop_h); } + } } -void -mroute_create(switchlink_handle_t vrf_h, switchlink_ip_addr_t *src, - switchlink_ip_addr_t *dst, switchlink_handle_t iif_h, - switchlink_handle_t oifl_h) { - if (!src || !dst) { - return; - } - - // get the multicast route from the db (if it already exists) - switchlink_db_mroute_info_t mroute_info; - memset(&mroute_info, 0, sizeof(switchlink_db_mroute_info_t)); - mroute_info.vrf_h = vrf_h; - memcpy(&(mroute_info.src_ip), src, sizeof(switchlink_ip_addr_t)); - memcpy(&(mroute_info.dst_ip), dst, sizeof(switchlink_ip_addr_t)); - switchlink_db_status_t status = switchlink_db_mroute_get_info(&mroute_info); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - if ((mroute_info.iif_h == iif_h) && (mroute_info.oifl_h == oifl_h)) { - // no change - return; - } - // mutlticast route has changed, delete the current route - mroute_delete(vrf_h, src, dst); - } - - memset(&mroute_info, 0, sizeof(switchlink_db_mroute_info_t)); - mroute_info.vrf_h = vrf_h; - memcpy(&(mroute_info.src_ip), src, sizeof(switchlink_ip_addr_t)); - memcpy(&(mroute_info.dst_ip), dst, sizeof(switchlink_ip_addr_t)); - mroute_info.iif_h = iif_h; - mroute_info.oifl_h = oifl_h; - - // add the multicast route - if (switchlink_mroute_create(&mroute_info) == -1) { - oifl_delete(mroute_info.oifl_h); - return; - } - - // add the multicast route to the db - if (switchlink_db_mroute_add(&mroute_info) == - SWITCHLINK_DB_STATUS_SUCCESS) { - switchlink_db_oifl_ref_inc(mroute_info.oifl_h); +void route_delete(switchlink_handle_t vrf_h, switchlink_ip_addr_t *dst) { + if (!dst) { + return; + } + + switchlink_db_status_t status; + switchlink_db_route_info_t route_info; + memset(&route_info, 0, sizeof(switchlink_db_route_info_t)); + route_info.vrf_h = vrf_h; + memcpy(&(route_info.ip_addr), dst, sizeof(switchlink_ip_addr_t)); + status = switchlink_db_route_get_info(&route_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } + + if (switchlink_route_delete(&route_info) == -1) { + return; + } + + status = switchlink_db_route_delete(&route_info); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + if (route_info.ecmp) { + ecmp_delete(route_info.nhop_h); } + } } -static switchlink_handle_t -process_ecmp(uint8_t family, struct nlattr *attr, switchlink_handle_t vrf_h) { - switchlink_db_status_t status; +void mroute_delete(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *src, + switchlink_ip_addr_t *dst) { + if (!src || !dst) { + return; + } + + switchlink_db_status_t status; + switchlink_db_mroute_info_t mroute_info; + memset(&mroute_info, 0, sizeof(switchlink_db_mroute_info_t)); + mroute_info.vrf_h = vrf_h; + memcpy(&(mroute_info.src_ip), src, sizeof(switchlink_ip_addr_t)); + memcpy(&(mroute_info.dst_ip), dst, sizeof(switchlink_ip_addr_t)); + status = switchlink_db_mroute_get_info(&mroute_info); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + return; + } + + if (switchlink_mroute_delete(&mroute_info) == -1) { + return; + } + + status = switchlink_db_mroute_delete(&mroute_info); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + oifl_delete(mroute_info.oifl_h); + } +} - if ((family != AF_INET) && (family != AF_INET6)) { - return 0; +void mroute_create(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *src, + switchlink_ip_addr_t *dst, + switchlink_handle_t iif_h, + switchlink_handle_t oifl_h) { + if (!src || !dst) { + return; + } + + // get the multicast route from the db (if it already exists) + switchlink_db_mroute_info_t mroute_info; + memset(&mroute_info, 0, sizeof(switchlink_db_mroute_info_t)); + mroute_info.vrf_h = vrf_h; + memcpy(&(mroute_info.src_ip), src, sizeof(switchlink_ip_addr_t)); + memcpy(&(mroute_info.dst_ip), dst, sizeof(switchlink_ip_addr_t)); + switchlink_db_status_t status = switchlink_db_mroute_get_info(&mroute_info); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + if ((mroute_info.iif_h == iif_h) && (mroute_info.oifl_h == oifl_h)) { + // no change + return; } + // mutlticast route has changed, delete the current route + mroute_delete(vrf_h, src, dst); + } + + memset(&mroute_info, 0, sizeof(switchlink_db_mroute_info_t)); + mroute_info.vrf_h = vrf_h; + memcpy(&(mroute_info.src_ip), src, sizeof(switchlink_ip_addr_t)); + memcpy(&(mroute_info.dst_ip), dst, sizeof(switchlink_ip_addr_t)); + mroute_info.iif_h = iif_h; + mroute_info.oifl_h = oifl_h; + + // add the multicast route + if (switchlink_mroute_create(&mroute_info) == -1) { + oifl_delete(mroute_info.oifl_h); + return; + } + + // add the multicast route to the db + if (switchlink_db_mroute_add(&mroute_info) == SWITCHLINK_DB_STATUS_SUCCESS) { + switchlink_db_oifl_ref_inc(mroute_info.oifl_h); + } +} - switchlink_db_ecmp_info_t ecmp_info; - memset(&ecmp_info, 0, sizeof(switchlink_db_ecmp_info_t)); - - struct rtnexthop *rnh = (struct rtnexthop *)nla_data(attr); - int attrlen = nla_len(attr); - while (RTNH_OK(rnh, attrlen)) { - struct rtattr *rta = RTNH_DATA(rnh); - if (rta->rta_type == RTA_GATEWAY) { - switchlink_ip_addr_t gateway; - memset(&gateway, 0, sizeof(switchlink_ip_addr_t)); - gateway.family = family; - if (family == AF_INET) { - gateway.ip.v4addr.s_addr = ntohl(*((uint32_t *)RTA_DATA(rta))); - gateway.prefix_len = 32; - } else { - gateway.prefix_len = 128; - } - - switchlink_db_interface_info_t ifinfo; - memset(&ifinfo, 0, sizeof(switchlink_db_interface_info_t)); - status = switchlink_db_interface_get_info(rnh->rtnh_ifindex, - &ifinfo); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - switchlink_db_neigh_info_t neigh_info; - memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); - memcpy(&(neigh_info.ip_addr), &gateway, - sizeof(switchlink_ip_addr_t)); - neigh_info.intf_h = ifinfo.intf_h; - neigh_info.vrf_h = vrf_h; - status = switchlink_db_neighbor_get_info(&neigh_info); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - ecmp_info.nhops[ecmp_info.num_nhops] = neigh_info.nhop_h; - } else { - ecmp_info.nhops[ecmp_info.num_nhops] = g_cpu_rx_nhop_h; - } - ecmp_info.num_nhops++; - assert(ecmp_info.num_nhops < SWITCHLINK_ECMP_NUM_MEMBERS_MAX); - } +static switchlink_handle_t process_ecmp(uint8_t family, + struct nlattr *attr, + switchlink_handle_t vrf_h) { + switchlink_db_status_t status; + + if ((family != AF_INET) && (family != AF_INET6)) { + return 0; + } + + switchlink_db_ecmp_info_t ecmp_info; + memset(&ecmp_info, 0, sizeof(switchlink_db_ecmp_info_t)); + + struct rtnexthop *rnh = (struct rtnexthop *)nla_data(attr); + int attrlen = nla_len(attr); + while (RTNH_OK(rnh, attrlen)) { + struct rtattr *rta = RTNH_DATA(rnh); + if (rta->rta_type == RTA_GATEWAY) { + switchlink_ip_addr_t gateway; + memset(&gateway, 0, sizeof(switchlink_ip_addr_t)); + gateway.family = family; + if (family == AF_INET) { + gateway.ip.v4addr.s_addr = ntohl(*((uint32_t *)RTA_DATA(rta))); + gateway.prefix_len = 32; + } else { + gateway.prefix_len = 128; + } + + switchlink_db_interface_info_t ifinfo; + memset(&ifinfo, 0, sizeof(switchlink_db_interface_info_t)); + status = switchlink_db_interface_get_info(rnh->rtnh_ifindex, &ifinfo); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + switchlink_db_neigh_info_t neigh_info; + memset(&neigh_info, 0, sizeof(switchlink_db_neigh_info_t)); + memcpy(&(neigh_info.ip_addr), &gateway, sizeof(switchlink_ip_addr_t)); + neigh_info.intf_h = ifinfo.intf_h; + neigh_info.vrf_h = vrf_h; + status = switchlink_db_neighbor_get_info(&neigh_info); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + ecmp_info.nhops[ecmp_info.num_nhops] = neigh_info.nhop_h; + } else { + ecmp_info.nhops[ecmp_info.num_nhops] = g_cpu_rx_nhop_h; } - rnh = RTNH_NEXT(rnh); + ecmp_info.num_nhops++; + assert(ecmp_info.num_nhops < SWITCHLINK_ECMP_NUM_MEMBERS_MAX); + } } + rnh = RTNH_NEXT(rnh); + } - if (!ecmp_info.num_nhops) { - return 0; - } + if (!ecmp_info.num_nhops) { + return 0; + } - status = switchlink_db_ecmp_get_info(&ecmp_info); - if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { - switchlink_ecmp_create(&ecmp_info); - switchlink_db_ecmp_add(&ecmp_info); - } + status = switchlink_db_ecmp_get_info(&ecmp_info); + if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { + switchlink_ecmp_create(&ecmp_info); + switchlink_db_ecmp_add(&ecmp_info); + } - return ecmp_info.ecmp_h; + return ecmp_info.ecmp_h; } -static switchlink_handle_t -process_oif_list(struct nlattr *attr, switchlink_handle_t vrf_h) { - switchlink_db_status_t status; +static switchlink_handle_t process_oif_list(struct nlattr *attr, + switchlink_handle_t vrf_h) { + switchlink_db_status_t status; - switchlink_db_oifl_info_t oifl_info; - memset(&oifl_info, 0, sizeof(switchlink_db_oifl_info_t)); + switchlink_db_oifl_info_t oifl_info; + memset(&oifl_info, 0, sizeof(switchlink_db_oifl_info_t)); - struct rtnexthop *rnh = (struct rtnexthop *)nla_data(attr); - int attrlen = nla_len(attr); - while (RTNH_OK(rnh, attrlen)) { - switchlink_db_interface_info_t ifinfo; - memset(&ifinfo, 0, sizeof(switchlink_db_interface_info_t)); - status = switchlink_db_interface_get_info(rnh->rtnh_ifindex, &ifinfo); - if (status == SWITCHLINK_DB_STATUS_SUCCESS) { - oifl_info.intfs[oifl_info.num_intfs++] = ifinfo.intf_h; - } - rnh = RTNH_NEXT(rnh); + struct rtnexthop *rnh = (struct rtnexthop *)nla_data(attr); + int attrlen = nla_len(attr); + while (RTNH_OK(rnh, attrlen)) { + switchlink_db_interface_info_t ifinfo; + memset(&ifinfo, 0, sizeof(switchlink_db_interface_info_t)); + status = switchlink_db_interface_get_info(rnh->rtnh_ifindex, &ifinfo); + if (status == SWITCHLINK_DB_STATUS_SUCCESS) { + oifl_info.intfs[oifl_info.num_intfs++] = ifinfo.intf_h; } + rnh = RTNH_NEXT(rnh); + } - if (!oifl_info.num_intfs) { - return 0; - } + if (!oifl_info.num_intfs) { + return 0; + } - status = switchlink_db_oifl_get_info(&oifl_info); - if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { - switchlink_db_oifl_add(&oifl_info); - } + status = switchlink_db_oifl_get_info(&oifl_info); + if (status == SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND) { + switchlink_db_oifl_add(&oifl_info); + } - return oifl_info.oifl_h; + return oifl_info.oifl_h; } -void -process_route_msg(struct nlmsghdr *nlmsg, int type) { - int hdrlen, attrlen; - struct nlattr *attr; - struct rtmsg *rmsg; - bool src_valid = false; - bool dst_valid = false; - bool gateway_valid = false; - switchlink_handle_t ecmp_h = 0; - switchlink_ip_addr_t src_addr; - switchlink_ip_addr_t dst_addr; - switchlink_ip_addr_t gateway_addr; - switchlink_db_interface_info_t ifinfo; - uint8_t af = AF_UNSPEC; - bool oif_valid = false; - uint32_t oif = 0; - - switchlink_handle_t oifl_h = 0; - bool ip_multicast = false; - bool iif_valid = false; - uint32_t iif = 0; - - assert((type == RTM_NEWROUTE) || (type == RTM_DELROUTE)); - rmsg = nlmsg_data(nlmsg); - hdrlen = sizeof(struct rtmsg); - NL_LOG_DEBUG(("%sroute: family = %d, dst_len = %d, src_len = %d, tos = %d, " - "table = %d, proto = %d, scope = %d, type = %d, " - "flags = 0x%x\n", - ((type == RTM_NEWROUTE) ? "new" : "del"), - rmsg->rtm_family, rmsg->rtm_dst_len, rmsg->rtm_src_len, - rmsg->rtm_tos, rmsg->rtm_table, rmsg->rtm_protocol, - rmsg->rtm_scope, rmsg->rtm_type, rmsg->rtm_flags)); - - if (rmsg->rtm_family > AF_MAX) { - assert(rmsg->rtm_type == RTN_MULTICAST); - if (rmsg->rtm_family == RTNL_FAMILY_IPMR) { - af = AF_INET; - } else if (rmsg->rtm_family == RTNL_FAMILY_IP6MR) { - af = AF_INET6; - } - ip_multicast = true; - } else { - af = rmsg->rtm_family; - } - - if ((af != AF_INET) && (af != AF_INET6)) { - return; +void process_route_msg(struct nlmsghdr *nlmsg, int type) { + int hdrlen, attrlen; + struct nlattr *attr; + struct rtmsg *rmsg; + bool src_valid = false; + bool dst_valid = false; + bool gateway_valid = false; + switchlink_handle_t ecmp_h = 0; + switchlink_ip_addr_t src_addr; + switchlink_ip_addr_t dst_addr; + switchlink_ip_addr_t gateway_addr; + switchlink_db_interface_info_t ifinfo; + uint8_t af = AF_UNSPEC; + bool oif_valid = false; + uint32_t oif = 0; + + switchlink_handle_t oifl_h = 0; + bool ip_multicast = false; + bool iif_valid = false; + uint32_t iif = 0; + + assert((type == RTM_NEWROUTE) || (type == RTM_DELROUTE)); + rmsg = nlmsg_data(nlmsg); + hdrlen = sizeof(struct rtmsg); + NL_LOG_DEBUG( + ("%sroute: family = %d, dst_len = %d, src_len = %d, tos = %d, " + "table = %d, proto = %d, scope = %d, type = %d, " + "flags = 0x%x\n", + ((type == RTM_NEWROUTE) ? "new" : "del"), + rmsg->rtm_family, + rmsg->rtm_dst_len, + rmsg->rtm_src_len, + rmsg->rtm_tos, + rmsg->rtm_table, + rmsg->rtm_protocol, + rmsg->rtm_scope, + rmsg->rtm_type, + rmsg->rtm_flags)); + + if (rmsg->rtm_family > AF_MAX) { + assert(rmsg->rtm_type == RTN_MULTICAST); + if (rmsg->rtm_family == RTNL_FAMILY_IPMR) { + af = AF_INET; + } else if (rmsg->rtm_family == RTNL_FAMILY_IP6MR) { + af = AF_INET6; } - - memset(&dst_addr, 0, sizeof(switchlink_ip_addr_t)); - memset(&gateway_addr, 0, sizeof(switchlink_ip_addr_t)); - - attrlen = nlmsg_attrlen(nlmsg, hdrlen); - attr = nlmsg_attrdata(nlmsg, hdrlen); - while (nla_ok(attr, attrlen)) { - int attr_type = nla_type(attr); - switch (attr_type) { - case RTA_SRC: - src_valid = true; - memset(&src_addr, 0, sizeof(switchlink_ip_addr_t)); - src_addr.family = af; - src_addr.prefix_len = rmsg->rtm_src_len; - if (src_addr.family == AF_INET) { - src_addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); - } else { - memcpy(&(src_addr.ip.v6addr), nla_data(attr), - nla_len(attr)); - } - break; - case RTA_DST: - dst_valid = true; - memset(&dst_addr, 0, sizeof(switchlink_ip_addr_t)); - dst_addr.family = af; - dst_addr.prefix_len = rmsg->rtm_dst_len; - if (dst_addr.family == AF_INET) { - dst_addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); - } else { - memcpy(&(dst_addr.ip.v6addr), nla_data(attr), - nla_len(attr)); - } - break; - case RTA_GATEWAY: - gateway_valid = true; - memset(&gateway_addr, 0, sizeof(switchlink_ip_addr_t)); - gateway_addr.family = rmsg->rtm_family; - if (rmsg->rtm_family == AF_INET) { - gateway_addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); - gateway_addr.prefix_len = 32; - } else { - memcpy(&(gateway_addr.ip.v6addr), nla_data(attr), - nla_len(attr)); - gateway_addr.prefix_len = 128; - } - break; - case RTA_MULTIPATH: - if (ip_multicast) { - oifl_h = process_oif_list(attr, g_default_vrf_h); - } else { - ecmp_h = process_ecmp(af, attr, g_default_vrf_h); - } - break; - case RTA_OIF: - oif_valid = true; - oif = nla_get_u32(attr); - break; - case RTA_IIF: - iif_valid = true; - iif = nla_get_u32(attr); - break; - default: - NL_LOG_DEBUG(("route: skipping attr(%d)\n", attr_type)); - break; + ip_multicast = true; + } else { + af = rmsg->rtm_family; + } + + if ((af != AF_INET) && (af != AF_INET6)) { + return; + } + + memset(&dst_addr, 0, sizeof(switchlink_ip_addr_t)); + memset(&gateway_addr, 0, sizeof(switchlink_ip_addr_t)); + + attrlen = nlmsg_attrlen(nlmsg, hdrlen); + attr = nlmsg_attrdata(nlmsg, hdrlen); + while (nla_ok(attr, attrlen)) { + int attr_type = nla_type(attr); + switch (attr_type) { + case RTA_SRC: + src_valid = true; + memset(&src_addr, 0, sizeof(switchlink_ip_addr_t)); + src_addr.family = af; + src_addr.prefix_len = rmsg->rtm_src_len; + if (src_addr.family == AF_INET) { + src_addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); + } else { + memcpy(&(src_addr.ip.v6addr), nla_data(attr), nla_len(attr)); } - attr = nla_next(attr, &attrlen); - } - - if (rmsg->rtm_dst_len == 0) { + break; + case RTA_DST: dst_valid = true; memset(&dst_addr, 0, sizeof(switchlink_ip_addr_t)); dst_addr.family = af; - dst_addr.prefix_len = 0; - } - - if (!ip_multicast) { - if (type == RTM_NEWROUTE) { - 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), - ecmp_h, ifinfo.intf_h); + dst_addr.prefix_len = rmsg->rtm_dst_len; + if (dst_addr.family == AF_INET) { + dst_addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); } else { - route_delete(g_default_vrf_h, (dst_valid ? &dst_addr : NULL)); + memcpy(&(dst_addr.ip.v6addr), nla_data(attr), nla_len(attr)); } - } else { - if (rmsg->rtm_src_len == 0) { - src_valid = true; - memset(&src_addr, 0, sizeof(switchlink_ip_addr_t)); - src_addr.family = af; - src_addr.prefix_len = 0; + break; + case RTA_GATEWAY: + gateway_valid = true; + memset(&gateway_addr, 0, sizeof(switchlink_ip_addr_t)); + gateway_addr.family = rmsg->rtm_family; + if (rmsg->rtm_family == AF_INET) { + gateway_addr.ip.v4addr.s_addr = ntohl(nla_get_u32(attr)); + gateway_addr.prefix_len = 32; + } else { + memcpy(&(gateway_addr.ip.v6addr), nla_data(attr), nla_len(attr)); + gateway_addr.prefix_len = 128; } - - if (type == RTM_NEWROUTE) { - if (!iif_valid || !oifl_h) { - // multicast route cache is not resolved yet - return; - } - switchlink_db_status_t status; - status = switchlink_db_interface_get_info(iif, &ifinfo); - if (status != SWITCHLINK_DB_STATUS_SUCCESS) { - NL_LOG_DEBUG(("route: switchlink_db_interface_get_info " - "(multicast) failed\n")); - return; - } - mroute_create(g_default_vrf_h, (src_valid ? &src_addr : NULL), - (dst_valid ? &dst_addr : NULL), - ifinfo.intf_h, oifl_h); + break; + case RTA_MULTIPATH: + if (ip_multicast) { + oifl_h = process_oif_list(attr, g_default_vrf_h); } else { - mroute_delete(g_default_vrf_h, (src_valid ? &src_addr : NULL), - (dst_valid ? &dst_addr : NULL)); + ecmp_h = process_ecmp(af, attr, g_default_vrf_h); + } + break; + case RTA_OIF: + oif_valid = true; + oif = nla_get_u32(attr); + break; + case RTA_IIF: + iif_valid = true; + iif = nla_get_u32(attr); + break; + default: + NL_LOG_DEBUG(("route: skipping attr(%d)\n", attr_type)); + break; + } + attr = nla_next(attr, &attrlen); + } + + if (rmsg->rtm_dst_len == 0) { + dst_valid = true; + memset(&dst_addr, 0, sizeof(switchlink_ip_addr_t)); + dst_addr.family = af; + dst_addr.prefix_len = 0; + } + + if (!ip_multicast) { + if (type == RTM_NEWROUTE) { + 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), + ecmp_h, + ifinfo.intf_h); + } else { + route_delete(g_default_vrf_h, (dst_valid ? &dst_addr : NULL)); + } + } else { + if (rmsg->rtm_src_len == 0) { + src_valid = true; + memset(&src_addr, 0, sizeof(switchlink_ip_addr_t)); + src_addr.family = af; + src_addr.prefix_len = 0; + } + + if (type == RTM_NEWROUTE) { + if (!iif_valid || !oifl_h) { + // multicast route cache is not resolved yet + return; + } + switchlink_db_status_t status; + status = switchlink_db_interface_get_info(iif, &ifinfo); + if (status != SWITCHLINK_DB_STATUS_SUCCESS) { + NL_LOG_DEBUG( + ("route: switchlink_db_interface_get_info " + "(multicast) failed\n")); + return; + } + mroute_create(g_default_vrf_h, + (src_valid ? &src_addr : NULL), + (dst_valid ? &dst_addr : NULL), + ifinfo.intf_h, + oifl_h); + } else { + mroute_delete(g_default_vrf_h, + (src_valid ? &src_addr : NULL), + (dst_valid ? &dst_addr : NULL)); } + } } diff --git a/switchlink/src/switchlink_route.h b/switchlink/src/switchlink_route.h index c49587b..0e7898f 100644 --- a/switchlink/src/switchlink_route.h +++ b/switchlink/src/switchlink_route.h @@ -17,12 +17,12 @@ limitations under the License. #ifndef __SWITCHLINK_ROUTE_H__ #define __SWITCHLINK_ROUTE_H__ -extern void -route_create(switchlink_handle_t vrf_h, switchlink_ip_addr_t *dst, - switchlink_ip_addr_t *gateway, switchlink_handle_t ecmp_h, - switchlink_handle_t intf_h); +extern void route_create(switchlink_handle_t vrf_h, + switchlink_ip_addr_t *dst, + switchlink_ip_addr_t *gateway, + switchlink_handle_t ecmp_h, + switchlink_handle_t intf_h); -extern void -route_delete(switchlink_handle_t vrf_h, switchlink_ip_addr_t *dst); +extern void route_delete(switchlink_handle_t vrf_h, switchlink_ip_addr_t *dst); #endif /* __SWITCHLINK_ROUTE_H__ */ diff --git a/switchlink/src/switchlink_sai.c b/switchlink/src/switchlink_sai.c index b182a76..6038d50 100644 --- a/switchlink/src/switchlink_sai.c +++ b/switchlink/src/switchlink_sai.c @@ -33,955 +33,923 @@ extern sai_status_t sai_create_hostif_trap(sai_hostif_trap_id_t hostif_trapid, uint32_t attr_count, const sai_attribute_t *attr_list); -static sai_switch_api_t *switch_api = NULL; -static sai_virtual_router_api_t *vrf_api = NULL; -static sai_vlan_api_t *vlan_api = NULL; -static sai_stp_api_t *stp_api = NULL; -static sai_fdb_api_t *fdb_api = NULL; -static sai_router_interface_api_t *rintf_api = NULL; -static sai_neighbor_api_t *neigh_api = NULL; -static sai_next_hop_api_t *nhop_api = NULL; -static sai_next_hop_group_api_t *nhop_group_api = NULL; -static sai_route_api_t *route_api = NULL; -static sai_ipmc_api_t *ipmc_api = NULL; -static sai_l2mc_api_t *l2mc_api = NULL; -static sai_hostif_api_t *host_intf_api = NULL; -static sai_acl_api_t *acl_api = NULL; -static sai_object_id_t *s_port_list = NULL; -static sai_object_id_t s_cpu_port; -static uint16_t s_max_ports = 0; - -static inline uint32_t -ipv4_prefix_len_to_mask(uint32_t prefix_len) { - return (((uint32_t)0xFFFFFFFF) << (32 - prefix_len)); -} - -static inline struct in6_addr -ipv6_prefix_len_to_mask(uint32_t prefix_len) { - struct in6_addr mask; - memset(&mask, 0, sizeof(mask)); - assert(prefix_len <= 128); - - int i; - for (i = 0; i < 4; i++) { - if (prefix_len > 32) { - mask.s6_addr32[i] = 0xFFFFFFFF; - } else { - mask.s6_addr32[i] = htonl(ipv4_prefix_len_to_mask(prefix_len)); - break; - } - prefix_len -= 32; - } - return mask; -} - -static sai_urpf_mode_t -switchlink_to_sai_urpf_mode(switchlink_urpf_mode_t switchlink_urpf_mode) { - switch (switchlink_urpf_mode) { - case SWITCHLINK_URPF_MODE_NONE: - return SAI_URPF_MODE_NONE; - break; - case SWITCHLINK_URPF_MODE_STRICT: - return SAI_URPF_MODE_STRICT; - break; - case SWITCHLINK_URPF_MODE_LOOSE: - return SAI_URPF_MODE_LOOSE; - break; - } - return SWITCHLINK_URPF_MODE_NONE; -} - -static void -get_port_list() { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_attribute_t port_attr; - - memset(&port_attr, 0, sizeof(port_attr)); - port_attr.id = SAI_SWITCH_ATTR_CPU_PORT; - status = switch_api->get_switch_attribute(1, &port_attr); - assert(status == SAI_STATUS_SUCCESS); - s_cpu_port = port_attr.value.oid; - - memset(&port_attr, 0, sizeof(port_attr)); - port_attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; - status = switch_api->get_switch_attribute(1, &port_attr); - assert(status == SAI_STATUS_SUCCESS); - s_max_ports = port_attr.value.u32; - - memset(&port_attr, 0, sizeof(port_attr)); - port_attr.id = SAI_SWITCH_ATTR_PORT_LIST; - s_port_list = (sai_object_id_t *)switchlink_malloc(sizeof(sai_object_id_t), - s_max_ports); - port_attr.value.objlist.list = s_port_list; - status = switch_api->get_switch_attribute(1, &port_attr); - assert(status == SAI_STATUS_SUCCESS); -} - -static sai_object_id_t -get_port_object(uint16_t port_id) { - if (port_id > s_max_ports) { - return s_cpu_port; +static sai_switch_api_t *switch_api = NULL; +static sai_virtual_router_api_t *vrf_api = NULL; +static sai_vlan_api_t *vlan_api = NULL; +static sai_stp_api_t *stp_api = NULL; +static sai_fdb_api_t *fdb_api = NULL; +static sai_router_interface_api_t *rintf_api = NULL; +static sai_neighbor_api_t *neigh_api = NULL; +static sai_next_hop_api_t *nhop_api = NULL; +static sai_next_hop_group_api_t *nhop_group_api = NULL; +static sai_route_api_t *route_api = NULL; +static sai_ipmc_api_t *ipmc_api = NULL; +static sai_l2mc_api_t *l2mc_api = NULL; +static sai_hostif_api_t *host_intf_api = NULL; +static sai_acl_api_t *acl_api = NULL; +static sai_object_id_t *s_port_list = NULL; +static sai_object_id_t s_cpu_port; +static uint16_t s_max_ports = 0; + +static inline uint32_t ipv4_prefix_len_to_mask(uint32_t prefix_len) { + return (prefix_len ? (((uint32_t)0xFFFFFFFF) << (32 - prefix_len)) : 0); +} + +static inline struct in6_addr ipv6_prefix_len_to_mask(uint32_t prefix_len) { + struct in6_addr mask; + memset(&mask, 0, sizeof(mask)); + assert(prefix_len <= 128); + + int i; + for (i = 0; i < 4; i++) { + if (prefix_len > 32) { + mask.s6_addr32[i] = 0xFFFFFFFF; } else { - return s_port_list[port_id]; - } -} - -static int -port_handle_to_port_id(switchlink_handle_t port_h, uint16_t *port_id) { - int i; - for (i = 0; i < s_max_ports; i++) { - if (s_port_list[i] == port_h) { - *port_id = i; - return 0; - } + mask.s6_addr32[i] = htonl(ipv4_prefix_len_to_mask(prefix_len)); + break; } - return -1; -} - -static void -on_fdb_event(uint32_t count, sai_fdb_event_notification_data_t *data) { - switchlink_mac_addr_t mac_addr; - 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(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; - } - } - assert(intf_h != 0); - create = true; - } else if ((data->event_type == SAI_FDB_EVENT_AGED) || - (data->event_type == SAI_FDB_EVENT_FLUSHED)) { - create = false; + prefix_len -= 32; + } + return mask; +} + +static sai_urpf_mode_t switchlink_to_sai_urpf_mode( + switchlink_urpf_mode_t switchlink_urpf_mode) { + switch (switchlink_urpf_mode) { + case SWITCHLINK_URPF_MODE_NONE: + return SAI_URPF_MODE_NONE; + break; + case SWITCHLINK_URPF_MODE_STRICT: + return SAI_URPF_MODE_STRICT; + break; + case SWITCHLINK_URPF_MODE_LOOSE: + return SAI_URPF_MODE_LOOSE; + break; + } + return SWITCHLINK_URPF_MODE_NONE; +} + +static void get_port_list() { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_attribute_t port_attr; + + memset(&port_attr, 0, sizeof(port_attr)); + port_attr.id = SAI_SWITCH_ATTR_CPU_PORT; + status = switch_api->get_switch_attribute(1, &port_attr); + assert(status == SAI_STATUS_SUCCESS); + s_cpu_port = port_attr.value.oid; + + memset(&port_attr, 0, sizeof(port_attr)); + port_attr.id = SAI_SWITCH_ATTR_PORT_NUMBER; + status = switch_api->get_switch_attribute(1, &port_attr); + assert(status == SAI_STATUS_SUCCESS); + s_max_ports = port_attr.value.u32; + + memset(&port_attr, 0, sizeof(port_attr)); + port_attr.id = SAI_SWITCH_ATTR_PORT_LIST; + s_port_list = (sai_object_id_t *)switchlink_malloc(sizeof(sai_object_id_t), + s_max_ports); + port_attr.value.objlist.list = s_port_list; + status = switch_api->get_switch_attribute(1, &port_attr); + assert(status == SAI_STATUS_SUCCESS); +} + +static sai_object_id_t get_port_object(uint16_t port_id) { + if (port_id > s_max_ports) { + return s_cpu_port; + } else { + return s_port_list[port_id]; + } +} + +static int port_handle_to_port_id(switchlink_handle_t port_h, + uint16_t *port_id) { + int i; + for (i = 0; i < s_max_ports; i++) { + if (s_port_list[i] == port_h) { + *port_id = i; + return 0; } - switchlink_linux_mac_update(mac_addr, bridge_h, intf_h, create); -} - -static void -on_packet_event(const void *buf, sai_size_t buf_size, uint32_t attr_count, - const sai_attribute_t *attr_list) { - int ret; - uint32_t i; - uint16_t port_id; - switchlink_handle_t port_h = 0; - - for (i = 0; i < attr_count; i++, attr_list++) { - switch (attr_list->id) { - case SAI_HOSTIF_PACKET_INGRESS_PORT: - port_h = attr_list->value.oid; - break; - default: - break; - } + } + return -1; +} + +static void on_fdb_event(uint32_t count, + sai_fdb_event_notification_data_t *data) { + switchlink_mac_addr_t mac_addr; + 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 (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; + } } - if (port_h == 0) { - return; + assert(intf_h != 0); + create = true; + } else if ((data->event_type == SAI_FDB_EVENT_AGED) || + (data->event_type == SAI_FDB_EVENT_FLUSHED)) { + create = false; + } + switchlink_linux_mac_update(mac_addr, bridge_h, intf_h, create); +} + +static void on_packet_event(const void *buf, + sai_size_t buf_size, + uint32_t attr_count, + const sai_attribute_t *attr_list) { + int ret; + uint32_t i; + uint16_t port_id; + switchlink_handle_t port_h = 0; + + for (i = 0; i < attr_count; i++, attr_list++) { + switch (attr_list->id) { + case SAI_HOSTIF_PACKET_ATTR_INGRESS_PORT: + port_h = attr_list->value.oid; + break; + default: + break; } - - ret = port_handle_to_port_id(port_h, &port_id); - if (ret == -1) { - return; - } - switchlink_packet_from_hardware(buf, buf_size, port_id); -} - -static void -register_sai_notifications() { - sai_switch_notification_t switch_notifications; - sai_status_t status = SAI_STATUS_SUCCESS; - - memset(&switch_notifications, 0, sizeof(switch_notifications)); - switch_notifications.on_fdb_event = on_fdb_event; - switch_notifications.on_packet_event = on_packet_event; - status = switch_api->initialize_switch(0, NULL, NULL, - &switch_notifications); - assert(status == SAI_STATUS_SUCCESS); -} - -static void -register_sai_traps() { - sai_attribute_t attr_list[3]; - sai_status_t status = SAI_STATUS_SUCCESS; - - // STP, redirect to CPU - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_TRAP; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 1; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_STP, 3, attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // OSPF, copy to CPU - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 101; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_OSPF, 3, attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // IPv6 ND, copy to CPU - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 102; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_IPV6_NEIGHBOR_DISCOVERY, - 3, attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // OSPFv3, copy to CPU - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 103; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_OSPFV6, 3, attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // ARP request, copy to CPU - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 104; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_ARP_REQUEST, 3, - attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // ARP response, redirect to CPU - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_TRAP; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 105; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_ARP_RESPONSE, 3, - attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // PIM, copy to CPU + } + if (port_h == 0) { + return; + } + + ret = port_handle_to_port_id(port_h, &port_id); + if (ret == -1) { + return; + } + switchlink_packet_from_hardware(buf, buf_size, port_id); +} + +static void register_sai_notifications() { + sai_switch_notification_t switch_notifications; + sai_status_t status = SAI_STATUS_SUCCESS; + + memset(&switch_notifications, 0, sizeof(switch_notifications)); + switch_notifications.on_fdb_event = on_fdb_event; + switch_notifications.on_packet_event = on_packet_event; + status = switch_api->initialize_switch(0, NULL, NULL, &switch_notifications); + assert(status == SAI_STATUS_SUCCESS); +} + +static void register_sai_traps() { + sai_attribute_t attr_list[3]; + sai_status_t status = SAI_STATUS_SUCCESS; + + // STP, redirect to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_TRAP; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 1; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_STP, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // OSPF, copy to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 101; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_OSPF, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // IPv6 ND, copy to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 102; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap( + SAI_HOSTIF_TRAP_ID_IPV6_NEIGHBOR_DISCOVERY, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // OSPFv3, copy to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 103; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_OSPFV6, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // ARP request, copy to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 104; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_ARP_REQUEST, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // ARP response, redirect to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_TRAP; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 105; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = + sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_ARP_RESPONSE, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // PIM, copy to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 106; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_PIM, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); + + // IGMPv2 report, copy to CPU + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; + attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; + attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; + attr_list[1].value.u32 = 106; + attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; + attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; + status = sai_create_hostif_trap( + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT, 3, attr_list); + assert(status == SAI_STATUS_SUCCESS); +} + +int switchlink_vrf_create(uint16_t vrf_id, switchlink_handle_t *vrf_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_attribute_t attr_list[2]; + + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE; + attr_list[0].value.booldata = true; + attr_list[1].id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V6_STATE; + attr_list[1].value.booldata = true; + + status = vrf_api->create_virtual_router(vrf_h, 2, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_interface_create(switchlink_db_interface_info_t *intf, + switchlink_handle_t *intf_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + + if (intf->intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { + *intf_h = get_port_object(intf->port_id); + } else if (intf->intf_type == SWITCHLINK_INTF_TYPE_L3) { + sai_attribute_t attr_list[10]; + int ac = 0; memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 106; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_PIM, 3, attr_list); - assert(status == SAI_STATUS_SUCCESS); - - // IGMPv2 report, copy to CPU + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; + attr_list[ac].value.oid = intf->vrf_h; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; + 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); + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE; + attr_list[ac].value.booldata = intf->flags.ipv4_unicast_enabled; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE; + attr_list[ac].value.booldata = intf->flags.ipv6_unicast_enabled; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS; + memcpy(attr_list[ac].value.mac, intf->mac_addr, sizeof(sai_mac_t)); + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE; + attr_list[ac].value.booldata = intf->flags.ipv4_multicast_enabled; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE; + 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.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.s32 = + switchlink_to_sai_urpf_mode(intf->flags.ipv6_urpf_mode); + ac++; + + status = rintf_api->create_router_interface(intf_h, ac++, attr_list); + } else if (intf->intf_type == SWITCHLINK_INTF_TYPE_L3VI) { + sai_attribute_t attr_list[10]; + int ac = 0; memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION; - attr_list[0].value.u32 = SAI_PACKET_ACTION_LOG; - attr_list[1].id = SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY; - attr_list[1].value.u32 = 106; - attr_list[2].id = SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL; - attr_list[2].value.u32 = SAI_HOSTIF_TRAP_CHANNEL_CB; - status = sai_create_hostif_trap(SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT, 3, - attr_list); - assert(status == SAI_STATUS_SUCCESS); -} - -int -switchlink_vrf_create(uint16_t vrf_id, switchlink_handle_t *vrf_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_attribute_t attr_list[2]; - - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE; - attr_list[0].value.booldata = true; - attr_list[1].id = SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V6_STATE; - attr_list[1].value.booldata = true; - - status = vrf_api->create_virtual_router(vrf_h, 2, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_interface_create(switchlink_db_interface_info_t *intf, - switchlink_handle_t *intf_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - - if (intf->intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { - *intf_h = get_port_object(intf->port_id); - } else if (intf->intf_type == SWITCHLINK_INTF_TYPE_L3) { - sai_attribute_t attr_list[10]; - int ac = 0; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; - attr_list[ac].value.oid = intf->vrf_h; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; - 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); - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE; - attr_list[ac].value.booldata = intf->flags.ipv4_unicast_enabled; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE; - attr_list[ac].value.booldata = intf->flags.ipv6_unicast_enabled; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS; - memcpy(attr_list[ac].value.mac, intf->mac_addr, sizeof(sai_mac_t)); - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE; - attr_list[ac].value.booldata = intf->flags.ipv4_multicast_enabled; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE; - 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.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.s32 = - switchlink_to_sai_urpf_mode(intf->flags.ipv6_urpf_mode); - ac++; - - status = rintf_api->create_router_interface(intf_h, ac++, attr_list); - } else if (intf->intf_type == SWITCHLINK_INTF_TYPE_L3VI) { - sai_attribute_t attr_list[10]; - int ac = 0; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; - attr_list[ac].value.oid = intf->vrf_h; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; - 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; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE; - attr_list[ac].value.booldata = intf->flags.ipv4_unicast_enabled; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE; - attr_list[ac].value.booldata = intf->flags.ipv6_unicast_enabled; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS; - memcpy(attr_list[ac].value.mac, intf->mac_addr, sizeof(sai_mac_t)); - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE; - attr_list[ac].value.booldata = intf->flags.ipv4_multicast_enabled; - ac++; - attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE; - 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.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.s32 = - switchlink_to_sai_urpf_mode(intf->flags.ipv6_urpf_mode); - ac++; - - status = rintf_api->create_router_interface(intf_h, ac++, attr_list); - } - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_interface_forwarding_update(switchlink_handle_t intf_h, int af, - bool value) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_attribute_t attr; - - memset(&attr, 0, sizeof(attr)); - if (af == AF_INET) { - attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE; - } else { - attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE; - } - attr.value.booldata = value; - status = rintf_api->set_router_interface_attribute(intf_h, &attr); - - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_interface_mc_forwarding_update(switchlink_handle_t intf_h, int af, - bool value) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_attribute_t attr; - memset(&attr, 0, sizeof(attr)); - if (af == AF_INET) { - attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE; - } else { - attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE; - } - attr.value.booldata = value; - status = rintf_api->set_router_interface_attribute(intf_h, &attr); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_interface_urpf_mode_update(switchlink_handle_t intf_h, int af, - uint8_t value) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_attribute_t attr; - memset(&attr, 0, sizeof(attr)); - if (af == AF_INET) { - attr.id = SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE; - } else { - attr.id = SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE; - } - attr.value.s32 = value; - status = rintf_api->set_router_interface_attribute(intf_h, &attr); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_interface_delete(switchlink_db_interface_info_t *intf, - switchlink_handle_t intf_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - if (intf->intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { - // nothing to do - } else if (intf->intf_type == SWITCHLINK_INTF_TYPE_L3) { - status = rintf_api->remove_router_interface(intf_h); - } - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -static sai_port_stp_port_state_t -get_sai_stp_state(switchlink_stp_state_t switchlink_stp_state) { - sai_port_stp_port_state_t sai_stp_state = SAI_PORT_STP_STATE_FORWARDING; - switch (switchlink_stp_state) { - case SWITCHLINK_STP_STATE_NONE: - case SWITCHLINK_STP_STATE_DISABLED: - case SWITCHLINK_STP_STATE_FORWARDING: - sai_stp_state = SAI_PORT_STP_STATE_FORWARDING; - break; - case SWITCHLINK_STP_STATE_LEARNING: - sai_stp_state = SAI_PORT_STP_STATE_LEARNING; - break; - case SWITCHLINK_STP_STATE_BLOCKING: - sai_stp_state = SAI_PORT_STP_STATE_BLOCKING; - break; - } - return sai_stp_state; -} - -int -switchlink_stp_state_update(switchlink_db_interface_info_t *intf) { - sai_status_t status = SAI_STATUS_SUCCESS; - status = stp_api->set_stp_port_state(intf->stp_h, intf->intf_h, - get_sai_stp_state(intf->stp_state)); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; + attr_list[ac].value.oid = intf->vrf_h; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_TYPE; + 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; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE; + attr_list[ac].value.booldata = intf->flags.ipv4_unicast_enabled; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE; + attr_list[ac].value.booldata = intf->flags.ipv6_unicast_enabled; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS; + memcpy(attr_list[ac].value.mac, intf->mac_addr, sizeof(sai_mac_t)); + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE; + attr_list[ac].value.booldata = intf->flags.ipv4_multicast_enabled; + ac++; + attr_list[ac].id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE; + 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.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.s32 = + switchlink_to_sai_urpf_mode(intf->flags.ipv6_urpf_mode); + ac++; + + status = rintf_api->create_router_interface(intf_h, ac++, attr_list); + } + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_interface_forwarding_update(switchlink_handle_t intf_h, + int af, + bool value) { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_attribute_t attr; + + memset(&attr, 0, sizeof(attr)); + if (af == AF_INET) { + attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE; + } else { + attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE; + } + attr.value.booldata = value; + status = rintf_api->set_router_interface_attribute(intf_h, &attr); + + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_interface_mc_forwarding_update(switchlink_handle_t intf_h, + int af, + bool value) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_attribute_t attr; + memset(&attr, 0, sizeof(attr)); + if (af == AF_INET) { + attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE; + } else { + attr.id = SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE; + } + attr.value.booldata = value; + status = rintf_api->set_router_interface_attribute(intf_h, &attr); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_interface_urpf_mode_update(switchlink_handle_t intf_h, + int af, + uint8_t value) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_attribute_t attr; + memset(&attr, 0, sizeof(attr)); + if (af == AF_INET) { + attr.id = SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE; + } else { + attr.id = SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE; + } + attr.value.s32 = value; + status = rintf_api->set_router_interface_attribute(intf_h, &attr); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_interface_delete(switchlink_db_interface_info_t *intf, + switchlink_handle_t intf_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + if (intf->intf_type == SWITCHLINK_INTF_TYPE_L2_ACCESS) { + // nothing to do + } else if (intf->intf_type == SWITCHLINK_INTF_TYPE_L3) { + status = rintf_api->remove_router_interface(intf_h); + } + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +static sai_port_stp_port_state_t get_sai_stp_state( + switchlink_stp_state_t switchlink_stp_state) { + sai_port_stp_port_state_t sai_stp_state = SAI_PORT_STP_STATE_FORWARDING; + switch (switchlink_stp_state) { + case SWITCHLINK_STP_STATE_NONE: + case SWITCHLINK_STP_STATE_DISABLED: + case SWITCHLINK_STP_STATE_FORWARDING: + sai_stp_state = SAI_PORT_STP_STATE_FORWARDING; + break; + case SWITCHLINK_STP_STATE_LEARNING: + sai_stp_state = SAI_PORT_STP_STATE_LEARNING; + break; + case SWITCHLINK_STP_STATE_BLOCKING: + sai_stp_state = SAI_PORT_STP_STATE_BLOCKING; + break; + } + return sai_stp_state; +} + +int switchlink_stp_state_update(switchlink_db_interface_info_t *intf) { + sai_status_t status = SAI_STATUS_SUCCESS; + status = stp_api->set_stp_port_state( + intf->stp_h, intf->intf_h, get_sai_stp_state(intf->stp_state)); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_add_interface_to_bridge(switchlink_db_interface_info_t *intf) { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_attribute_t attr_list[3]; + memset(attr_list, 0, sizeof(attr_list)); + + attr_list[0].id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; + attr_list[0].value.u16 = intf->bridge_h; + attr_list[1].id = SAI_VLAN_MEMBER_ATTR_PORT_ID; + attr_list[1].value.oid = intf->intf_h; + attr_list[2].id = SAI_VLAN_MEMBER_ATTR_TAGGING_MODE; + attr_list[2].value.s32 = SAI_VLAN_PORT_UNTAGGED; + status = vlan_api->create_vlan_member(&intf->vlan_member_h, 3, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_del_interface_from_bridge(switchlink_db_interface_info_t *intf, + switchlink_handle_t old_bridge_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + status = vlan_api->remove_vlan_member(intf->vlan_member_h); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_bridge_create(switchlink_db_bridge_info_t *bridge_db_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + static uint32_t vlan_id = 1; + + status = vlan_api->create_vlan(vlan_id); + if (status != SAI_STATUS_SUCCESS) { + return -1; + } + + sai_attribute_t attr_list[1]; + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_STP_ATTR_VLAN_LIST; + attr_list[0].value.vlanlist.count = 1; + attr_list[0].value.vlanlist.list = (sai_vlan_id_t *)&vlan_id; + status = stp_api->create_stp(&(bridge_db_info->stp_h), 1, attr_list); + if (status != SAI_STATUS_SUCCESS) { + return -1; + } -int -switchlink_add_interface_to_bridge(switchlink_db_interface_info_t *intf) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_vlan_port_t vlan_port; + bridge_db_info->bridge_h = vlan_id; + vlan_id++; - vlan_port.port_id = intf->intf_h; - vlan_port.tagging_mode = SAI_VLAN_PORT_UNTAGGED; - status = vlan_api->add_ports_to_vlan(intf->bridge_h, 1, &vlan_port); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); + return 0; } -int -switchlink_del_interface_from_bridge(switchlink_db_interface_info_t *intf, - switchlink_handle_t old_bridge_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_vlan_port_t vlan_port; - - vlan_port.port_id = intf->intf_h; - vlan_port.tagging_mode = SAI_VLAN_PORT_UNTAGGED; - status = vlan_api->remove_ports_from_vlan(old_bridge_h, 1, &vlan_port); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +int switchlink_bridge_update(switchlink_db_bridge_info_t *bridge_db_info) { + return 0; } -int -switchlink_bridge_create(switchlink_db_bridge_info_t *bridge_db_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - static uint32_t vlan_id = 1; - - status = vlan_api->create_vlan(vlan_id); - if (status != SAI_STATUS_SUCCESS) { - return -1; - } - - sai_attribute_t attr_list[1]; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_STP_ATTR_VLAN_LIST; - attr_list[0].value.vlanlist.vlan_count = 1; - attr_list[0].value.vlanlist.vlan_list = (sai_vlan_id_t *)&vlan_id; - status = stp_api->create_stp(&(bridge_db_info->stp_h), 1, attr_list); - if (status != SAI_STATUS_SUCCESS) { - return -1; - } +int switchlink_bridge_delete(switchlink_db_bridge_info_t *bridge_db_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + int ret = 0; - bridge_db_info->bridge_h = vlan_id; - vlan_id++; + status = stp_api->remove_stp(bridge_db_info->stp_h); + if (status != SAI_STATUS_SUCCESS) { + ret = -1; + } - return 0; -} + status = vlan_api->remove_vlan(bridge_db_info->bridge_h); + if (status != SAI_STATUS_SUCCESS) { + ret = -1; + } -int -switchlink_bridge_update(switchlink_db_bridge_info_t *bridge_db_info) { - return 0; + return ret; } -int -switchlink_bridge_delete(switchlink_db_bridge_info_t *bridge_db_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - int ret = 0; +int switchlink_lag_create(switchlink_handle_t *lag_h) { return -1; } - status = stp_api->remove_stp(bridge_db_info->stp_h); - if (status != SAI_STATUS_SUCCESS) { - ret = -1; - } +int switchlink_mac_create(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_fdb_entry_t fdb_entry; + memset(&fdb_entry, 0, sizeof(fdb_entry)); + memcpy(fdb_entry.mac_address, mac_addr, sizeof(sai_mac_t)); + fdb_entry.vlan_id = bridge_h; - status = vlan_api->remove_vlan(bridge_db_info->bridge_h); - if (status != SAI_STATUS_SUCCESS) { - ret = -1; - } + 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.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.s32 = SAI_PACKET_ACTION_FORWARD; - return ret; + status = fdb_api->create_fdb_entry(&fdb_entry, 3, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); } -int -switchlink_lag_create(switchlink_handle_t *lag_h) { - return -1; -} +int switchlink_mac_update(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_fdb_entry_t fdb_entry; + memset(&fdb_entry, 0, sizeof(fdb_entry)); + memcpy(fdb_entry.mac_address, mac_addr, sizeof(sai_mac_t)); + fdb_entry.vlan_id = bridge_h; -int -switchlink_mac_create(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_fdb_entry_t fdb_entry; - memset(&fdb_entry, 0, sizeof(fdb_entry)); - memcpy(fdb_entry.mac_address, mac_addr, sizeof(sai_mac_t)); - fdb_entry.vlan_id = bridge_h; - - 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.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.s32 = SAI_PACKET_ACTION_FORWARD; - - status = fdb_api->create_fdb_entry(&fdb_entry, 3, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_mac_update(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_fdb_entry_t fdb_entry; - memset(&fdb_entry, 0, sizeof(fdb_entry)); - memcpy(fdb_entry.mac_address, mac_addr, sizeof(sai_mac_t)); - fdb_entry.vlan_id = bridge_h; - - sai_attribute_t attr_list[1]; - memset(&attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_FDB_ENTRY_ATTR_PORT_ID; - attr_list[0].value.oid = intf_h; - - status = fdb_api->set_fdb_entry_attribute(&fdb_entry, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_mac_delete(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h) { - sai_status_t status = SAI_STATUS_SUCCESS; - sai_fdb_entry_t fdb_entry; - memset(&fdb_entry, 0, sizeof(fdb_entry)); - memcpy(fdb_entry.mac_address, mac_addr, sizeof(sai_mac_t)); - fdb_entry.vlan_id = bridge_h; - - status = fdb_api->remove_fdb_entry(&fdb_entry); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_nexthop_create(switchlink_db_neigh_info_t *neigh_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - 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.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; - attr_list[1].value.ipaddr.addr.ip4 = - htonl(neigh_info->ip_addr.ip.v4addr.s_addr); - } else { - attr_list[1].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(attr_list[1].value.ipaddr.addr.ip6, - &(neigh_info->ip_addr.ip.v6addr), sizeof(sai_ip6_t)); - } - attr_list[2].id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; - attr_list[2].value.oid = neigh_info->intf_h; - status = nhop_api->create_next_hop(&(neigh_info->nhop_h), 3, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} + sai_attribute_t attr_list[1]; + memset(&attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_FDB_ENTRY_ATTR_PORT_ID; + attr_list[0].value.oid = intf_h; -int -switchlink_nexthop_delete(switchlink_db_neigh_info_t *neigh_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - status = nhop_api->remove_next_hop(neigh_info->nhop_h); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); + status = fdb_api->set_fdb_entry_attribute(&fdb_entry, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); } -int -switchlink_neighbor_create(switchlink_db_neigh_info_t *neigh_info) { - sai_status_t status = SAI_STATUS_SUCCESS; +int switchlink_mac_delete(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h) { + sai_status_t status = SAI_STATUS_SUCCESS; + sai_fdb_entry_t fdb_entry; + memset(&fdb_entry, 0, sizeof(fdb_entry)); + memcpy(fdb_entry.mac_address, mac_addr, sizeof(sai_mac_t)); + fdb_entry.vlan_id = bridge_h; - sai_attribute_t attr_list[1]; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; - memcpy(attr_list[0].value.mac, neigh_info->mac_addr, sizeof(sai_mac_t)); - - sai_neighbor_entry_t neighbor_entry; - memset(&neighbor_entry, 0, sizeof(neighbor_entry)); - neighbor_entry.rif_id = neigh_info->intf_h; - if (neigh_info->ip_addr.family == AF_INET) { - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - neighbor_entry.ip_address.addr.ip4 = - htonl(neigh_info->ip_addr.ip.v4addr.s_addr); - } else { - assert(neigh_info->ip_addr.family == AF_INET6); - neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(neighbor_entry.ip_address.addr.ip6, - &(neigh_info->ip_addr.ip.v6addr), sizeof(sai_ip6_t)); - } - - status = neigh_api->create_neighbor_entry(&neighbor_entry, 1, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); + status = fdb_api->remove_fdb_entry(&fdb_entry); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); } -int -switchlink_neighbor_delete(switchlink_db_neigh_info_t *neigh_info) { - sai_status_t status = SAI_STATUS_SUCCESS; +int switchlink_nexthop_create(switchlink_db_neigh_info_t *neigh_info) { + sai_status_t status = SAI_STATUS_SUCCESS; - sai_neighbor_entry_t neighbor_entry; - memset(&neighbor_entry, 0, sizeof(neighbor_entry)); - neighbor_entry.rif_id = neigh_info->intf_h; + 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.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; + attr_list[1].value.ipaddr.addr.ip4 = + htonl(neigh_info->ip_addr.ip.v4addr.s_addr); + } else { + attr_list[1].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(attr_list[1].value.ipaddr.addr.ip6, + &(neigh_info->ip_addr.ip.v6addr), + sizeof(sai_ip6_t)); + } + attr_list[2].id = SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID; + attr_list[2].value.oid = neigh_info->intf_h; + status = nhop_api->create_next_hop(&(neigh_info->nhop_h), 3, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_nexthop_delete(switchlink_db_neigh_info_t *neigh_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + status = nhop_api->remove_next_hop(neigh_info->nhop_h); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_neighbor_create(switchlink_db_neigh_info_t *neigh_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_attribute_t attr_list[1]; + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS; + memcpy(attr_list[0].value.mac, neigh_info->mac_addr, sizeof(sai_mac_t)); + + sai_neighbor_entry_t neighbor_entry; + memset(&neighbor_entry, 0, sizeof(neighbor_entry)); + neighbor_entry.rif_id = neigh_info->intf_h; + if (neigh_info->ip_addr.family == AF_INET) { neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; neighbor_entry.ip_address.addr.ip4 = htonl(neigh_info->ip_addr.ip.v4addr.s_addr); - - status = neigh_api->remove_neighbor_entry(&neighbor_entry); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_ecmp_create(switchlink_db_ecmp_info_t *ecmp_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - 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.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; - attr_list[2].value.objlist.count = ecmp_info->num_nhops; - attr_list[2].value.objlist.list = (sai_object_id_t *)ecmp_info->nhops; - status = nhop_group_api->create_next_hop_group(&(ecmp_info->ecmp_h), 3, - attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_ecmp_delete(switchlink_db_ecmp_info_t *ecmp_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - status = nhop_group_api->remove_next_hop_group(ecmp_info->ecmp_h); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_route_create(switchlink_db_route_info_t *route_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_unicast_route_entry_t route_entry; - memset(&route_entry, 0, sizeof(route_entry)); - route_entry.vr_id = route_info->vrf_h; - if (route_info->ip_addr.family == AF_INET) { - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = - htonl(route_info->ip_addr.ip.v4addr.s_addr); - route_entry.destination.mask.ip4 = - htonl(ipv4_prefix_len_to_mask(route_info->ip_addr.prefix_len)); - } else { - assert(route_info->ip_addr.family == AF_INET6); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(route_entry.destination.addr.ip6, - &(route_info->ip_addr.ip.v6addr), sizeof(sai_ip6_t)); - struct in6_addr mask = - ipv6_prefix_len_to_mask(route_info->ip_addr.prefix_len); - memcpy(route_entry.destination.mask.ip6, &mask, sizeof(sai_ip6_t)); - } - - sai_attribute_t attr_list[1]; - memset(attr_list, 0, sizeof(attr_list)); - if (route_info->nhop_h == g_cpu_rx_nhop_h) { - attr_list[0].id = SAI_ROUTE_ATTR_PACKET_ACTION; - attr_list[0].value.s32 = SAI_PACKET_ACTION_TRAP; - } else { - attr_list[0].id = SAI_ROUTE_ATTR_NEXT_HOP_ID; - attr_list[0].value.oid = route_info->nhop_h; - } - - status = route_api->create_route(&route_entry, 1, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_route_delete(switchlink_db_route_info_t *route_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_unicast_route_entry_t route_entry; - memset(&route_entry, 0, sizeof(route_entry)); - route_entry.vr_id = route_info->vrf_h; - if (route_info->ip_addr.family == AF_INET) { - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - route_entry.destination.addr.ip4 = - htonl(route_info->ip_addr.ip.v4addr.s_addr); - route_entry.destination.mask.ip4 = - htonl(ipv4_prefix_len_to_mask(route_info->ip_addr.prefix_len)); - } else { - assert(route_info->ip_addr.family == AF_INET6); - route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(route_entry.destination.addr.ip6, - &(route_info->ip_addr.ip.v6addr), sizeof(sai_ip6_t)); - struct in6_addr mask = - ipv6_prefix_len_to_mask(route_info->ip_addr.prefix_len); - memcpy(route_entry.destination.mask.ip6, &mask, sizeof(sai_ip6_t)); - } - - status = route_api->remove_route(&route_entry); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_mroute_create(switchlink_db_mroute_info_t *mroute_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_ipmc_entry_t ipmc_entry; - memset(&ipmc_entry, 0, sizeof(ipmc_entry)); - ipmc_entry.vr_id = mroute_info->vrf_h; - if (mroute_info->src_ip.family == AF_INET) { - ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - ipmc_entry.source.addr.ip4 = - htonl(mroute_info->src_ip.ip.v4addr.s_addr); - ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - ipmc_entry.group.addr.ip4 = - htonl(mroute_info->dst_ip.ip.v4addr.s_addr); - ipmc_entry.group.mask.ip4 = - htonl(ipv4_prefix_len_to_mask(mroute_info->dst_ip.prefix_len)); - } else { - ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(ipmc_entry.source.addr.ip6, - &(mroute_info->src_ip.ip.v6addr), sizeof(sai_ip6_t)); - ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(ipmc_entry.group.addr.ip6, - &(mroute_info->dst_ip.ip.v6addr), sizeof(sai_ip6_t)); - struct in6_addr mask = - ipv6_prefix_len_to_mask(mroute_info->dst_ip.prefix_len); - memcpy(ipmc_entry.group.mask.ip6, &mask, sizeof(sai_ip6_t)); - } - - switchlink_db_status_t db_status; - switchlink_db_oifl_info_t oifl_info; - db_status = switchlink_db_oifl_handle_get_info(mroute_info->oifl_h, - &oifl_info); - assert(db_status == SWITCHLINK_DB_STATUS_SUCCESS); - - sai_attribute_t attr_list[2]; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_IPMC_ATTR_OUTPUT_ROUTER_INTERFACE_LIST; - attr_list[0].value.objlist.count = oifl_info.num_intfs; - attr_list[0].value.objlist.list = oifl_info.intfs; - attr_list[1].id = SAI_IPMC_ATTR_RPF_ROUTER_INTERFACE_LIST; - attr_list[1].value.objlist.count = 1; - attr_list[1].value.objlist.list = (sai_object_id_t *)&(mroute_info->iif_h); - - status = ipmc_api->create_ipmc_entry(&ipmc_entry, 2, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_mroute_delete(switchlink_db_mroute_info_t *mroute_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_ipmc_entry_t ipmc_entry; - memset(&ipmc_entry, 0, sizeof(ipmc_entry)); - ipmc_entry.vr_id = mroute_info->vrf_h; - if (mroute_info->src_ip.family == AF_INET) { - ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - ipmc_entry.source.addr.ip4 = - htonl(mroute_info->src_ip.ip.v4addr.s_addr); - ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - ipmc_entry.group.addr.ip4 = - htonl(mroute_info->dst_ip.ip.v4addr.s_addr); - ipmc_entry.group.mask.ip4 = - htonl(ipv4_prefix_len_to_mask(mroute_info->dst_ip.prefix_len)); - } else { - ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(ipmc_entry.source.addr.ip6, - &(mroute_info->src_ip.ip.v6addr), sizeof(sai_ip6_t)); - ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(ipmc_entry.group.addr.ip6, - &(mroute_info->dst_ip.ip.v6addr), sizeof(sai_ip6_t)); - struct in6_addr mask = - ipv6_prefix_len_to_mask(mroute_info->dst_ip.prefix_len); - memcpy(ipmc_entry.group.mask.ip6, &mask, sizeof(sai_ip6_t)); - } - - status = ipmc_api->remove_ipmc_entry(&ipmc_entry); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_mdb_create(switchlink_db_mdb_info_t *mdb_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_l2mc_entry_t l2mc_entry; - memset(&l2mc_entry, 0, sizeof(l2mc_entry)); - l2mc_entry.vlan_id = mdb_info->bridge_h; - if (mdb_info->grp_ip.family == AF_INET) { - l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - l2mc_entry.group.addr.ip4 = - htonl(mdb_info->grp_ip.ip.v4addr.s_addr); - } else { - l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(l2mc_entry.group.addr.ip6, - &(mdb_info->grp_ip.ip.v6addr), sizeof(sai_ip6_t)); - } - - sai_attribute_t attr_list[1]; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_L2MC_ATTR_PORT_LIST; - attr_list[0].value.objlist.count = mdb_info->num_intfs; - attr_list[0].value.objlist.list = (sai_object_id_t *)(mdb_info->intfs); - - status = l2mc_api->create_l2mc_entry(&l2mc_entry, 1, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_mdb_delete(switchlink_db_mdb_info_t *mdb_info) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_l2mc_entry_t l2mc_entry; - memset(&l2mc_entry, 0, sizeof(l2mc_entry)); - l2mc_entry.vlan_id = mdb_info->bridge_h; - if (mdb_info->grp_ip.family == AF_INET) { - l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; - l2mc_entry.group.addr.ip4 = - htonl(mdb_info->grp_ip.ip.v4addr.s_addr); - } else { - l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; - memcpy(l2mc_entry.group.addr.ip6, - &(mdb_info->grp_ip.ip.v6addr), sizeof(sai_ip6_t)); - } - - status = l2mc_api->remove_l2mc_entry(&l2mc_entry); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -int -switchlink_send_packet(char *buf, uint32_t buf_size, uint16_t port_id) { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_attribute_t attr_list[2]; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_HOSTIF_PACKET_TX_TYPE; - attr_list[0].value.u32 = SAI_HOSTIF_TX_TYPE_PIPELINE_BYPASS; - attr_list[1].id = SAI_HOSTIF_PACKET_EGRESS_PORT_OR_LAG; - attr_list[1].value.oid = get_port_object(port_id); - - status = host_intf_api->send_packet(0, buf, buf_size, 2, attr_list); - return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); -} - -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]; - memset(attr_list, 0, sizeof(attr_list)); - attr_list[0].id = SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP; - attr_list[1].id = SAI_ACL_ENTRY_ATTR_FIELD_DST_IP; - status = acl_api->create_acl_table(table_id, 2, attr_list); - return status; -} - -void -switchlink_api_init() { - sai_status_t status = SAI_STATUS_SUCCESS; - - sai_initialize(); - - status = sai_api_query(SAI_API_SWITCH, (void **)&switch_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_VIRTUAL_ROUTER, (void **)&vrf_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_VLAN, (void **)&vlan_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_STP, (void **)&stp_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_FDB, (void **)&fdb_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_ROUTER_INTERFACE, (void **)&rintf_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_NEIGHBOR, (void **)&neigh_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_NEXT_HOP, (void **)&nhop_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_NEXT_HOP_GROUP, (void **)&nhop_group_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_ROUTE, (void **)&route_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_IPMC, (void **)&ipmc_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_L2MC, (void **)&l2mc_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_HOST_INTERFACE, (void **)&host_intf_api); - assert(status == SAI_STATUS_SUCCESS); - status = sai_api_query(SAI_API_ACL, (void **)&acl_api); - assert(status == SAI_STATUS_SUCCESS); - - register_sai_notifications(); - register_sai_traps(); - - get_port_list(); + } else { + assert(neigh_info->ip_addr.family == AF_INET6); + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(neighbor_entry.ip_address.addr.ip6, + &(neigh_info->ip_addr.ip.v6addr), + sizeof(sai_ip6_t)); + } + + status = neigh_api->create_neighbor_entry(&neighbor_entry, 1, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_neighbor_delete(switchlink_db_neigh_info_t *neigh_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_neighbor_entry_t neighbor_entry; + memset(&neighbor_entry, 0, sizeof(neighbor_entry)); + neighbor_entry.rif_id = neigh_info->intf_h; + neighbor_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + neighbor_entry.ip_address.addr.ip4 = + htonl(neigh_info->ip_addr.ip.v4addr.s_addr); + + status = neigh_api->remove_neighbor_entry(&neighbor_entry); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_ecmp_create(switchlink_db_ecmp_info_t *ecmp_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + 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.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; + attr_list[2].value.objlist.count = ecmp_info->num_nhops; + attr_list[2].value.objlist.list = (sai_object_id_t *)ecmp_info->nhops; + status = + nhop_group_api->create_next_hop_group(&(ecmp_info->ecmp_h), 3, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_ecmp_delete(switchlink_db_ecmp_info_t *ecmp_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + status = nhop_group_api->remove_next_hop_group(ecmp_info->ecmp_h); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_route_create(switchlink_db_route_info_t *route_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_unicast_route_entry_t route_entry; + memset(&route_entry, 0, sizeof(route_entry)); + route_entry.vr_id = route_info->vrf_h; + if (route_info->ip_addr.family == AF_INET) { + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = + htonl(route_info->ip_addr.ip.v4addr.s_addr); + route_entry.destination.mask.ip4 = + htonl(ipv4_prefix_len_to_mask(route_info->ip_addr.prefix_len)); + } else { + assert(route_info->ip_addr.family == AF_INET6); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(route_entry.destination.addr.ip6, + &(route_info->ip_addr.ip.v6addr), + sizeof(sai_ip6_t)); + struct in6_addr mask = + ipv6_prefix_len_to_mask(route_info->ip_addr.prefix_len); + memcpy(route_entry.destination.mask.ip6, &mask, sizeof(sai_ip6_t)); + } + + sai_attribute_t attr_list[1]; + memset(attr_list, 0, sizeof(attr_list)); + if (route_info->nhop_h == g_cpu_rx_nhop_h) { + attr_list[0].id = SAI_ROUTE_ATTR_PACKET_ACTION; + attr_list[0].value.s32 = SAI_PACKET_ACTION_TRAP; + } else { + attr_list[0].id = SAI_ROUTE_ATTR_NEXT_HOP_ID; + attr_list[0].value.oid = route_info->nhop_h; + } + + status = route_api->create_route(&route_entry, 1, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_route_delete(switchlink_db_route_info_t *route_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_unicast_route_entry_t route_entry; + memset(&route_entry, 0, sizeof(route_entry)); + route_entry.vr_id = route_info->vrf_h; + if (route_info->ip_addr.family == AF_INET) { + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + route_entry.destination.addr.ip4 = + htonl(route_info->ip_addr.ip.v4addr.s_addr); + route_entry.destination.mask.ip4 = + htonl(ipv4_prefix_len_to_mask(route_info->ip_addr.prefix_len)); + } else { + assert(route_info->ip_addr.family == AF_INET6); + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(route_entry.destination.addr.ip6, + &(route_info->ip_addr.ip.v6addr), + sizeof(sai_ip6_t)); + struct in6_addr mask = + ipv6_prefix_len_to_mask(route_info->ip_addr.prefix_len); + memcpy(route_entry.destination.mask.ip6, &mask, sizeof(sai_ip6_t)); + } + + status = route_api->remove_route(&route_entry); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_mroute_create(switchlink_db_mroute_info_t *mroute_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_ipmc_entry_t ipmc_entry; + memset(&ipmc_entry, 0, sizeof(ipmc_entry)); + ipmc_entry.vr_id = mroute_info->vrf_h; + if (mroute_info->src_ip.family == AF_INET) { + ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + ipmc_entry.source.addr.ip4 = htonl(mroute_info->src_ip.ip.v4addr.s_addr); + ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + ipmc_entry.group.addr.ip4 = htonl(mroute_info->dst_ip.ip.v4addr.s_addr); + ipmc_entry.group.mask.ip4 = + htonl(ipv4_prefix_len_to_mask(mroute_info->dst_ip.prefix_len)); + } else { + ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(ipmc_entry.source.addr.ip6, + &(mroute_info->src_ip.ip.v6addr), + sizeof(sai_ip6_t)); + ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(ipmc_entry.group.addr.ip6, + &(mroute_info->dst_ip.ip.v6addr), + sizeof(sai_ip6_t)); + struct in6_addr mask = + ipv6_prefix_len_to_mask(mroute_info->dst_ip.prefix_len); + memcpy(ipmc_entry.group.mask.ip6, &mask, sizeof(sai_ip6_t)); + } + + switchlink_db_status_t db_status; + switchlink_db_oifl_info_t oifl_info; + db_status = + switchlink_db_oifl_handle_get_info(mroute_info->oifl_h, &oifl_info); + assert(db_status == SWITCHLINK_DB_STATUS_SUCCESS); + + sai_attribute_t attr_list[2]; + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_IPMC_ATTR_OUTPUT_ROUTER_INTERFACE_LIST; + attr_list[0].value.objlist.count = oifl_info.num_intfs; + attr_list[0].value.objlist.list = oifl_info.intfs; + attr_list[1].id = SAI_IPMC_ATTR_RPF_ROUTER_INTERFACE_LIST; + attr_list[1].value.objlist.count = 1; + attr_list[1].value.objlist.list = (sai_object_id_t *)&(mroute_info->iif_h); + + status = ipmc_api->create_ipmc_entry(&ipmc_entry, 2, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_mroute_delete(switchlink_db_mroute_info_t *mroute_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_ipmc_entry_t ipmc_entry; + memset(&ipmc_entry, 0, sizeof(ipmc_entry)); + ipmc_entry.vr_id = mroute_info->vrf_h; + if (mroute_info->src_ip.family == AF_INET) { + ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + ipmc_entry.source.addr.ip4 = htonl(mroute_info->src_ip.ip.v4addr.s_addr); + ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + ipmc_entry.group.addr.ip4 = htonl(mroute_info->dst_ip.ip.v4addr.s_addr); + ipmc_entry.group.mask.ip4 = + htonl(ipv4_prefix_len_to_mask(mroute_info->dst_ip.prefix_len)); + } else { + ipmc_entry.source.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(ipmc_entry.source.addr.ip6, + &(mroute_info->src_ip.ip.v6addr), + sizeof(sai_ip6_t)); + ipmc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(ipmc_entry.group.addr.ip6, + &(mroute_info->dst_ip.ip.v6addr), + sizeof(sai_ip6_t)); + struct in6_addr mask = + ipv6_prefix_len_to_mask(mroute_info->dst_ip.prefix_len); + memcpy(ipmc_entry.group.mask.ip6, &mask, sizeof(sai_ip6_t)); + } + + status = ipmc_api->remove_ipmc_entry(&ipmc_entry); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_mdb_create(switchlink_db_mdb_info_t *mdb_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_l2mc_entry_t l2mc_entry; + memset(&l2mc_entry, 0, sizeof(l2mc_entry)); + l2mc_entry.vlan_id = mdb_info->bridge_h; + if (mdb_info->grp_ip.family == AF_INET) { + l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + l2mc_entry.group.addr.ip4 = htonl(mdb_info->grp_ip.ip.v4addr.s_addr); + } else { + l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(l2mc_entry.group.addr.ip6, + &(mdb_info->grp_ip.ip.v6addr), + sizeof(sai_ip6_t)); + } + + sai_attribute_t attr_list[1]; + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_L2MC_ATTR_PORT_LIST; + attr_list[0].value.objlist.count = mdb_info->num_intfs; + attr_list[0].value.objlist.list = (sai_object_id_t *)(mdb_info->intfs); + + status = l2mc_api->create_l2mc_entry(&l2mc_entry, 1, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_mdb_delete(switchlink_db_mdb_info_t *mdb_info) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_l2mc_entry_t l2mc_entry; + memset(&l2mc_entry, 0, sizeof(l2mc_entry)); + l2mc_entry.vlan_id = mdb_info->bridge_h; + if (mdb_info->grp_ip.family == AF_INET) { + l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + l2mc_entry.group.addr.ip4 = htonl(mdb_info->grp_ip.ip.v4addr.s_addr); + } else { + l2mc_entry.group.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(l2mc_entry.group.addr.ip6, + &(mdb_info->grp_ip.ip.v6addr), + sizeof(sai_ip6_t)); + } + + status = l2mc_api->remove_l2mc_entry(&l2mc_entry); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +int switchlink_send_packet(char *buf, uint32_t buf_size, uint16_t port_id) { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_attribute_t attr_list[2]; + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_HOSTIF_PACKET_ATTR_TX_TYPE; + attr_list[0].value.u32 = SAI_HOSTIF_TX_TYPE_PIPELINE_BYPASS; + attr_list[1].id = SAI_HOSTIF_PACKET_ATTR_EGRESS_PORT_OR_LAG; + attr_list[1].value.oid = get_port_object(port_id); + + status = host_intf_api->send_packet(0, buf, buf_size, 2, attr_list); + return ((status == SAI_STATUS_SUCCESS) ? 0 : -1); +} + +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]; + memset(attr_list, 0, sizeof(attr_list)); + attr_list[0].id = SAI_ACL_ENTRY_ATTR_FIELD_SRC_IP; + attr_list[1].id = SAI_ACL_ENTRY_ATTR_FIELD_DST_IP; + status = acl_api->create_acl_table(table_id, 2, attr_list); + return status; +} + +void switchlink_api_init() { + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_initialize(); + + status = sai_api_query(SAI_API_SWITCH, (void **)&switch_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_VIRTUAL_ROUTER, (void **)&vrf_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_VLAN, (void **)&vlan_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_STP, (void **)&stp_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_FDB, (void **)&fdb_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_ROUTER_INTERFACE, (void **)&rintf_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_NEIGHBOR, (void **)&neigh_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_NEXT_HOP, (void **)&nhop_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_NEXT_HOP_GROUP, (void **)&nhop_group_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_ROUTE, (void **)&route_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_IPMC, (void **)&ipmc_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_L2MC, (void **)&l2mc_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_HOST_INTERFACE, (void **)&host_intf_api); + assert(status == SAI_STATUS_SUCCESS); + status = sai_api_query(SAI_API_ACL, (void **)&acl_api); + assert(status == SAI_STATUS_SUCCESS); + + register_sai_notifications(); + register_sai_traps(); + + get_port_list(); } diff --git a/switchlink/src/switchlink_sai.h b/switchlink/src/switchlink_sai.h index dd09b46..ff18c1c 100644 --- a/switchlink/src/switchlink_sai.h +++ b/switchlink/src/switchlink_sai.h @@ -17,108 +17,86 @@ limitations under the License. #ifndef __SWITCHLINK_SAI_H__ #define __SWITCHLINK_SAI_H__ -extern int -switchlink_vrf_create(uint16_t vrf_id, switchlink_handle_t *vrf_h); +extern int switchlink_vrf_create(uint16_t vrf_id, switchlink_handle_t *vrf_h); -extern int -switchlink_interface_create(switchlink_db_interface_info_t *intf, - switchlink_handle_t *intf_h); +extern int switchlink_interface_create(switchlink_db_interface_info_t *intf, + switchlink_handle_t *intf_h); -extern int -switchlink_interface_forwarding_update(switchlink_handle_t intf_h, int af, - bool value); +extern int switchlink_interface_forwarding_update(switchlink_handle_t intf_h, + int af, + bool value); -extern int -switchlink_interface_mc_forwarding_update(switchlink_handle_t intf_h, int af, - bool value); +extern int switchlink_interface_mc_forwarding_update(switchlink_handle_t intf_h, + int af, + bool value); -extern int -switchlink_interface_urpf_mode_update(switchlink_handle_t intf_h, int af, - bool value); +extern int switchlink_interface_urpf_mode_update(switchlink_handle_t intf_h, + int af, + bool value); -extern int -switchlink_interface_delete(switchlink_db_interface_info_t *intf, - switchlink_handle_t intf_h); +extern int switchlink_interface_delete(switchlink_db_interface_info_t *intf, + switchlink_handle_t intf_h); -extern int -switchlink_stp_state_update(switchlink_db_interface_info_t *intf); +extern int switchlink_stp_state_update(switchlink_db_interface_info_t *intf); -extern int -switchlink_stp_group_create(switchlink_handle_t *stp_h); +extern int switchlink_stp_group_create(switchlink_handle_t *stp_h); -extern int -switchlink_stp_group_delete(switchlink_handle_t stp_h); +extern int switchlink_stp_group_delete(switchlink_handle_t stp_h); -extern int -switchlink_add_interface_to_bridge(switchlink_db_interface_info_t *intf); +extern int switchlink_add_interface_to_bridge( + switchlink_db_interface_info_t *intf); -extern int -switchlink_del_interface_from_bridge(switchlink_db_interface_info_t *intf, - switchlink_handle_t old_bridge_h); +extern int switchlink_del_interface_from_bridge( + switchlink_db_interface_info_t *intf, switchlink_handle_t old_bridge_h); -extern int -switchlink_bridge_create(switchlink_db_bridge_info_t *bridge_db_info); +extern int switchlink_bridge_create( + switchlink_db_bridge_info_t *bridge_db_info); -extern int -switchlink_bridge_update(switchlink_db_bridge_info_t *bridge_db_info); +extern int switchlink_bridge_update( + switchlink_db_bridge_info_t *bridge_db_info); -extern int -switchlink_bridge_delete(switchlink_db_bridge_info_t *bridge_db_info); +extern int switchlink_bridge_delete( + switchlink_db_bridge_info_t *bridge_db_info); -extern int -switchlink_lag_create(switchlink_handle_t *lag_h); +extern int switchlink_lag_create(switchlink_handle_t *lag_h); -extern int -switchlink_mac_create(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h); +extern int switchlink_mac_create(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h); -extern int -switchlink_mac_update(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h, - switchlink_handle_t intf_h); +extern int switchlink_mac_update(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h, + switchlink_handle_t intf_h); -extern int -switchlink_mac_delete(switchlink_mac_addr_t mac_addr, - switchlink_handle_t bridge_h); +extern int switchlink_mac_delete(switchlink_mac_addr_t mac_addr, + switchlink_handle_t bridge_h); -extern int -switchlink_neighbor_create(switchlink_db_neigh_info_t *neigh_info); +extern int switchlink_neighbor_create(switchlink_db_neigh_info_t *neigh_info); -extern int -switchlink_neighbor_delete(switchlink_db_neigh_info_t *neigh_info); +extern int switchlink_neighbor_delete(switchlink_db_neigh_info_t *neigh_info); -extern int -switchlink_nexthop_create(switchlink_db_neigh_info_t *neigh_info); +extern int switchlink_nexthop_create(switchlink_db_neigh_info_t *neigh_info); -extern int -switchlink_nexthop_delete(switchlink_db_neigh_info_t *neigh_info); +extern int switchlink_nexthop_delete(switchlink_db_neigh_info_t *neigh_info); -extern int -switchlink_ecmp_create(switchlink_db_ecmp_info_t *ecmp_info); +extern int switchlink_ecmp_create(switchlink_db_ecmp_info_t *ecmp_info); -extern int -switchlink_ecmp_delete(switchlink_db_ecmp_info_t *ecmp_info); +extern int switchlink_ecmp_delete(switchlink_db_ecmp_info_t *ecmp_info); -extern int -switchlink_route_create(switchlink_db_route_info_t *route_info); +extern int switchlink_route_create(switchlink_db_route_info_t *route_info); -extern int -switchlink_route_delete(switchlink_db_route_info_t *route_info); +extern int switchlink_route_delete(switchlink_db_route_info_t *route_info); -extern int -switchlink_mroute_create(switchlink_db_mroute_info_t *mroute_info); +extern int switchlink_mroute_create(switchlink_db_mroute_info_t *mroute_info); -extern int -switchlink_mroute_delete(switchlink_db_mroute_info_t *mroute_info); +extern int switchlink_mroute_delete(switchlink_db_mroute_info_t *mroute_info); -extern int -switchlink_mdb_create(switchlink_db_mdb_info_t *mdb_info); +extern int switchlink_mdb_create(switchlink_db_mdb_info_t *mdb_info); -extern int -switchlink_mdb_delete(switchlink_db_mdb_info_t *mdb_info); +extern int switchlink_mdb_delete(switchlink_db_mdb_info_t *mdb_info); -extern int -switchlink_send_packet(char *buf, uint32_t buf_size, uint16_t port_id); +extern int switchlink_send_packet(char *buf, + uint32_t buf_size, + uint16_t port_id); #endif /* __SWITCHLINK_SAI_H__ */ diff --git a/switchsai/Makefile.am b/switchsai/Makefile.am index 9d8aa35..7424732 100644 --- a/switchsai/Makefile.am +++ b/switchsai/Makefile.am @@ -33,9 +33,11 @@ libswitchsai_la_SOURCES = \ $(thrift_cpp_sources) \ src/saiacl.c \ src/saiapi.h \ +src/saibuffer.c \ src/sai.c \ src/sai_bmlib.c \ src/saifdb.c \ +src/saihash.c \ src/saihostintf.c \ src/saiinternal.h \ src/saiipmc.c \ @@ -45,11 +47,17 @@ src/saimirror.c \ src/saineighbor.c \ src/sainexthop.c \ src/sainexthopgroup.c \ +src/saiobject.c \ src/saipolicer.c \ src/saiport.c \ +src/saiqosmaps.c \ +src/saiqueue.c \ src/sairoute.c \ src/sairouter.c \ src/sairouterintf.c \ +src/saischeduler.c \ +src/saischedulergroup.c \ +src/saiudf.c \ src/saistp.c \ src/saiswitch.c \ src/saiutils.c \ diff --git a/switchsai/src/sai-param-check.c b/switchsai/src/sai-param-check.c index edd3633..0a3f5da 100644 --- a/switchsai/src/sai-param-check.c +++ b/switchsai/src/sai-param-check.c @@ -42,7 +42,7 @@ Each function has the following attribute parameter check rule Range Specified Boolean Min, Max - + 3. Get: Possible attribute list For each attribute: @@ -51,7 +51,7 @@ Each function has the following attribute parameter check rule Range Specified Boolean Min, Max - + 4. Destroy/Delete: No applicable parameter check */ @@ -60,464 +60,438 @@ Each function has the following attribute parameter check rule #include "saiinternal.h" typedef enum { - SAI_ATTRIBUTE_PARAM_API_TYPE_MIN, - SAI_ATTRIBUTE_PARAM_API_TYPE_CREATE = SAI_ATTRIBUTE_PARAM_API_TYPE_MIN, - SAI_ATTRIBUTE_PARAM_API_TYPE_SET, - SAI_ATTRIBUTE_PARAM_API_TYPE_GET, - SAI_ATTRIBUTE_PARAM_API_TYPE_MAX + SAI_ATTRIBUTE_PARAM_API_TYPE_MIN, + SAI_ATTRIBUTE_PARAM_API_TYPE_CREATE = SAI_ATTRIBUTE_PARAM_API_TYPE_MIN, + SAI_ATTRIBUTE_PARAM_API_TYPE_SET, + SAI_ATTRIBUTE_PARAM_API_TYPE_GET, + SAI_ATTRIBUTE_PARAM_API_TYPE_MAX } sai_attribute_param_api_type_t; typedef enum { - SAI_ATTRIBUTE_PARAM_TYPE_MIN, - SAI_ATTRIBUTE_PARAM_TYPE_RW = SAI_ATTRIBUTE_PARAM_TYPE_MIN, - SAI_ATTRIBUTE_PARAM_TYPE_RO, - SAI_ATTRIBUTE_PARAM_TYPE_WO, - SAI_ATTRIBUTE_PARAM_TYPE_MAX + SAI_ATTRIBUTE_PARAM_TYPE_MIN, + SAI_ATTRIBUTE_PARAM_TYPE_RW = SAI_ATTRIBUTE_PARAM_TYPE_MIN, + SAI_ATTRIBUTE_PARAM_TYPE_RO, + SAI_ATTRIBUTE_PARAM_TYPE_WO, + SAI_ATTRIBUTE_PARAM_TYPE_MAX } sai_attribute_param_type_e; - typedef struct sat_attribute_param_type_s sat_attribute_param_type_t; struct sai_attribute_param_default_s { - bool enable; - sai_attr_id_t id; - sai_attribute_value_t value; + bool enable; + sai_attr_id_t id; + sai_attribute_value_t value; }; typedef struct sai_attribute_param_default_s sai_attribute_param_default_t; struct sai_attribute_param_range_s { - bool enable; - sai_attr_id_t id; - sai_attribute_value_t min, max; + bool enable; + sai_attr_id_t id; + sai_attribute_value_t min, max; }; typedef struct sai_attribute_param_range_s sai_attribute_param_range_t; - struct sai_attribute_param_create_s { - sai_attribute_param_type_e type; - sai_attribute_param_default_t def; - sai_attribute_param_range_t range; + sai_attribute_param_type_e type; + sai_attribute_param_default_t def; + sai_attribute_param_range_t range; }; typedef struct sai_attribute_param_create_s sai_attribute_param_create_t; struct sai_attribute_param_set_s { - sai_attribute_param_type_e type; - sai_attribute_param_range_t range; + sai_attribute_param_type_e type; + sai_attribute_param_range_t range; }; typedef struct sai_attribute_param_set_s sai_attribute_param_set_t; - typedef struct { - tommy_node node; - union { - sai_attr_id_t id; - sai_attribute_param_create_t create; - sai_attribute_param_set_t set; - } u; + tommy_node node; + union { + sai_attr_id_t id; + sai_attribute_param_create_t create; + sai_attribute_param_set_t set; + } u; } sai_attribute_param_desc_t; /* create functions */ struct sai_attribute_param_check_create_s { - unsigned int mandatory_count; -// sai_attr_id_t *mandatory_list; - tommy_list mandatory_list; - unsigned int possible_count; -// sai_attribute_param_create_t *possible_list; - tommy_list possible_list; + unsigned int mandatory_count; + // sai_attr_id_t *mandatory_list; + tommy_list mandatory_list; + unsigned int possible_count; + // sai_attribute_param_create_t *possible_list; + tommy_list possible_list; }; -typedef struct sai_attribute_param_check_create_s sai_attribute_param_check_create_t; - +typedef struct sai_attribute_param_check_create_s + sai_attribute_param_check_create_t; /* set functions */ struct sai_attribute_param_check_set_s { - unsigned int possible_count; -// sai_attribute_param_create_t *possible_list; - tommy_list possible_list; + unsigned int possible_count; + // sai_attribute_param_create_t *possible_list; + tommy_list possible_list; }; typedef struct sai_attribute_param_check_set_s sai_attribute_param_check_set_t; typedef struct { - tommy_node node; - int api; - sai_attribute_param_check_create_t create; - sai_attribute_param_check_set_t set; + tommy_node node; + int api; + sai_attribute_param_check_create_t create; + sai_attribute_param_check_set_t set; } sai_attribute_param_t; sai_attribute_param_t sai_param_validation[SAI_API_MAX]; -int sai_param_check_init( void ) -{ - for(unsigned int i=0;iu.create.type = type; - p->u.create.def.id = id; - p->u.create.def.value = *def; - p->u.create.def.enable = TRUE; - } - else if(mandatory) { - p->u.id = id; - } - if(min || max) { - // range is valid - // set the defaults to ignore min & max? - if(min) { - p->u.create.range.min = *min; - } - if(max) { - p->u.create.range.min = *max; - } - p->u.create.range.id = id; - p->u.create.type = type; - p->u.create.range.enable = TRUE; - } - // insert into list - if(mandatory) { - tommy_list_insert_tail(&(sai_param_validation[api].create.mandatory_list), &(p->node), p); - } - else { - tommy_list_insert_tail(&(sai_param_validation[api].create.possible_list), &(p->node), p); - } +int sai_param_check_insert(int api, + sai_attribute_param_api_type_t api_type, + sai_attr_id_t id, + sai_attribute_value_t *def, + sai_attribute_value_t *min, + sai_attribute_value_t *max, + sai_attribute_param_type_e type, + bool mandatory) { + sai_attribute_param_desc_t *p = NULL; + // create a tommy node to hold the values + p = switch_malloc(sizeof(*p), 1); + if (p) { + memset(p, 0, sizeof(*p)); + if (api_type == SAI_ATTRIBUTE_PARAM_API_TYPE_CREATE) { + if (def) { + // default value extract + p->u.create.type = type; + p->u.create.def.id = id; + p->u.create.def.value = *def; + p->u.create.def.enable = TRUE; + } else if (mandatory) { + p->u.id = id; + } + if (min || max) { + // range is valid + // set the defaults to ignore min & max? + if (min) { + p->u.create.range.min = *min; } - else if(api_type == SAI_ATTRIBUTE_PARAM_API_TYPE_SET) { + if (max) { + p->u.create.range.min = *max; } + p->u.create.range.id = id; + p->u.create.type = type; + p->u.create.range.enable = TRUE; + } + // insert into list + if (mandatory) { + tommy_list_insert_tail( + &(sai_param_validation[api].create.mandatory_list), &(p->node), p); + } else { + tommy_list_insert_tail( + &(sai_param_validation[api].create.possible_list), &(p->node), p); + } + } else if (api_type == SAI_ATTRIBUTE_PARAM_API_TYPE_SET) { } - return 0; + } + return 0; } - -int sai_param_check(int api, sai_attribute_param_api_type_t api_type, - unsigned int attr_count, sai_attribute_t *attr_list) -{ - return 0; +int sai_param_check(int api, + sai_attribute_param_api_type_t api_type, + unsigned int attr_count, + sai_attribute_t *attr_list) { + return 0; } typedef enum sai_param_rw_type_ { - SAI_ATTRIBUTE_RW_NONE = 0, - SAI_ATTRIBUTE_RW_READ_ONLY = 1, - SAI_ATTRIBUTE_RW_READ_WRITE = 2, - SAI_ATTRIBUTE_RW_WRITE_ONLY = 3 + SAI_ATTRIBUTE_RW_NONE = 0, + SAI_ATTRIBUTE_RW_READ_ONLY = 1, + SAI_ATTRIBUTE_RW_READ_WRITE = 2, + SAI_ATTRIBUTE_RW_WRITE_ONLY = 3 } sai_param_rw_type_t; typedef enum sai_param_data_type_ { - SAI_ATTRIBUTE_DATA_TYPE_NONE = 0, - SAI_ATTRIBUTE_DATA_TYPE_BOOL = 1, - SAI_ATTRIBUTE_DATA_TYPE_CHAR = 2, - SAI_ATTRIBUTE_DATA_TYPE_U8 = 3, - SAI_ATTRIBUTE_DATA_TYPE_S8 = 4, - SAI_ATTRIBUTE_DATA_TYPE_U16 = 5, - SAI_ATTRIBUTE_DATA_TYPE_S16 = 6, - SAI_ATTRIBUTE_DATA_TYPE_U32 = 7, - SAI_ATTRIBUTE_DATA_TYPE_S32 = 8, - SAI_ATTRIBUTE_DATA_TYPE_U64 = 9, - SAI_ATTRIBUTE_DATA_TYPE_S64 = 10, - SAI_ATTRIBUTE_DATA_TYPE_MAC = 11, - SAI_ATTRIBUTE_DATA_TYPE_IP4 = 12, - SAI_ATTRIBUTE_DATA_TYPE_IP6 = 13, - SAI_ATTRIBUTE_DATA_TYPE_IP_ADDRESS = 14, - SAI_ATTRIBUTE_DATA_TYPE_OID = 15, - SAI_ATTRIBUTE_DATA_TYPE_OID_LIST = 16, - SAI_ATTRIBUTE_DATA_TYPE_U32_LIST = 17, - SAI_ATTRIBUTE_DATA_TYPE_S32_LIST = 18, - SAI_ATTRIBUTE_DATA_TYPE_U32_RANGE = 19, - SAI_ATTRIBUTE_DATA_TYPE_S32_RANGE = 20, - SAI_ATTRIBUTE_DATA_TYPE_VLAN_LIST = 21, - SAI_ATTRIBUTE_DATA_TYPE_VLAN_PORT_LIST = 22, - SAI_ATTRIBUTE_DATA_TYPE_ACL_FIELD = 23, - SAI_ATTRIBUTE_DATA_TYPE_ACL_ACTION = 24, - SAI_ATTRIBUTE_DATA_TYPE_PORT_BREAKOUT = 25 + SAI_ATTRIBUTE_DATA_TYPE_NONE = 0, + SAI_ATTRIBUTE_DATA_TYPE_BOOL = 1, + SAI_ATTRIBUTE_DATA_TYPE_CHAR = 2, + SAI_ATTRIBUTE_DATA_TYPE_U8 = 3, + SAI_ATTRIBUTE_DATA_TYPE_S8 = 4, + SAI_ATTRIBUTE_DATA_TYPE_U16 = 5, + SAI_ATTRIBUTE_DATA_TYPE_S16 = 6, + SAI_ATTRIBUTE_DATA_TYPE_U32 = 7, + SAI_ATTRIBUTE_DATA_TYPE_S32 = 8, + SAI_ATTRIBUTE_DATA_TYPE_U64 = 9, + SAI_ATTRIBUTE_DATA_TYPE_S64 = 10, + SAI_ATTRIBUTE_DATA_TYPE_MAC = 11, + SAI_ATTRIBUTE_DATA_TYPE_IP4 = 12, + SAI_ATTRIBUTE_DATA_TYPE_IP6 = 13, + SAI_ATTRIBUTE_DATA_TYPE_IP_ADDRESS = 14, + SAI_ATTRIBUTE_DATA_TYPE_OID = 15, + SAI_ATTRIBUTE_DATA_TYPE_OID_LIST = 16, + SAI_ATTRIBUTE_DATA_TYPE_U32_LIST = 17, + SAI_ATTRIBUTE_DATA_TYPE_S32_LIST = 18, + SAI_ATTRIBUTE_DATA_TYPE_U32_RANGE = 19, + SAI_ATTRIBUTE_DATA_TYPE_S32_RANGE = 20, + SAI_ATTRIBUTE_DATA_TYPE_VLAN_LIST = 21, + SAI_ATTRIBUTE_DATA_TYPE_VLAN_PORT_LIST = 22, + SAI_ATTRIBUTE_DATA_TYPE_ACL_FIELD = 23, + SAI_ATTRIBUTE_DATA_TYPE_ACL_ACTION = 24, + SAI_ATTRIBUTE_DATA_TYPE_PORT_BREAKOUT = 25 } sai_param_data_type_t; typedef struct sai_param_attribute_ { - tommy_node node; - sai_attr_id_t id; - bool mandatory; - bool create; - bool set; - bool get; - sai_param_data_type_t data_type; - sai_param_rw_type_t rw_type; - sai_attribute_value_t default_value; + tommy_node node; + sai_attr_id_t id; + bool mandatory; + bool create; + bool set; + bool get; + sai_param_data_type_t data_type; + sai_param_rw_type_t rw_type; + sai_attribute_value_t default_value; } sai_param_attribute_t; typedef struct sai_param_attribute_info_ { - tommy_node node; - char attribute_desc[20]; - bool match_one; - tommy_list attribute_list; + tommy_node node; + char attribute_desc[20]; + bool match_one; + tommy_list attribute_list; } sai_param_attribute_info_t; typedef struct sai_param_module_info_ { - char module_name[20]; - tommy_list attribute_info_list; + char module_name[20]; + tommy_list attribute_info_list; } sai_param_module_info_t; sai_param_module_info_t param_module_info[SAI_API_MAX]; -static char *sai_param_json_file_get(sai_api_id_t api_id) -{ - switch (api_id) { - case SAI_API_SWITCH: - return "saiswitch.json" - case SAI_API_PORT: - return "saiport.json" - case SAI_API_FDB: - return "saifdb.json" - case SAI_API_VLAN: - return "saivlan.json" - case SAI_API_VIRTUAL_ROUTER: - return "sairouter.json" - case SAI_API_ROUTE: - return "sairoute.json" - case SAI_API_NEXT_HOP: - return "sainextop.json" - case SAI_API_NEXT_HOP_GROUP: - return "sainexthopgroup.json" - case SAI_API_ROUTER_INTERFACE: - return "sairouterinterface.json" - case SAI_API_NEIGHBOR: - return "saineighbor.json" - case SAI_API_ACL: - return "saiacl.json" - case SAI_API_HOST_INTERFACE: - return "saihostintf.json" - case SAI_API_MIRROR: - return "saimirror.json" - case SAI_API_STP: - return "saistp.json" - case SAI_API_LAG: - return "sailag.json" - default: - return NULL; - } -} - -static sai_param_rw_type_t -sai_param_rw_type_get( - _In_ char *rw_type) { - if (!strcmp(rw_type, "READ_ONLY")) { - return SAI_ATTRIBUTE_RW_READ_ONLY; - } else if (!strcmp(rw_type, "READ_WRITE")) { - return SAI_ATTRIBUTE_RW_READ_WRITE; - } else if (!strcmp(rw_type, "WRITE_ONLY")) { - return SAI_ATTRIBUTE_RW_WRITE_ONLY; - } else { - return SAI_ATTRIBUTE_RW_TYPE_NONE; +static char *sai_param_json_file_get(sai_api_id_t api_id) { + switch (api_id) { + case SAI_API_SWITCH: + return "saiswitch.json" case SAI_API_PORT + : return "saiport.json" case SAI_API_FDB + : return "saifdb.json" case SAI_API_VLAN + : return "saivlan.json" case SAI_API_VIRTUAL_ROUTER + : return "sairouter.json" case SAI_API_ROUTE + : return "sairoute.json" case SAI_API_NEXT_HOP + : return "sainextop.json" case SAI_API_NEXT_HOP_GROUP + : return "sainexthopgroup." + "json" case SAI_API_ROUTER_INTERFACE + : return "sairouterinterface.json" case SAI_API_NEIGHBOR + : return "saineighbor.json" case SAI_API_ACL + : return "saiacl.json" case SAI_API_HOST_INTERFACE + : return "saihostintf.json" case SAI_API_MIRROR + : return "saimirror.json" case SAI_API_STP + : return "saistp.json" case SAI_API_LAG + : return "sailag.json" default + : return NULL; + } } -static sai_param_data_type_t -sai_param_data_type_get( - _In_ char *data_type) { +static sai_param_rw_type_t sai_param_rw_type_get(_In_ char *rw_type) { + if (!strcmp(rw_type, "READ_ONLY")) { + return SAI_ATTRIBUTE_RW_READ_ONLY; + } else if (!strcmp(rw_type, "READ_WRITE")) { + return SAI_ATTRIBUTE_RW_READ_WRITE; + } else if (!strcmp(rw_type, "WRITE_ONLY")) { + return SAI_ATTRIBUTE_RW_WRITE_ONLY; + } else { + return SAI_ATTRIBUTE_RW_TYPE_NONE; + } + + static sai_param_data_type_t sai_param_data_type_get(_In_ char *data_type) { if (!strcmp(data_type, "bool")) { - return SAI_ATTRIBUTE_DATA_TYPE_BOOL; + return SAI_ATTRIBUTE_DATA_TYPE_BOOL; } else if (!strcmp(data_type, "chardata")) { - return SAI_ATTRIBUTE_DATA_TYPE_CHAR; + return SAI_ATTRIBUTE_DATA_TYPE_CHAR; } else if (!strcmp(data_type, "u8")) { - return SAI_ATTRIBUTE_DATA_TYPE_U8; + return SAI_ATTRIBUTE_DATA_TYPE_U8; } else if (!strcmp(data_type, "s8")) { - return SAI_ATTRIBUTE_DATA_TYPE_S8; + return SAI_ATTRIBUTE_DATA_TYPE_S8; } else if (!strcmp(data_type, "u16")) { - return SAI_ATTRIBUTE_DATA_TYPE_U16; + return SAI_ATTRIBUTE_DATA_TYPE_U16; } else if (!strcmp(data_type, "s16")) { - return SAI_ATTRIBUTE_DATA_TYPE_S16; + return SAI_ATTRIBUTE_DATA_TYPE_S16; } else if (!strcmp(data_type, "u32")) { - return SAI_ATTRIBUTE_DATA_TYPE_U32; + return SAI_ATTRIBUTE_DATA_TYPE_U32; } else if (!strcmp(data_type, "s32")) { - return SAI_ATTRIBUTE_DATA_TYPE_S32; + return SAI_ATTRIBUTE_DATA_TYPE_S32; } else if (!strcmp(data_type, "u64")) { - return SAI_ATTRIBUTE_DATA_TYPE_U64; + return SAI_ATTRIBUTE_DATA_TYPE_U64; } else if (!strcmp(data_type, "s64")) { - return SAI_ATTRIBUTE_DATA_TYPE_S64; + return SAI_ATTRIBUTE_DATA_TYPE_S64; } else if (!strcmp(data_type, "mac")) { - return SAI_ATTRIBUTE_DATA_TYPE_MAC; + return SAI_ATTRIBUTE_DATA_TYPE_MAC; } else if (!strcmp(data_type, "ip4")) { - return SAI_ATTRIBUTE_DATA_TYPE_IP4; + return SAI_ATTRIBUTE_DATA_TYPE_IP4; } else if (!strcmp(data_type, "ip6")) { - return SAI_ATTRIBUTE_DATA_TYPE_IP6; + return SAI_ATTRIBUTE_DATA_TYPE_IP6; } else if (!strcmp(data_type, "ip_address")) { - return SAI_ATTRIBUTE_DATA_TYPE_IP_ADDRESS; + return SAI_ATTRIBUTE_DATA_TYPE_IP_ADDRESS; } else if (!strcmp(data_type, "oid")) { - return SAI_ATTRIBUTE_DATA_TYPE_OID; + return SAI_ATTRIBUTE_DATA_TYPE_OID; } else if (!strcmp(data_type, "oid_list")) { - return SAI_ATTRIBUTE_DATA_TYPE_OID_LIST; + return SAI_ATTRIBUTE_DATA_TYPE_OID_LIST; } else if (!strcmp(data_type, "u32_list")) { - return SAI_ATTRIBUTE_DATA_TYPE_U32_LIST; + return SAI_ATTRIBUTE_DATA_TYPE_U32_LIST; } else if (!strcmp(data_type, "s32_list")) { - return SAI_ATTRIBUTE_DATA_TYPE_S32_LIST; + return SAI_ATTRIBUTE_DATA_TYPE_S32_LIST; } else if (!strcmp(data_type, "u32_range")) { - return SAI_ATTRIBUTE_DATA_TYPE_U32_RANGE; + return SAI_ATTRIBUTE_DATA_TYPE_U32_RANGE; } else if (!strcmp(data_type, "s32_range")) { - return SAI_ATTRIBUTE_DATA_TYPE_S32_RANGE; + return SAI_ATTRIBUTE_DATA_TYPE_S32_RANGE; } else if (!strcmp(data_type, "vlan_list")) { - return SAI_ATTRIBUTE_DATA_TYPE_VLAN_LIST; + return SAI_ATTRIBUTE_DATA_TYPE_VLAN_LIST; } else if (!strcmp(data_type, "vlan_port_list")) { - return SAI_ATTRIBUTE_DATA_TYPE_VLAN_PORT_LIST; + return SAI_ATTRIBUTE_DATA_TYPE_VLAN_PORT_LIST; } else if (!strcmp(data_type, "acl_field")) { - return SAI_ATTRIBUTE_DATA_TYPE_ACL_FIELD; + return SAI_ATTRIBUTE_DATA_TYPE_ACL_FIELD; } else if (!strcmp(data_type, "acl_action")) { - return SAI_ATTRIBUTE_DATA_TYPE_ACL_ACTION; + return SAI_ATTRIBUTE_DATA_TYPE_ACL_ACTION; } else if (!strcmp(data_type, "port_breakout")) { - return SAI_ATTRIBUTE_DATA_TYPE_PORT_BREAKOUT; + return SAI_ATTRIBUTE_DATA_TYPE_PORT_BREAKOUT; } else { - return SAI_ATTRIBUTE_DATA_TYPE_NONE; -} + return SAI_ATTRIBUTE_DATA_TYPE_NONE; + } -sai_status_t sai_param_parse_attributes( - _In_ cJSON *attr_object - _In_ sai_param_attribute_info_t *attr_info) -{ - sai_param_attribute_t *attr = NULL; + sai_status_t sai_param_parse_attributes( + _In_ cJSON * attr_object _In_ sai_param_attribute_info_t * attr_info) { + sai_param_attribute_t *attr = NULL; - while (attr_object) { + while (attr_object) { attr = SAI_MALLOC(sizeof(sai_param_attribute_t)); if (!attr) { - return SAI_STATUS_NO_MEMORY; + return SAI_STATUS_NO_MEMORY; } attr->mandatory = FALSE; attr->create = FALSE; attr->set = FALSE; attr->get = FALSE; if (!strcmp(attr_object->string, "name")) { - //convert string to enum + // convert string to enum } else if (!strcmp(attr_object->string, "mandatory")) { - if (!strcmp(attr_object->valueString, "true")) { - attr->mandatory = TRUE; - } + if (!strcmp(attr_object->valueString, "true")) { + attr->mandatory = TRUE; + } } else if (!strcmp(attr_object->string, "create")) { - if (!strcmp(attr_object->valueString, "true")) { - attr->create = TRUE; - } + if (!strcmp(attr_object->valueString, "true")) { + attr->create = TRUE; + } } else if (!strcmp(attr_object->string, "set")) { - if (!strcmp(attr_object->valueString, "true")) { - attr->set = TRUE; - } + if (!strcmp(attr_object->valueString, "true")) { + attr->set = TRUE; + } } else if (!strcmp(attr_object->string, "get")) { - if (!strcmp(attr_object->valueString, "true")) { - attr->get = TRUE; - } + if (!strcmp(attr_object->valueString, "true")) { + attr->get = TRUE; + } } else if (!strcmp(attr_object->string, "rw_type")) { - attr->rw_type = sai_param_rw_type_get(attr_object->valueString); + attr->rw_type = sai_param_rw_type_get(attr_object->valueString); } else if (!strcmp(attr_object->string, "data_type")) { - attr->data_type = sai_param_data_type_get(attr_object->valueString); + attr->data_type = sai_param_data_type_get(attr_object->valueString); } - tommy_list_insert_tail(&(attr_info->attributes_list), &(attr->node), attr); + tommy_list_insert_tail( + &(attr_info->attributes_list), &(attr->node), attr); attr_object = attr_object->next; + } } -} -sai_status_t sai_param_parse_atttibute_info( - _In_ cJSON *attributes_object, - _Out_ sai_param_module_info_t *module_info) -{ - sai_param_attribute_info_t *attr_info = NULL; - cJSON *attr_info_object = NULL; + sai_status_t sai_param_parse_atttibute_info( + _In_ cJSON * attributes_object, + _Out_ sai_param_module_info_t * module_info) { + sai_param_attribute_info_t *attr_info = NULL; + cJSON *attr_info_object = NULL; - while (attributes_object) { + while (attributes_object) { attr_info = SAI_MALLOC(sizeof(sai_param_attribute_info_t)); if (!attr_info) { - return SAI_STATUS_NO_MEMORY; + return SAI_STATUS_NO_MEMORY; } tommy_list_init(&(attr_info->attributes_list)); attr_info_object = attributes_object->child; while (attr_info_object) { - if (attr_info_object->type == cJSON_String) { - if (!strcmp(attr_info_object->string, "attribute_desc")) { - strcpy(attr_info->attribute_desc, attr_info_object->valueString); - } else if (!strcmp(attr_info_object->string, "match_one")) { - attr_info->match_one = TRUE; - } - } else if (attr_info_object->type == cJSON_Object) { - if (!strcmp(attr_info_object->string, "attribute_list")) { - status = sai_param_parse_attributes(attr_info_object->child, attr_info); - if (status != SAI_STATUS_SUCCESS) { - SAI_FREE(attr_info); - return status; - } - } + if (attr_info_object->type == cJSON_String) { + if (!strcmp(attr_info_object->string, "attribute_desc")) { + strcpy(attr_info->attribute_desc, attr_info_object->valueString); + } else if (!strcmp(attr_info_object->string, "match_one")) { + attr_info->match_one = TRUE; + } + } else if (attr_info_object->type == cJSON_Object) { + if (!strcmp(attr_info_object->string, "attribute_list")) { + status = sai_param_parse_attributes(attr_info_object->child, + attr_info); + if (status != SAI_STATUS_SUCCESS) { + SAI_FREE(attr_info); + return status; + } } - attr_info_object = attr_info_object->next; + } + attr_info_object = attr_info_object->next; } - tommy_list_insert_tail(&(module_info->attribute_info_list), &(attr_info->node), attr_info); + tommy_list_insert_tail( + &(module_info->attribute_info_list), &(attr_info->node), attr_info); attributes_object = attributes_object->next; + } + return SAI_STATUS_SUCCESS; } - return SAI_STATUS_SUCCESS; -} -sai_status_t sai_param_parse_json( - _In_ sai_api_id_t api_id, - _In_ char *file_name) -{ - cJSON *module_object = NULL; - cJSON *attr_info_object = NULL; - cJSON *attr_object = NULL; - sai_param_module_info_t *module_info = NULL; - sai_param_atribute_info_t *attr_info = NULL; - sai_param_attribute_t *attr = NULL; - - object = cJSON_Parse(file_name); - module_info = param_module_info[api_id]; - tommy_list_init(&(module_info->attribute_info_list)); - - while (module_object) { + sai_status_t sai_param_parse_json(_In_ sai_api_id_t api_id, + _In_ char *file_name) { + cJSON *module_object = NULL; + cJSON *attr_info_object = NULL; + cJSON *attr_object = NULL; + sai_param_module_info_t *module_info = NULL; + sai_param_atribute_info_t *attr_info = NULL; + sai_param_attribute_t *attr = NULL; + + object = cJSON_Parse(file_name); + module_info = param_module_info[api_id]; + tommy_list_init(&(module_info->attribute_info_list)); + + while (module_object) { if (module_object->type == cJSON_String) { - if (!strcmp(module_object->string, "module_info")) { - strcpy(module_info->module_name, module_object->valueString); - } + if (!strcmp(module_object->string, "module_info")) { + strcpy(module_info->module_name, module_object->valueString); + } } else if (module_object->type == cJSON_Object) { - if (!strcmp(module_object->string, "attributes")) { - sai_param_parse_attribute_info(module_object->child, module_info); - } + if (!strcmp(module_object->string, "attributes")) { + sai_param_parse_attribute_info(module_object->child, module_info); + } } module_object = module_object->next; + } } -} -sai_status_t sai_param_load_modules_json() -{ - sai_api_id_t api_id; - char *filename = NULL; + sai_status_t sai_param_load_modules_json() { + sai_api_id_t api_id; + char *filename = NULL; - for (api_id = 0; api_id < SAI_API_MAX; api_id++) { + for (api_id = 0; api_id < SAI_API_MAX; api_id++) { filename = sai_param_json_file_get(api_id); if (file_name) { - status = sai_param_parse_json(api_id, filename); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to load json"); - } + status = sai_param_parse_json(api_id, filename); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to load json"); + } } + } } -} - - diff --git a/switchsai/src/sai.c b/switchsai/src/sai.c index 1d055ae..c35c073 100644 --- a/switchsai/src/sai.c +++ b/switchsai/src/sai.c @@ -59,116 +59,133 @@ static const char *module[] = { "L2MC", }; -sai_status_t sai_api_query( - _In_ sai_api_t sai_api_id, - _Out_ void ** api_method_table) -{ - sai_status_t status = SAI_STATUS_SUCCESS; - - SAI_LOG_ENTER(); - - if (!api_method_table) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null api method table: %s", - sai_status_to_string(status)); - return status; - } - - switch (sai_api_id) { - case SAI_API_SWITCH: - *api_method_table = &sai_api_service.switch_api; - break; - - case SAI_API_PORT: - *api_method_table = &sai_api_service.port_api; - break; - - case SAI_API_FDB: - *api_method_table = &sai_api_service.fdb_api; - break; - - case SAI_API_VLAN: - *api_method_table = &sai_api_service.vlan_api; - break; - - case SAI_API_VIRTUAL_ROUTER: - *api_method_table = &sai_api_service.vr_api; - break; - - case SAI_API_ROUTER_INTERFACE: - *api_method_table = &sai_api_service.rif_api; - break; - - case SAI_API_ROUTE: - *api_method_table = &sai_api_service.route_api; - break; - - case SAI_API_NEIGHBOR: - *api_method_table = &sai_api_service.neighbor_api; - break; - - case SAI_API_NEXT_HOP: - *api_method_table = &sai_api_service.nhop_api; - break; - - case SAI_API_NEXT_HOP_GROUP: - *api_method_table = &sai_api_service.nhop_group_api; - break; - - case SAI_API_QOS_MAPS: - *api_method_table = &sai_api_service.qos_api; - break; - - case SAI_API_ACL: - *api_method_table = &sai_api_service.acl_api; - break; - - case SAI_API_LAG: - *api_method_table = &sai_api_service.lag_api; - break; - - case SAI_API_STP: - *api_method_table = &sai_api_service.stp_api; - break; - - case SAI_API_HOST_INTERFACE: - *api_method_table = &sai_api_service.hostif_api; - break; - - case SAI_API_MIRROR: - *api_method_table = &sai_api_service.mirror_api; - break; - - case SAI_API_SAMPLEPACKET: - *api_method_table = &sai_api_service.samplepacket_api; - break; - - case SAI_API_IPMC: - *api_method_table = &sai_api_service.ipmc_api; - break; - - case SAI_API_L2MC: - *api_method_table = &sai_api_service.l2mc_api; - break; - - case SAI_API_POLICER: - *api_method_table = &sai_api_service.policer_api; - break; - - default: - *api_method_table = NULL; - status = SAI_STATUS_INVALID_PARAMETER; - } - - if (status == SAI_STATUS_SUCCESS) { - SAI_LOG_INFO("api query for module: %s", module[sai_api_id]); - } else { - SAI_LOG_ERROR("api query failed. invalid api id"); - } +sai_status_t sai_api_query(_In_ sai_api_t sai_api_id, + _Out_ void **api_method_table) { + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_ENTER(); + if (!api_method_table) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null api method table: %s", sai_status_to_string(status)); return status; + } + + switch (sai_api_id) { + case SAI_API_SWITCH: + *api_method_table = &sai_api_service.switch_api; + break; + + case SAI_API_PORT: + *api_method_table = &sai_api_service.port_api; + break; + + case SAI_API_FDB: + *api_method_table = &sai_api_service.fdb_api; + break; + + case SAI_API_VLAN: + *api_method_table = &sai_api_service.vlan_api; + break; + + case SAI_API_VIRTUAL_ROUTER: + *api_method_table = &sai_api_service.vr_api; + break; + + case SAI_API_ROUTER_INTERFACE: + *api_method_table = &sai_api_service.rif_api; + break; + + case SAI_API_ROUTE: + *api_method_table = &sai_api_service.route_api; + break; + + case SAI_API_NEIGHBOR: + *api_method_table = &sai_api_service.neighbor_api; + break; + + case SAI_API_NEXT_HOP: + *api_method_table = &sai_api_service.nhop_api; + break; + + case SAI_API_NEXT_HOP_GROUP: + *api_method_table = &sai_api_service.nhop_group_api; + break; + + case SAI_API_QOS_MAPS: + *api_method_table = &sai_api_service.qos_api; + break; + + case SAI_API_ACL: + *api_method_table = &sai_api_service.acl_api; + break; + + case SAI_API_LAG: + *api_method_table = &sai_api_service.lag_api; + break; + + case SAI_API_STP: + *api_method_table = &sai_api_service.stp_api; + break; + + case SAI_API_HOST_INTERFACE: + *api_method_table = &sai_api_service.hostif_api; + break; + + case SAI_API_MIRROR: + *api_method_table = &sai_api_service.mirror_api; + break; + + case SAI_API_SAMPLEPACKET: + *api_method_table = &sai_api_service.samplepacket_api; + break; + + case SAI_API_HASH: + *api_method_table = &sai_api_service.hash_api; + break; + + case SAI_API_UDF: + *api_method_table = &sai_api_service.udf_api; + break; + + case SAI_API_IPMC: + *api_method_table = &sai_api_service.ipmc_api; + break; + + case SAI_API_L2MC: + *api_method_table = &sai_api_service.l2mc_api; + break; + + case SAI_API_POLICER: + *api_method_table = &sai_api_service.policer_api; + break; + + case SAI_API_QUEUE: + *api_method_table = &sai_api_service.queue_api; + break; + + case SAI_API_BUFFERS: + *api_method_table = &sai_api_service.buffer_api; + break; + + case SAI_API_SCHEDULER: + *api_method_table = &sai_api_service.scheduler_api; + break; + + default: + *api_method_table = NULL; + status = SAI_STATUS_INVALID_PARAMETER; + } + + if (status == SAI_STATUS_SUCCESS) { + SAI_LOG_INFO("api query for module: %s", module[sai_api_id]); + } else { + SAI_LOG_ERROR("api query failed. invalid api id"); + } + + SAI_LOG_EXIT(); + + return status; } /* @@ -182,140 +199,158 @@ sai_status_t sai_api_query( * Return SAI_OBJECT_TYPE_NULL when sai_object_id is not valid. * Otherwise, return a valid sai object type SAI_OBJECT_TYPE_XXX */ -sai_object_type_t -sai_object_type_query( - _In_ sai_object_id_t sai_object_id) { - - SAI_LOG_ENTER(); - - sai_object_type_t object_type = SAI_OBJECT_TYPE_NULL; - switch_nhop_index_type_t nhop_type = 0; - switch_handle_type_t handle_type = SWITCH_HANDLE_TYPE_NONE; - - handle_type = switch_handle_get_type(sai_object_id); - switch (handle_type) { - case SWITCH_HANDLE_TYPE_PORT: - object_type = SAI_OBJECT_TYPE_PORT; - break; - case SWITCH_HANDLE_TYPE_LAG: - object_type = SAI_OBJECT_TYPE_LAG; - break; - case SWITCH_HANDLE_TYPE_LAG_MEMBER: - object_type = SAI_OBJECT_TYPE_LAG_MEMBER; - break; - case SWITCH_HANDLE_TYPE_INTERFACE: - object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE; - break; - case SWITCH_HANDLE_TYPE_VRF: - object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER; - break; - case SWITCH_HANDLE_TYPE_NHOP: - nhop_type = switch_api_nhop_type_get(sai_object_id); - if (nhop_type == SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { - object_type = SAI_OBJECT_TYPE_NEXT_HOP; - } else if (nhop_type == SWITCH_NHOP_INDEX_TYPE_ECMP) { - object_type = SAI_OBJECT_TYPE_NEXT_HOP_GROUP; - } else { - object_type = SAI_OBJECT_TYPE_NULL; - } - break; - case SWITCH_HANDLE_TYPE_STP: - object_type = SAI_OBJECT_TYPE_STP_INSTANCE; - break; - case SWITCH_HANDLE_TYPE_ACL: - object_type = SAI_OBJECT_TYPE_ACL_TABLE; - break; - case SWITCH_HANDLE_TYPE_ACE: - object_type = SAI_OBJECT_TYPE_ACL_ENTRY; - break; - case SWITCH_HANDLE_TYPE_HOSTIF: - object_type = SAI_OBJECT_TYPE_HOST_INTERFACE; - break; - case SWITCH_HANDLE_TYPE_HOSTIF_GROUP: - object_type = SAI_OBJECT_TYPE_TRAP_GROUP; - break; - case SWITCH_HANDLE_TYPE_MIRROR: - object_type = SAI_OBJECT_TYPE_MIRROR; - break; - case SWITCH_HANDLE_TYPE_MGID: - object_type = SAI_OBJECT_TYPE_NEXT_HOP_GROUP; - break; - case SWITCH_HANDLE_TYPE_ACL_COUNTER: - object_type = SAI_OBJECT_TYPE_ACL_COUNTER; - break; - case SWITCH_HANDLE_TYPE_METER: - object_type = SAI_OBJECT_TYPE_POLICER; - break; - default: - object_type = SAI_OBJECT_TYPE_NULL; - break; - } - - SAI_LOG_INFO("object type query: %lx : %s", - sai_object_id, - sai_object_type_to_string(object_type)); - - SAI_LOG_EXIT(); - - return object_type; +sai_object_type_t sai_object_type_query(_In_ sai_object_id_t sai_object_id) { + SAI_LOG_ENTER(); + + sai_object_type_t object_type = SAI_OBJECT_TYPE_NULL; + switch_nhop_index_type_t nhop_type = 0; + switch_handle_type_t handle_type = SWITCH_HANDLE_TYPE_NONE; + + handle_type = switch_handle_get_type(sai_object_id); + switch (handle_type) { + case SWITCH_HANDLE_TYPE_PORT: + object_type = SAI_OBJECT_TYPE_PORT; + break; + case SWITCH_HANDLE_TYPE_LAG: + object_type = SAI_OBJECT_TYPE_LAG; + break; + case SWITCH_HANDLE_TYPE_LAG_MEMBER: + object_type = SAI_OBJECT_TYPE_LAG_MEMBER; + break; + case SWITCH_HANDLE_TYPE_INTERFACE: + object_type = SAI_OBJECT_TYPE_ROUTER_INTERFACE; + break; + case SWITCH_HANDLE_TYPE_VRF: + object_type = SAI_OBJECT_TYPE_VIRTUAL_ROUTER; + break; + case SWITCH_HANDLE_TYPE_NHOP: + nhop_type = switch_api_nhop_type_get(sai_object_id); + if (nhop_type == SWITCH_NHOP_INDEX_TYPE_ONE_PATH) { + object_type = SAI_OBJECT_TYPE_NEXT_HOP; + } else if (nhop_type == SWITCH_NHOP_INDEX_TYPE_ECMP) { + object_type = SAI_OBJECT_TYPE_NEXT_HOP_GROUP; + } else { + object_type = SAI_OBJECT_TYPE_NULL; + } + break; + case SWITCH_HANDLE_TYPE_STP: + object_type = SAI_OBJECT_TYPE_STP_INSTANCE; + break; + case SWITCH_HANDLE_TYPE_ACL: + object_type = SAI_OBJECT_TYPE_ACL_TABLE; + break; + case SWITCH_HANDLE_TYPE_ACE: + object_type = SAI_OBJECT_TYPE_ACL_ENTRY; + break; + case SWITCH_HANDLE_TYPE_HOSTIF: + object_type = SAI_OBJECT_TYPE_HOST_INTERFACE; + break; + case SWITCH_HANDLE_TYPE_HOSTIF_GROUP: + object_type = SAI_OBJECT_TYPE_TRAP_GROUP; + break; + case SWITCH_HANDLE_TYPE_MIRROR: + object_type = SAI_OBJECT_TYPE_MIRROR; + break; + case SWITCH_HANDLE_TYPE_MGID: + object_type = SAI_OBJECT_TYPE_NEXT_HOP_GROUP; + break; + case SWITCH_HANDLE_TYPE_ACL_COUNTER: + object_type = SAI_OBJECT_TYPE_ACL_COUNTER; + break; + case SWITCH_HANDLE_TYPE_METER: + object_type = SAI_OBJECT_TYPE_POLICER; + break; + case SWITCH_HANDLE_TYPE_SCHEDULER: + object_type = SAI_OBJECT_TYPE_SCHEDULER; + break; + case SWITCH_HANDLE_TYPE_QUEUE: + object_type = SAI_OBJECT_TYPE_QUEUE; + break; + case SWITCH_HANDLE_TYPE_BUFFER_POOL: + object_type = SAI_OBJECT_TYPE_BUFFER_POOL; + break; + case SWITCH_HANDLE_TYPE_BUFFER_PROFILE: + object_type = SAI_OBJECT_TYPE_BUFFER_PROFILE; + break; + case SWITCH_HANDLE_TYPE_QOS_MAP: + object_type = SAI_OBJECT_TYPE_QOS_MAPS; + break; + case SWITCH_HANDLE_TYPE_PRIORITY_GROUP: + object_type = SAI_OBJECT_TYPE_PRIORITY_GROUP; + break; + default: + object_type = SAI_OBJECT_TYPE_NULL; + break; + } + + SAI_LOG_INFO("object type query: %lx : %s", + sai_object_id, + sai_object_type_to_string(object_type)); + + SAI_LOG_EXIT(); + + return object_type; } sai_status_t sai_initialize() { - - sai_api_t api = 0; - - for (api = 0; api < SAI_API_MAX; api++) { - sai_log_set(api, SAI_LOG_CRITICAL); - } - - SAI_LOG_ENTER(); - - sai_switch_initialize(&sai_api_service); - sai_port_initialize(&sai_api_service); - sai_fdb_initialize(&sai_api_service); - sai_vlan_initialize(&sai_api_service); - sai_lag_initialize(&sai_api_service); - sai_router_interface_initialize(&sai_api_service); - sai_next_hop_initialize(&sai_api_service); - sai_next_hop_group_initialize(&sai_api_service); - sai_route_initialize(&sai_api_service); - sai_virtual_router_initialize(&sai_api_service); - sai_stp_initialize(&sai_api_service); - sai_neighbor_initialize(&sai_api_service); - sai_hostif_initialize(&sai_api_service); - sai_acl_initialize(&sai_api_service); - sai_mirror_initialize(&sai_api_service); - sai_policer_initialize(&sai_api_service); - sai_ipmc_initialize(&sai_api_service); - sai_l2mc_initialize(&sai_api_service); - - SAI_LOG_EXIT(); - - return SAI_STATUS_SUCCESS; + sai_api_t api = 0; + + for (api = 0; api < SAI_API_MAX; api++) { + sai_log_set(api, SAI_LOG_CRITICAL); + } + + SAI_LOG_ENTER(); + + sai_switch_initialize(&sai_api_service); + sai_port_initialize(&sai_api_service); + sai_fdb_initialize(&sai_api_service); + sai_vlan_initialize(&sai_api_service); + sai_lag_initialize(&sai_api_service); + sai_router_interface_initialize(&sai_api_service); + sai_next_hop_initialize(&sai_api_service); + sai_next_hop_group_initialize(&sai_api_service); + sai_route_initialize(&sai_api_service); + sai_virtual_router_initialize(&sai_api_service); + sai_stp_initialize(&sai_api_service); + sai_neighbor_initialize(&sai_api_service); + sai_hostif_initialize(&sai_api_service); + sai_acl_initialize(&sai_api_service); + sai_mirror_initialize(&sai_api_service); + sai_policer_initialize(&sai_api_service); + sai_buffer_initialize(&sai_api_service); + sai_scheduler_initialize(&sai_api_service); + sai_scheduler_group_initialize(&sai_api_service); + sai_qos_map_initialize(&sai_api_service); + sai_ipmc_initialize(&sai_api_service); + sai_l2mc_initialize(&sai_api_service); + sai_hash_initialize(&sai_api_service); + sai_udf_initialize(&sai_api_service); + + SAI_LOG_EXIT(); + + return SAI_STATUS_SUCCESS; } -sai_status_t sai_log_set( - _In_ sai_api_t sai_api_id, - _In_ sai_log_level_t log_level) { - sai_status_t status = SAI_STATUS_SUCCESS; - api_log_level[sai_api_id] = log_level; - return status; +sai_status_t sai_log_set(_In_ sai_api_t sai_api_id, + _In_ sai_log_level_t log_level) { + sai_status_t status = SAI_STATUS_SUCCESS; + api_log_level[sai_api_id] = log_level; + return status; } -void sai_log(int level, sai_api_t api, char *fmt, ...) -{ - va_list args; - // compare if level of each API here? - if(level < api_log_level[api]) { - return; - } - va_start(args, fmt); - vsnprintf(log_buffer, SAI_LOG_BUFFER_SIZE, fmt, args); - va_end(args); +void sai_log(int level, sai_api_t api, char *fmt, ...) { + va_list args; + // compare if level of each API here? + if (level < api_log_level[api]) { + return; + } + va_start(args, fmt); + vsnprintf(log_buffer, SAI_LOG_BUFFER_SIZE, fmt, args); + va_end(args); #if 1 - printf("%s: %s\n", module[api], log_buffer); + printf("%s: %s\n", module[api], log_buffer); #else - syslog(LOG_DEBUG-level, "%s: %s", module[api], log_buffer); + syslog(LOG_DEBUG - level, "%s: %s", module[api], log_buffer); #endif } diff --git a/switchsai/src/sai_bmlib.c b/switchsai/src/sai_bmlib.c index 893aa22..92cc36b 100644 --- a/switchsai/src/sai_bmlib.c +++ b/switchsai/src/sai_bmlib.c @@ -18,31 +18,25 @@ limitations under the License. static unsigned int initialized = 0; static sai_api_t api_id = SAI_API_UNSPECIFIED; -const char * -sai_profile_get_value(_In_ sai_switch_profile_id_t profile_id, - _In_ const char* variable) -{ - return NULL; +const char *sai_profile_get_value(_In_ sai_switch_profile_id_t profile_id, + _In_ const char *variable) { + return NULL; } - /* * Enumerate all the K/V pairs in a profile. * Pointer to NULL passed as variable restarts enumeration. * Function returns 0 if next value exists, -1 at the end of the list. */ -int -sai_profile_get_next_value(_In_ sai_switch_profile_id_t profile_id, - _Out_ const char** variable, - _Out_ const char** value) -{ - return -1; +int sai_profile_get_next_value(_In_ sai_switch_profile_id_t profile_id, + _Out_ const char **variable, + _Out_ const char **value) { + return -1; } const service_method_table_t sai_services = { .profile_get_value = sai_profile_get_value, - .profile_get_next_value = sai_profile_get_next_value -}; + .profile_get_next_value = sai_profile_get_next_value}; #ifdef SAI_BMLIB @@ -58,131 +52,124 @@ 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, - _In_ int length) -{ - static char log_pkt[512]; - int i = 0; - - sprintf(log_pkt, "Packet in on port %d length %d; first bytes:\n", - port_num, length); - for (i = 0; i < 32; i++) { - if (i && ((i % 4) == 0)) { - sprintf(log_pkt, "%s ", log_pkt); - } - sprintf(log_pkt, "%s%02x", log_pkt, (uint8_t) buffer[i]); +static void sai_log_packet(_In_ int port_num, + _In_ const char *buffer, + _In_ int length) { + static char log_pkt[512]; + int i = 0; + + sprintf(log_pkt, + "Packet in on port %d length %d; first bytes:\n", + port_num, + length); + for (i = 0; i < 32; i++) { + if (i && ((i % 4) == 0)) { + sprintf(log_pkt, "%s ", log_pkt); } - printf("%s\n", log_pkt); + sprintf(log_pkt, "%s%02x", log_pkt, (uint8_t)buffer[i]); + } + printf("%s\n", log_pkt); } -static void sai_transmit_packet( - _In_ p4_port_t egress, - _In_ void *pkt, - _In_ int len) { - if (log_level >= P4_LOG_LEVEL_TRACE) { - sai_log_packet(egress, pkt, len); - } - if (bmi_port_send(port_mgr, egress, pkt, len) < 0) { - printf("Error sending packet\n"); - } +static void sai_transmit_packet(_In_ p4_port_t egress, + _In_ void *pkt, + _In_ int len) { + if (log_level >= P4_LOG_LEVEL_TRACE) { + sai_log_packet(egress, pkt, len); + } + if (bmi_port_send(port_mgr, egress, pkt, len) < 0) { + printf("Error sending packet\n"); + } } -static void sai_receive_packet( - _In_ int port_num, - _In_ const char *buffer, - _In_ int length) -{ - if (log_level >= P4_LOG_LEVEL_TRACE) { - sai_log_packet(port_num, buffer, length); - } - rmt_process_pkt(port_num, (char*)buffer, length); +static void sai_receive_packet(_In_ int port_num, + _In_ const char *buffer, + _In_ int length) { + if (log_level >= P4_LOG_LEVEL_TRACE) { + sai_log_packet(port_num, buffer, length); + } + rmt_process_pkt(port_num, (char *)buffer, length); } -static sai_status_t sai_load_config( - _In_ char *fname, - _In_ unsigned int *num_ports, - _In_ int *log_level) -{ - sai_status_t status = SAI_STATUS_SUCCESS; - char s[256]; - int port; - char veth[32]; - char pcap[36]; - char tmp[32]; - char *pcap_file = NULL; - int r = 0; - FILE *fp = NULL; - - fp = fopen(fname, "r"); - if (!fp) { - SAI_LOG_ERROR("failed to open config file: %s", - sai_status_to_string(status)); - return status; +static sai_status_t sai_load_config(_In_ char *fname, + _In_ unsigned int *num_ports, + _In_ int *log_level) { + sai_status_t status = SAI_STATUS_SUCCESS; + char s[256]; + int port; + char veth[32]; + char pcap[36]; + char tmp[32]; + char *pcap_file = NULL; + int r = 0; + FILE *fp = NULL; + + fp = fopen(fname, "r"); + if (!fp) { + SAI_LOG_ERROR("failed to open config file: %s", + sai_status_to_string(status)); + return status; + } + + while (fgets(s, 256, fp)) { + pcap[0] = 0; + pcap_file = NULL; + if (s[0] == '#') { + continue; } - while (fgets(s, 256, fp)) { - pcap[0] = 0; - pcap_file = NULL; - if (s[0] == '#') { - continue; - } - - if (!strncmp(s, "num_ports", 9)) { - sscanf(s, "%s = %d", tmp, num_ports); - } else if (!strncmp(s, "log_level", 9)) { - sscanf(s, "%s = %d", tmp, log_level); - } else { - if ((r= sscanf(s, "%d:%s %s", &port, veth, pcap)) >= 2) { - pcap_file = pcap; - } - if (bmi_port_interface_add(port_mgr, veth, port, pcap_file)) { - fclose(fp); - status = SAI_STATUS_FAILURE; - SAI_LOG_ERROR("failed to add port to bmi: %s", - sai_status_to_string(status)); - return status; - } - } + if (!strncmp(s, "num_ports", 9)) { + sscanf(s, "%s = %d", tmp, num_ports); + } else if (!strncmp(s, "log_level", 9)) { + sscanf(s, "%s = %d", tmp, log_level); + } else { + if ((r = sscanf(s, "%d:%s %s", &port, veth, pcap)) >= 2) { + pcap_file = pcap; + } + if (bmi_port_interface_add(port_mgr, veth, port, pcap_file)) { + fclose(fp); + status = SAI_STATUS_FAILURE; + SAI_LOG_ERROR("failed to add port to bmi: %s", + sai_status_to_string(status)); + return status; + } } - fclose(fp); - return SAI_STATUS_SUCCESS; + } + fclose(fp); + return SAI_STATUS_SUCCESS; } -sai_status_t -sai_api_initialize(_In_ uint64_t flags, - _In_ 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"); - bmi_port_create_mgr(&port_mgr); - rmt_init(); - rmt_logger_set((p4_logging_f) printf); - status = sai_load_config("port.cfg", &num_ports, &log_level); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to load port config"); - return status; - } - rmt_log_level_set(log_level); - rmt_transmit_register(sai_transmit_packet); - switch_api_init(0, num_ports); - start_switch_api_packet_driver(); - initialized = 1; - sai_initialize(); - bmi_set_packet_handler(port_mgr, sai_receive_packet); +sai_status_t sai_api_initialize(_In_ uint64_t flags, + _In_ 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"); + bmi_port_create_mgr(&port_mgr); + rmt_init(); + rmt_logger_set((p4_logging_f)printf); + status = sai_load_config("port.cfg", &num_ports, &log_level); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to load port config"); + return status; } - - services = &sai_services; - return status; + rmt_log_level_set(log_level); + rmt_transmit_register(sai_transmit_packet); + switch_api_init(0, num_ports); + start_switch_api_packet_driver(); + initialized = 1; + sai_initialize(); + bmi_set_packet_handler(port_mgr, sai_receive_packet); + } + + services = &sai_services; + return status; } -sai_status_t -sai_api_uninitialize(void) { - sai_status_t status = SAI_STATUS_SUCCESS; - return status; +sai_status_t sai_api_uninitialize(void) { + sai_status_t status = SAI_STATUS_SUCCESS; + return status; } #ifdef __cplusplus @@ -192,21 +179,21 @@ sai_api_uninitialize(void) { #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; +sai_status_t sai_api_initialize(uint64_t flags, + const service_method_table_t *services) { + sai_status_t status = SAI_STATUS_SUCCESS; + UNUSED(services); + if (!initialized) { + SAI_LOG_WARN("Initializing device"); + initialized = 1; + bmv2_model_init(); + sai_initialize(); + } + + services = &sai_services; + return status; } +sai_status_t sai_api_uninitialize() { return SAI_STATUS_SUCCESS; } + #endif /* SAI_BMLIB */ diff --git a/switchsai/src/saiacl.c b/switchsai/src/saiacl.c index 60cfd6a..41967ef 100644 --- a/switchsai/src/saiacl.c +++ b/switchsai/src/saiacl.c @@ -24,327 +24,362 @@ static sai_api_t api_id = SAI_API_ACL; /* Note: SAI ACL action processing implementation changes in the future This is an interim solution to handling actions for the ACL in a more -static way. In a future implementation a dynamic action composiitng +static way. In a future implementation a dynamic action composiitng scheme will allow for having multiple actions be speicifed in any combination in response to a match */ -typedef int sai_acl_table_match_qualifiers[SAI_ACL_TABLE_ATTR_FIELD_END - SAI_ACL_TABLE_ATTR_FIELD_START + 1]; +typedef int sai_acl_table_match_qualifiers[SAI_ACL_TABLE_ATTR_FIELD_END - + SAI_ACL_TABLE_ATTR_FIELD_START + 1]; typedef struct sai_handle_node_ { - tommy_node node; - switch_handle_t handle; + tommy_node node; + switch_handle_t handle; } sai_handle_node_t; - static sai_acl_table_match_qualifiers ip_acl = { - -1, -1, // v6 - -1, -1, // MAC - SWITCH_ACL_IP_FIELD_IPV4_SRC, SWITCH_ACL_IP_FIELD_IPV4_DEST, // v4 - -2, -2, -2, -1, // ports - -1, -1, -1, -1, -1, -1, // VLAN outer and inner - SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT, SWITCH_ACL_IP_FIELD_L4_DEST_PORT, // l4 ports - -1, - SWITCH_ACL_IP_FIELD_IP_PROTO, - SWITCH_ACL_IP_FIELD_DSCP, - -1, // ecn - SWITCH_ACL_IP_FIELD_TTL, // ttl - SWITCH_ACL_IP_FIELD_TOS, - SWITCH_ACL_IP_FIELD_IP_FLAGS, - SWITCH_ACL_IP_FIELD_TCP_FLAGS, // tcp flags - -1, // ip type - -1, // ip frag - -1, // ipv6 flow - -1 // tc - }; + -1, + -1, // v6 + -1, + -1, // MAC + SWITCH_ACL_IP_FIELD_IPV4_SRC, + SWITCH_ACL_IP_FIELD_IPV4_DEST, // v4 + -2, + -2, + -2, + -1, + -1, // ports + -1, + -1, + -1, + -1, + -1, + -1, // VLAN outer and inner + SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT, + SWITCH_ACL_IP_FIELD_L4_DEST_PORT, // l4 ports + -1, + SWITCH_ACL_IP_FIELD_IP_PROTO, + -1, // dscp + -1, // ecn + SWITCH_ACL_IP_FIELD_TTL, // ttl + -1, // tos + SWITCH_ACL_IP_FIELD_IP_FLAGS, + SWITCH_ACL_IP_FIELD_TCP_FLAGS, // tcp flags + -1, // ip type + -1, // ip frag + -1, // ipv6 flow + -1 // tc +}; static sai_acl_table_match_qualifiers ipv6_acl = { - SWITCH_ACL_IPV6_FIELD_IPV6_SRC, SWITCH_ACL_IPV6_FIELD_IPV6_DEST, - -1, -1, // MAC - -1, -1, // v4 - -2, -2, -1, -1, // ports - -1, -1, -1, -1, -1, -1, // VLAN outer and inner - SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT, SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT, // l4 ports - -1, - SWITCH_ACL_IPV6_FIELD_IP_PROTO, - -1, // dscp - -1, // ecn - SWITCH_ACL_IPV6_FIELD_TTL, // ttl - SWITCH_ACL_IPV6_FIELD_TOS, - -1, // ip flags - SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, // tcp flags - -1, // ip type - -1, // ip frag - SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, - -1 // tc - }; + SWITCH_ACL_IPV6_FIELD_IPV6_SRC, + SWITCH_ACL_IPV6_FIELD_IPV6_DEST, + -1, + -1, // MAC + -1, + -1, // v4 + -2, + -2, + -1, + -1, + -1, // ports + -1, + -1, + -1, + -1, + -1, + -1, // VLAN outer and inner + SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT, + SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT, // l4 ports + -1, + SWITCH_ACL_IPV6_FIELD_IP_PROTO, + -1, // dscp + -1, // ecn + SWITCH_ACL_IPV6_FIELD_TTL, // ttl + -1, // tos + -1, // ip flags + SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, // tcp flags + -1, // ip type + -1, // ip frag + SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, + -1 // tc +}; static sai_acl_table_match_qualifiers mac_acl = { - -1, -1, // v6 - SWITCH_ACL_MAC_FIELD_SOURCE_MAC, SWITCH_ACL_MAC_FIELD_DEST_MAC, // MAC - -1, -1, // v4 - -2, -2, -1, -1, // ports - -1, SWITCH_ACL_MAC_FIELD_VLAN_PRI, SWITCH_ACL_MAC_FIELD_VLAN_CFI, -1, -1, -1, // VLAN outer and inner - -1, -1, // l4 ports - SWITCH_ACL_MAC_FIELD_ETH_TYPE, - -1, - -1, - -1, // ecn - -1, // ttl - -1, - -1, - -1, // tcp flags - -1, // ip type - -1, // ip frag - -1, // ipv6 flow - -1 // tc - }; + -1, + -1, // v6 + SWITCH_ACL_MAC_FIELD_SOURCE_MAC, + SWITCH_ACL_MAC_FIELD_DEST_MAC, // MAC + -1, + -1, // v4 + -2, + -2, + -1, + -1, + -1, // ports + -1, + SWITCH_ACL_MAC_FIELD_VLAN_PRI, + SWITCH_ACL_MAC_FIELD_VLAN_CFI, + -1, + -1, + -1, // VLAN outer and inner + -1, + -1, // l4 ports + SWITCH_ACL_MAC_FIELD_ETH_TYPE, + -1, + -1, + -1, // ecn + -1, // ttl + -1, + -1, + -1, // tcp flags + -1, // ip type + -1, // ip frag + -1, // ipv6 flow + -1 // tc +}; static sai_acl_table_match_qualifiers egress_acl = { - -1, -1, // v6 - -1, -1, // MAC - -1, -1, // v4 - -2, -2, -1, SWITCH_ACL_EGR_DEST_PORT, // ports - -1, -1, -1, -1, -1, -1, // VLAN outer and inner - -1, -1, // l4 ports - -1, - -1, - -1, - -1, // ecn - -1, // ttl - -1, - -1, - -1, // tcp flags - -1, // ip type - -1, // ip frag - -1, // ipv6 flow - -1 // tc - }; - - -static int * sai_acl_p4_match_table_get(switch_acl_type_t table_type) -{ - switch (table_type) { - case SWITCH_ACL_TYPE_IP: - return ip_acl; - case SWITCH_ACL_TYPE_IPV6: - return ipv6_acl; - case SWITCH_ACL_TYPE_MAC: - return mac_acl; - case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - return egress_acl; - default: - return NULL; - } + -1, + -1, // v6 + -1, + -1, // MAC + -1, + -1, // v4 + -2, + -2, + -1, + SWITCH_ACL_EGR_DEST_PORT, // ports + -1, + -1, + -1, + -1, + -1, + -1, // VLAN outer and inner + -1, + -1, // l4 ports + -1, + -1, + -1, + -1, // ecn + -1, // ttl + -1, + -1, + -1, // tcp flags + -1, // ip type + -1, // ip frag + -1, // ipv6 flow + -1 // tc +}; + +static int *sai_acl_p4_match_table_get(switch_acl_type_t table_type) { + switch (table_type) { + case SWITCH_ACL_TYPE_IP: + return ip_acl; + case SWITCH_ACL_TYPE_IPV6: + return ipv6_acl; + case SWITCH_ACL_TYPE_MAC: + return mac_acl; + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: + return egress_acl; + default: + return NULL; + } } /* Ensure that all the fields in the attribute list can be handled by the ACL */ static sai_status_t sai_acl_match_table_type_get( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list, - _In_ switch_acl_type_t *acl_type) -{ - uint32_t index1 = 0, index2 = 0; - int *table; - bool table_matched = TRUE; - - for (index1 = 0; index1 < SWITCH_ACL_TYPE_MAX; index1++) { - table = sai_acl_p4_match_table_get(index1); - if (!table) { - continue; - } - table_matched = TRUE; - 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 (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; + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _In_ switch_acl_type_t *acl_type) { + uint32_t index1 = 0, index2 = 0; + int *table; + bool table_matched = TRUE; + + for (index1 = 0; index1 < SWITCH_ACL_TYPE_MAX; index1++) { + table = sai_acl_p4_match_table_get(index1); + if (!table) { + continue; + } + table_matched = TRUE; + 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 (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; } - } - if (table_matched && index2 == attr_count) { - *acl_type = index1; - return SAI_STATUS_SUCCESS; - } + } + break; + } } - return SAI_STATUS_FAILURE; + if (table_matched && index2 == attr_count) { + *acl_type = index1; + return SAI_STATUS_SUCCESS; + } + } + return SAI_STATUS_FAILURE; } static sai_status_t sai_acl_match_table_field( - _In_ int table_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list, - _Out_ int *match_fields, - _Out_ int *actions) -{ - uint32_t index = 0; - int id = 0; - int *table; - - table = sai_acl_p4_match_table_get(table_id); - if (!table) { + _In_ int table_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _Out_ int *match_fields, + _Out_ int *actions) { + uint32_t index = 0; + int id = 0; + int *table; + + table = sai_acl_p4_match_table_get(table_id); + if (!table) { + return SAI_STATUS_FAILURE; + } + + for (index = 0; index < attr_count; index++) { + id = attr_list[index].id; + if ((id >= SAI_ACL_TABLE_ATTR_FIELD_START) && + (id <= SAI_ACL_TABLE_ATTR_FIELD_END)) { + id -= SAI_ACL_TABLE_ATTR_FIELD_START; + if (table[id] != -1) { + match_fields[index] = table[id]; + } else { return SAI_STATUS_FAILURE; + } } - - for (index = 0; index < attr_count; index++) { - id = attr_list[index].id; - if ((id >= SAI_ACL_TABLE_ATTR_FIELD_START) && - (id <= SAI_ACL_TABLE_ATTR_FIELD_END)) { - id -= SAI_ACL_TABLE_ATTR_FIELD_START; - if (table[id] != -1) { - match_fields[index] = table[id]; - } else { - return SAI_STATUS_FAILURE; - } - } - } - return SAI_STATUS_SUCCESS; + } + return SAI_STATUS_SUCCESS; } static sai_status_t sai_acl_xform_field_value( - _In_ switch_acl_type_t acl_type, - _In_ int field, - _In_ void *dest, - _In_ const sai_acl_field_data_t *source) -{ - switch(acl_type) { - case SWITCH_ACL_TYPE_IP: - { - switch_acl_ip_key_value_pair_t *kvp = (switch_acl_ip_key_value_pair_t *)dest; - switch (field) { - case SWITCH_ACL_IP_FIELD_IPV4_SRC: - kvp->value.ipv4_source = ntohl(source->data.ip4); - kvp->mask.u.mask = ntohl(source->mask.ip4); - break; - case SWITCH_ACL_IP_FIELD_IPV4_DEST: - kvp->value.ipv4_dest = ntohl(source->data.ip4); - kvp->mask.u.mask = ntohl(source->mask.ip4); - break; - case SWITCH_ACL_IP_FIELD_IP_PROTO: - kvp->value.ip_proto = source->data.u16; - kvp->mask.u.mask = source->mask.u16; - break; - case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT: - kvp->value.l4_source_port = source->data.u16; - kvp->mask.u.mask = source->mask.u16; - break; - case SWITCH_ACL_IP_FIELD_L4_DEST_PORT: - kvp->value.l4_dest_port = source->data.u16; - kvp->mask.u.mask = source->mask.u16; - break; - case SWITCH_ACL_IP_FIELD_ICMP_TYPE: - case SWITCH_ACL_IP_FIELD_ICMP_CODE: - case SWITCH_ACL_IP_FIELD_TCP_FLAGS: - kvp->value.tcp_flags = source->data.u8; - kvp->mask.u.mask = source->mask.u8; - break; - case SWITCH_ACL_IP_FIELD_TTL: - kvp->value.ttl = source->data.u8; - kvp->mask.u.mask = source->mask.u8; - break; - case SWITCH_ACL_IP_FIELD_DSCP: - kvp->value.dscp = source->data.u8; - kvp->mask.u.mask = source->mask.u8; - break; - case SWITCH_ACL_IP_FIELD_IP_FLAGS: - kvp->value.ip_flags = source->data.u8; - kvp->mask.u.mask = source->mask.u8; - break; - case SWITCH_ACL_IP_FIELD_TOS: - kvp->value.tos = source->data.u8; - kvp->mask.u.mask = source->mask.u8; - break; - case SWITCH_ACL_IP_FIELD_IP_FRAGMENT: - kvp->value.ip_frag = source->data.u8; - kvp->mask.u.mask = source->mask.u8; - break; - default: - break; - } - } - break; - case SWITCH_ACL_TYPE_IPV6: - { - switch (field) { - case SWITCH_ACL_IPV6_FIELD_IPV6_SRC: - case SWITCH_ACL_IPV6_FIELD_IPV6_DEST: - case SWITCH_ACL_IPV6_FIELD_IP_PROTO: - case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT: - case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT: - case SWITCH_ACL_IPV6_FIELD_ICMP_TYPE: - case SWITCH_ACL_IPV6_FIELD_ICMP_CODE: - case SWITCH_ACL_IPV6_FIELD_TCP_FLAGS: - case SWITCH_ACL_IPV6_FIELD_TTL: - case SWITCH_ACL_IPV6_FIELD_FLOW_LABEL: - break; - default: - break; - } - } - break; - case SWITCH_ACL_TYPE_MAC: - { - switch_acl_mac_key_value_pair_t *kvp = (switch_acl_mac_key_value_pair_t *)dest; - switch (field) { - case SWITCH_ACL_MAC_FIELD_SOURCE_MAC: - memcpy(kvp->value.source_mac, source->data.mac, 6); - memcpy(kvp->mask.u.mac_mask, source->mask.mac, 6); - break; - case SWITCH_ACL_MAC_FIELD_DEST_MAC: - memcpy(kvp->value.dest_mac, source->data.mac, 6); - memcpy(kvp->mask.u.mac_mask, source->mask.mac, 6); - break; - case SWITCH_ACL_MAC_FIELD_VLAN_PRI: - kvp->value.vlan_pri = source->data.u8; - kvp->mask.u.mask16 = source->mask.u8; - break; - case SWITCH_ACL_MAC_FIELD_VLAN_CFI: - kvp->value.vlan_cfi = source->data.u8; - kvp->mask.u.mask16 = source->mask.u8; - break; - case SWITCH_ACL_MAC_FIELD_ETH_TYPE: - kvp->value.eth_type = source->data.u16; - kvp->mask.u.mask16 = source->mask.u16; - break; - default: - break; - } - } - break; - case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - { - switch_acl_egr_key_value_pair_t *kvp = (switch_acl_egr_key_value_pair_t *)dest; - switch (field) { - case SWITCH_ACL_EGR_DEST_PORT: - kvp->value.egr_port = source->data.oid; - kvp->mask.u.mask = 0xFFFF; - break; - default: - break; - } - } - break; + _In_ switch_acl_type_t acl_type, + _In_ int field, + _In_ void *dest, + _In_ const sai_acl_field_data_t *source) { + switch (acl_type) { + case SWITCH_ACL_TYPE_IP: { + switch_acl_ip_key_value_pair_t *kvp = + (switch_acl_ip_key_value_pair_t *)dest; + switch (field) { + case SWITCH_ACL_IP_FIELD_IPV4_SRC: + kvp->value.ipv4_source = ntohl(source->data.ip4); + kvp->mask.u.mask = ntohl(source->mask.ip4); + break; + case SWITCH_ACL_IP_FIELD_IPV4_DEST: + kvp->value.ipv4_dest = ntohl(source->data.ip4); + kvp->mask.u.mask = ntohl(source->mask.ip4); + break; + case SWITCH_ACL_IP_FIELD_IP_PROTO: + kvp->value.ip_proto = source->data.u16; + kvp->mask.u.mask = source->mask.u16; + break; + case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT: + kvp->value.l4_source_port = source->data.u16; + kvp->mask.u.mask = source->mask.u16; + break; + case SWITCH_ACL_IP_FIELD_L4_DEST_PORT: + kvp->value.l4_dest_port = source->data.u16; + kvp->mask.u.mask = source->mask.u16; + break; + case SWITCH_ACL_IP_FIELD_ICMP_TYPE: + case SWITCH_ACL_IP_FIELD_ICMP_CODE: + case SWITCH_ACL_IP_FIELD_TCP_FLAGS: + kvp->value.tcp_flags = source->data.u8; + kvp->mask.u.mask = source->mask.u8; + break; + case SWITCH_ACL_IP_FIELD_TTL: + kvp->value.ttl = source->data.u8; + kvp->mask.u.mask = source->mask.u8; + break; + case SWITCH_ACL_IP_FIELD_IP_FLAGS: + kvp->value.ip_flags = source->data.u8; + kvp->mask.u.mask = source->mask.u8; + break; + case SWITCH_ACL_IP_FIELD_IP_FRAGMENT: + kvp->value.ip_frag = source->data.u8; + kvp->mask.u.mask = source->mask.u8; + break; default: - break; - } - return SAI_STATUS_SUCCESS; + break; + } + } break; + case SWITCH_ACL_TYPE_IPV6: { + switch (field) { + case SWITCH_ACL_IPV6_FIELD_IPV6_SRC: + case SWITCH_ACL_IPV6_FIELD_IPV6_DEST: + case SWITCH_ACL_IPV6_FIELD_IP_PROTO: + case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT: + case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT: + case SWITCH_ACL_IPV6_FIELD_ICMP_TYPE: + case SWITCH_ACL_IPV6_FIELD_ICMP_CODE: + case SWITCH_ACL_IPV6_FIELD_TCP_FLAGS: + case SWITCH_ACL_IPV6_FIELD_TTL: + case SWITCH_ACL_IPV6_FIELD_FLOW_LABEL: + break; + default: + break; + } + } break; + case SWITCH_ACL_TYPE_MAC: { + switch_acl_mac_key_value_pair_t *kvp = + (switch_acl_mac_key_value_pair_t *)dest; + switch (field) { + case SWITCH_ACL_MAC_FIELD_SOURCE_MAC: + memcpy(kvp->value.source_mac.mac_addr, source->data.mac, 6); + memcpy(&kvp->mask.u.mask, source->mask.mac, 6); + break; + case SWITCH_ACL_MAC_FIELD_DEST_MAC: + memcpy(kvp->value.dest_mac.mac_addr, source->data.mac, 6); + memcpy(&kvp->mask.u.mask, source->mask.mac, 6); + break; + case SWITCH_ACL_MAC_FIELD_VLAN_PRI: + kvp->value.vlan_pri = source->data.u8; + kvp->mask.u.mask16 = source->mask.u8; + break; + case SWITCH_ACL_MAC_FIELD_VLAN_CFI: + kvp->value.vlan_cfi = source->data.u8; + kvp->mask.u.mask16 = source->mask.u8; + break; + case SWITCH_ACL_MAC_FIELD_ETH_TYPE: + kvp->value.eth_type = source->data.u16; + kvp->mask.u.mask16 = source->mask.u16; + break; + default: + break; + } + } break; + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: { + switch_acl_egr_key_value_pair_t *kvp = + (switch_acl_egr_key_value_pair_t *)dest; + switch (field) { + case SWITCH_ACL_EGR_DEST_PORT: + kvp->value.egr_port = source->data.oid; + kvp->mask.u.mask = 0xFFFF; + break; + default: + break; + } + } break; + default: + break; + } + return SAI_STATUS_SUCCESS; } /* @@ -360,44 +395,40 @@ static sai_status_t sai_acl_xform_field_value( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_acl_table( - _Out_ sai_object_id_t* acl_table_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { +sai_status_t sai_create_acl_table(_Out_ sai_object_id_t *acl_table_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_acl_type_t acl_type = 0; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_acl_type_t acl_type = 0; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - status = sai_acl_match_table_type_get(attr_count, attr_list, &acl_type); - if (status != SAI_STATUS_SUCCESS) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("failed to find match table: %s", - sai_status_to_string(status)); - return status; - } + status = sai_acl_match_table_type_get(attr_count, attr_list, &acl_type); + if (status != SAI_STATUS_SUCCESS) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("failed to find match table: %s", + sai_status_to_string(status)); + return status; + } - *acl_table_id = (sai_object_id_t)switch_api_acl_list_create(device, acl_type); + *acl_table_id = (sai_object_id_t)switch_api_acl_list_create(device, acl_type); - status = (*acl_table_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create acl table: %s", - sai_status_to_string(status)); - } + status = (*acl_table_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create acl table: %s", + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -411,28 +442,27 @@ sai_status_t sai_create_acl_table( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_delete_acl_table( - _In_ sai_object_id_t acl_table_id) { +sai_status_t sai_delete_acl_table(_In_ sai_object_id_t acl_table_id) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + SAI_ASSERT(sai_object_type_query(acl_table_id) == SAI_OBJECT_TYPE_ACL_TABLE); - SAI_ASSERT(sai_object_type_query(acl_table_id) == SAI_OBJECT_TYPE_ACL_TABLE); + switch_status = + switch_api_acl_list_delete(device, (switch_handle_t)acl_table_id); + status = sai_switch_status_to_sai_status(switch_status); - switch_status = switch_api_acl_list_delete(device, (switch_handle_t) acl_table_id); - status = sai_switch_status_to_sai_status(switch_status); - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to delete acl table%lx : %s", - acl_table_id, - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to delete acl table%lx : %s", + acl_table_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -448,259 +478,256 @@ sai_status_t sai_delete_acl_table( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_acl_entry( - _Out_ sai_object_id_t *acl_entry_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_object_id_t acl_table_id = 0ULL; - int *match_fields = NULL; - switch_acl_ip_key_value_pair_t *kvp=NULL; - unsigned int field_size; - sai_packet_action_t packet_action = 0; - switch_acl_action_t acl_action = 0; - switch_acl_action_params_t action_params; - switch_acl_opt_action_params_t opt_action_params; - uint32_t priority = 0; - switch_acl_info_t *acl_info = NULL; - switch_acl_type_t acl_type; - tommy_list handle_list; - sai_handle_node_t *handle_node = NULL; - uint32_t index1 = 0, index2 = 0; - sai_object_id_t *objlist = NULL; - int *actions = NULL; - tommy_node *node; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - *acl_entry_id = 0ULL; - memset(&action_params, 0, sizeof(switch_acl_action_params_t)); - memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); - tommy_list_init(&handle_list); - // get the table id - for (index1 = 0; index1 < attr_count; index1++) { - switch(attr_list[index1].id) { - case SAI_ACL_ENTRY_ATTR_TABLE_ID: - // ACL table identifier - acl_table_id = attr_list[index1].value.aclfield.data.oid; - SAI_ASSERT(sai_object_type_query(acl_table_id) == - SAI_OBJECT_TYPE_ACL_TABLE); - break; - case SAI_ACL_ENTRY_ATTR_PRIORITY: - // ACL entry priority - priority = attr_list[index1].value.aclfield.data.u32; - break; - case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS: - // ACL REFERENCE handling - { - objlist = attr_list[index1].value.aclfield.data.objlist.list; - for (index2 = 0; index2 < attr_list[index1].value.aclfield.data.objlist.count; index2++) { - // accumulate handle mask - handle_node = SAI_MALLOC(sizeof(sai_handle_node_t)); - if (!handle_node) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; - } - memset(handle_node, 0, sizeof(sai_handle_node_t)); - handle_node->handle = (switch_handle_t) * (objlist + index2); - tommy_list_insert_head(&handle_list, &(handle_node->node), handle_node); - } - SAI_FREE(attr_list[index1].value.aclfield.data.objlist.list); - } - break; - case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT: - case SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT: - handle_node = SAI_MALLOC(sizeof(sai_handle_node_t)); - if (!handle_node) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; - } - memset(handle_node, 0, sizeof(sai_handle_node_t)); - handle_node->handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - tommy_list_insert_head(&handle_list, &(handle_node->node), handle_node); - break; - case SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID: - handle_node = SAI_MALLOC(sizeof(sai_handle_node_t)); - if (!handle_node) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; - } - memset(handle_node, 0, sizeof(sai_handle_node_t)); - handle_node->handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - tommy_list_insert_head(&handle_list, &(handle_node->node), handle_node); - break; - case SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID: - break; - case SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT: - { - // ACTION handling - switch_handle_t handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - /* - if (SAI_CPU_PORT(port_handle)) { - acl_action = SWITCH_ACL_ACTION_REDIRECT_TO_CPU; - } else { - */ - acl_action = SWITCH_ACL_ACTION_REDIRECT; - // set the action params - action_params.redirect.handle = handle; - } - break; - case SAI_ACL_ENTRY_ATTR_PACKET_ACTION: - acl_action = 0; - 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) { - acl_action = SWITCH_ACL_ACTION_PERMIT; - } - break; - case SAI_ACL_ENTRY_ATTR_ACTION_FLOOD: - acl_action = SWITCH_ACL_ACTION_FLOOD_TO_VLAN; - break; - case SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS: - { - switch_handle_t handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - acl_action = SWITCH_ACL_ACTION_SET_MIRROR; - opt_action_params.mirror_handle = handle; - } - break; - case SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS: - { - switch_handle_t handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - acl_action = SWITCH_ACL_EGR_ACTION_SET_MIRROR; - opt_action_params.mirror_handle = handle; - } - break; - case SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER: - { - switch_handle_t handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - opt_action_params.meter_handle = handle; - } - break; - case SAI_ACL_ENTRY_ATTR_ACTION_COUNTER: - { - switch_handle_t handle = (switch_handle_t)attr_list[index1].value.aclfield.data.oid; - opt_action_params.counter_handle = handle; - } - break; - +sai_status_t sai_create_acl_entry(_Out_ sai_object_id_t *acl_entry_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_object_id_t acl_table_id = 0ULL; + int *match_fields = NULL; + switch_acl_ip_key_value_pair_t *kvp = NULL; + unsigned int field_size; + sai_packet_action_t packet_action = 0; + switch_acl_action_t acl_action = 0; + switch_acl_action_params_t action_params; + switch_acl_opt_action_params_t opt_action_params; + uint32_t priority = 0; + switch_acl_info_t *acl_info = NULL; + switch_acl_type_t acl_type; + tommy_list handle_list; + sai_handle_node_t *handle_node = NULL; + uint32_t index1 = 0, index2 = 0; + sai_object_id_t *objlist = NULL; + int *actions = NULL; + tommy_node *node; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + *acl_entry_id = 0ULL; + memset(&action_params, 0, sizeof(switch_acl_action_params_t)); + memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); + tommy_list_init(&handle_list); + // get the table id + for (index1 = 0; index1 < attr_count; index1++) { + switch (attr_list[index1].id) { + case SAI_ACL_ENTRY_ATTR_TABLE_ID: + // ACL table identifier + acl_table_id = attr_list[index1].value.aclfield.data.oid; + SAI_ASSERT(sai_object_type_query(acl_table_id) == + SAI_OBJECT_TYPE_ACL_TABLE); + break; + case SAI_ACL_ENTRY_ATTR_PRIORITY: + // ACL entry priority + priority = attr_list[index1].value.aclfield.data.u32; + break; + case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS: + // ACL REFERENCE handling + { + objlist = attr_list[index1].value.aclfield.data.objlist.list; + for (index2 = 0; + index2 < attr_list[index1].value.aclfield.data.objlist.count; + index2++) { + // accumulate handle mask + handle_node = SAI_MALLOC(sizeof(sai_handle_node_t)); + if (!handle_node) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + memset(handle_node, 0, sizeof(sai_handle_node_t)); + handle_node->handle = (switch_handle_t) * (objlist + index2); + tommy_list_insert_head( + &handle_list, &(handle_node->node), handle_node); + } + SAI_FREE(attr_list[index1].value.aclfield.data.objlist.list); } + break; + case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORT: + case SAI_ACL_ENTRY_ATTR_FIELD_OUT_PORT: + handle_node = SAI_MALLOC(sizeof(sai_handle_node_t)); + if (!handle_node) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + memset(handle_node, 0, sizeof(sai_handle_node_t)); + handle_node->handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + tommy_list_insert_head(&handle_list, &(handle_node->node), handle_node); + break; + case SAI_ACL_ENTRY_ATTR_FIELD_OUTER_VLAN_ID: + handle_node = SAI_MALLOC(sizeof(sai_handle_node_t)); + if (!handle_node) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + memset(handle_node, 0, sizeof(sai_handle_node_t)); + handle_node->handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + tommy_list_insert_head(&handle_list, &(handle_node->node), handle_node); + break; + case SAI_ACL_ENTRY_ATTR_FIELD_INNER_VLAN_ID: + break; + case SAI_ACL_ENTRY_ATTR_ACTION_REDIRECT: { + // ACTION handling + switch_handle_t handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + /* + if (SAI_CPU_PORT(port_handle)) { + acl_action = SWITCH_ACL_ACTION_REDIRECT_TO_CPU; + } else { + */ + acl_action = SWITCH_ACL_ACTION_REDIRECT; + // set the action params + action_params.redirect.handle = handle; + } break; + case SAI_ACL_ENTRY_ATTR_PACKET_ACTION: + acl_action = 0; + 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) { + acl_action = SWITCH_ACL_ACTION_PERMIT; + } + break; + case SAI_ACL_ENTRY_ATTR_ACTION_FLOOD: + acl_action = SWITCH_ACL_ACTION_FLOOD_TO_VLAN; + break; + case SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS: { + switch_handle_t handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + acl_action = SWITCH_ACL_ACTION_SET_MIRROR; + opt_action_params.mirror_handle = handle; + } break; + case SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS: { + switch_handle_t handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + acl_action = SWITCH_ACL_EGR_ACTION_SET_MIRROR; + opt_action_params.mirror_handle = handle; + } break; + case SAI_ACL_ENTRY_ATTR_ACTION_SET_POLICER: { + switch_handle_t handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + opt_action_params.meter_handle = handle; + } break; + case SAI_ACL_ENTRY_ATTR_ACTION_COUNTER: { + switch_handle_t handle = + (switch_handle_t)attr_list[index1].value.aclfield.data.oid; + opt_action_params.counter_handle = handle; + } break; } + } - acl_info = switch_acl_get((switch_handle_t) acl_table_id); - if (!acl_info) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("failed to get acl info: %s", - sai_status_to_string(status)); - return status; - } - acl_type = acl_info->type; - - // switch on type to get more values! - field_size = SWITCH_ACL_IP_FIELD_MAX; - match_fields = SAI_MALLOC(sizeof(int) * field_size); - if (!match_fields) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; - } - - // init the array to unknown - for (index1 = 0; index1 < field_size; index1++) { - match_fields[index1] = -1; - } - actions = SAI_MALLOC(sizeof(int) * SWITCH_ACL_ACTION_MAX); - if (!actions) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; + acl_info = switch_acl_get((switch_handle_t)acl_table_id); + if (!acl_info) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("failed to get acl info: %s", sai_status_to_string(status)); + return status; + } + acl_type = acl_info->type; + + // switch on type to get more values! + field_size = SWITCH_ACL_IP_FIELD_MAX; + match_fields = SAI_MALLOC(sizeof(int) * field_size); + if (!match_fields) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + + // init the array to unknown + for (index1 = 0; index1 < field_size; index1++) { + match_fields[index1] = -1; + } + actions = SAI_MALLOC(sizeof(int) * SWITCH_ACL_ACTION_MAX); + if (!actions) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + // get the match fields + status = sai_acl_match_table_field( + acl_type, attr_count, attr_list, match_fields, actions); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + // allocate to store key-value pairs + kvp = SAI_MALLOC(sizeof(switch_acl_ip_key_value_pair_t) * field_size); + if (!kvp) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + return status; + } + // Translate the ATTR to field values + index2 = 0; + for (index1 = 0; index1 < field_size; index1++) { + if (match_fields[index1] != -1) { + if (match_fields[index1] >= 0) { + kvp[index2].field = match_fields[index1]; + sai_acl_xform_field_value(acl_type, + match_fields[index1], + &kvp[index2], + &(attr_list[index1].value.aclfield)); + index2++; + } } - // get the match fields - status = sai_acl_match_table_field(acl_type, attr_count, - attr_list, - match_fields, - actions); + } + // add entry with kvp and j + if (index2 > 0) { + // create the rule + switch_status = switch_api_acl_rule_create(device, + acl_table_id, + priority, + index2, + kvp, + acl_action, + &action_params, + &opt_action_params, + acl_entry_id); + status = sai_switch_status_to_sai_status(switch_status); if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; - } - // allocate to store key-value pairs - kvp = SAI_MALLOC(sizeof(switch_acl_ip_key_value_pair_t) * field_size); - if (!kvp) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - return status; + SAI_LOG_ERROR("failed to create acl entry: %s", + sai_status_to_string(status)); + SAI_FREE(kvp); + SAI_FREE(actions); + SAI_FREE(match_fields); + return status; } - // Translate the ATTR to field values - index2 = 0; - for (index1 = 0; index1 < field_size; index1++) { - if (match_fields[index1] != -1) { - if (match_fields[index1] >= 0) { - kvp[index2].field = match_fields[index1]; - sai_acl_xform_field_value(acl_type, - match_fields[index1], - &kvp[index2], - &(attr_list[index1].value.aclfield)); - index2++; - } - } + // reference the ACL on handle + node = tommy_list_head(&handle_list); + while (node) { + handle_node = node->data; + if (handle_node) { + switch_api_acl_reference(device, acl_table_id, handle_node->handle); + } + node = node->next; } - // add entry with kvp and j - if (index2 > 0) { - // create the rule - switch_status = switch_api_acl_rule_create(device, acl_table_id, - priority, index2, kvp, - acl_action, &action_params, - &opt_action_params, - acl_entry_id); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create acl entry: %s", - sai_status_to_string(status)); - SAI_FREE(kvp); - SAI_FREE(actions); - SAI_FREE(match_fields); - return status; - } - // reference the ACL on handle - node = tommy_list_head(&handle_list); - while (node) { - handle_node = node->data; - if (handle_node) { - switch_api_acl_reference(device, acl_table_id, handle_node->handle); - } - node = node->next; - } - // SAI_FREE handle_list - tommy_list_foreach(&handle_list, free); - } - SAI_FREE(kvp); - SAI_FREE(actions); - SAI_FREE(match_fields); + // SAI_FREE handle_list + tommy_list_foreach(&handle_list, free); + } + SAI_FREE(kvp); + SAI_FREE(actions); + SAI_FREE(match_fields); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -714,33 +741,29 @@ sai_status_t sai_create_acl_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_delete_acl_entry( - _In_ sai_object_id_t acl_entry_id) { +sai_status_t sai_delete_acl_entry(_In_ sai_object_id_t acl_entry_id) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + SAI_ASSERT(sai_object_type_query(acl_entry_id) == SAI_OBJECT_TYPE_ACL_ENTRY); - SAI_ASSERT(sai_object_type_query(acl_entry_id) == SAI_OBJECT_TYPE_ACL_ENTRY); + switch_status = switch_api_acl_rule_delete( + device, (switch_handle_t)0, (switch_handle_t)acl_entry_id); + status = sai_switch_status_to_sai_status(switch_status); - switch_status = switch_api_acl_rule_delete(device, - (switch_handle_t)0, - (switch_handle_t)acl_entry_id); - status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to delete acl entry %lx : %s", + acl_entry_id, + sai_status_to_string(status)); + } - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to delete acl entry %lx : %s", - acl_entry_id, - sai_status_to_string(status)); - } + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); - - return (sai_status_t) status; + return (sai_status_t)status; } - /** * Routine Description: * @brief Create an ACL counter @@ -754,35 +777,31 @@ sai_status_t sai_delete_acl_entry( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_acl_counter( - _Out_ sai_object_id_t *acl_counter_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - sai_status_t status = SAI_STATUS_SUCCESS; +sai_status_t sai_create_acl_counter(_Out_ sai_object_id_t *acl_counter_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_ENTER(); + SAI_LOG_ENTER(); - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - *acl_counter_id = switch_api_acl_counter_create(device); - status = (*acl_counter_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create acl counter: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + *acl_counter_id = switch_api_acl_counter_create(device); + status = (*acl_counter_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create acl counter: %s", + sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /** @@ -796,28 +815,28 @@ sai_status_t sai_create_acl_counter( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_delete_acl_counter( - _In_ sai_object_id_t acl_counter_id) -{ - SAI_LOG_ENTER(); +sai_status_t sai_delete_acl_counter(_In_ sai_object_id_t acl_counter_id) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(acl_counter_id) == SAI_OBJECT_TYPE_ACL_COUNTER); + SAI_ASSERT(sai_object_type_query(acl_counter_id) == + SAI_OBJECT_TYPE_ACL_COUNTER); - switch_status = switch_api_acl_counter_delete(device, (switch_handle_t) acl_counter_id); - status = sai_switch_status_to_sai_status(switch_status); + switch_status = + switch_api_acl_counter_delete(device, (switch_handle_t)acl_counter_id); + status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to delete acl counter%lx : %s", - acl_counter_id, - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to delete acl counter%lx : %s", + acl_counter_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -832,26 +851,24 @@ sai_status_t sai_delete_acl_counter( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_acl_counter_attribute( - _In_ sai_object_id_t acl_counter_id, - _In_ const sai_attribute_t *attr) -{ - SAI_LOG_ENTER(); +sai_status_t sai_set_acl_counter_attribute(_In_ sai_object_id_t acl_counter_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(acl_counter_id) == SAI_OBJECT_TYPE_ACL_COUNTER); + SAI_ASSERT(sai_object_type_query(acl_counter_id) == + SAI_OBJECT_TYPE_ACL_COUNTER); - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -867,71 +884,66 @@ sai_status_t sai_set_acl_counter_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_acl_counter_attribute( - _In_ sai_object_id_t acl_counter_id, - _In_ uint32_t attr_count, - _Out_ sai_attribute_t *attr_list) -{ - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_counter_t counter; - sai_attribute_t *attribute = NULL; - uint32_t index = 0; - - SAI_ASSERT(sai_object_type_query(acl_counter_id) == SAI_OBJECT_TYPE_ACL_COUNTER); - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - - memset(&counter, 0, sizeof(switch_counter_t)); - switch_status = switch_api_acl_stats_get( - device, - acl_counter_id, - &counter); - status = sai_switch_status_to_sai_status(switch_status); - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT: - case SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT: - break; - case SAI_ACL_COUNTER_ATTR_PACKETS: - attribute->value.u64 = counter.num_packets; - break; - case SAI_ACL_COUNTER_ATTR_BYTES: - attribute->value.u64 = counter.num_bytes; - break; - } +sai_status_t sai_get_acl_counter_attribute(_In_ sai_object_id_t acl_counter_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_counter_t counter; + sai_attribute_t *attribute = NULL; + uint32_t index = 0; + + SAI_ASSERT(sai_object_type_query(acl_counter_id) == + SAI_OBJECT_TYPE_ACL_COUNTER); + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + + memset(&counter, 0, sizeof(switch_counter_t)); + switch_status = switch_api_acl_stats_get(device, acl_counter_id, &counter); + status = sai_switch_status_to_sai_status(switch_status); + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT: + case SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT: + break; + case SAI_ACL_COUNTER_ATTR_PACKETS: + attribute->value.u64 = counter.num_packets; + break; + case SAI_ACL_COUNTER_ATTR_BYTES: + attribute->value.u64 = counter.num_bytes; + break; } + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * ACL methods table retrieved with sai_api_query() */ sai_acl_api_t acl_api = { - .create_acl_table = sai_create_acl_table, - .delete_acl_table = sai_delete_acl_table, - .create_acl_entry = sai_create_acl_entry, - .delete_acl_entry = sai_delete_acl_entry, - .create_acl_counter = sai_create_acl_counter, - .delete_acl_counter = sai_delete_acl_counter, - .set_acl_counter_attribute = sai_set_acl_counter_attribute, - .get_acl_counter_attribute = sai_get_acl_counter_attribute + .create_acl_table = sai_create_acl_table, + .delete_acl_table = sai_delete_acl_table, + .create_acl_entry = sai_create_acl_entry, + .delete_acl_entry = sai_delete_acl_entry, + .create_acl_counter = sai_create_acl_counter, + .delete_acl_counter = sai_delete_acl_counter, + .set_acl_counter_attribute = sai_set_acl_counter_attribute, + .get_acl_counter_attribute = sai_get_acl_counter_attribute }; sai_status_t sai_acl_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing acl"); - sai_api_service->acl_api = acl_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing acl"); + sai_api_service->acl_api = acl_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saibuffer.c b/switchsai/src/saibuffer.c new file mode 100644 index 0000000..233f4bb --- /dev/null +++ b/switchsai/src/saibuffer.c @@ -0,0 +1,379 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "saiinternal.h" +#include + +static sai_api_t api_id = SAI_API_BUFFERS; + +/** + * @brief Set ingress priority group attribute + * @param[in] ingress_pg_id ingress priority group id + * @param[in] attr attribute to set + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_ingress_priority_group_attribute( + _In_ sai_object_id_t ingress_pg_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(ingress_pg_id) == + SAI_OBJECT_TYPE_PRIORITY_GROUP); + SAI_ASSERT(sai_object_type_query(attr->value.oid) == + SAI_OBJECT_TYPE_BUFFER_PROFILE); + + status = switch_api_priority_group_buffer_profile_set( + device, ingress_pg_id, attr->value.oid); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set pg buffer profile :%s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Get ingress priority group attributes + * @param[in] ingress_pg_id ingress priority group id + * @param[in] attr_count number of attributes + * @param[inout] attr_list array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_get_ingress_priority_group_attribute( + _In_ sai_object_id_t ingress_pg_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_LOG_EXIT(); + + return status; +} + +static void sai_buffer_pool_attribute_parse( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + switch_direction_t *direction, + uint32_t *size) { + const sai_attribute_t *attribute; + uint32_t i = 0; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_BUFFER_POOL_ATTR_SHARED_SIZE: + break; + case SAI_BUFFER_POOL_ATTR_TYPE: + if (attribute->value.u32 == SAI_BUFFER_POOL_INGRESS) { + *direction = SWITCH_API_DIRECTION_INGRESS; + } else { + *direction = SWITCH_API_DIRECTION_EGRESS; + } + break; + case SAI_BUFFER_POOL_ATTR_SIZE: + *size = attribute->value.u32; + break; + case SAI_BUFFER_POOL_ATTR_TH_MODE: + break; + default: + break; + } + } +} + +/** + * @brief Create buffer pool + * @param[out] pool_id buffer pool id + * @param[in] attr_count number of attributes + * @param[in] attr_list array of attributes + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_create_buffer_pool(_Out_ sai_object_id_t *pool_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_direction_t direction = 0; + uint32_t size = 0; + + sai_buffer_pool_attribute_parse(attr_count, attr_list, &direction, &size); + + *pool_id = switch_api_buffer_pool_create(device, direction, size); + + status = (*pool_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create buffer pool: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Remove buffer pool + * @param[in] pool_id buffer pool id + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_buffer_pool(_In_ sai_object_id_t pool_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(pool_id) == SAI_OBJECT_TYPE_BUFFER_POOL); + + status = switch_api_buffer_pool_delete(device, pool_id); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to delete buffer pool: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Set buffer pool attribute + * @param[in] pool_id buffer pool id + * @param[in] attr attribute + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_buffer_pool_attribute(_In_ sai_object_id_t pool_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(pool_id) == SAI_OBJECT_TYPE_BUFFER_POOL); + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Get buffer pool attributes + * @param[in] pool_id buffer pool id + * @param[in] attr_count number of attributes + * @param[inout] attr_list array of attributes + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_get_buffer_pool_attribute(_In_ sai_object_id_t pool_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(pool_id) == SAI_OBJECT_TYPE_BUFFER_POOL); + + SAI_LOG_EXIT(); + + return status; +} + +static void sai_buffer_profile_attribute_parse( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + switch_api_buffer_profile_t *buffer_profile_info) { + const sai_attribute_t *attribute; + uint32_t i = 0; + sai_buffer_threshold_mode_t threshold_mode; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_BUFFER_PROFILE_ATTR_POOL_ID: + buffer_profile_info->pool_handle = attribute->value.oid; + break; + case SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE: + buffer_profile_info->buffer_size = attribute->value.u32; + break; + /* + case SAI_BUFFER_PROFILE_ATTR_TH_MODE: + threshold_mode = attribute->value.u32; + break; + */ + case SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH: + SAI_ASSERT(threshold_mode == SAI_BUFFER_THRESHOLD_MODE_DYNAMIC); + buffer_profile_info->threshold_mode = + SWITCH_BUFFER_THRESHOLD_MODE_DYNAMIC; + buffer_profile_info->threshold = attribute->value.u32; + break; + case SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH: + SAI_ASSERT(threshold_mode == SAI_BUFFER_THRESHOLD_MODE_STATIC); + buffer_profile_info->threshold_mode = + SWITCH_BUFFER_THRESHOLD_MODE_STATIC; + buffer_profile_info->threshold = attribute->value.u32; + break; + case SAI_BUFFER_PROFILE_ATTR_XOFF_TH: + buffer_profile_info->xoff_threshold = attribute->value.u32; + break; + case SAI_BUFFER_PROFILE_ATTR_XON_TH: + buffer_profile_info->xon_threshold = attribute->value.u32; + break; + default: + break; + } + } +} + +/** + * @brief Create buffer profile + * @param[out] buffer_profile_id buffer profile id + * @param[in] attr_count number of attributes + * @param[in] attr_list array of attributes + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_create_buffer_profile(_Out_ sai_object_id_t *buffer_profile_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_api_buffer_profile_t buffer_profile_info; + + memset(&buffer_profile_info, 0x0, sizeof(buffer_profile_info)); + + sai_buffer_profile_attribute_parse( + attr_count, attr_list, &buffer_profile_info); + *buffer_profile_id = + switch_api_buffer_profile_create(device, &buffer_profile_info); + + status = (*buffer_profile_id == SWITCH_API_INVALID_HANDLE) + ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create buffer pool: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Remove buffer profile + * @param[in] buffer_profile_id buffer profile id + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_buffer_profile(_In_ sai_object_id_t buffer_profile_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(buffer_profile_id) == + SAI_OBJECT_TYPE_BUFFER_PROFILE); + + status = switch_api_buffer_profile_delete(device, buffer_profile_id); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove buffer pool: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Set buffer profile attribute + * @param[in] buffer_profile_id buffer profile id + * @param[in] attr attribute + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_buffer_profile_attribute( + _In_ sai_object_id_t buffer_profile_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(buffer_profile_id) == + SAI_OBJECT_TYPE_BUFFER_PROFILE); + + SAI_LOG_EXIT(); + + return status; +} + +/** + * @brief Get buffer profile attributes + * @param[in] buffer_profile_id buffer profile id + * @param[in] attr_count number of attributes + * @param[inout] attr_list array of attributes + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_get_buffer_profile_attribute( + _In_ sai_object_id_t buffer_profile_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(buffer_profile_id) == + SAI_OBJECT_TYPE_BUFFER_PROFILE); + + SAI_LOG_EXIT(); + + return status; +} + +/* +* Buffer methods table retrieved with sai_api_query() +*/ +sai_buffer_api_t buffer_api = { + .create_buffer_pool = sai_create_buffer_pool, + .remove_buffer_pool = sai_remove_buffer_pool, + .set_buffer_pool_attr = sai_set_buffer_pool_attribute, + .get_buffer_pool_attr = sai_get_buffer_pool_attribute, + .set_ingress_priority_group_attr = sai_set_ingress_priority_group_attribute, + .get_ingress_priority_group_attr = sai_get_ingress_priority_group_attribute, + .create_buffer_profile = sai_create_buffer_profile, + .remove_buffer_profile = sai_remove_buffer_profile, + .set_buffer_profile_attr = sai_set_buffer_profile_attribute, + .get_buffer_profile_attr = sai_get_buffer_profile_attribute}; + +sai_status_t sai_buffer_initialize(sai_api_service_t *sai_api_service) { + SAI_LOG_DEBUG("Initializing buffer"); + sai_api_service->buffer_api = buffer_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saifdb.c b/switchsai/src/saifdb.c index cbe59da..4430fcc 100644 --- a/switchsai/src/saifdb.c +++ b/switchsai/src/saifdb.c @@ -22,71 +22,67 @@ limitations under the License. static sai_api_t api_id = SAI_API_FDB; -static void sai_fdb_entry_to_string( - _In_ const sai_fdb_entry_t *fdb_entry, - _Out_ char *entry_string) -{ - snprintf(entry_string, SAI_MAX_ENTRY_STRING_LEN, - "fdb entry mac [%02x:%02x:%02x:%02x:%02x:%02x] vlan %u", - fdb_entry->mac_address[0], - fdb_entry->mac_address[1], - fdb_entry->mac_address[2], - fdb_entry->mac_address[3], - fdb_entry->mac_address[4], - fdb_entry->mac_address[5], - fdb_entry->vlan_id); +static void sai_fdb_entry_to_string(_In_ const sai_fdb_entry_t *fdb_entry, + _Out_ char *entry_string) { + snprintf(entry_string, + SAI_MAX_ENTRY_STRING_LEN, + "fdb entry mac [%02x:%02x:%02x:%02x:%02x:%02x] vlan %u", + fdb_entry->mac_address[0], + fdb_entry->mac_address[1], + fdb_entry->mac_address[2], + fdb_entry->mac_address[3], + fdb_entry->mac_address[4], + fdb_entry->mac_address[5], + fdb_entry->vlan_id); } -static void sai_fdb_entry_parse( - const sai_fdb_entry_t *fdb_entry, - switch_api_mac_entry_t *mac_entry) { - switch_api_vlan_id_to_handle_get(fdb_entry->vlan_id, &mac_entry->vlan_handle); - memcpy(mac_entry->mac.mac_addr, fdb_entry->mac_address, ETH_ALEN); +static void sai_fdb_entry_parse(const sai_fdb_entry_t *fdb_entry, + switch_api_mac_entry_t *mac_entry) { + switch_api_vlan_id_to_handle_get(fdb_entry->vlan_id, &mac_entry->vlan_handle); + memcpy(mac_entry->mac.mac_addr, fdb_entry->mac_address, ETH_ALEN); } -static void sai_fdb_entry_attribute_parse( - uint32_t attr_count, - const sai_attribute_t *attr_list, - switch_api_mac_entry_t *mac_entry) { - - const sai_attribute_t *attribute; - uint32_t i = 0; - sai_packet_action_t action = 0; - - for (i = 0; i < attr_count; i++) { - attribute = &attr_list[i]; - switch (attribute->id) { - case SAI_FDB_ENTRY_ATTR_TYPE: - switch (attribute->value.s32) { - case SAI_FDB_ENTRY_DYNAMIC: - mac_entry->entry_type = SWITCH_MAC_ENTRY_DYNAMIC; - break; - - case SAI_FDB_ENTRY_STATIC: - mac_entry->entry_type = SWITCH_MAC_ENTRY_STATIC; - break; - } - break; - - case SAI_FDB_ENTRY_ATTR_PORT_ID: - mac_entry->handle = (switch_handle_t) attribute->value.oid; - break; - - case SAI_FDB_ENTRY_ATTR_PACKET_ACTION: - action = (switch_mac_action_t) attribute->value.s32; - switch (action) { - case SAI_PACKET_ACTION_DROP: - mac_entry->mac_action = SWITCH_MAC_ACTION_DROP; - break; - case SAI_PACKET_ACTION_FORWARD: - mac_entry->mac_action = SWITCH_MAC_ACTION_FORWARD; - break; - default: - return; - } - break; +static void sai_fdb_entry_attribute_parse(uint32_t attr_count, + const sai_attribute_t *attr_list, + switch_api_mac_entry_t *mac_entry) { + const sai_attribute_t *attribute; + uint32_t i = 0; + sai_packet_action_t action = 0; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_FDB_ENTRY_ATTR_TYPE: + switch (attribute->value.s32) { + case SAI_FDB_ENTRY_DYNAMIC: + mac_entry->entry_type = SWITCH_MAC_ENTRY_DYNAMIC; + break; + + case SAI_FDB_ENTRY_STATIC: + mac_entry->entry_type = SWITCH_MAC_ENTRY_STATIC; + break; } + break; + + case SAI_FDB_ENTRY_ATTR_PORT_ID: + mac_entry->handle = (switch_handle_t)attribute->value.oid; + break; + + case SAI_FDB_ENTRY_ATTR_PACKET_ACTION: + action = (switch_mac_action_t)attribute->value.s32; + switch (action) { + case SAI_PACKET_ACTION_DROP: + mac_entry->mac_action = SWITCH_MAC_ACTION_DROP; + break; + case SAI_PACKET_ACTION_FORWARD: + mac_entry->mac_action = SWITCH_MAC_ACTION_FORWARD; + break; + default: + return; + } + break; } + } } /* @@ -102,49 +98,45 @@ static void sai_fdb_entry_attribute_parse( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_fdb_entry( - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - switch_api_mac_entry_t mac_entry; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - - SAI_LOG_ENTER(); - - if (!fdb_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null fdb entry: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_create_fdb_entry(_In_ const sai_fdb_entry_t *fdb_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + switch_api_mac_entry_t mac_entry; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + char entry_string[SAI_MAX_ENTRY_STRING_LEN]; + + SAI_LOG_ENTER(); + + if (!fdb_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null fdb entry: %s", sai_status_to_string(status)); + return status; + } - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - memset(&mac_entry, 0, sizeof(mac_entry)); - sai_fdb_entry_parse(fdb_entry, &mac_entry); - sai_fdb_entry_attribute_parse(attr_count, attr_list, &mac_entry); + memset(&mac_entry, 0, sizeof(mac_entry)); + sai_fdb_entry_parse(fdb_entry, &mac_entry); + sai_fdb_entry_attribute_parse(attr_count, attr_list, &mac_entry); - switch_status = switch_api_mac_table_entry_add(device, &mac_entry); - status = sai_switch_status_to_sai_status(switch_status); + switch_status = switch_api_mac_table_entry_add(device, &mac_entry); + status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - sai_fdb_entry_to_string(fdb_entry, entry_string); - SAI_LOG_ERROR("failed to create fdb entry %s : %s", - entry_string, - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + sai_fdb_entry_to_string(fdb_entry, entry_string); + SAI_LOG_ERROR("failed to create fdb entry %s : %s", + entry_string, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -158,38 +150,36 @@ sai_status_t sai_create_fdb_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_fdb_entry( - _In_ const sai_fdb_entry_t *fdb_entry) { - switch_api_mac_entry_t mac_entry; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - - SAI_LOG_ENTER(); - - if (!fdb_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null fdb entry: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_remove_fdb_entry(_In_ const sai_fdb_entry_t *fdb_entry) { + switch_api_mac_entry_t mac_entry; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - memset(&mac_entry, 0, sizeof(mac_entry)); - sai_fdb_entry_parse(fdb_entry, &mac_entry); + SAI_LOG_ENTER(); - switch_status = switch_api_mac_table_entry_delete(device, &mac_entry); - status = sai_switch_status_to_sai_status(switch_status); + if (!fdb_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null fdb entry: %s", sai_status_to_string(status)); + return status; + } - if (status != SAI_STATUS_SUCCESS) { - sai_fdb_entry_to_string(fdb_entry, entry_string); - SAI_LOG_ERROR("failed to remove fdb entry %s : %s", - entry_string, - sai_status_to_string(status)); - } + memset(&mac_entry, 0, sizeof(mac_entry)); + sai_fdb_entry_parse(fdb_entry, &mac_entry); + + switch_status = switch_api_mac_table_entry_delete(device, &mac_entry); + status = sai_switch_status_to_sai_status(switch_status); - SAI_LOG_EXIT(); + if (status != SAI_STATUS_SUCCESS) { + sai_fdb_entry_to_string(fdb_entry, entry_string); + SAI_LOG_ERROR("failed to remove fdb entry %s : %s", + entry_string, + sai_status_to_string(status)); + } - return (sai_status_t) status; + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -204,47 +194,44 @@ sai_status_t sai_remove_fdb_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_fdb_entry_attribute( - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const sai_attribute_t *attr) { - switch_api_mac_entry_t mac_entry; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - - SAI_LOG_ENTER(); - - if (!fdb_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null fdb entry: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_set_fdb_entry_attribute(_In_ const sai_fdb_entry_t *fdb_entry, + _In_ const sai_attribute_t *attr) { + switch_api_mac_entry_t mac_entry; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + char entry_string[SAI_MAX_ENTRY_STRING_LEN]; + + SAI_LOG_ENTER(); + + if (!fdb_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null fdb entry: %s", sai_status_to_string(status)); + return status; + } - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - memset(&mac_entry, 0, sizeof(mac_entry)); - sai_fdb_entry_parse(fdb_entry, &mac_entry); - sai_fdb_entry_attribute_parse(1, attr, &mac_entry); + memset(&mac_entry, 0, sizeof(mac_entry)); + sai_fdb_entry_parse(fdb_entry, &mac_entry); + sai_fdb_entry_attribute_parse(1, attr, &mac_entry); - switch_status = switch_api_mac_table_entry_update(device, &mac_entry); - status = sai_switch_status_to_sai_status(switch_status); + switch_status = switch_api_mac_table_entry_update(device, &mac_entry); + status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - sai_fdb_entry_to_string(fdb_entry, entry_string); - SAI_LOG_ERROR("failed to update fdb entry %s : %s", - entry_string, - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + sai_fdb_entry_to_string(fdb_entry, entry_string); + SAI_LOG_ERROR("failed to update fdb entry %s : %s", + entry_string, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -260,29 +247,26 @@ sai_status_t sai_set_fdb_entry_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_fdb_entry_attribute( - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!fdb_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null fdb entry: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_get_fdb_entry_attribute(_In_ const sai_fdb_entry_t *fdb_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - SAI_LOG_EXIT(); + sai_status_t status = SAI_STATUS_SUCCESS; + + if (!fdb_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null fdb entry: %s", sai_status_to_string(status)); return status; + } + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + SAI_LOG_EXIT(); + return status; } /* @@ -297,166 +281,155 @@ sai_status_t sai_get_fdb_entry_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_flush_fdb_entries( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - const sai_attribute_t *attribute; - uint32_t index = 0; - sai_object_id_t port_id = 0; - sai_vlan_id_t vlan_id = 0; - bool flush_all = false; - bool port_valid = false; - bool vlan_valid = false; - switch_handle_t vlan_handle = 0; - sai_fdb_flush_entry_type_t entry_type = 0; - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_FDB_FLUSH_ATTR_PORT_ID: - port_id = attribute->value.oid; - port_valid = true; - break; - case SAI_FDB_FLUSH_ATTR_VLAN_ID: - vlan_id = attribute->value.u16; - vlan_valid = true; - break; - case SAI_FDB_FLUSH_ATTR_ENTRY_TYPE: - entry_type = attribute->value.s32; - switch (entry_type) { - case SAI_FDB_FLUSH_ENTRY_DYNAMIC: - case SAI_FDB_FLUSH_ENTRY_STATIC: - break; - } - break; +sai_status_t sai_flush_fdb_entries(_In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + const sai_attribute_t *attribute; + uint32_t index = 0; + sai_object_id_t port_id = 0; + sai_vlan_id_t vlan_id = 0; + bool flush_all = false; + bool port_valid = false; + bool vlan_valid = false; + switch_handle_t vlan_handle = 0; + sai_fdb_flush_entry_type_t entry_type = 0; + sai_status_t status = SAI_STATUS_SUCCESS; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_FDB_FLUSH_ATTR_PORT_ID: + port_id = attribute->value.oid; + port_valid = true; + break; + case SAI_FDB_FLUSH_ATTR_VLAN_ID: + vlan_id = attribute->value.u16; + vlan_valid = true; + break; + case SAI_FDB_FLUSH_ATTR_ENTRY_TYPE: + entry_type = attribute->value.s32; + switch (entry_type) { + case SAI_FDB_FLUSH_ENTRY_DYNAMIC: + case SAI_FDB_FLUSH_ENTRY_STATIC: + break; } + break; } - if (flush_all) { - status = switch_api_mac_table_entries_delete_all(device); + } + if (flush_all) { + status = switch_api_mac_table_entries_delete_all(device); + } else { + if (port_valid && vlan_valid) { + switch_api_vlan_id_to_handle_get(vlan_id, &vlan_handle); + status = switch_api_mac_table_entries_delete_by_interface_vlan( + device, (switch_handle_t)port_id, vlan_handle); + } else if (port_valid) { + status = switch_api_mac_table_entries_delete_by_interface( + device, (switch_handle_t)port_id); + } else if (vlan_valid) { + switch_api_vlan_id_to_handle_get(vlan_id, &vlan_handle); + status = switch_api_mac_table_entries_delete_by_vlan(device, vlan_handle); } else { - if (port_valid && vlan_valid) { - switch_api_vlan_id_to_handle_get(vlan_id, &vlan_handle); - status = switch_api_mac_table_entries_delete_by_interface_vlan( - device, (switch_handle_t)port_id, vlan_handle); - } else if (port_valid) { - status = switch_api_mac_table_entries_delete_by_interface( - device, (switch_handle_t)port_id); - } else if (vlan_valid) { - switch_api_vlan_id_to_handle_get(vlan_id, &vlan_handle); - status = switch_api_mac_table_entries_delete_by_vlan(device, - vlan_handle); - } else { - status = SAI_STATUS_FAILURE; - } + status = SAI_STATUS_FAILURE; } + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } -static void -sai_mac_learn_notify_cb(switch_api_mac_entry_t *mac_entry) -{ - - SAI_LOG_ENTER(); - - if (!sai_switch_notifications.on_fdb_event) { - return; - } - - if (!mac_entry) { - SAI_LOG_ERROR("invalid argument"); - return; - } +static void sai_mac_learn_notify_cb(switch_api_mac_entry_t *mac_entry) { + SAI_LOG_ENTER(); - switch_vlan_t vlan_id; - switch_handle_t intf_h; - switch_status_t status = SWITCH_STATUS_SUCCESS; - status = switch_api_vlan_handle_to_id_get(mac_entry->vlan_handle, &vlan_id); - assert(status == SWITCH_STATUS_SUCCESS); - status = switch_api_interface_get_port_handle(mac_entry->handle, &intf_h); - assert(status == SWITCH_STATUS_SUCCESS); - - sai_fdb_event_notification_data_t fdb_event; - memset(&fdb_event, 0, sizeof(fdb_event)); - fdb_event.event_type = SAI_FDB_EVENT_LEARNED; - memcpy(fdb_event.fdb_entry.mac_address, mac_entry->mac.mac_addr, ETH_ALEN); - fdb_event.fdb_entry.vlan_id = vlan_id; - 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.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.s32 = SAI_PACKET_ACTION_FORWARD; - fdb_event.attr = attr_list; - fdb_event.attr_count = 3; - sai_switch_notifications.on_fdb_event(1, &fdb_event); - - SAI_LOG_EXIT(); + if (!sai_switch_notifications.on_fdb_event) { + return; + } + if (!mac_entry) { + SAI_LOG_ERROR("invalid argument"); return; + } + + switch_vlan_t vlan_id; + switch_handle_t intf_h; + switch_status_t status = SWITCH_STATUS_SUCCESS; + status = switch_api_vlan_handle_to_id_get(mac_entry->vlan_handle, &vlan_id); + assert(status == SWITCH_STATUS_SUCCESS); + status = switch_api_interface_get_port_handle(mac_entry->handle, &intf_h); + assert(status == SWITCH_STATUS_SUCCESS); + + sai_fdb_event_notification_data_t fdb_event; + memset(&fdb_event, 0, sizeof(fdb_event)); + fdb_event.event_type = SAI_FDB_EVENT_LEARNED; + memcpy(fdb_event.fdb_entry.mac_address, mac_entry->mac.mac_addr, ETH_ALEN); + fdb_event.fdb_entry.vlan_id = vlan_id; + 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.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.s32 = SAI_PACKET_ACTION_FORWARD; + fdb_event.attr = attr_list; + fdb_event.attr_count = 3; + sai_switch_notifications.on_fdb_event(1, &fdb_event); + + SAI_LOG_EXIT(); + + return; } -static void -sai_mac_age_notify_cb(switch_api_mac_entry_t *mac_entry) -{ - if (!sai_switch_notifications.on_fdb_event) { - return; - } +static void sai_mac_age_notify_cb(switch_api_mac_entry_t *mac_entry) { + if (!sai_switch_notifications.on_fdb_event) { + return; + } - if (!mac_entry) { - SAI_LOG_ERROR("invalid argument"); - return; - } + if (!mac_entry) { + SAI_LOG_ERROR("invalid argument"); + return; + } - switch_vlan_t vlan_id; - switch_status_t status = SWITCH_STATUS_SUCCESS; - status = switch_api_vlan_handle_to_id_get(mac_entry->vlan_handle, &vlan_id); - assert(status == SWITCH_STATUS_SUCCESS); + switch_vlan_t vlan_id; + switch_status_t status = SWITCH_STATUS_SUCCESS; + status = switch_api_vlan_handle_to_id_get(mac_entry->vlan_handle, &vlan_id); + assert(status == SWITCH_STATUS_SUCCESS); - sai_fdb_event_notification_data_t fdb_event; - memset(&fdb_event, 0, sizeof(fdb_event)); - fdb_event.event_type = SAI_FDB_EVENT_AGED; - memcpy(fdb_event.fdb_entry.mac_address, mac_entry->mac.mac_addr, ETH_ALEN); - fdb_event.fdb_entry.vlan_id = vlan_id; - fdb_event.attr = NULL; - fdb_event.attr_count = 0; - sai_switch_notifications.on_fdb_event(1, &fdb_event); + sai_fdb_event_notification_data_t fdb_event; + memset(&fdb_event, 0, sizeof(fdb_event)); + fdb_event.event_type = SAI_FDB_EVENT_AGED; + memcpy(fdb_event.fdb_entry.mac_address, mac_entry->mac.mac_addr, ETH_ALEN); + fdb_event.fdb_entry.vlan_id = vlan_id; + fdb_event.attr = NULL; + fdb_event.attr_count = 0; + sai_switch_notifications.on_fdb_event(1, &fdb_event); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return; + return; } /* * FDB methods table retrieved with sai_api_query() */ -sai_fdb_api_t fdb_api = { - .create_fdb_entry = sai_create_fdb_entry, - .remove_fdb_entry = sai_remove_fdb_entry, - .set_fdb_entry_attribute = sai_set_fdb_entry_attribute, - .get_fdb_entry_attribute = sai_get_fdb_entry_attribute, - .flush_fdb_entries = sai_flush_fdb_entries -}; +sai_fdb_api_t fdb_api = {.create_fdb_entry = sai_create_fdb_entry, + .remove_fdb_entry = sai_remove_fdb_entry, + .set_fdb_entry_attribute = sai_set_fdb_entry_attribute, + .get_fdb_entry_attribute = sai_get_fdb_entry_attribute, + .flush_fdb_entries = sai_flush_fdb_entries}; sai_status_t sai_fdb_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("initializing fdb"); - sai_api_service->fdb_api = fdb_api; - switch_api_mac_register_learning_callback(&sai_mac_learn_notify_cb); - switch_api_mac_register_aging_callback(&sai_mac_age_notify_cb); - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("initializing fdb"); + sai_api_service->fdb_api = fdb_api; + switch_api_mac_register_learning_callback(&sai_mac_learn_notify_cb); + switch_api_mac_register_aging_callback(&sai_mac_age_notify_cb); + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saihash.c b/switchsai/src/saihash.c new file mode 100644 index 0000000..9643429 --- /dev/null +++ b/switchsai/src/saihash.c @@ -0,0 +1,55 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include + +#include "saiinternal.h" + +// Unused for now +/* static sai_api_t api_id = SAI_API_HASH; */ + +sai_status_t sai_create_hash(_Out_ sai_object_id_t *hash_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_remove_hash(_In_ sai_object_id_t hash_id) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_set_hash_attribute(_In_ sai_object_id_t hash_id, + _In_ const sai_attribute_t *attr) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_get_hash_attribute(_In_ sai_object_id_t hash_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_hash_api_t hash_api = { + .create_hash = sai_create_hash, + .remove_hash = sai_remove_hash, + .set_hash_attribute = sai_set_hash_attribute, + .get_hash_attribute = sai_get_hash_attribute, +}; + +sai_status_t sai_hash_initialize(sai_api_service_t *sai_api_service) { + sai_api_service->hash_api = hash_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saihostintf.c b/switchsai/src/saihostintf.c index 0cda6b0..e75f857 100644 --- a/switchsai/src/saihostintf.c +++ b/switchsai/src/saihostintf.c @@ -33,54 +33,48 @@ static sai_api_t api_id = SAI_API_HOST_INTERFACE; * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_hostif( - _Out_ sai_object_id_t * hif_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - const sai_attribute_t *attribute; - uint32_t index = 0; - switch_hostif_t hostif; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_HOSTIF_ATTR_TYPE: - if (attribute->value.u32 != SAI_HOSTIF_TYPE_NETDEV) { - return SAI_STATUS_FAILURE; - } - break; - case SAI_HOSTIF_ATTR_RIF_OR_PORT_ID: - hostif.handle = attribute->value.oid; - break; - case SAI_HOSTIF_ATTR_NAME: - memcpy(hostif.intf_name, attribute->value.chardata, HOSTIF_NAME_SIZE); - break; - default: - break; +sai_status_t sai_create_hostif(_Out_ sai_object_id_t *hif_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + const sai_attribute_t *attribute; + uint32_t index = 0; + switch_hostif_t hostif; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_HOSTIF_ATTR_TYPE: + if (attribute->value.u32 != SAI_HOSTIF_TYPE_NETDEV) { + return SAI_STATUS_FAILURE; } - } - *hif_id = switch_api_hostif_create(device, &hostif); - status = (*hif_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create hostif: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - return (sai_status_t) status; + break; + case SAI_HOSTIF_ATTR_RIF_OR_PORT_ID: + break; + case SAI_HOSTIF_ATTR_NAME: + memcpy(hostif.intf_name, attribute->value.chardata, HOSTIF_NAME_SIZE); + break; + default: + break; + } + } + *hif_id = switch_api_hostif_create(device, &hostif); + status = (*hif_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create hostif: %s", sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + return (sai_status_t)status; } /* @@ -94,25 +88,24 @@ sai_status_t sai_create_hostif( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_hostif( - _In_ sai_object_id_t hif_id) { - - SAI_LOG_ENTER(); +sai_status_t sai_remove_hostif(_In_ sai_object_id_t hif_id) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); - switch_status = switch_api_hostif_delete(device, hif_id); - status = sai_switch_status_to_sai_status(switch_status); + SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); + switch_status = switch_api_hostif_delete(device, hif_id); + status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove hostif %lx: %s", - hif_id, sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove hostif %lx: %s", + hif_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); - return status; + SAI_LOG_EXIT(); + return status; } /* @@ -127,25 +120,22 @@ sai_status_t sai_remove_hostif( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_hostif_attribute( - _In_ sai_object_id_t hif_id, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_set_hostif_attribute(_In_ sai_object_id_t hif_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); + SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } /* @@ -161,26 +151,23 @@ sai_status_t sai_set_hostif_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_hostif_attribute( - _In_ sai_object_id_t hif_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_get_hostif_attribute(_In_ sai_object_id_t hif_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); + SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } /* @@ -200,51 +187,47 @@ sai_status_t sai_create_hostif_trap_group( _Out_ sai_object_id_t *hostif_trap_group_id, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - const sai_attribute_t *attribute; - switch_hostif_group_t hostif_group; - uint32_t index = 0; + sai_status_t status = SAI_STATUS_SUCCESS; + const sai_attribute_t *attribute; + switch_hostif_group_t hostif_group; + uint32_t index = 0; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - memset(&hostif_group, 0, sizeof(switch_hostif_group_t)); - hostif_group.priority = 1000; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_HOSTIF_TRAP_GROUP_ATTR_ADMIN_STATE: - break; - case SAI_HOSTIF_TRAP_GROUP_ATTR_PRIO: - hostif_group.priority = attribute->value.u32; - break; - case SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE: - hostif_group.egress_queue = attribute->value.u32; - break; - case SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER: - break; - } - } - - *hostif_trap_group_id = switch_api_hostif_group_create(device, &hostif_group); - status = (*hostif_trap_group_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create hostif trap group: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return SAI_STATUS_SUCCESS; + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + memset(&hostif_group, 0, sizeof(switch_hostif_group_t)); + hostif_group.priority = 1000; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_HOSTIF_TRAP_GROUP_ATTR_ADMIN_STATE: + break; + case SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE: + hostif_group.queue_id = attribute->value.u32; + break; + case SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER: + hostif_group.policer_handle = attribute->value.oid; + break; + } + } + + *hostif_trap_group_id = switch_api_hostif_group_create(device, &hostif_group); + status = (*hostif_trap_group_id == SWITCH_API_INVALID_HANDLE) + ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create hostif trap group: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return SAI_STATUS_SUCCESS; } /* @@ -259,20 +242,20 @@ sai_status_t sai_create_hostif_trap_group( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_hostif_trap_group( - _In_ sai_object_id_t hostif_trap_group_id) { - - SAI_LOG_ENTER(); +sai_status_t sai_remove_hostif_trap_group(_In_ sai_object_id_t + hostif_trap_group_id) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(hostif_trap_group_id) == SAI_OBJECT_TYPE_TRAP_GROUP); + SAI_ASSERT(sai_object_type_query(hostif_trap_group_id) == + SAI_OBJECT_TYPE_TRAP_GROUP); - status = switch_api_hostif_group_delete(device, hostif_trap_group_id); + status = switch_api_hostif_group_delete(device, hostif_trap_group_id); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /* @@ -290,22 +273,21 @@ sai_status_t sai_remove_hostif_trap_group( sai_status_t sai_set_hostif_trap_group_attribute( _In_ sai_object_id_t hostif_trap_group_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - SAI_ASSERT(sai_object_type_query(hostif_trap_group_id) == SAI_OBJECT_TYPE_TRAP_GROUP); + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + SAI_ASSERT(sai_object_type_query(hostif_trap_group_id) == + SAI_OBJECT_TYPE_TRAP_GROUP); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } /* @@ -326,161 +308,160 @@ sai_status_t sai_get_hostif_trap_group_attribute( _In_ sai_object_id_t hostif_trap_group_id, _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(hostif_trap_group_id) == SAI_OBJECT_TYPE_TRAP_GROUP); + SAI_ASSERT(sai_object_type_query(hostif_trap_group_id) == + SAI_OBJECT_TYPE_TRAP_GROUP); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } switch_hostif_reason_code_t switch_sai_to_switch_api_reason_code( - sai_hostif_trap_id_t trap_id) { - switch_hostif_reason_code_t reason_code = SWITCH_HOSTIF_REASON_CODE_NONE; - switch (trap_id) { - case SAI_HOSTIF_TRAP_ID_STP: - reason_code = SWITCH_HOSTIF_REASON_CODE_STP; - break; - case SAI_HOSTIF_TRAP_ID_LACP: - reason_code = SWITCH_HOSTIF_REASON_CODE_LACP; - break; - case SAI_HOSTIF_TRAP_ID_EAPOL: - reason_code = SWITCH_HOSTIF_REASON_CODE_EAPOL; - break; - case SAI_HOSTIF_TRAP_ID_LLDP: - reason_code = SWITCH_HOSTIF_REASON_CODE_LLDP; - break; - case SAI_HOSTIF_TRAP_ID_PVRST: - reason_code = SWITCH_HOSTIF_REASON_CODE_PVRST; - break; - case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_QUERY: - reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_QUERY; - break; - case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_LEAVE: - reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_LEAVE; - break; - case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V1_REPORT: - reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V1_REPORT; - break; - case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT: - reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT; - break; - case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V3_REPORT: - reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V3_REPORT; - break; - case SAI_HOSTIF_TRAP_ID_SAMPLEPACKET: - reason_code = SWITCH_HOSTIF_REASON_CODE_SAMPLEPACKET; - break; - case SAI_HOSTIF_TRAP_ID_ARP_REQUEST: - reason_code = SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST; - break; - case SAI_HOSTIF_TRAP_ID_ARP_RESPONSE: - reason_code = SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE; - break; - case SAI_HOSTIF_TRAP_ID_DHCP: - reason_code = SWITCH_HOSTIF_REASON_CODE_DHCP; - break; - case SAI_HOSTIF_TRAP_ID_OSPF: - reason_code = SWITCH_HOSTIF_REASON_CODE_OSPF; - break; - case SAI_HOSTIF_TRAP_ID_PIM: - reason_code = SWITCH_HOSTIF_REASON_CODE_PIM; - break; - case SAI_HOSTIF_TRAP_ID_VRRP: - reason_code = SWITCH_HOSTIF_REASON_CODE_VRRP; - break; - case SAI_HOSTIF_TRAP_ID_BGP: - reason_code = SWITCH_HOSTIF_REASON_CODE_BGP; - break; - case SAI_HOSTIF_TRAP_ID_DHCPV6: - reason_code = SWITCH_HOSTIF_REASON_CODE_DHCPV6; - break; - case SAI_HOSTIF_TRAP_ID_OSPFV6: - reason_code = SWITCH_HOSTIF_REASON_CODE_OSPFV6; - break; - case SAI_HOSTIF_TRAP_ID_VRRPV6: - reason_code = SWITCH_HOSTIF_REASON_CODE_VRRPV6; - break; - case SAI_HOSTIF_TRAP_ID_BGPV6: - reason_code = SWITCH_HOSTIF_REASON_CODE_BGPV6; - break; - case SAI_HOSTIF_TRAP_ID_IPV6_NEIGHBOR_DISCOVERY: - reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY; - break; - case SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_V2: - reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_V2; - break; - case SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_REPORT: - reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_REPORT; - break; - case SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_DONE: - reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_DONE; - break; - case SAI_HOSTIF_TRAP_ID_MLD_V2_REPORT: - reason_code = SWITCH_HOSTIF_REASON_CODE_MLD_V2_REPORT; - break; - case SAI_HOSTIF_TRAP_ID_L3_MTU_ERROR: - reason_code = SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR; - break; - case SAI_HOSTIF_TRAP_ID_TTL_ERROR: - reason_code = SWITCH_HOSTIF_REASON_CODE_TTL_ERROR; - break; - default: - break; - } - return reason_code; + sai_hostif_trap_id_t trap_id) { + switch_hostif_reason_code_t reason_code = SWITCH_HOSTIF_REASON_CODE_NONE; + switch (trap_id) { + case SAI_HOSTIF_TRAP_ID_STP: + reason_code = SWITCH_HOSTIF_REASON_CODE_STP; + break; + case SAI_HOSTIF_TRAP_ID_LACP: + reason_code = SWITCH_HOSTIF_REASON_CODE_LACP; + break; + case SAI_HOSTIF_TRAP_ID_EAPOL: + reason_code = SWITCH_HOSTIF_REASON_CODE_EAPOL; + break; + case SAI_HOSTIF_TRAP_ID_LLDP: + reason_code = SWITCH_HOSTIF_REASON_CODE_LLDP; + break; + case SAI_HOSTIF_TRAP_ID_PVRST: + reason_code = SWITCH_HOSTIF_REASON_CODE_PVRST; + break; + case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_QUERY: + reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_QUERY; + break; + case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_LEAVE: + reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_LEAVE; + break; + case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V1_REPORT: + reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V1_REPORT; + break; + case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT: + reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT; + break; + case SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V3_REPORT: + reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V3_REPORT; + break; + case SAI_HOSTIF_TRAP_ID_SAMPLEPACKET: + reason_code = SWITCH_HOSTIF_REASON_CODE_SAMPLEPACKET; + break; + case SAI_HOSTIF_TRAP_ID_ARP_REQUEST: + reason_code = SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST; + break; + case SAI_HOSTIF_TRAP_ID_ARP_RESPONSE: + reason_code = SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE; + break; + case SAI_HOSTIF_TRAP_ID_DHCP: + reason_code = SWITCH_HOSTIF_REASON_CODE_DHCP; + break; + case SAI_HOSTIF_TRAP_ID_OSPF: + reason_code = SWITCH_HOSTIF_REASON_CODE_OSPF; + break; + case SAI_HOSTIF_TRAP_ID_PIM: + reason_code = SWITCH_HOSTIF_REASON_CODE_PIM; + break; + case SAI_HOSTIF_TRAP_ID_VRRP: + reason_code = SWITCH_HOSTIF_REASON_CODE_VRRP; + break; + case SAI_HOSTIF_TRAP_ID_BGP: + reason_code = SWITCH_HOSTIF_REASON_CODE_BGP; + break; + case SAI_HOSTIF_TRAP_ID_DHCPV6: + reason_code = SWITCH_HOSTIF_REASON_CODE_DHCPV6; + break; + case SAI_HOSTIF_TRAP_ID_OSPFV6: + reason_code = SWITCH_HOSTIF_REASON_CODE_OSPFV6; + break; + case SAI_HOSTIF_TRAP_ID_VRRPV6: + reason_code = SWITCH_HOSTIF_REASON_CODE_VRRPV6; + break; + case SAI_HOSTIF_TRAP_ID_BGPV6: + reason_code = SWITCH_HOSTIF_REASON_CODE_BGPV6; + break; + case SAI_HOSTIF_TRAP_ID_IPV6_NEIGHBOR_DISCOVERY: + reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY; + break; + case SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_V2: + reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_V2; + break; + case SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_REPORT: + reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_REPORT; + break; + case SAI_HOSTIF_TRAP_ID_IPV6_MLD_V1_DONE: + reason_code = SWITCH_HOSTIF_REASON_CODE_IPV6_MLD_V1_DONE; + break; + case SAI_HOSTIF_TRAP_ID_MLD_V2_REPORT: + reason_code = SWITCH_HOSTIF_REASON_CODE_MLD_V2_REPORT; + break; + case SAI_HOSTIF_TRAP_ID_L3_MTU_ERROR: + reason_code = SWITCH_HOSTIF_REASON_CODE_L3_MTU_ERROR; + break; + case SAI_HOSTIF_TRAP_ID_TTL_ERROR: + reason_code = SWITCH_HOSTIF_REASON_CODE_TTL_ERROR; + break; + default: + break; + } + return reason_code; } switch_acl_action_t switch_sai_action_to_switch_api_action( - sai_packet_action_t packet_action) { - switch_acl_action_t acl_action = SWITCH_ACL_ACTION_NOP; - switch (packet_action) { - case SAI_PACKET_ACTION_DROP: - acl_action = SWITCH_ACL_ACTION_DROP; - break; - case SAI_PACKET_ACTION_FORWARD: - acl_action = SWITCH_ACL_ACTION_PERMIT; - break; - case SAI_PACKET_ACTION_TRAP: - acl_action = SWITCH_ACL_ACTION_REDIRECT_TO_CPU; - break; - case SAI_PACKET_ACTION_LOG: - acl_action = SWITCH_ACL_ACTION_COPY_TO_CPU; - break; - default: - break; - } - return acl_action; + sai_packet_action_t packet_action) { + switch_acl_action_t acl_action = SWITCH_ACL_ACTION_NOP; + switch (packet_action) { + case SAI_PACKET_ACTION_DROP: + acl_action = SWITCH_ACL_ACTION_DROP; + break; + case SAI_PACKET_ACTION_FORWARD: + acl_action = SWITCH_ACL_ACTION_PERMIT; + break; + case SAI_PACKET_ACTION_TRAP: + acl_action = SWITCH_ACL_ACTION_REDIRECT_TO_CPU; + break; + case SAI_PACKET_ACTION_LOG: + acl_action = SWITCH_ACL_ACTION_COPY_TO_CPU; + break; + default: + break; + } + return acl_action; } switch_hostif_channel_t switch_sai_channel_to_switch_api_channel( - sai_hostif_trap_channel_t trap_channel) { - switch_hostif_channel_t hostif_channel = 0; - switch (trap_channel) { - case SAI_HOSTIF_TRAP_CHANNEL_FD: - hostif_channel = SWITCH_HOSTIF_CHANNEL_CB; - break; - case SAI_HOSTIF_TRAP_CHANNEL_CB: - hostif_channel = SWITCH_HOSTIF_CHANNEL_CB; - break; - case SAI_HOSTIF_TRAP_CHANNEL_NETDEV: - hostif_channel = SWITCH_HOSTIF_CHANNEL_NETDEV; - break; - default: - break; - } - return hostif_channel; + sai_hostif_trap_channel_t trap_channel) { + switch_hostif_channel_t hostif_channel = 0; + switch (trap_channel) { + case SAI_HOSTIF_TRAP_CHANNEL_FD: + hostif_channel = SWITCH_HOSTIF_CHANNEL_CB; + break; + case SAI_HOSTIF_TRAP_CHANNEL_CB: + hostif_channel = SWITCH_HOSTIF_CHANNEL_CB; + break; + case SAI_HOSTIF_TRAP_CHANNEL_NETDEV: + hostif_channel = SWITCH_HOSTIF_CHANNEL_NETDEV; + break; + default: + break; + } + return hostif_channel; } /* * Routine Description: @@ -495,60 +476,60 @@ switch_hostif_channel_t switch_sai_channel_to_switch_api_channel( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_hostif_trap( - _In_ sai_hostif_trap_id_t hostif_trapid, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_api_hostif_rcode_info_t rcode_api_info; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - const sai_attribute_t *attribute; - uint32_t index = 0; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - memset(&rcode_api_info, 0, sizeof(switch_api_hostif_rcode_info_t)); - rcode_api_info.reason_code = switch_sai_to_switch_api_reason_code(hostif_trapid); - rcode_api_info.priority = 1000; - rcode_api_info.channel = SWITCH_HOSTIF_CHANNEL_NETDEV; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION: - rcode_api_info.action = switch_sai_action_to_switch_api_action(attribute->value.u32); - break; - case SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY: - rcode_api_info.priority = attribute->value.u32; - break; - case SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL: - rcode_api_info.channel = switch_sai_channel_to_switch_api_channel(attribute->value.u32); - break; - case SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP: - rcode_api_info.hostif_group_id = attribute->value.oid; - break; - default: - break; - } - } - switch_status = switch_api_hostif_reason_code_create(device, &rcode_api_info); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create hostif trap %x: %s", - hostif_trapid, - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - +sai_status_t sai_create_hostif_trap(_In_ sai_hostif_trap_id_t hostif_trapid, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_api_hostif_rcode_info_t rcode_api_info; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + const sai_attribute_t *attribute; + uint32_t index = 0; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); return status; + } + + memset(&rcode_api_info, 0, sizeof(switch_api_hostif_rcode_info_t)); + rcode_api_info.reason_code = + switch_sai_to_switch_api_reason_code(hostif_trapid); + rcode_api_info.priority = 1000; + rcode_api_info.channel = SWITCH_HOSTIF_CHANNEL_NETDEV; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION: + rcode_api_info.action = + switch_sai_action_to_switch_api_action(attribute->value.u32); + break; + case SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY: + rcode_api_info.priority = attribute->value.u32; + break; + case SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL: + rcode_api_info.channel = + switch_sai_channel_to_switch_api_channel(attribute->value.u32); + break; + case SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP: + rcode_api_info.hostif_group_id = attribute->value.oid; + break; + default: + break; + } + } + switch_status = switch_api_hostif_reason_code_create(device, &rcode_api_info); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create hostif trap %x: %s", + hostif_trapid, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; } /* @@ -562,27 +543,25 @@ sai_status_t sai_create_hostif_trap( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_hostif_trap( - _In_ sai_hostif_trap_id_t hostif_trapid) { - - SAI_LOG_ENTER(); - - switch_hostif_reason_code_t reason_code; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - - reason_code = switch_sai_to_switch_api_reason_code(hostif_trapid); - switch_status = switch_api_hostif_reason_code_delete(device, reason_code); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove hostif trap %x: %s", - hostif_trapid, - sai_status_to_string(status)); - } +sai_status_t sai_remove_hostif_trap(_In_ sai_hostif_trap_id_t hostif_trapid) { + SAI_LOG_ENTER(); - SAI_LOG_EXIT(); + switch_hostif_reason_code_t reason_code; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - return status; + reason_code = switch_sai_to_switch_api_reason_code(hostif_trapid); + switch_status = switch_api_hostif_reason_code_delete(device, reason_code); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove hostif trap %x: %s", + hostif_trapid, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; } /* @@ -597,54 +576,54 @@ sai_status_t sai_remove_hostif_trap( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_hostif_trap_attribute( - _In_ sai_hostif_trap_id_t hostif_trapid, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); +sai_status_t sai_set_hostif_trap_attribute(_In_ sai_hostif_trap_id_t + hostif_trapid, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - switch_api_hostif_rcode_info_t rcode_api_info; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - memset(&rcode_api_info, 0, sizeof(switch_api_hostif_rcode_info_t)); - rcode_api_info.reason_code = switch_sai_to_switch_api_reason_code(hostif_trapid); - rcode_api_info.channel = SWITCH_HOSTIF_CHANNEL_NETDEV; - rcode_api_info.priority = 1000; - switch (attr->id) { - case SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION: - rcode_api_info.action = switch_sai_action_to_switch_api_action(attr->value.u32); - break; - case SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY: - rcode_api_info.priority = attr->value.u32; - break; - case SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL: - rcode_api_info.channel = switch_sai_channel_to_switch_api_channel(attr->value.u32); - break; - case SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP: - rcode_api_info.hostif_group_id = attr->value.oid; - break; - default: - break; - } - switch_status = switch_api_hostif_reason_code_update(device, &rcode_api_info); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to update hostif trap %x: %s", - hostif_trapid, - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); + switch_api_hostif_rcode_info_t rcode_api_info; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + if (!attr) { + status = sai_remove_hostif_trap(hostif_trapid); return status; + } + + memset(&rcode_api_info, 0, sizeof(switch_api_hostif_rcode_info_t)); + rcode_api_info.reason_code = + switch_sai_to_switch_api_reason_code(hostif_trapid); + rcode_api_info.channel = SWITCH_HOSTIF_CHANNEL_NETDEV; + rcode_api_info.priority = 1000; + switch (attr->id) { + case SAI_HOSTIF_TRAP_ATTR_PACKET_ACTION: + rcode_api_info.action = + switch_sai_action_to_switch_api_action(attr->value.u32); + break; + case SAI_HOSTIF_TRAP_ATTR_TRAP_PRIORITY: + rcode_api_info.priority = attr->value.u32; + break; + case SAI_HOSTIF_TRAP_ATTR_TRAP_CHANNEL: + rcode_api_info.channel = + switch_sai_channel_to_switch_api_channel(attr->value.u32); + break; + case SAI_HOSTIF_TRAP_ATTR_TRAP_GROUP: + rcode_api_info.hostif_group_id = attr->value.oid; + break; + default: + break; + } + switch_status = switch_api_hostif_reason_code_update(device, &rcode_api_info); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to update hostif trap %x: %s", + hostif_trapid, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; } /* @@ -660,25 +639,23 @@ sai_status_t sai_set_hostif_trap_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_hostif_trap_attribute( - _In_ sai_hostif_trap_id_t hostif_trapid, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); +sai_status_t sai_get_hostif_trap_attribute(_In_ sai_hostif_trap_id_t + hostif_trapid, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } /* @@ -696,21 +673,19 @@ sai_status_t sai_get_hostif_trap_attribute( sai_status_t sai_set_hostif_user_defined_trap_attribute( _In_ sai_hostif_user_defined_trap_id_t hostif_user_defined_trapid, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } /* @@ -730,24 +705,21 @@ sai_status_t sai_get_hostif_user_defined_trap_attribute( _In_ sai_hostif_user_defined_trap_id_t hostif_user_defined_trapid, _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } - /* * Routine Description: * hostif receive function @@ -755,7 +727,8 @@ sai_status_t sai_get_hostif_user_defined_trap_attribute( * Arguments: * [in] hif_id - host interface id * [out] buffer - packet buffer -* [in,out] buffer_size - [in] allocated buffer size. [out] actual packet size in bytes +* [in,out] buffer_size - [in] allocated buffer size. [out] actual packet size +*in bytes * [in,out] attr_count - [in] allocated list size. [out] number of attributes * [out] attr_list - array of attributes * @@ -767,45 +740,41 @@ sai_status_t sai_get_hostif_user_defined_trap_attribute( * will be filled with required count. * Failure status code on error */ -sai_status_t sai_recv_hostif_packet( - _In_ sai_object_id_t hif_id, - _Out_ void *buffer, - _Inout_ sai_size_t *buffer_size, - _Inout_ uint32_t *attr_count, - _Out_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_recv_hostif_packet(_In_ sai_object_id_t hif_id, + _Out_ void *buffer, + _Inout_ sai_size_t *buffer_size, + _Inout_ uint32_t *attr_count, + _Out_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); + SAI_ASSERT(sai_object_type_query(hif_id) == SAI_OBJECT_TYPE_HOST_INTERFACE); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } -bool switch_sai_tx_type_to_switch_api_tx_type( - sai_hostif_tx_type_t tx_type) { - bool bypass = TRUE; - switch (tx_type) { - case SAI_HOSTIF_TX_TYPE_PIPELINE_BYPASS: - bypass = TRUE; - break; - case SAI_HOSTIF_TX_TYPE_PIPELINE_LOOKUP: - bypass = FALSE; - break; - default: - break; - } - return bypass; +bool switch_sai_tx_type_to_switch_api_tx_type(sai_hostif_tx_type_t tx_type) { + bool bypass = TRUE; + switch (tx_type) { + case SAI_HOSTIF_TX_TYPE_PIPELINE_BYPASS: + bypass = TRUE; + break; + case SAI_HOSTIF_TX_TYPE_PIPELINE_LOOKUP: + bypass = FALSE; + break; + default: + break; + } + return bypass; } /* @@ -813,7 +782,8 @@ bool switch_sai_tx_type_to_switch_api_tx_type( * hostif send function * * Arguments: -* [in] hif_id - host interface id. only valid for send through FD channel. Use SAI_NULL_OBJECT_ID for send through CB channel. +* [in] hif_id - host interface id. only valid for send through FD channel. +*Use SAI_NULL_OBJECT_ID for send through CB channel. * [In] buffer - packet buffer * [in] buffer size - packet size in bytes * [in] attr_count - number of attributes @@ -823,62 +793,60 @@ bool switch_sai_tx_type_to_switch_api_tx_type( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_send_hostif_packet( - _In_ sai_object_id_t hif_id, - _In_ void *buffer, - _In_ sai_size_t buffer_size, - _In_ uint32_t attr_count, - _In_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - switch_hostif_packet_t hostif_packet; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - memset(&hostif_packet, 0, sizeof(switch_hostif_packet_t)); - hostif_packet.pkt = buffer; - hostif_packet.pkt_size = buffer_size; - const sai_attribute_t *attribute; - uint32_t index = 0; - - if (!buffer) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return SAI_STATUS_INVALID_PARAMETER; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return SAI_STATUS_INVALID_PARAMETER; - } - - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_HOSTIF_PACKET_TX_TYPE: - hostif_packet.tx_bypass = switch_sai_tx_type_to_switch_api_tx_type(attribute->value.u32); - break; - case SAI_HOSTIF_PACKET_EGRESS_PORT_OR_LAG: - hostif_packet.handle = attribute->value.oid; - //Set is_lag flag if oid is lag - break; - default: - break; - } - } - switch_status = switch_api_hostif_tx_packet(device, &hostif_packet); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to send hostif packet on %lx: %s", - hif_id, sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return status; +sai_status_t sai_send_hostif_packet(_In_ sai_object_id_t hif_id, + _In_ void *buffer, + _In_ sai_size_t buffer_size, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + switch_hostif_packet_t hostif_packet; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + memset(&hostif_packet, 0, sizeof(switch_hostif_packet_t)); + hostif_packet.pkt = buffer; + hostif_packet.pkt_size = buffer_size; + const sai_attribute_t *attribute; + uint32_t index = 0; + + if (!buffer) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return SAI_STATUS_INVALID_PARAMETER; + } + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return SAI_STATUS_INVALID_PARAMETER; + } + + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_HOSTIF_PACKET_ATTR_TX_TYPE: + hostif_packet.tx_bypass = + switch_sai_tx_type_to_switch_api_tx_type(attribute->value.u32); + break; + case SAI_HOSTIF_PACKET_ATTR_EGRESS_PORT_OR_LAG: + hostif_packet.handle = attribute->value.oid; + // Set is_lag flag if oid is lag + break; + default: + break; + } + } + switch_status = switch_api_hostif_tx_packet(device, &hostif_packet); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to send hostif packet on %lx: %s", + hif_id, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return status; } /* @@ -893,68 +861,64 @@ sai_status_t sai_send_hostif_packet( * * Return Values: */ -void sai_recv_hostif_packet_cb( - switch_hostif_packet_t *hostif_packet) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!hostif_packet) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return; - } - - int max_attr_count = 2; - int attr_count = 0; - sai_attribute_t attr_list[max_attr_count]; - sai_attribute_t *attribute; - attribute = &attr_list[attr_count]; - attribute->id = SAI_HOSTIF_PACKET_TRAP_ID; - attribute->value.u32 = hostif_packet->reason_code; - attr_count++; - attribute = &attr_list[attr_count]; - attribute->id = SAI_HOSTIF_PACKET_INGRESS_PORT; - attribute->value.oid = hostif_packet->handle; - attr_count++; - - if (sai_switch_notifications.on_packet_event) { - sai_switch_notifications.on_packet_event(hostif_packet->pkt, - hostif_packet->pkt_size, - attr_count, - attr_list); - } +void sai_recv_hostif_packet_cb(switch_hostif_packet_t *hostif_packet) { + SAI_LOG_ENTER(); - SAI_LOG_EXIT(); + sai_status_t status = SAI_STATUS_SUCCESS; + if (!hostif_packet) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); return; + } + + int max_attr_count = 2; + int attr_count = 0; + sai_attribute_t attr_list[max_attr_count]; + sai_attribute_t *attribute; + attribute = &attr_list[attr_count]; + attribute->id = SAI_HOSTIF_PACKET_ATTR_TRAP_ID; + attribute->value.u32 = hostif_packet->reason_code; + attr_count++; + attribute = &attr_list[attr_count]; + attribute->id = SAI_HOSTIF_PACKET_ATTR_INGRESS_PORT; + attribute->value.oid = hostif_packet->handle; + attr_count++; + + if (sai_switch_notifications.on_packet_event) { + sai_switch_notifications.on_packet_event( + hostif_packet->pkt, hostif_packet->pkt_size, attr_count, attr_list); + } + + SAI_LOG_EXIT(); + + return; } /* * hostif methods table retrieved with sai_api_query() */ sai_hostif_api_t hostif_api = { - .create_hostif = sai_create_hostif, - .remove_hostif = sai_remove_hostif, - .set_hostif_attribute = sai_set_hostif_attribute, - .get_hostif_attribute = sai_get_hostif_attribute, - .create_hostif_trap_group = sai_create_hostif_trap_group, - .remove_hostif_trap_group = sai_remove_hostif_trap_group, - .set_trap_group_attribute = sai_set_hostif_trap_group_attribute, - .get_trap_group_attribute = sai_get_hostif_trap_group_attribute, - .set_trap_attribute = sai_set_hostif_trap_attribute, - .get_trap_attribute = sai_get_hostif_trap_attribute, - .set_user_defined_trap_attribute = sai_set_hostif_user_defined_trap_attribute, - .get_user_defined_trap_attribute = sai_get_hostif_user_defined_trap_attribute, - .recv_packet = sai_recv_hostif_packet, - .send_packet = sai_send_hostif_packet -}; + .create_hostif = sai_create_hostif, + .remove_hostif = sai_remove_hostif, + .set_hostif_attribute = sai_set_hostif_attribute, + .get_hostif_attribute = sai_get_hostif_attribute, + .create_hostif_trap_group = sai_create_hostif_trap_group, + .remove_hostif_trap_group = sai_remove_hostif_trap_group, + .set_trap_group_attribute = sai_set_hostif_trap_group_attribute, + .get_trap_group_attribute = sai_get_hostif_trap_group_attribute, + .set_trap_attribute = sai_set_hostif_trap_attribute, + .get_trap_attribute = sai_get_hostif_trap_attribute, + .set_user_defined_trap_attribute = + sai_set_hostif_user_defined_trap_attribute, + .get_user_defined_trap_attribute = + sai_get_hostif_user_defined_trap_attribute, + .recv_packet = sai_recv_hostif_packet, + .send_packet = sai_send_hostif_packet}; sai_status_t sai_hostif_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing host interface"); - sai_api_service->hostif_api = hostif_api; - switch_api_hostif_register_rx_callback(device, &sai_recv_hostif_packet_cb); - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing host interface"); + sai_api_service->hostif_api = hostif_api; + switch_api_hostif_register_rx_callback(device, &sai_recv_hostif_packet_cb); + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiinternal.h b/switchsai/src/saiinternal.h index d87d6f4..5da8be4 100644 --- a/switchsai/src/saiinternal.h +++ b/switchsai/src/saiinternal.h @@ -21,6 +21,7 @@ limitations under the License. #include #include #include +#include #include #include @@ -45,57 +46,63 @@ limitations under the License. void sai_log(int level, sai_api_t api, char *fmt, ...); -#define SAI_LOG(level, api_id, fmt, arg ...) \ - do { \ - sai_log(level, api_id, "[F:%s L:%d Func:%s] " fmt, \ - __FILE__, __LINE__, __func__, ##arg); \ - } while(0); +#define SAI_LOG(level, api_id, fmt, arg...) \ + do { \ + sai_log(level, \ + api_id, \ + "[F:%s L:%d Func:%s] " fmt, \ + __FILE__, \ + __LINE__, \ + __func__, \ + ##arg); \ + } while (0); -#define SAI_LOG_ENTER() \ - SAI_LOG(SAI_LOG_DEBUG, api_id, "Entering %s\n", __FUNCTION__) +#define SAI_LOG_ENTER() \ + SAI_LOG(SAI_LOG_DEBUG, api_id, "Entering %s\n", __FUNCTION__) -#define SAI_LOG_EXIT() \ - SAI_LOG(SAI_LOG_DEBUG, api_id, "Exiting %s\n", __FUNCTION__) +#define SAI_LOG_EXIT() \ + SAI_LOG(SAI_LOG_DEBUG, api_id, "Exiting %s\n", __FUNCTION__) -#define SAI_LOG_DEBUG(fmt, arg ...) \ - SAI_LOG(SAI_LOG_DEBUG, api_id, fmt, ## arg) +#define SAI_LOG_DEBUG(fmt, arg...) SAI_LOG(SAI_LOG_DEBUG, api_id, fmt, ##arg) -#define SAI_LOG_INFO(fmt, arg ...) \ - SAI_LOG(SAI_LOG_INFO, api_id, fmt, ## arg) +#define SAI_LOG_INFO(fmt, arg...) SAI_LOG(SAI_LOG_INFO, api_id, fmt, ##arg) -#define SAI_LOG_NOTICE(fmt, arg ...) \ - SAI_LOG(SAI_LOG_NOTICE, api_id, fmt, ## arg) +#define SAI_LOG_NOTICE(fmt, arg...) SAI_LOG(SAI_LOG_NOTICE, api_id, fmt, ##arg) -#define SAI_LOG_WARN(fmt, arg ...) \ - SAI_LOG(SAI_LOG_WARN, api_id, fmt, ## arg) +#define SAI_LOG_WARN(fmt, arg...) SAI_LOG(SAI_LOG_WARN, api_id, fmt, ##arg) -#define SAI_LOG_ERROR(fmt, arg ...) \ - SAI_LOG(SAI_LOG_ERROR, api_id, fmt, ## arg) +#define SAI_LOG_ERROR(fmt, arg...) SAI_LOG(SAI_LOG_ERROR, api_id, fmt, ##arg) -#define SAI_LOG_CRITICAL(fmt, arg ...) \ - SAI_LOG(SAI_LOG_CRITICAL, api_id, fmt, ## arg) +#define SAI_LOG_CRITICAL(fmt, arg...) \ + SAI_LOG(SAI_LOG_CRITICAL, api_id, fmt, ##arg) typedef struct _sai_api_service_t { - sai_switch_api_t switch_api; - sai_port_api_t port_api; - sai_fdb_api_t fdb_api; - sai_vlan_api_t vlan_api; - sai_virtual_router_api_t vr_api; - sai_router_interface_api_t rif_api; - sai_route_api_t route_api; - sai_neighbor_api_t neighbor_api; - sai_next_hop_api_t nhop_api; - sai_next_hop_group_api_t nhop_group_api; - sai_qos_map_api_t qos_api; - sai_acl_api_t acl_api; - sai_lag_api_t lag_api; - sai_stp_api_t stp_api; - sai_hostif_api_t hostif_api; - sai_mirror_api_t mirror_api; - sai_samplepacket_api_t samplepacket_api; - sai_policer_api_t policer_api; - sai_ipmc_api_t ipmc_api; - sai_l2mc_api_t l2mc_api; + sai_switch_api_t switch_api; + sai_port_api_t port_api; + sai_fdb_api_t fdb_api; + sai_vlan_api_t vlan_api; + sai_virtual_router_api_t vr_api; + sai_router_interface_api_t rif_api; + sai_route_api_t route_api; + sai_neighbor_api_t neighbor_api; + sai_next_hop_api_t nhop_api; + sai_next_hop_group_api_t nhop_group_api; + sai_qos_map_api_t qos_api; + sai_acl_api_t acl_api; + sai_lag_api_t lag_api; + sai_stp_api_t stp_api; + sai_hostif_api_t hostif_api; + sai_mirror_api_t mirror_api; + sai_samplepacket_api_t samplepacket_api; + sai_policer_api_t policer_api; + sai_buffer_api_t buffer_api; + sai_scheduler_api_t scheduler_api; + sai_scheduler_group_api_t scheduler_group_api; + sai_ipmc_api_t ipmc_api; + sai_l2mc_api_t l2mc_api; + sai_queue_api_t queue_api; + sai_hash_api_t hash_api; + sai_udf_api_t udf_api; } sai_api_service_t; extern switch_device_t device; @@ -107,7 +114,8 @@ sai_status_t sai_port_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_fdb_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_vlan_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_lag_initialize(sai_api_service_t *sai_api_service); -sai_status_t sai_router_interface_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_router_interface_initialize( + sai_api_service_t *sai_api_service); sai_status_t sai_next_hop_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_next_hop_group_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_route_initialize(sai_api_service_t *sai_api_service); @@ -117,61 +125,66 @@ sai_status_t sai_neighbor_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_hostif_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_acl_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_mirror_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_hash_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_udf_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_buffer_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_policer_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_scheduler_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_scheduler_group_initialize(sai_api_service_t *sai_api_service); +sai_status_t sai_qos_map_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_ipmc_initialize(sai_api_service_t *sai_api_service); sai_status_t sai_l2mc_initialize(sai_api_service_t *sai_api_service); -char *sai_status_to_string( - _In_ const sai_status_t status); +char *sai_status_to_string(_In_ const sai_status_t status); -char * sai_object_type_to_string( - _In_ sai_object_type_t object_type); +char *sai_object_type_to_string(_In_ sai_object_type_t object_type); -sai_status_t sai_switch_status_to_sai_status( - _In_ const switch_status_t status); +sai_status_t sai_switch_status_to_sai_status(_In_ const switch_status_t status); -sai_status_t sai_ipv4_prefix_length( - _In_ sai_ip4_t ip4, - _Out_ uint32_t *prefix_length); +sai_status_t sai_ipv4_prefix_length(_In_ sai_ip4_t ip4, + _Out_ uint32_t *prefix_length); -sai_status_t sai_ipv6_prefix_length( - _In_ const sai_ip6_t ip6, - _Out_ uint32_t *prefix_length); +sai_status_t sai_ipv6_prefix_length(_In_ const sai_ip6_t ip6, + _Out_ uint32_t *prefix_length); -sai_status_t sai_ipv4_to_string( - _In_ sai_ip4_t ip4, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length); +sai_status_t sai_ipv4_to_string(_In_ sai_ip4_t ip4, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length); -sai_status_t sai_ipv6_to_string( - _In_ sai_ip6_t ip6, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length); +sai_status_t sai_ipv6_to_string(_In_ sai_ip6_t ip6, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length); -sai_status_t sai_ipaddress_to_string( - _In_ sai_ip_address_t ip_addr, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length); +sai_status_t sai_ipaddress_to_string(_In_ sai_ip_address_t ip_addr, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length); -sai_status_t sai_ipprefix_to_string( - _In_ sai_ip_prefix_t ip_prefix, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length); +sai_status_t sai_ipprefix_to_string(_In_ sai_ip_prefix_t ip_prefix, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length); sai_status_t sai_ip_prefix_to_switch_ip_addr( - const _In_ sai_ip_prefix_t *sai_ip_prefix, - _Out_ switch_ip_addr_t *ip_addr); + const _In_ sai_ip_prefix_t *sai_ip_prefix, _Out_ switch_ip_addr_t *ip_addr); sai_status_t sai_ip_addr_to_switch_ip_addr( - const _In_ sai_ip_address_t *sai_ip_addr, - _Out_ switch_ip_addr_t *ip_addr); + const _In_ sai_ip_address_t *sai_ip_addr, _Out_ switch_ip_addr_t *ip_addr); -switch_acl_action_t -sai_packet_action_to_switch_packet_action( - _In_ sai_packet_action_t action); +sai_status_t sai_port_speed_to_switch_port_speed( + uint32_t sai_port_speed, _Out_ switch_port_speed_t *switch_port_speed); + +switch_acl_action_t sai_packet_action_to_switch_packet_action( + _In_ sai_packet_action_t action); + +sai_status_t sai_switch_status_to_sai_status(_In_ const switch_status_t status); + +sai_status_t sai_switch_ip_addr_to_sai_ip_addr( + _Out_ sai_ip_address_t *sai_ip_addr, const _In_ switch_ip_addr_t *ip_addr); + +sai_status_t sai_switch_port_enabled_to_sai_oper_status( + _In_ _Out_ sai_attribute_t *attr); #endif // __SAIINTERNAL_H_ diff --git a/switchsai/src/saiipmc.c b/switchsai/src/saiipmc.c index 280119a..b21282b 100644 --- a/switchsai/src/saiipmc.c +++ b/switchsai/src/saiipmc.c @@ -22,181 +22,181 @@ limitations under the License. static sai_api_t api_id = SAI_API_IPMC; -static void sai_ipmc_entry_to_string( - _In_ const sai_ipmc_entry_t *ipmc_entry, - _Out_ char *entry_string) { - int count = 0; - int len = 0; - count = snprintf(entry_string, SAI_MAX_ENTRY_STRING_LEN, - "route: vrf %lx (", ipmc_entry->vr_id); - if (count > SAI_MAX_ENTRY_STRING_LEN) { - return; - } - sai_ipaddress_to_string(ipmc_entry->source, - SAI_MAX_ENTRY_STRING_LEN - count, - entry_string + count, &len); - count += len; - if (count > SAI_MAX_ENTRY_STRING_LEN) { - return; - } - count += snprintf(entry_string + count, - SAI_MAX_ENTRY_STRING_LEN - count, ","); - if (count > SAI_MAX_ENTRY_STRING_LEN) { - return; - } - sai_ipprefix_to_string(ipmc_entry->group, - SAI_MAX_ENTRY_STRING_LEN - count, - entry_string + count, &len); - count += len; - if (count > SAI_MAX_ENTRY_STRING_LEN) { - return; - } - count += snprintf(entry_string + count, - SAI_MAX_ENTRY_STRING_LEN - count, ")"); +static void sai_ipmc_entry_to_string(_In_ const sai_ipmc_entry_t *ipmc_entry, + _Out_ char *entry_string) { + int count = 0; + int len = 0; + count = snprintf(entry_string, + SAI_MAX_ENTRY_STRING_LEN, + "route: vrf %" PRIx64 " (", + ipmc_entry->vr_id); + if (count > SAI_MAX_ENTRY_STRING_LEN) { + return; + } + sai_ipaddress_to_string(ipmc_entry->source, + SAI_MAX_ENTRY_STRING_LEN - count, + entry_string + count, + &len); + count += len; + if (count > SAI_MAX_ENTRY_STRING_LEN) { + return; + } + count += + snprintf(entry_string + count, SAI_MAX_ENTRY_STRING_LEN - count, ","); + if (count > SAI_MAX_ENTRY_STRING_LEN) { return; + } + sai_ipprefix_to_string(ipmc_entry->group, + SAI_MAX_ENTRY_STRING_LEN - count, + entry_string + count, + &len); + count += len; + if (count > SAI_MAX_ENTRY_STRING_LEN) { + return; + } + count += + snprintf(entry_string + count, SAI_MAX_ENTRY_STRING_LEN - count, ")"); + return; } -static void sai_ipmc_entry_parse( - _In_ const sai_ipmc_entry_t *ipmc_entry, - _Out_ switch_handle_t *vrf_handle, - _Out_ switch_ip_addr_t *src_addr, - _Out_ switch_ip_addr_t *grp_addr) { - SAI_ASSERT(sai_object_type_query(ipmc_entry->vr_id) == - SAI_OBJECT_TYPE_VIRTUAL_ROUTER); - *vrf_handle = (switch_handle_t) ipmc_entry->vr_id; - - memset(src_addr, 0, sizeof(switch_ip_addr_t)); - sai_ip_addr_to_switch_ip_addr(&(ipmc_entry->source), src_addr); - if (((src_addr->type == SWITCH_API_IP_ADDR_V4) && - (src_addr->ip.v4addr == 0)) || - ((src_addr->type == SWITCH_API_IP_ADDR_V6) && - (memcmp(src_addr->ip.v6addr, &in6addr_any, - sizeof(in6addr_any)) == 0))) { - src_addr->prefix_len = 0; - } - sai_ip_prefix_to_switch_ip_addr(&(ipmc_entry->group), grp_addr); +static void sai_ipmc_entry_parse(_In_ const sai_ipmc_entry_t *ipmc_entry, + _Out_ switch_handle_t *vrf_handle, + _Out_ switch_ip_addr_t *src_addr, + _Out_ switch_ip_addr_t *grp_addr) { + SAI_ASSERT(sai_object_type_query(ipmc_entry->vr_id) == + SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + *vrf_handle = (switch_handle_t)ipmc_entry->vr_id; + + memset(src_addr, 0, sizeof(switch_ip_addr_t)); + sai_ip_addr_to_switch_ip_addr(&(ipmc_entry->source), src_addr); + if (((src_addr->type == SWITCH_API_IP_ADDR_V4) && + (src_addr->ip.v4addr == 0)) || + ((src_addr->type == SWITCH_API_IP_ADDR_V6) && + (memcmp(src_addr->ip.v6addr, &in6addr_any, sizeof(in6addr_any)) == 0))) { + src_addr->prefix_len = 0; + } + sai_ip_prefix_to_switch_ip_addr(&(ipmc_entry->group), grp_addr); } static void sai_ipmc_entry_attribute_parse( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list, - _Out_ switch_handle_t **oif_list_handle, - _Out_ int *oif_list_count, - _Out_ switch_handle_t **rpf_list_handle, - _Out_ int *rpf_list_count, - _Out_ int *action, - _Out_ int *pri) { - const sai_attribute_t *attribute; - uint32_t index = 0; - - *action = SAI_PACKET_ACTION_FORWARD; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_IPMC_ATTR_OUTPUT_ROUTER_INTERFACE_LIST: - *oif_list_handle = - (switch_handle_t *) attribute->value.objlist.list; - *oif_list_count = attribute->value.objlist.count; - break; - case SAI_IPMC_ATTR_RPF_ROUTER_INTERFACE_LIST: - *rpf_list_handle = - (switch_handle_t *) attribute->value.objlist.list; - *rpf_list_count = attribute->value.objlist.count; - case SAI_ROUTE_ATTR_TRAP_PRIORITY: - *pri = attribute->value.u8; - break; - case SAI_ROUTE_ATTR_PACKET_ACTION: - *action = attribute->value.s32; - break; - } + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _Out_ switch_handle_t **oif_list_handle, + _Out_ int *oif_list_count, + _Out_ switch_handle_t **rpf_list_handle, + _Out_ int *rpf_list_count, + _Out_ int *action, + _Out_ int *pri) { + const sai_attribute_t *attribute; + uint32_t index = 0; + + *action = SAI_PACKET_ACTION_FORWARD; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_IPMC_ATTR_OUTPUT_ROUTER_INTERFACE_LIST: + *oif_list_handle = (switch_handle_t *)attribute->value.objlist.list; + *oif_list_count = attribute->value.objlist.count; + break; + case SAI_IPMC_ATTR_RPF_ROUTER_INTERFACE_LIST: + *rpf_list_handle = (switch_handle_t *)attribute->value.objlist.list; + *rpf_list_count = attribute->value.objlist.count; + case SAI_ROUTE_ATTR_TRAP_PRIORITY: + *pri = attribute->value.u8; + break; + case SAI_ROUTE_ATTR_PACKET_ACTION: + *action = attribute->value.s32; + break; } + } } -static switch_handle_t sai_ipmc_tree_create ( - _In_ switch_handle_t vrf_handle, - _In_ switch_ip_addr_t *src_addr, - _In_ switch_ip_addr_t *grp_addr, - _In_ int oif_list_count, - _In_ switch_handle_t *oif_list_handle) { - switch_handle_t mcast_handle; - switch_status_t status; - - uint16_t mbr_count_max = oif_list_count; - uint16_t mbr_count = 0; - switch_vlan_interface_t *mbrs = NULL; - mbrs = switch_malloc(sizeof(switch_vlan_interface_t), oif_list_count); - - mcast_handle = switch_api_multicast_tree_create(device); - for (int i = 0; i < oif_list_count; i++) { - switch_handle_t intf_handle = oif_list_handle[i]; - switch_interface_type_t type; - status = switch_api_interface_get_type(intf_handle, &type); +static switch_handle_t sai_ipmc_tree_create( + _In_ switch_handle_t vrf_handle, + _In_ switch_ip_addr_t *src_addr, + _In_ switch_ip_addr_t *grp_addr, + _In_ int oif_list_count, + _In_ switch_handle_t *oif_list_handle) { + switch_handle_t mcast_handle; + switch_status_t status; + + uint16_t mbr_count_max = oif_list_count; + uint16_t mbr_count = 0; + switch_vlan_interface_t *mbrs = NULL; + mbrs = switch_malloc(sizeof(switch_vlan_interface_t), oif_list_count); + + mcast_handle = switch_api_multicast_tree_create(device); + for (int i = 0; i < oif_list_count; i++) { + switch_handle_t intf_handle = oif_list_handle[i]; + switch_interface_type_t type; + status = switch_api_interface_get_type(intf_handle, &type); + assert(status == SWITCH_STATUS_SUCCESS); + if (type == SWITCH_API_INTERFACE_L3) { + mbrs[mbr_count].vlan_handle = 0; + mbrs[mbr_count].intf_handle = intf_handle; + mbr_count++; + } else { + uint64_t snooping_enabled = true; + switch_handle_t vlan_handle; + status = switch_api_interface_get_vlan_handle(intf_handle, &vlan_handle); + assert(status == SWITCH_STATUS_SUCCESS); + if (grp_addr->type == SWITCH_API_IP_ADDR_V4) { + status = switch_api_vlan_igmp_snooping_enabled_get(vlan_handle, + &snooping_enabled); + assert(status == SWITCH_STATUS_SUCCESS); + } else { + status = switch_api_vlan_mld_snooping_enabled_get(vlan_handle, + &snooping_enabled); assert(status == SWITCH_STATUS_SUCCESS); - if (type == SWITCH_API_INTERFACE_L3) { - mbrs[mbr_count].vlan_handle = 0; - mbrs[mbr_count].intf_handle = intf_handle; - mbr_count++; - } else { - uint64_t snooping_enabled = true; - switch_handle_t vlan_handle; - status = switch_api_interface_get_vlan_handle( - intf_handle, &vlan_handle); - assert(status == SWITCH_STATUS_SUCCESS); - if (grp_addr->type == SWITCH_API_IP_ADDR_V4) { - status = switch_api_vlan_igmp_snooping_enabled_get( - vlan_handle, &snooping_enabled); - assert(status == SWITCH_STATUS_SUCCESS); - } else { - status = switch_api_vlan_mld_snooping_enabled_get( - vlan_handle, &snooping_enabled); - assert(status == SWITCH_STATUS_SUCCESS); - } - if (snooping_enabled) { - switch_handle_t l2mcast_handle; - status = switch_api_multicast_l2route_tree_get( - device, vlan_handle, src_addr, grp_addr, &l2mcast_handle); - if (status != SWITCH_STATUS_SUCCESS) { - continue; - } - uint16_t l2mbr_count = 0; - switch_vlan_interface_t *l2mbrs = NULL; - status = switch_api_multicast_member_get(device, l2mcast_handle, - &l2mbr_count, &l2mbrs); - if (status != SWITCH_STATUS_SUCCESS) { - continue; - } - mbr_count_max += l2mbr_count; - mbrs = switch_realloc(mbrs, (sizeof(switch_vlan_interface_t) * - mbr_count_max)); - memcpy(mbrs + mbr_count, l2mbrs, - (sizeof(switch_vlan_interface_t) * l2mbr_count)); - mbr_count += l2mbr_count; - - switch_free(l2mbrs); - } else { - uint16_t l2mbr_count = 0; - switch_vlan_interface_t *l2mbrs = NULL; - status = switch_api_vlan_interfaces_get(device, vlan_handle, - &l2mbr_count, &l2mbrs); - if (status != SWITCH_STATUS_SUCCESS) { - continue; - } - - mbr_count_max += l2mbr_count; - mbrs = switch_realloc(mbrs, (sizeof(switch_vlan_interface_t) * - mbr_count_max)); - memcpy(mbrs + mbr_count, l2mbrs, - (sizeof(switch_vlan_interface_t) * l2mbr_count)); - mbr_count += l2mbr_count; - } + } + if (snooping_enabled) { + switch_handle_t l2mcast_handle; + status = switch_api_multicast_l2route_tree_get( + device, vlan_handle, src_addr, grp_addr, &l2mcast_handle); + if (status != SWITCH_STATUS_SUCCESS) { + continue; } + uint16_t l2mbr_count = 0; + switch_vlan_interface_t *l2mbrs = NULL; + status = switch_api_multicast_member_get( + device, l2mcast_handle, &l2mbr_count, &l2mbrs); + if (status != SWITCH_STATUS_SUCCESS) { + continue; + } + mbr_count_max += l2mbr_count; + mbrs = switch_realloc( + mbrs, (sizeof(switch_vlan_interface_t) * mbr_count_max)); + memcpy(mbrs + mbr_count, + l2mbrs, + (sizeof(switch_vlan_interface_t) * l2mbr_count)); + mbr_count += l2mbr_count; + + switch_free(l2mbrs); + } else { + uint16_t l2mbr_count = 0; + switch_vlan_interface_t *l2mbrs = NULL; + status = switch_api_vlan_interfaces_get( + device, vlan_handle, &l2mbr_count, &l2mbrs); + if (status != SWITCH_STATUS_SUCCESS) { + continue; + } + + mbr_count_max += l2mbr_count; + mbrs = switch_realloc( + mbrs, (sizeof(switch_vlan_interface_t) * mbr_count_max)); + memcpy(mbrs + mbr_count, + l2mbrs, + (sizeof(switch_vlan_interface_t) * l2mbr_count)); + mbr_count += l2mbr_count; + } } - status = switch_api_multicast_member_add(device, - mcast_handle, mbr_count, mbrs); - assert(status == SWITCH_STATUS_SUCCESS); + } + status = + switch_api_multicast_member_add(device, mcast_handle, mbr_count, mbrs); + assert(status == SWITCH_STATUS_SUCCESS); - switch_free(mbrs); - return mcast_handle; + switch_free(mbrs); + return mcast_handle; } /* @@ -212,56 +212,63 @@ static switch_handle_t sai_ipmc_tree_create ( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_ipmc_entry( - _In_ const sai_ipmc_entry_t *ipmc_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_ip_addr_t src_addr, grp_addr; - switch_handle_t vrf_handle = 0; - switch_handle_t *oif_list_handle = 0; - switch_handle_t *rpf_list_handle = 0; - int oif_list_count = 0; - int rpf_list_count = 0; - int action=-1, pri=-1; - switch_handle_t mcast_handle; - char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - - if (!ipmc_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); - return status; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); - return status; - } - - sai_ipmc_entry_parse(ipmc_entry, &vrf_handle, &src_addr, &grp_addr); - sai_ipmc_entry_attribute_parse(attr_count, attr_list, - &oif_list_handle, &oif_list_count, - &rpf_list_handle, &rpf_list_count, - &action, &pri); - - sai_ipmc_entry_to_string(ipmc_entry, entry_string); - mcast_handle = sai_ipmc_tree_create(vrf_handle, &src_addr, &grp_addr, - oif_list_count, oif_list_handle); - status = sai_switch_status_to_sai_status(switch_status); - - switch_status = switch_api_multicast_mroute_add( - device, mcast_handle, vrf_handle, &src_addr, &grp_addr, 1, - rpf_list_handle, rpf_list_count); - status = sai_switch_status_to_sai_status(switch_status); - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_create_ipmc_entry(_In_ const sai_ipmc_entry_t *ipmc_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_ip_addr_t src_addr, grp_addr; + switch_handle_t vrf_handle = 0; + switch_handle_t *oif_list_handle = 0; + switch_handle_t *rpf_list_handle = 0; + int oif_list_count = 0; + int rpf_list_count = 0; + int action = -1, pri = -1; + switch_handle_t mcast_handle; + char entry_string[SAI_MAX_ENTRY_STRING_LEN]; + + if (!ipmc_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); + return status; + } + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + sai_ipmc_entry_parse(ipmc_entry, &vrf_handle, &src_addr, &grp_addr); + sai_ipmc_entry_attribute_parse(attr_count, + attr_list, + &oif_list_handle, + &oif_list_count, + &rpf_list_handle, + &rpf_list_count, + &action, + &pri); + + sai_ipmc_entry_to_string(ipmc_entry, entry_string); + mcast_handle = sai_ipmc_tree_create( + vrf_handle, &src_addr, &grp_addr, oif_list_count, oif_list_handle); + status = sai_switch_status_to_sai_status(switch_status); + + switch_status = switch_api_multicast_mroute_add(device, + mcast_handle, + vrf_handle, + &src_addr, + &grp_addr, + 1, + rpf_list_handle, + rpf_list_count); + status = sai_switch_status_to_sai_status(switch_status); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /** @@ -275,44 +282,42 @@ sai_status_t sai_create_ipmc_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_ipmc_entry( - _In_ const sai_ipmc_entry_t *ipmc_entry) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_ip_addr_t src_addr, grp_addr; - switch_handle_t vrf_handle = 0; - - if (!ipmc_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); - return status; - } - - sai_ipmc_entry_parse(ipmc_entry, &vrf_handle, &src_addr, &grp_addr); - - switch_handle_t mcast_handle; - switch_status = switch_api_multicast_mroute_tree_get( - device, vrf_handle, &src_addr, &grp_addr, &mcast_handle); - if (status == SWITCH_STATUS_SUCCESS) { - switch_status = switch_api_multicast_tree_delete(device, mcast_handle); - assert(switch_status == SWITCH_STATUS_SUCCESS); - } - - switch_status = switch_api_multicast_mroute_delete( - device, vrf_handle, &src_addr, &grp_addr); - status = sai_switch_status_to_sai_status(switch_status); - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove ipmc entry: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_remove_ipmc_entry(_In_ const sai_ipmc_entry_t *ipmc_entry) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_ip_addr_t src_addr, grp_addr; + switch_handle_t vrf_handle = 0; + + if (!ipmc_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); + return status; + } + + sai_ipmc_entry_parse(ipmc_entry, &vrf_handle, &src_addr, &grp_addr); + + switch_handle_t mcast_handle; + switch_status = switch_api_multicast_mroute_tree_get( + device, vrf_handle, &src_addr, &grp_addr, &mcast_handle); + if (status == SWITCH_STATUS_SUCCESS) { + switch_status = switch_api_multicast_tree_delete(device, mcast_handle); + assert(switch_status == SWITCH_STATUS_SUCCESS); + } + + switch_status = switch_api_multicast_mroute_delete( + device, vrf_handle, &src_addr, &grp_addr); + status = sai_switch_status_to_sai_status(switch_status); + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove ipmc entry: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /** @@ -328,28 +333,26 @@ sai_status_t sai_remove_ipmc_entry( * Failure status code on error */ sai_status_t sai_set_ipmc_entry_attribute( - _In_ const sai_ipmc_entry_t *ipmc_entry, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); + _In_ const sai_ipmc_entry_t *ipmc_entry, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!ipmc_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); - return status; - } + if (!ipmc_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); + return status; + } - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -366,43 +369,42 @@ sai_status_t sai_set_ipmc_entry_attribute( * Failure status code on error */ sai_status_t sai_get_ipmc_entry_attribute( - _In_ const sai_ipmc_entry_t *ipmc_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { + _In_ const sai_ipmc_entry_t *ipmc_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!ipmc_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); + return status; + } - if (!ipmc_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null ipmc entry: %s", sai_status_to_string(status)); - return status; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** * IP multicast method table retrieved with sai_api_query() */ sai_ipmc_api_t ipmc_api = { - .create_ipmc_entry = sai_create_ipmc_entry, - .remove_ipmc_entry = sai_remove_ipmc_entry, - .set_ipmc_entry_attribute = sai_set_ipmc_entry_attribute, - .get_ipmc_entry_attribute = sai_get_ipmc_entry_attribute, + .create_ipmc_entry = sai_create_ipmc_entry, + .remove_ipmc_entry = sai_remove_ipmc_entry, + .set_ipmc_entry_attribute = sai_set_ipmc_entry_attribute, + .get_ipmc_entry_attribute = sai_get_ipmc_entry_attribute, }; sai_status_t sai_ipmc_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing ipmc"); - sai_api_service->ipmc_api = ipmc_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing ipmc"); + sai_api_service->ipmc_api = ipmc_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/sail2mc.c b/switchsai/src/sail2mc.c index 9ef0338..33d598a 100644 --- a/switchsai/src/sail2mc.c +++ b/switchsai/src/sail2mc.c @@ -47,64 +47,60 @@ static void sai_l2mc_entry_to_string( } #endif -static bool sai_l2mc_entry_parse( - _In_ const sai_l2mc_entry_t *l2mc_entry, - _Out_ switch_handle_t *vlan_handle, - _Out_ switch_ip_addr_t *src_addr, - _Out_ switch_ip_addr_t *grp_addr) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_status = switch_api_vlan_id_to_handle_get( - (switch_vlan_t) l2mc_entry->vlan_id, vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - return false; - } - - memset(src_addr, 0, sizeof(switch_ip_addr_t)); - memset(grp_addr, 0, sizeof(switch_ip_addr_t)); - sai_ip_addr_to_switch_ip_addr(&(l2mc_entry->source), src_addr); - if (((src_addr->type == SWITCH_API_IP_ADDR_V4) && - (src_addr->ip.v4addr == 0)) || - ((src_addr->type == SWITCH_API_IP_ADDR_V6) && - (memcmp(src_addr->ip.v6addr, &in6addr_any, - sizeof(in6addr_any)) == 0))) { - src_addr->prefix_len = 0; - } - sai_ip_addr_to_switch_ip_addr(&(l2mc_entry->group), grp_addr); - return true; +static bool sai_l2mc_entry_parse(_In_ const sai_l2mc_entry_t *l2mc_entry, + _Out_ switch_handle_t *vlan_handle, + _Out_ switch_ip_addr_t *src_addr, + _Out_ switch_ip_addr_t *grp_addr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_status = switch_api_vlan_id_to_handle_get( + (switch_vlan_t)l2mc_entry->vlan_id, vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + return false; + } + + memset(src_addr, 0, sizeof(switch_ip_addr_t)); + memset(grp_addr, 0, sizeof(switch_ip_addr_t)); + sai_ip_addr_to_switch_ip_addr(&(l2mc_entry->source), src_addr); + if (((src_addr->type == SWITCH_API_IP_ADDR_V4) && + (src_addr->ip.v4addr == 0)) || + ((src_addr->type == SWITCH_API_IP_ADDR_V6) && + (memcmp(src_addr->ip.v6addr, &in6addr_any, sizeof(in6addr_any)) == 0))) { + src_addr->prefix_len = 0; + } + sai_ip_addr_to_switch_ip_addr(&(l2mc_entry->group), grp_addr); + return true; } static void sai_l2mc_entry_attribute_parse( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list, - _Out_ switch_handle_t **port_list_handle, - _Out_ int *port_list_count, - _Out_ int *action, - _Out_ int *pri) { - const sai_attribute_t *attribute; - uint32_t index = 0; - - *action = SAI_PACKET_ACTION_FORWARD; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_L2MC_ATTR_PORT_LIST: - *port_list_count = attribute->value.objlist.count; - *port_list_handle = - (switch_handle_t *) attribute->value.objlist.list; - break; - case SAI_ROUTE_ATTR_TRAP_PRIORITY: - *pri = attribute->value.u8; - break; - case SAI_ROUTE_ATTR_PACKET_ACTION: - *action = attribute->value.s32; - break; - } + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _Out_ switch_handle_t **port_list_handle, + _Out_ int *port_list_count, + _Out_ int *action, + _Out_ int *pri) { + const sai_attribute_t *attribute; + uint32_t index = 0; + + *action = SAI_PACKET_ACTION_FORWARD; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_L2MC_ATTR_PORT_LIST: + *port_list_count = attribute->value.objlist.count; + *port_list_handle = (switch_handle_t *)attribute->value.objlist.list; + break; + case SAI_ROUTE_ATTR_TRAP_PRIORITY: + *pri = attribute->value.u8; + break; + case SAI_ROUTE_ATTR_PACKET_ACTION: + *action = attribute->value.s32; + break; } + } } /* @@ -120,64 +116,64 @@ static void sai_l2mc_entry_attribute_parse( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_l2mc_entry( - _In_ const sai_l2mc_entry_t *l2mc_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_ip_addr_t src_addr; - switch_ip_addr_t grp_addr; - switch_handle_t vlan_handle = 0; - switch_handle_t *port_list_handle = 0; - int port_list_count = 0; - int action=-1, pri=-1; - - if (!l2mc_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null l2mc entry: %s", sai_status_to_string(status)); - return status; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); - return status; - } - - sai_l2mc_entry_parse(l2mc_entry, &vlan_handle, &src_addr, &grp_addr); - sai_l2mc_entry_attribute_parse(attr_count, attr_list, - &port_list_handle, &port_list_count, - &action, &pri); - - switch_handle_t mcast_hdl; - mcast_hdl = switch_api_multicast_tree_create(device); - - switch_vlan_interface_t *mbrs; - mbrs = switch_malloc(sizeof(switch_vlan_interface_t), port_list_count); - for (int i = 0; i < port_list_count; i++) { - mbrs[i].vlan_handle = vlan_handle; - mbrs[i].intf_handle = port_list_handle[i]; - } - - switch_status = switch_api_multicast_member_add(device, mcast_hdl, - port_list_count, mbrs); +sai_status_t sai_create_l2mc_entry(_In_ const sai_l2mc_entry_t *l2mc_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_ip_addr_t src_addr; + switch_ip_addr_t grp_addr; + switch_handle_t vlan_handle = 0; + switch_handle_t *port_list_handle = 0; + int port_list_count = 0; + int action = -1, pri = -1; + + if (!l2mc_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null l2mc entry: %s", sai_status_to_string(status)); + return status; + } - switch_free(mbrs); + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + sai_l2mc_entry_parse(l2mc_entry, &vlan_handle, &src_addr, &grp_addr); + sai_l2mc_entry_attribute_parse(attr_count, + attr_list, + &port_list_handle, + &port_list_count, + &action, + &pri); + + switch_handle_t mcast_hdl; + mcast_hdl = switch_api_multicast_tree_create(device); + + switch_vlan_interface_t *mbrs; + mbrs = switch_malloc(sizeof(switch_vlan_interface_t), port_list_count); + for (int i = 0; i < port_list_count; i++) { + mbrs[i].vlan_handle = vlan_handle; + mbrs[i].intf_handle = port_list_handle[i]; + } + + switch_status = + switch_api_multicast_member_add(device, mcast_hdl, port_list_count, mbrs); + + switch_free(mbrs); + status = sai_switch_status_to_sai_status(switch_status); + if (switch_status == SWITCH_STATUS_SUCCESS) { + switch_status = switch_api_multicast_l2route_add( + device, mcast_hdl, vlan_handle, &src_addr, &grp_addr); status = sai_switch_status_to_sai_status(switch_status); - if (switch_status == SWITCH_STATUS_SUCCESS) { - switch_status = switch_api_multicast_l2route_add(device, mcast_hdl, - vlan_handle, - &src_addr, &grp_addr); - status = sai_switch_status_to_sai_status(switch_status); - } + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /** @@ -191,40 +187,37 @@ sai_status_t sai_create_l2mc_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_l2mc_entry( - _In_ const sai_l2mc_entry_t *l2mc_entry) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_ip_addr_t src_addr; - switch_ip_addr_t grp_addr; - switch_handle_t vlan_handle = 0; - switch_handle_t mgid_handle = 0; - - if (!l2mc_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null l2mc entry: %s", sai_status_to_string(status)); - return status; - } - - sai_l2mc_entry_parse(l2mc_entry, &vlan_handle, &src_addr, &grp_addr); - switch_status = switch_api_multicast_l2route_tree_get(device, vlan_handle, - &src_addr, &grp_addr, - &mgid_handle); - assert(switch_handle_get_type(mgid_handle) == SWITCH_HANDLE_TYPE_MGID); - switch_status = switch_api_multicast_tree_delete(device, mgid_handle); +sai_status_t sai_remove_l2mc_entry(_In_ const sai_l2mc_entry_t *l2mc_entry) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_ip_addr_t src_addr; + switch_ip_addr_t grp_addr; + switch_handle_t vlan_handle = 0; + switch_handle_t mgid_handle = 0; + + if (!l2mc_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null l2mc entry: %s", sai_status_to_string(status)); + return status; + } + + sai_l2mc_entry_parse(l2mc_entry, &vlan_handle, &src_addr, &grp_addr); + switch_status = switch_api_multicast_l2route_tree_get( + device, vlan_handle, &src_addr, &grp_addr, &mgid_handle); + assert(switch_handle_get_type(mgid_handle) == SWITCH_HANDLE_TYPE_MGID); + switch_status = switch_api_multicast_tree_delete(device, mgid_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (switch_status == SWITCH_STATUS_SUCCESS) { + switch_status = switch_api_multicast_l2route_delete( + device, vlan_handle, &src_addr, &grp_addr); status = sai_switch_status_to_sai_status(switch_status); - if (switch_status == SWITCH_STATUS_SUCCESS) { - switch_status = switch_api_multicast_l2route_delete( - device, vlan_handle, &src_addr, &grp_addr); - status = sai_switch_status_to_sai_status(switch_status); - } + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /** @@ -240,16 +233,14 @@ sai_status_t sai_remove_l2mc_entry( * Failure status code on error */ sai_status_t sai_set_l2mc_entry_attribute( - _In_ const sai_l2mc_entry_t *l2mc_entry, - _In_ const sai_attribute_t *attr) { + _In_ const sai_l2mc_entry_t *l2mc_entry, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); - - return status; + return status; } /** @@ -266,17 +257,16 @@ sai_status_t sai_set_l2mc_entry_attribute( * Failure status code on error */ sai_status_t sai_get_l2mc_entry_attribute( - _In_ const sai_l2mc_entry_t *l2mc_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); + _In_ const sai_l2mc_entry_t *l2mc_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /** @@ -293,15 +283,14 @@ sai_status_t sai_get_l2mc_entry_attribute( * Failure status code on error */ sai_status_t sai_add_ports_to_l2mc_entry( - _In_ const sai_l2mc_entry_t *l2mc_entry, - _In_ uint32_t port_count, - _In_ const sai_object_list_t *port_list) { - - sai_status_t status = SAI_STATUS_SUCCESS; + _In_ const sai_l2mc_entry_t *l2mc_entry, + _In_ uint32_t port_count, + _In_ const sai_object_list_t *port_list) { + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /** @@ -318,31 +307,30 @@ sai_status_t sai_add_ports_to_l2mc_entry( * Failure status code on error */ sai_status_t sai_remove_ports_from_l2mc_entry( - _In_ const sai_l2mc_entry_t *l2mc_entry, - _In_ uint32_t port_count, - _In_ const sai_object_list_t *port_list) { + _In_ const sai_l2mc_entry_t *l2mc_entry, + _In_ uint32_t port_count, + _In_ const sai_object_list_t *port_list) { + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); - - return status; + return status; } /** * L2 multicast method table retrieved with sai_api_query() */ sai_l2mc_api_t l2mc_api = { - .create_l2mc_entry = sai_create_l2mc_entry, - .remove_l2mc_entry = sai_remove_l2mc_entry, - .set_l2mc_entry_attribute = sai_set_l2mc_entry_attribute, - .get_l2mc_entry_attribute = sai_get_l2mc_entry_attribute, - .add_ports_to_l2mc_entry = sai_add_ports_to_l2mc_entry, - .remove_ports_from_l2mc_entry = sai_remove_ports_from_l2mc_entry, + .create_l2mc_entry = sai_create_l2mc_entry, + .remove_l2mc_entry = sai_remove_l2mc_entry, + .set_l2mc_entry_attribute = sai_set_l2mc_entry_attribute, + .get_l2mc_entry_attribute = sai_get_l2mc_entry_attribute, + .add_ports_to_l2mc_entry = sai_add_ports_to_l2mc_entry, + .remove_ports_from_l2mc_entry = sai_remove_ports_from_l2mc_entry, }; sai_status_t sai_l2mc_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing l2mc"); - sai_api_service->l2mc_api = l2mc_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing l2mc"); + sai_api_service->l2mc_api = l2mc_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/sailag.c b/switchsai/src/sailag.c index a310a95..248695d 100644 --- a/switchsai/src/sailag.c +++ b/switchsai/src/sailag.c @@ -20,21 +20,17 @@ limitations under the License. static sai_api_t api_id = SAI_API_LAG; -sai_status_t sai_create_lag_entry( - _Out_ sai_object_id_t* lag_id, - _In_ uint32_t attr_count, - _In_ sai_attribute_t *attr_list); +sai_status_t sai_create_lag_entry(_Out_ sai_object_id_t *lag_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); -sai_status_t sai_remove_lag_entry( - _In_ sai_object_id_t lag_id); +sai_status_t sai_remove_lag_entry(_In_ sai_object_id_t lag_id); -sai_status_t sai_set_lag_entry_attribute( - _In_ sai_object_id_t lag_id, - _In_ const sai_attribute_t *attr); +sai_status_t sai_set_lag_entry_attribute(_In_ sai_object_id_t lag_id, + _In_ const sai_attribute_t *attr); -sai_status_t sai_add_ports_to_lag( - _In_ sai_object_id_t lag_id, - _In_ const sai_object_list_t *port_list); +sai_status_t sai_add_ports_to_lag(_In_ sai_object_id_t lag_id, + _In_ const sai_object_list_t *port_list); /* \brief Create LAG @@ -44,36 +40,31 @@ sai_status_t sai_add_ports_to_lag( \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_create_lag_entry( - _Out_ sai_object_id_t* lag_id, - _In_ uint32_t attr_count, - _In_ sai_attribute_t *attr_list) { +sai_status_t sai_create_lag_entry(_Out_ sai_object_id_t *lag_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (attr_count && !attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - if (attr_count && !attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - *lag_id = (sai_object_id_t) switch_api_lag_create(device); - status = (*lag_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; + *lag_id = (sai_object_id_t)switch_api_lag_create(device); + status = (*lag_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create lag: %s", - sai_status_to_string(status)); - return status; - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create lag: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -82,27 +73,24 @@ sai_status_t sai_create_lag_entry( \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_remove_lag_entry( - _In_ sai_object_id_t lag_id) { +sai_status_t sai_remove_lag_entry(_In_ sai_object_id_t lag_id) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); - SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); + switch_status = switch_api_lag_delete(device, (switch_handle_t)lag_id); + status = sai_switch_status_to_sai_status(switch_status); - switch_status = switch_api_lag_delete(device, (switch_handle_t) lag_id); - status = sai_switch_status_to_sai_status(switch_status); - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove lag %lx: %s", - lag_id, - sai_status_to_string(status)); - } - SAI_LOG_EXIT(); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR( + "failed to remove lag %lx: %s", lag_id, sai_status_to_string(status)); + } + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -112,84 +100,77 @@ sai_status_t sai_remove_lag_entry( \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_set_lag_attribute( - _In_ sai_object_id_t lag_id, - _In_ const sai_attribute_t *attr) { +sai_status_t sai_set_lag_attribute(_In_ sai_object_id_t lag_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - - SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); + SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* \brief Get LAG Attribute \param[in] lag_id LAG id \param[in] attr_count Number of attributes to be get - \param[in,out] attr_list List of structures containing ID and value to be get + \param[in,out] attr_list List of structures containing ID and value to be + get \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_get_lag_attribute( - _In_ sai_object_id_t lag_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { +sai_status_t sai_get_lag_attribute(_In_ sai_object_id_t lag_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); + SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } -sai_status_t sai_lag_member_entry_parse( - _In_ sai_attribute_t *attr_list, - _In_ uint32_t attr_count, - _Out_ sai_object_id_t *lag_id, - _Out_ sai_object_id_t *port_id) { - - const sai_attribute_t *attribute; - uint32_t index = 0; - - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_LAG_MEMBER_ATTR_LAG_ID: - *lag_id = attribute->value.oid; - break; - case SAI_LAG_MEMBER_ATTR_PORT_ID: - *port_id = attribute->value.oid; - break; - case SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE: - break; - case SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE: - break; - } +sai_status_t sai_lag_member_entry_parse(_In_ const sai_attribute_t *attr_list, + _In_ uint32_t attr_count, + _Out_ sai_object_id_t *lag_id, + _Out_ sai_object_id_t *port_id) { + const sai_attribute_t *attribute; + uint32_t index = 0; + + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_LAG_MEMBER_ATTR_LAG_ID: + *lag_id = attribute->value.oid; + break; + case SAI_LAG_MEMBER_ATTR_PORT_ID: + *port_id = attribute->value.oid; + break; + case SAI_LAG_MEMBER_ATTR_EGRESS_DISABLE: + break; + case SAI_LAG_MEMBER_ATTR_INGRESS_DISABLE: + break; } - return SAI_STATUS_SUCCESS; + } + return SAI_STATUS_SUCCESS; } /* @@ -200,52 +181,45 @@ sai_status_t sai_lag_member_entry_parse( \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_create_lag_member( - _Out_ sai_object_id_t* lag_member_id, - _In_ uint32_t attr_count, - _In_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_direction_t direction = SWITCH_API_DIRECTION_BOTH; - sai_object_id_t lag_id = 0; - sai_object_id_t port_id = 0; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null port list: %s", - sai_status_to_string(status)); - return status; - } - - status = sai_lag_member_entry_parse(attr_list, attr_count, &lag_id, &port_id); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to parse lag member attributes: %s", - sai_status_to_string(status)); - return status; - } - - SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); - SAI_ASSERT(sai_object_type_query(port_id) == SAI_OBJECT_TYPE_PORT); - - *lag_member_id = switch_api_lag_member_create(device, - (switch_handle_t) lag_id, - direction, - port_id); - status = (*lag_member_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create lag: %s", - sai_status_to_string(status)); - return status; - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_create_lag_member(_Out_ sai_object_id_t *lag_member_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_direction_t direction = SWITCH_API_DIRECTION_BOTH; + sai_object_id_t lag_id = 0; + sai_object_id_t port_id = 0; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null port list: %s", sai_status_to_string(status)); + return status; + } + + status = sai_lag_member_entry_parse(attr_list, attr_count, &lag_id, &port_id); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to parse lag member attributes: %s", + sai_status_to_string(status)); + return status; + } + + SAI_ASSERT(sai_object_type_query(lag_id) == SAI_OBJECT_TYPE_LAG); + SAI_ASSERT(sai_object_type_query(port_id) == SAI_OBJECT_TYPE_PORT); + + *lag_member_id = switch_api_lag_member_create( + device, (switch_handle_t)lag_id, direction, port_id); + status = (*lag_member_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create lag: %s", sai_status_to_string(status)); + return status; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -254,27 +228,27 @@ sai_status_t sai_create_lag_member( \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_remove_lag_member( - _In_ sai_object_id_t lag_member_id) { +sai_status_t sai_remove_lag_member(_In_ sai_object_id_t lag_member_id) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + SAI_ASSERT(sai_object_type_query(lag_member_id) == + SAI_OBJECT_TYPE_LAG_MEMBER); - SAI_ASSERT(sai_object_type_query(lag_member_id) == SAI_OBJECT_TYPE_LAG_MEMBER); - - switch_status = switch_api_lag_member_remove(device, - (switch_handle_t) lag_member_id); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove lag member %lx : %s", - lag_member_id, sai_status_to_string(status)); - } + switch_status = + switch_api_lag_member_remove(device, (switch_handle_t)lag_member_id); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove lag member %lx : %s", + lag_member_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -284,56 +258,55 @@ sai_status_t sai_remove_lag_member( \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_set_lag_member_attribute( - _In_ sai_object_id_t lag_member_id, - _In_ const sai_attribute_t *attr) { - SAI_LOG_ENTER(); +sai_status_t sai_set_lag_member_attribute(_In_ sai_object_id_t lag_member_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* \brief Get LAG Member Attribute \param[in] lag_member_id LAG Member id \param[in] attr_count Number of attributes to be get - \param[in,out] attr_list List of structures containing ID and value to be get + \param[in,out] attr_list List of structures containing ID and value to be + get \return Success: SAI_STATUS_SUCCESS Failure: Failure status code on error */ -sai_status_t sai_get_lag_member_attribute( - _In_ sai_object_id_t lag_member_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - SAI_LOG_ENTER(); +sai_status_t sai_get_lag_member_attribute(_In_ sai_object_id_t lag_member_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * LAG methods table retrieved with sai_api_query() */ sai_lag_api_t lag_api = { - .create_lag = sai_create_lag_entry, - .remove_lag = sai_remove_lag_entry, - .set_lag_attribute = sai_set_lag_attribute, - .get_lag_attribute = sai_get_lag_attribute, - .create_lag_member = sai_create_lag_member, - .remove_lag_member = sai_remove_lag_member, - .set_lag_member_attribute = sai_set_lag_member_attribute, - .get_lag_member_attribute = sai_get_lag_member_attribute, + .create_lag = sai_create_lag_entry, + .remove_lag = sai_remove_lag_entry, + .set_lag_attribute = sai_set_lag_attribute, + .get_lag_attribute = sai_get_lag_attribute, + .create_lag_member = sai_create_lag_member, + .remove_lag_member = sai_remove_lag_member, + .set_lag_member_attribute = sai_set_lag_member_attribute, + .get_lag_member_attribute = sai_get_lag_member_attribute, }; sai_status_t sai_lag_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing lag"); - sai_api_service->lag_api = lag_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing lag"); + sai_api_service->lag_api = lag_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saimirror.c b/switchsai/src/saimirror.c index 9684952..f9d7f87 100644 --- a/switchsai/src/saimirror.c +++ b/switchsai/src/saimirror.c @@ -20,98 +20,95 @@ limitations under the License. static sai_api_t api_id = SAI_API_MIRROR; -static switch_mirror_type_t -sai_session_to_switch_session( - _In_ sai_mirror_type_t mirror_type) { - switch (mirror_type) { - case SAI_MIRROR_TYPE_LOCAL: - return SWITCH_MIRROR_TYPE_LOCAL; - case SAI_MIRROR_TYPE_REMOTE: - return SWITCH_MIRROR_TYPE_REMOTE; - case SAI_MIRROR_TYPE_ENHANCED_REMOTE: - return SWITCH_MIRROR_TYPE_ENHANCED_REMOTE; - default: - return SWITCH_MIRROR_TYPE_NONE; - } +static switch_mirror_type_t sai_session_to_switch_session(_In_ sai_mirror_type_t + mirror_type) { + switch (mirror_type) { + case SAI_MIRROR_TYPE_LOCAL: + return SWITCH_MIRROR_TYPE_LOCAL; + case SAI_MIRROR_TYPE_REMOTE: + return SWITCH_MIRROR_TYPE_REMOTE; + case SAI_MIRROR_TYPE_ENHANCED_REMOTE: + return SWITCH_MIRROR_TYPE_ENHANCED_REMOTE; + default: + return SWITCH_MIRROR_TYPE_NONE; + } } -static switch_encap_type_t -sai_erspan_encap_to_switch_erspan_encap( - _In_ sai_erspan_encapsulation_type_t encap_type) { - switch (encap_type) { - case SAI_MIRROR_L3_GRE_TUNNEL: - return SWITCH_API_ENCAP_TYPE_ERSPAN_T3; - default: - return SWITCH_API_ENCAP_TYPE_NONE; - } +static switch_encap_type_t sai_erspan_encap_to_switch_erspan_encap( + _In_ sai_erspan_encapsulation_type_t encap_type) { + switch (encap_type) { + case SAI_MIRROR_L3_GRE_TUNNEL: + return SWITCH_API_ENCAP_TYPE_ERSPAN_T3; + default: + return SWITCH_API_ENCAP_TYPE_NONE; + } } static void sai_mirror_session_attribute_parse( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list, - _Out_ switch_api_mirror_info_t *api_mirror_info) { - - const sai_attribute_t *attribute = NULL; - switch_tunnel_info_t *tunnel_info = NULL; - uint32_t index = 0; - - memset(api_mirror_info, 0, sizeof(switch_api_mirror_info_t)); - tunnel_info = &api_mirror_info->tunnel_info; - - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_MIRROR_SESSION_ATTR_TYPE: - api_mirror_info->mirror_type = - sai_session_to_switch_session(attribute->value.s32); - break; - case SAI_MIRROR_SESSION_ATTR_MONITOR_PORT: - api_mirror_info->egress_port = attribute->value.oid; - break; - case SAI_MIRROR_SESSION_ATTR_TC: - break; - case SAI_MIRROR_SESSION_ATTR_VLAN_TPID: - api_mirror_info->vlan_tpid = attribute->value.u16; - break; - case SAI_MIRROR_SESSION_ATTR_VLAN_ID: - api_mirror_info->vlan_id = attribute->value.u16; - api_mirror_info->vlan_create = TRUE; - break; - case SAI_MIRROR_SESSION_ATTR_VLAN_PRI: - api_mirror_info->vlan_priority = attribute->value.u8; - break; - case SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE: - tunnel_info->encap_info.encap_type = - sai_erspan_encap_to_switch_erspan_encap(attribute->value.s32); - break; - case SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION: - break; - case SAI_MIRROR_SESSION_ATTR_TOS: - break; - case SAI_MIRROR_SESSION_ATTR_TTL: - break; - case SAI_MIRROR_SESSION_ATTR_SRC_IP_ADDRESS: - sai_ip_addr_to_switch_ip_addr(&attribute->value.ipaddr, - &tunnel_info->u.ip_encap.src_ip); - break; - case SAI_MIRROR_SESSION_ATTR_DST_IP_ADDRESS: - sai_ip_addr_to_switch_ip_addr(&attribute->value.ipaddr, - &tunnel_info->u.ip_encap.dst_ip); - api_mirror_info->tunnel_create = TRUE; - break; - case SAI_MIRROR_SESSION_ATTR_SRC_MAC_ADDRESS: - memcpy(&api_mirror_info->src_mac, &attribute->value.mac, 6); - break; - case SAI_MIRROR_SESSION_ATTR_DST_MAC_ADDRESS: - memcpy(&api_mirror_info->dst_mac, &attribute->value.mac, 6); - break; - case SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE: - tunnel_info->u.ip_encap.proto = attribute->value.u16; - break; - default: - break; - } + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _Out_ switch_api_mirror_info_t *api_mirror_info) { + const sai_attribute_t *attribute = NULL; + switch_tunnel_info_t *tunnel_info = NULL; + uint32_t index = 0; + + memset(api_mirror_info, 0, sizeof(switch_api_mirror_info_t)); + tunnel_info = &api_mirror_info->tunnel_info; + + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_MIRROR_SESSION_ATTR_TYPE: + api_mirror_info->mirror_type = + sai_session_to_switch_session(attribute->value.s32); + break; + case SAI_MIRROR_SESSION_ATTR_MONITOR_PORT: + api_mirror_info->egress_port = attribute->value.oid; + break; + case SAI_MIRROR_SESSION_ATTR_TC: + break; + case SAI_MIRROR_SESSION_ATTR_VLAN_TPID: + api_mirror_info->vlan_tpid = attribute->value.u16; + break; + case SAI_MIRROR_SESSION_ATTR_VLAN_ID: + api_mirror_info->vlan_id = attribute->value.u16; + api_mirror_info->vlan_create = TRUE; + break; + case SAI_MIRROR_SESSION_ATTR_VLAN_PRI: + api_mirror_info->vlan_priority = attribute->value.u8; + break; + case SAI_MIRROR_SESSION_ATTR_ENCAP_TYPE: + tunnel_info->encap_info.encap_type = + sai_erspan_encap_to_switch_erspan_encap(attribute->value.s32); + break; + case SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION: + break; + case SAI_MIRROR_SESSION_ATTR_TOS: + break; + case SAI_MIRROR_SESSION_ATTR_TTL: + break; + case SAI_MIRROR_SESSION_ATTR_SRC_IP_ADDRESS: + sai_ip_addr_to_switch_ip_addr(&attribute->value.ipaddr, + &tunnel_info->u.ip_encap.src_ip); + break; + case SAI_MIRROR_SESSION_ATTR_DST_IP_ADDRESS: + sai_ip_addr_to_switch_ip_addr(&attribute->value.ipaddr, + &tunnel_info->u.ip_encap.dst_ip); + api_mirror_info->tunnel_create = TRUE; + break; + case SAI_MIRROR_SESSION_ATTR_SRC_MAC_ADDRESS: + memcpy(&api_mirror_info->src_mac, &attribute->value.mac, 6); + break; + case SAI_MIRROR_SESSION_ATTR_DST_MAC_ADDRESS: + memcpy(&api_mirror_info->dst_mac, &attribute->value.mac, 6); + break; + case SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE: + tunnel_info->u.ip_encap.proto = attribute->value.u16; + break; + default: + break; } + } } /** @@ -123,36 +120,34 @@ static void sai_mirror_session_attribute_parse( * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_create_mirror_session( - _Out_ sai_object_id_t *session_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - sai_status_t status = SAI_STATUS_SUCCESS; - switch_api_mirror_info_t api_mirror_info; - - SAI_LOG_ENTER(); - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_create_mirror_session(_Out_ sai_object_id_t *session_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + sai_status_t status = SAI_STATUS_SUCCESS; + switch_api_mirror_info_t api_mirror_info; - sai_mirror_session_attribute_parse(attr_count, attr_list, &api_mirror_info); - *session_id = (sai_object_id_t) switch_api_mirror_session_create(device, &api_mirror_info); - status = (*session_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; + SAI_LOG_ENTER(); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create mirror session: %s", - sai_status_to_string(status)); - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + sai_mirror_session_attribute_parse(attr_count, attr_list, &api_mirror_info); + *session_id = (sai_object_id_t)switch_api_mirror_session_create( + device, &api_mirror_info); + status = (*session_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create mirror session: %s", + sai_status_to_string(status)); + } - return (sai_status_t) status; + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /** @@ -162,26 +157,25 @@ sai_status_t sai_create_mirror_session( * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_remove_mirror_session( - _In_ sai_object_id_t session_id) { - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; +sai_status_t sai_remove_mirror_session(_In_ sai_object_id_t session_id) { + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - SAI_LOG_ENTER(); + SAI_LOG_ENTER(); - SAI_ASSERT(sai_object_type_query(session_id) == SAI_OBJECT_TYPE_MIRROR); + SAI_ASSERT(sai_object_type_query(session_id) == SAI_OBJECT_TYPE_MIRROR); - switch_status = switch_api_mirror_session_delete(device, session_id); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove mirror session %lx: %s", - session_id, - sai_status_to_string(status)); - } + switch_status = switch_api_mirror_session_delete(device, session_id); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove mirror session %lx: %s", + session_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -193,24 +187,22 @@ sai_status_t sai_remove_mirror_session( * error code is returned. */ sai_status_t sai_set_mirror_session_attribute( - _In_ sai_object_id_t session_id, - _In_ const sai_attribute_t *attr) { - sai_status_t status = SAI_STATUS_SUCCESS; + _In_ sai_object_id_t session_id, _In_ const sai_attribute_t *attr) { + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_ENTER(); + SAI_LOG_ENTER(); - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(session_id) == SAI_OBJECT_TYPE_MIRROR); + SAI_ASSERT(sai_object_type_query(session_id) == SAI_OBJECT_TYPE_MIRROR); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -223,41 +215,38 @@ sai_status_t sai_set_mirror_session_attribute( * error code is returned. */ sai_status_t sai_get_mirror_session_attribute( - _In_ sai_object_id_t session_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; + _In_ sai_object_id_t session_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(session_id) == SAI_OBJECT_TYPE_MIRROR); + SAI_ASSERT(sai_object_type_query(session_id) == SAI_OBJECT_TYPE_MIRROR); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return status; + return status; } /* * Mirror API methods table retrieved with sai_api_query() */ sai_mirror_api_t mirror_api = { - .create_mirror_session = sai_create_mirror_session, - .remove_mirror_session = sai_remove_mirror_session, - .set_mirror_session_attribute = sai_set_mirror_session_attribute, - .get_mirror_session_attribute = sai_get_mirror_session_attribute, + .create_mirror_session = sai_create_mirror_session, + .remove_mirror_session = sai_remove_mirror_session, + .set_mirror_session_attribute = sai_set_mirror_session_attribute, + .get_mirror_session_attribute = sai_get_mirror_session_attribute, }; sai_status_t sai_mirror_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing mirror"); - sai_api_service->mirror_api = mirror_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing mirror"); + sai_api_service->mirror_api = mirror_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saineighbor.c b/switchsai/src/saineighbor.c index 7a1b630..3300f3e 100644 --- a/switchsai/src/saineighbor.c +++ b/switchsai/src/saineighbor.c @@ -23,69 +23,77 @@ limitations under the License. static sai_api_t api_id = SAI_API_NEIGHBOR; static void sai_neighbor_entry_to_string( - _In_ const sai_neighbor_entry_t *neighbor_entry, - _Out_ char * entry_string) { - int count = 0; - int entry_length = 0; - count = snprintf(entry_string, - SAI_MAX_ENTRY_STRING_LEN, - "neighbor: rif %lx", - neighbor_entry->rif_id); - sai_ipaddress_to_string(neighbor_entry->ip_address, - SAI_MAX_ENTRY_STRING_LEN - count, - entry_string + count, - &entry_length); - return; + _In_ const sai_neighbor_entry_t *neighbor_entry, _Out_ char *entry_string) { + int count = 0; + int entry_length = 0; + count = snprintf(entry_string, + SAI_MAX_ENTRY_STRING_LEN, + "neighbor: rif %" PRIx64 "", + neighbor_entry->rif_id); + sai_ipaddress_to_string(neighbor_entry->ip_address, + SAI_MAX_ENTRY_STRING_LEN - count, + entry_string + count, + &entry_length); + return; } -static void sai_neighbor_entry_parse( - const sai_neighbor_entry_t *neighbor_entry, - switch_api_neighbor_t *api_neighbor) { - - SAI_ASSERT(sai_object_type_query(neighbor_entry->rif_id) == - SAI_OBJECT_TYPE_ROUTER_INTERFACE); - - api_neighbor->interface = (switch_handle_t) neighbor_entry->rif_id; - api_neighbor->rw_type = SWITCH_API_NEIGHBOR_RW_TYPE_L3; - sai_ip_addr_to_switch_ip_addr(&neighbor_entry->ip_address, &api_neighbor->ip_addr); +static void sai_neighbor_entry_parse(const sai_neighbor_entry_t *neighbor_entry, + switch_api_neighbor_t *api_neighbor) { + SAI_ASSERT(sai_object_type_query(neighbor_entry->rif_id) == + SAI_OBJECT_TYPE_ROUTER_INTERFACE); + + uint64_t value; + switch_api_interface_vrf_get((switch_handle_t)neighbor_entry->rif_id, &value); + api_neighbor->interface = (switch_handle_t)neighbor_entry->rif_id; + api_neighbor->rw_type = SWITCH_API_NEIGHBOR_RW_TYPE_L3; + api_neighbor->vrf_handle = (switch_handle_t)value; + sai_ip_addr_to_switch_ip_addr(&neighbor_entry->ip_address, + &api_neighbor->ip_addr); } static void sai_neighbor_entry_attribute_parse( - uint32_t attr_count, - const sai_attribute_t *attr_list, - switch_api_neighbor_t *api_neighbor) { - const sai_attribute_t *attribute; - uint32_t index = 0; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS: - memcpy(&api_neighbor->mac_addr, attribute->value.mac, sizeof(switch_mac_addr_t)); - break; - case SAI_NEIGHBOR_ATTR_PACKET_ACTION: - break; - } + uint32_t attr_count, + const sai_attribute_t *attr_list, + switch_api_neighbor_t *api_neighbor, + int *set_host_route) { + const sai_attribute_t *attribute; + uint32_t index = 0; + *set_host_route = 1; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_NEIGHBOR_ATTR_DST_MAC_ADDRESS: + memcpy(&api_neighbor->mac_addr, + attribute->value.mac, + sizeof(switch_mac_addr_t)); + break; + case SAI_NEIGHBOR_ATTR_PACKET_ACTION: + break; + case SAI_NEIGHBOR_ATTR_NO_HOST_ROUTE: + *set_host_route = 0; + break; } + } } static void sai_neighbor_entry_nexthop_get( - switch_api_neighbor_t *api_neighbor) { - switch_ip_addr_t ip_addr; - switch_nhop_key_t nhop_key; - memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); - memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); - nhop_key.intf_handle = api_neighbor->interface; - memcpy(&nhop_key.ip_addr, &api_neighbor->ip_addr, sizeof(switch_ip_addr_t)); - nhop_key.ip_addr_valid = 1; - api_neighbor->nhop_handle = switch_api_nhop_handle_get(&nhop_key); + switch_api_neighbor_t *api_neighbor) { + switch_ip_addr_t ip_addr; + switch_nhop_key_t nhop_key; + memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); + memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); + nhop_key.intf_handle = api_neighbor->interface; + memcpy(&nhop_key.ip_addr, &api_neighbor->ip_addr, sizeof(switch_ip_addr_t)); + nhop_key.ip_addr_valid = 1; + api_neighbor->nhop_handle = switch_api_nhop_handle_get(&nhop_key); } /* * Routine Description: -* Create neighbor entry +* Create neighbor entry * * Arguments: -* [in] neighbor_entry - neighbor entry +* [in] neighbor_entry - neighbor entry * [in] attr_count - number of attributes * [in] attrs - array of attributes * @@ -96,58 +104,69 @@ static void sai_neighbor_entry_nexthop_get( * Note: IP address expected in Network Byte Order. */ sai_status_t sai_create_neighbor_entry( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_handle_t neighbor_handle = SWITCH_API_INVALID_HANDLE; - char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - switch_api_neighbor_t api_neighbor; - - if (!neighbor_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null neighbor entry: %s", - sai_status_to_string(status)); - return status; + _In_ const sai_neighbor_entry_t *neighbor_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_handle_t neighbor_handle = SWITCH_API_INVALID_HANDLE; + char entry_string[SAI_MAX_ENTRY_STRING_LEN]; + switch_api_neighbor_t api_neighbor; + int set_host_route = 1; + + if (!neighbor_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null neighbor entry: %s", sai_status_to_string(status)); + return status; + } + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); + sai_neighbor_entry_parse(neighbor_entry, &api_neighbor); + sai_neighbor_entry_attribute_parse( + attr_count, attr_list, &api_neighbor, &set_host_route); + sai_neighbor_entry_nexthop_get(&api_neighbor); + + sai_neighbor_entry_to_string(neighbor_entry, entry_string); + + neighbor_handle = switch_api_neighbor_entry_add(device, &api_neighbor); + status = (neighbor_handle == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create neighbor entry: %s", + sai_status_to_string(status)); + } + + if (set_host_route && (status == SAI_STATUS_SUCCESS)) { + // insert the /32 route using the nexthop + switch_handle_t nhop_handle = api_neighbor.nhop_handle; + if (nhop_handle != SWITCH_API_INVALID_HANDLE) { + switch_status_t switch_status = + switch_api_l3_route_add(device, + api_neighbor.vrf_handle, + &(api_neighbor.ip_addr), + nhop_handle); + status = sai_switch_status_to_sai_status(switch_status); } + } - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + SAI_LOG_EXIT(); - memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); - sai_neighbor_entry_parse(neighbor_entry, &api_neighbor); - sai_neighbor_entry_attribute_parse(attr_count, attr_list, &api_neighbor); - sai_neighbor_entry_nexthop_get(&api_neighbor); - - sai_neighbor_entry_to_string(neighbor_entry, entry_string); - - neighbor_handle = switch_api_neighbor_entry_add(device, &api_neighbor); - status = neighbor_handle == SWITCH_API_INVALID_HANDLE ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create neighbor entry: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + return (sai_status_t)status; } /* * Routine Description: -* Remove neighbor entry +* Remove neighbor entry * * Arguments: -* [in] neighbor_entry - neighbor entry +* [in] neighbor_entry - neighbor entry * * Return Values: * SAI_STATUS_SUCCESS on success @@ -156,37 +175,44 @@ sai_status_t sai_create_neighbor_entry( * Note: IP address expected in Network Byte Order. */ sai_status_t sai_remove_neighbor_entry( - _In_ const sai_neighbor_entry_t* neighbor_entry) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_api_neighbor_t api_neighbor; - switch_handle_t neighbor_handle; - - if (!neighbor_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null neighbor entry: %s", - sai_status_to_string(status)); - return status; - } - - memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); - sai_neighbor_entry_parse(neighbor_entry, &api_neighbor); - sai_neighbor_entry_nexthop_get(&api_neighbor); - - neighbor_handle = switch_api_neighbor_handle_get(api_neighbor.nhop_handle); - switch_status = switch_api_neighbor_entry_remove(device, neighbor_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create neighbor entry: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + _In_ const sai_neighbor_entry_t *neighbor_entry) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_api_neighbor_t api_neighbor; + switch_handle_t neighbor_handle; + + if (!neighbor_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null neighbor entry: %s", sai_status_to_string(status)); + return status; + } + + memset(&api_neighbor, 0, sizeof(switch_api_neighbor_t)); + sai_neighbor_entry_parse(neighbor_entry, &api_neighbor); + sai_neighbor_entry_nexthop_get(&api_neighbor); + + /* + remove the /32 route w/o checking for SET_NO_HOST_ROUTE + ignore error! + */ + switch_api_l3_route_delete(device, + api_neighbor.vrf_handle, + &(api_neighbor.ip_addr), + api_neighbor.nhop_handle); + + neighbor_handle = switch_api_neighbor_handle_get(api_neighbor.nhop_handle); + switch_status = switch_api_neighbor_entry_remove(device, neighbor_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create neighbor entry: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -202,31 +228,27 @@ sai_status_t sai_remove_neighbor_entry( * Failure status code on error */ sai_status_t sai_set_neighbor_entry_attribute( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ const sai_attribute_t *attr) { + _In_ const sai_neighbor_entry_t *neighbor_entry, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!neighbor_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null neighbor entry: %s", sai_status_to_string(status)); + return status; + } - if (!neighbor_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null neighbor entry: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - - - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -243,44 +265,40 @@ sai_status_t sai_set_neighbor_entry_attribute( * Failure status code on error */ sai_status_t sai_get_neighbor_entry_attribute( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { + _In_ const sai_neighbor_entry_t *neighbor_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!neighbor_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null neighbor entry: %s", sai_status_to_string(status)); + return status; + } - if (!neighbor_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null neighbor entry: %s", - sai_status_to_string(status)); - return status; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Neighbor methods table retrieved with sai_api_query() */ sai_neighbor_api_t neighbor_api = { - .create_neighbor_entry = sai_create_neighbor_entry, - .remove_neighbor_entry = sai_remove_neighbor_entry, - .set_neighbor_attribute = sai_set_neighbor_entry_attribute, - .get_neighbor_attribute = sai_get_neighbor_entry_attribute -}; + .create_neighbor_entry = sai_create_neighbor_entry, + .remove_neighbor_entry = sai_remove_neighbor_entry, + .set_neighbor_attribute = sai_set_neighbor_entry_attribute, + .get_neighbor_attribute = sai_get_neighbor_entry_attribute}; sai_status_t sai_neighbor_initialize(sai_api_service_t *sai_api_service) { - sai_api_service->neighbor_api = neighbor_api; - return SAI_STATUS_SUCCESS; + sai_api_service->neighbor_api = neighbor_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/sainexthop.c b/switchsai/src/sainexthop.c index ede5778..798bf20 100644 --- a/switchsai/src/sainexthop.c +++ b/switchsai/src/sainexthop.c @@ -35,63 +35,58 @@ static sai_api_t api_id = SAI_API_NEXT_HOP; * * Note: IP address expected in Network Byte Order. */ -sai_status_t sai_create_next_hop_entry( - _Out_ sai_object_id_t* next_hop_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - const sai_attribute_t *attribute; - sai_status_t status = SAI_STATUS_SUCCESS; - uint32_t index = 0; - const sai_ip_address_t *sai_ip_addr; - switch_nhop_key_t nhop_key; - sai_next_hop_type_t nhtype = SAI_NEXT_HOP_IP; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; +sai_status_t sai_create_next_hop_entry(_Out_ sai_object_id_t *next_hop_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + const sai_attribute_t *attribute; + sai_status_t status = SAI_STATUS_SUCCESS; + uint32_t index = 0; + const sai_ip_address_t *sai_ip_addr; + switch_nhop_key_t nhop_key; + sai_next_hop_type_t nhtype = SAI_NEXT_HOP_IP; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_NEXT_HOP_ATTR_TYPE: + nhtype = attribute->value.s32; + break; + case SAI_NEXT_HOP_ATTR_IP: + assert(nhtype == SAI_NEXT_HOP_IP); + sai_ip_addr = &attribute->value.ipaddr; + sai_ip_addr_to_switch_ip_addr(sai_ip_addr, &nhop_key.ip_addr); + nhop_key.ip_addr_valid = 1; + break; + case SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID: + SAI_ASSERT(sai_object_type_query(attribute->value.oid) == + SAI_OBJECT_TYPE_ROUTER_INTERFACE); + nhop_key.intf_handle = (switch_handle_t)attribute->value.oid; + break; + default: + return SAI_STATUS_INVALID_PARAMETER; } + } - memset(&nhop_key, 0, sizeof(switch_nhop_key_t)); - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_NEXT_HOP_ATTR_TYPE: - nhtype = attribute->value.s32; - break; - case SAI_NEXT_HOP_ATTR_IP: - assert(nhtype == SAI_NEXT_HOP_IP); - sai_ip_addr = &attribute->value.ipaddr; - sai_ip_addr_to_switch_ip_addr(sai_ip_addr, &nhop_key.ip_addr); - nhop_key.ip_addr_valid = 1; - break; - case SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID: - SAI_ASSERT(sai_object_type_query(attribute->value.oid) == - SAI_OBJECT_TYPE_ROUTER_INTERFACE); - nhop_key.intf_handle = (switch_handle_t) attribute->value.oid; - break; - default: - return SAI_STATUS_INVALID_PARAMETER; - } - } + *next_hop_id = (sai_object_id_t)switch_api_nhop_create(device, &nhop_key); + status = (*next_hop_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; - *next_hop_id = (sai_object_id_t) switch_api_nhop_create(device, &nhop_key); - status = (*next_hop_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create nexthop: %s", sai_status_to_string(status)); + } - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create nexthop: %s", - sai_status_to_string(status)); - } + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); - - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -105,31 +100,30 @@ sai_status_t sai_create_next_hop_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_next_hop_entry( - _In_ sai_object_id_t next_hop_id) { - - SAI_LOG_ENTER(); +sai_status_t sai_remove_next_hop_entry(_In_ sai_object_id_t next_hop_id) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - 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; - } + 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); + switch_status = switch_api_nhop_delete(device, (switch_handle_t)next_hop_id); + status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove nexthop %lx: %s", - next_hop_id, - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove nexthop %lx: %s", + next_hop_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -145,25 +139,51 @@ sai_status_t sai_remove_next_hop_entry( * Failure status code on error */ sai_status_t sai_set_next_hop_entry_attribute( - _In_ sai_object_id_t next_hop_id, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - - SAI_ASSERT(sai_object_type_query(next_hop_id) == SAI_OBJECT_TYPE_NEXT_HOP); - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + _In_ sai_object_id_t next_hop_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + + switch_nhop_key_t *key; + if ((switch_status = + switch_api_nhop_get(device, (switch_handle_t)next_hop_id, &key)) != + SWITCH_STATUS_SUCCESS) { + return sai_switch_status_to_sai_status(switch_status); + } + + switch (attr->id) { + case SAI_NEXT_HOP_ATTR_TYPE: + break; + case SAI_NEXT_HOP_ATTR_IP: + status = + sai_ip_addr_to_switch_ip_addr(&attr->value.ipaddr, &key->ip_addr); + break; + case SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID: + key->intf_handle = attr->value.oid; + break; + default: + return SAI_STATUS_INVALID_PARAMETER; + } + + if (switch_api_nhop_set(device, (switch_handle_t)next_hop_id, key) == + SWITCH_STATUS_SUCCESS) { + status = SAI_STATUS_SUCCESS; + } else { + status = SAI_STATUS_FAILURE; + } + + SAI_ASSERT(sai_object_type_query(next_hop_id) == SAI_OBJECT_TYPE_NEXT_HOP); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -180,40 +200,64 @@ sai_status_t sai_set_next_hop_entry_attribute( * Failure status code on error */ sai_status_t sai_get_next_hop_entry_attribute( - _In_ sai_object_id_t next_hop_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; + _In_ sai_object_id_t next_hop_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + switch_nhop_key_t *key; + if ((switch_status = + switch_api_nhop_get(device, (switch_handle_t)next_hop_id, &key)) != + SWITCH_STATUS_SUCCESS) { + return sai_switch_status_to_sai_status(switch_status); + } + + uint32_t index; + sai_attribute_t *attribute; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_NEXT_HOP_ATTR_TYPE: + break; + case SAI_NEXT_HOP_ATTR_IP: + status = sai_switch_ip_addr_to_sai_ip_addr(&attribute->value.ipaddr, + &key->ip_addr); + break; + case SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID: + attribute->value.oid = key->intf_handle; + break; + default: + return SAI_STATUS_INVALID_PARAMETER; } + } - SAI_ASSERT(sai_object_type_query(next_hop_id) == SAI_OBJECT_TYPE_NEXT_HOP); + SAI_ASSERT(sai_object_type_query(next_hop_id) == SAI_OBJECT_TYPE_NEXT_HOP); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Next Hop methods table retrieved with sai_api_query() */ sai_next_hop_api_t nhop_api = { - .create_next_hop = sai_create_next_hop_entry, - .remove_next_hop = sai_remove_next_hop_entry, - .set_next_hop_attribute = sai_set_next_hop_entry_attribute, - .get_next_hop_attribute = sai_get_next_hop_entry_attribute -}; + .create_next_hop = sai_create_next_hop_entry, + .remove_next_hop = sai_remove_next_hop_entry, + .set_next_hop_attribute = sai_set_next_hop_entry_attribute, + .get_next_hop_attribute = sai_get_next_hop_entry_attribute}; sai_status_t sai_next_hop_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing nexthop"); - sai_api_service->nhop_api = nhop_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing nexthop"); + sai_api_service->nhop_api = nhop_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/sainexthopgroup.c b/switchsai/src/sainexthopgroup.c index 3a18d56..95569d8 100644 --- a/switchsai/src/sainexthopgroup.c +++ b/switchsai/src/sainexthopgroup.c @@ -23,27 +23,25 @@ limitations under the License. static sai_api_t api_id = SAI_API_NEXT_HOP_GROUP; sai_status_t sai_create_next_hop_group_entry( - _Out_ sai_object_id_t* next_hop_group_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list); + _Out_ sai_object_id_t *next_hop_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); -sai_status_t sai_remove_next_hop_group_entry( - _In_ sai_object_id_t next_hop_group_id); +sai_status_t sai_remove_next_hop_group_entry(_In_ sai_object_id_t + next_hop_group_id); -sai_status_t sai_add_next_hop_to_group( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t next_hop_count, - _In_ const sai_object_id_t* nexthops); +sai_status_t sai_add_next_hop_to_group(_In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t next_hop_count, + _In_ const sai_object_id_t *nexthops); sai_status_t sai_remove_next_hop_from_group( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t next_hop_count, - _In_ const sai_object_id_t* nexthops); + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t next_hop_count, + _In_ const sai_object_id_t *nexthops); - -static sai_next_hop_group_type_t -sai_get_next_hop_group_type(sai_object_id_t next_hop_group_id) { - return SAI_NEXT_HOP_GROUP_ECMP; +static sai_next_hop_group_type_t sai_get_next_hop_group_type( + sai_object_id_t next_hop_group_id) { + return SAI_NEXT_HOP_GROUP_ECMP; } /* @@ -60,57 +58,55 @@ sai_get_next_hop_group_type(sai_object_id_t next_hop_group_id) { * Failure status code on error */ sai_status_t sai_create_next_hop_group_entry( - _Out_ sai_object_id_t* next_hop_group_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - sai_attribute_t attribute; - sai_object_id_t *nhop_list; - sai_next_hop_group_type_t nhgroup_type; - uint32_t nhop_count = 0; - uint32_t index = 0; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - for (index = 0; index < attr_count; index++) { - attribute = attr_list[index]; - switch(attribute.id) { - case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT: - break; - case SAI_NEXT_HOP_GROUP_ATTR_TYPE: - nhgroup_type = attribute.value.s32; - break; - case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST: - nhop_list = attribute.value.objlist.list; - nhop_count = attribute.value.objlist.count; - break; - } + _Out_ sai_object_id_t *next_hop_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + sai_attribute_t attribute; + sai_object_id_t *nhop_list = NULL; + sai_next_hop_group_type_t nhgroup_type = -1; + uint32_t nhop_count = 0; + uint32_t index = 0; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + for (index = 0; index < attr_count; index++) { + attribute = attr_list[index]; + switch (attribute.id) { + case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_COUNT: + break; + case SAI_NEXT_HOP_GROUP_ATTR_TYPE: + nhgroup_type = attribute.value.s32; + break; + case SAI_NEXT_HOP_GROUP_ATTR_NEXT_HOP_LIST: + nhop_list = attribute.value.objlist.list; + nhop_count = attribute.value.objlist.count; + break; } + } - assert(nhgroup_type == SAI_NEXT_HOP_GROUP_ECMP); - *next_hop_group_id = (sai_object_id_t) switch_api_ecmp_create(device); - status = ((*next_hop_group_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : SAI_STATUS_SUCCESS); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create next hop group %s", - sai_status_to_string(status)); - return status; - } + assert(nhgroup_type == SAI_NEXT_HOP_GROUP_ECMP); + *next_hop_group_id = (sai_object_id_t)switch_api_ecmp_create(device); + status = + ((*next_hop_group_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create next hop group %s", + sai_status_to_string(status)); + return status; + } - status = sai_add_next_hop_to_group(*next_hop_group_id, - nhop_count, nhop_list); + status = sai_add_next_hop_to_group(*next_hop_group_id, nhop_count, nhop_list); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -124,32 +120,31 @@ sai_status_t sai_create_next_hop_group_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_next_hop_group_entry( - _In_ sai_object_id_t next_hop_group_id) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - - SAI_ASSERT(sai_object_type_query(next_hop_group_id) == - SAI_OBJECT_TYPE_NEXT_HOP_GROUP); - - sai_next_hop_group_type_t nhgroup_type; - nhgroup_type = sai_get_next_hop_group_type(next_hop_group_id); - assert(nhgroup_type == SAI_NEXT_HOP_GROUP_ECMP); - switch_status = switch_api_ecmp_delete( - device, (switch_handle_t) next_hop_group_id); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove next hop group %lx: %s", - next_hop_group_id, - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_remove_next_hop_group_entry(_In_ sai_object_id_t + next_hop_group_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(next_hop_group_id) == + SAI_OBJECT_TYPE_NEXT_HOP_GROUP); + + sai_next_hop_group_type_t nhgroup_type; + nhgroup_type = sai_get_next_hop_group_type(next_hop_group_id); + assert(nhgroup_type == SAI_NEXT_HOP_GROUP_ECMP); + switch_status = + switch_api_ecmp_delete(device, (switch_handle_t)next_hop_group_id); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove next hop group %lx: %s", + next_hop_group_id, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -165,26 +160,23 @@ sai_status_t sai_remove_next_hop_group_entry( * Failure status code on error */ sai_status_t sai_set_next_hop_group_entry_attribute( - _In_ sai_object_id_t next_hop_group_id, - _In_ const sai_attribute_t *attr) { + _In_ sai_object_id_t next_hop_group_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + SAI_ASSERT(sai_object_type_query(next_hop_group_id) == + SAI_OBJECT_TYPE_NEXT_HOP_GROUP); - SAI_ASSERT(sai_object_type_query(next_hop_group_id) == - SAI_OBJECT_TYPE_NEXT_HOP_GROUP); + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); - - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -201,40 +193,38 @@ sai_status_t sai_set_next_hop_group_entry_attribute( * Failure status code on error */ sai_status_t sai_get_next_hop_group_entry_attribute( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - uint32_t index = 0; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + uint32_t index = 0; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + SAI_ASSERT(sai_object_type_query(next_hop_group_id) == + SAI_OBJECT_TYPE_NEXT_HOP_GROUP); + + for (index = 0; index < attr_count; index++) { + switch (attr_list[index].id) { + case SAI_NEXT_HOP_GROUP_ATTR_TYPE: { + attr_list[index].value.s32 = + sai_get_next_hop_group_type(next_hop_group_id); + break; + } + default: + break; } + } - SAI_ASSERT(sai_object_type_query(next_hop_group_id) == - SAI_OBJECT_TYPE_NEXT_HOP_GROUP); - - for (index = 0; index < attr_count; index++) { - switch(attr_list[index].id) { - case SAI_NEXT_HOP_GROUP_ATTR_TYPE: { - attr_list[index].value.s32 = - sai_get_next_hop_group_type(next_hop_group_id); - break; - } - default: - break; - } - } - - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -250,39 +240,43 @@ sai_status_t sai_get_next_hop_group_entry_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_add_next_hop_to_group( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t next_hop_count, - _In_ const sai_object_id_t* nexthops) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - - if (!nexthops) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null nexthops list: %s", - sai_status_to_string(status)); - return status; - } - - SAI_ASSERT(sai_object_type_query(next_hop_group_id) == - SAI_OBJECT_TYPE_NEXT_HOP_GROUP); - - switch_status = switch_api_ecmp_member_add( - device, (switch_handle_t) next_hop_group_id, - next_hop_count, (switch_handle_t *) nexthops); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to add next hop to group %lx : %s", - next_hop_group_id, - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_add_next_hop_to_group(_In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t next_hop_count, + _In_ const sai_object_id_t *nexthops) { + SAI_LOG_ENTER(); + + switch_handle_t *nh_list = NULL; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + uint32_t i = 0; + + if (!nexthops) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null nexthops list: %s", sai_status_to_string(status)); + return status; + } + + SAI_ASSERT(sai_object_type_query(next_hop_group_id) == + SAI_OBJECT_TYPE_NEXT_HOP_GROUP); + + nh_list = SAI_MALLOC(sizeof(switch_handle_t) * next_hop_count); + if (!nh_list) return SAI_STATUS_NO_MEMORY; + for (i = 0; i < next_hop_count; i++) *(nh_list + i) = nexthops[i]; + switch_status = switch_api_ecmp_member_add(device, + (switch_handle_t)next_hop_group_id, + next_hop_count, + (switch_handle_t *)nh_list); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to add next hop to group %lx : %s", + next_hop_group_id, + sai_status_to_string(status)); + } + + SAI_FREE(nh_list); + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -299,54 +293,59 @@ sai_status_t sai_add_next_hop_to_group( * Failure status code on error */ sai_status_t sai_remove_next_hop_from_group( - _In_ sai_object_id_t next_hop_group_id, - _In_ uint32_t next_hop_count, - _In_ const sai_object_id_t* nexthops) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - - if (!nexthops) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null nexthops list: %s", - sai_status_to_string(status)); - return status; - } - - SAI_ASSERT(sai_object_type_query(next_hop_group_id) == - SAI_OBJECT_TYPE_NEXT_HOP_GROUP); - - switch_status = switch_api_ecmp_member_delete( - device, (switch_handle_t) next_hop_group_id, - next_hop_count, (switch_handle_t *) nexthops); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove next hop from group %lx : %s", - next_hop_group_id, - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + _In_ sai_object_id_t next_hop_group_id, + _In_ uint32_t next_hop_count, + _In_ const sai_object_id_t *nexthops) { + SAI_LOG_ENTER(); + + switch_handle_t *nh_list = NULL; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + uint32_t i = 0; + + if (!nexthops) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null nexthops list: %s", sai_status_to_string(status)); + return status; + } + + SAI_ASSERT(sai_object_type_query(next_hop_group_id) == + SAI_OBJECT_TYPE_NEXT_HOP_GROUP); + + nh_list = SAI_MALLOC(sizeof(switch_handle_t) * next_hop_count); + if (!nh_list) return SAI_STATUS_NO_MEMORY; + for (i = 0; i < next_hop_count; i++) *(nh_list + i) = nexthops[i]; + switch_status = + switch_api_ecmp_member_delete(device, + (switch_handle_t)next_hop_group_id, + next_hop_count, + (switch_handle_t *)nh_list); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove next hop from group %lx : %s", + next_hop_group_id, + sai_status_to_string(status)); + } + + SAI_FREE(nh_list); + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* * Next Hop group methods table retrieved with sai_api_query() */ sai_next_hop_group_api_t nhop_group_api = { - .create_next_hop_group = sai_create_next_hop_group_entry, - .remove_next_hop_group = sai_remove_next_hop_group_entry, - .set_next_hop_group_attribute = sai_set_next_hop_group_entry_attribute, - .get_next_hop_group_attribute = sai_get_next_hop_group_entry_attribute, - .add_next_hop_to_group = sai_add_next_hop_to_group, - .remove_next_hop_from_group = sai_remove_next_hop_from_group -}; + .create_next_hop_group = sai_create_next_hop_group_entry, + .remove_next_hop_group = sai_remove_next_hop_group_entry, + .set_next_hop_group_attribute = sai_set_next_hop_group_entry_attribute, + .get_next_hop_group_attribute = sai_get_next_hop_group_entry_attribute, + .add_next_hop_to_group = sai_add_next_hop_to_group, + .remove_next_hop_from_group = sai_remove_next_hop_from_group}; sai_status_t sai_next_hop_group_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing nexthop group"); - sai_api_service->nhop_group_api = nhop_group_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing nexthop group"); + sai_api_service->nhop_group_api = nhop_group_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiobject.c b/switchsai/src/saiobject.c new file mode 100644 index 0000000..179955c --- /dev/null +++ b/switchsai/src/saiobject.c @@ -0,0 +1,42 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include + +sai_status_t sai_get_maximum_attribute_count(_In_ sai_object_type_t object_type, + _Inout_ uint32_t *count) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_get_object_count(_In_ sai_object_type_t object_type, + _Inout_ uint32_t *count) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_get_object_key(_In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _Inout_ sai_object_key_t *object_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_bulk_get_attribute(_In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ sai_object_key_t *object_key, + _Inout_ uint32_t *attr_count, + _Inout_ sai_attribute_t **attrs, + _Inout_ sai_status_t *object_statuses) { + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saipolicer.c b/switchsai/src/saipolicer.c index 9003018..ebe9ebd 100644 --- a/switchsai/src/saipolicer.c +++ b/switchsai/src/saipolicer.c @@ -20,94 +20,90 @@ limitations under the License. static sai_api_t api_id = SAI_API_POLICER; -static switch_meter_mode_t -sai_meter_mode_to_switch_meter_mode( - _In_ sai_policer_mode_t policer_mode) { - switch (policer_mode) { - case SAI_POLICER_MODE_Tr_TCM: - return SWITCH_METER_MODE_TWO_RATE_THREE_COLOR; - case SAI_POLICER_MODE_STORM_CONTROL: - return SWITCH_METER_MODE_STORM_CONTROL; - case SAI_POLICER_MODE_Sr_TCM: - default: - return SWITCH_METER_MODE_NONE; - } +static switch_meter_mode_t sai_meter_mode_to_switch_meter_mode( + _In_ sai_policer_mode_t policer_mode) { + switch (policer_mode) { + case SAI_POLICER_MODE_Tr_TCM: + return SWITCH_METER_MODE_TWO_RATE_THREE_COLOR; + case SAI_POLICER_MODE_STORM_CONTROL: + return SWITCH_METER_MODE_STORM_CONTROL; + case SAI_POLICER_MODE_Sr_TCM: + default: + return SWITCH_METER_MODE_NONE; + } } -static switch_meter_color_source_t -sai_color_source_to_switch_color_source( - _In_ sai_policer_color_source_t color_source) { - switch (color_source) { - case SAI_POLICER_COLOR_SOURCE_BLIND: - return SWITCH_METER_COLOR_SOURCE_BLIND; - case SAI_POLICER_COLOR_SOURCE_AWARE: - return SWITCH_METER_COLOR_SOURCE_AWARE; - default: - return SWITCH_METER_COLOR_SOURCE_NONE; - } +static switch_meter_color_source_t sai_color_source_to_switch_color_source( + _In_ sai_policer_color_source_t color_source) { + switch (color_source) { + case SAI_POLICER_COLOR_SOURCE_BLIND: + return SWITCH_METER_COLOR_SOURCE_BLIND; + case SAI_POLICER_COLOR_SOURCE_AWARE: + return SWITCH_METER_COLOR_SOURCE_AWARE; + default: + return SWITCH_METER_COLOR_SOURCE_NONE; + } } -static switch_meter_type_t -sai_meter_type_to_switch_meter_type( - _In_ sai_meter_type_t meter_type) { - switch (meter_type) { - case SAI_METER_TYPE_PACKETS: - return SWITCH_METER_TYPE_PACKETS; - case SAI_METER_TYPE_BYTES: - return SWITCH_METER_TYPE_BYTES; - default: - return SWITCH_METER_TYPE_NONE; - } +static switch_meter_type_t sai_meter_type_to_switch_meter_type( + _In_ sai_meter_type_t meter_type) { + switch (meter_type) { + case SAI_METER_TYPE_PACKETS: + return SWITCH_METER_TYPE_PACKETS; + case SAI_METER_TYPE_BYTES: + return SWITCH_METER_TYPE_BYTES; + default: + return SWITCH_METER_TYPE_NONE; + } } -sai_status_t sai_policer_attr_parse( - _In_ const int attr_count, - _In_ const sai_attribute_t *attr_list, - _Out_ switch_api_meter_t *api_meter_info) { - int index = 0; - const sai_attribute_t *attribute = NULL; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_POLICER_ATTR_METER_TYPE: - api_meter_info->meter_type = - 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.s32); - break; - case SAI_POLICER_ATTR_COLOR_SOURCE: - api_meter_info->color_source = - sai_color_source_to_switch_color_source(attribute->value.s32); - break; - case SAI_POLICER_ATTR_CBS: - api_meter_info->cbs = attribute->value.u64; - break; - case SAI_POLICER_ATTR_CIR: - api_meter_info->cir = attribute->value.u64; - break; - case SAI_POLICER_ATTR_PBS: - api_meter_info->pbs = attribute->value.u64; - break; - case SAI_POLICER_ATTR_PIR: - api_meter_info->pir = attribute->value.u64; - 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.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.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.s32); - break; - } +sai_status_t sai_policer_attr_parse(_In_ const int attr_count, + _In_ const sai_attribute_t *attr_list, + _Out_ switch_api_meter_t *api_meter_info) { + int index = 0; + const sai_attribute_t *attribute = NULL; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_POLICER_ATTR_METER_TYPE: + api_meter_info->meter_type = + 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.s32); + break; + case SAI_POLICER_ATTR_COLOR_SOURCE: + api_meter_info->color_source = + sai_color_source_to_switch_color_source(attribute->value.s32); + break; + case SAI_POLICER_ATTR_CBS: + api_meter_info->cbs = attribute->value.u64; + break; + case SAI_POLICER_ATTR_CIR: + api_meter_info->cir = attribute->value.u64; + break; + case SAI_POLICER_ATTR_PBS: + api_meter_info->pbs = attribute->value.u64; + break; + case SAI_POLICER_ATTR_PIR: + api_meter_info->pir = attribute->value.u64; + break; + case SAI_POLICER_ATTR_GREEN_PACKET_ACTION: + api_meter_info->action[SWITCH_COLOR_GREEN] = + sai_packet_action_to_switch_packet_action(attribute->value.s32); + break; + case SAI_POLICER_ATTR_YELLOW_PACKET_ACTION: + api_meter_info->action[SWITCH_COLOR_YELLOW] = + sai_packet_action_to_switch_packet_action(attribute->value.s32); + break; + case SAI_POLICER_ATTR_RED_PACKET_ACTION: + api_meter_info->action[SWITCH_COLOR_RED] = + sai_packet_action_to_switch_packet_action(attribute->value.s32); + break; } - return SAI_STATUS_SUCCESS; + } + return SAI_STATUS_SUCCESS; } /** @@ -120,38 +116,33 @@ sai_status_t sai_policer_attr_parse( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_policer( - _Out_ sai_object_id_t *policer_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { +sai_status_t sai_create_policer(_Out_ sai_object_id_t *policer_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_api_meter_t api_meter_info; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_api_meter_t api_meter_info; + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + memset(&api_meter_info, 0, sizeof(switch_api_meter_t)); + sai_policer_attr_parse(attr_count, attr_list, &api_meter_info); + *policer_id = switch_api_meter_create(device, &api_meter_info); + status = (*policer_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; - memset(&api_meter_info, 0, sizeof(switch_api_meter_t)); - sai_policer_attr_parse(attr_count, attr_list, &api_meter_info); - *policer_id = switch_api_meter_create(device, &api_meter_info); - status = (*policer_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create policer: %s", sai_status_to_string(status)); + } - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create policer: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -162,27 +153,25 @@ sai_status_t sai_create_policer( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_policer( - _In_ sai_object_id_t policer_id) { - - SAI_LOG_ENTER(); +sai_status_t sai_remove_policer(_In_ sai_object_id_t policer_id) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); + SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); - switch_status = switch_api_meter_delete(device, policer_id); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to delete policer %lx: %s", - policer_id, - sai_status_to_string(status)); - } + switch_status = switch_api_meter_delete(device, policer_id); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to delete policer %lx: %s", + policer_id, + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -194,25 +183,22 @@ sai_status_t sai_remove_policer( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_policer_attribute( - _In_ sai_object_id_t policer_id, - _In_ const sai_attribute_t *attr) { +sai_status_t sai_set_policer_attribute(_In_ sai_object_id_t policer_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); + SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); - SAI_LOG_EXIT(); - return (sai_status_t) status; + SAI_LOG_EXIT(); + return (sai_status_t)status; } /** @@ -225,159 +211,149 @@ sai_status_t sai_set_policer_attribute( * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_policer_attribute( - _In_ sai_object_id_t policer_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); +sai_status_t sai_get_policer_attribute(_In_ sai_object_id_t policer_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); + SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } -static sai_status_t -switch_meter_counters_to_sai_meter_counters( - _In_ uint32_t number_of_counters, - _In_ const sai_policer_stat_counter_t *counter_ids, - _In_ switch_counter_t *switch_counters, - _Out_ uint64_t *counters) { - uint32_t index = 0; - for (index = 0; index < number_of_counters; index++) { - switch (counter_ids[index]) { - case SAI_POLICER_STAT_PACKETS: - counters[index] = - switch_counters[SWITCH_METER_STATS_GREEEN].num_packets + - switch_counters[SWITCH_METER_STATS_YELLOW].num_packets + - switch_counters[SWITCH_METER_STATS_RED].num_packets; - break; - case SAI_POLICER_STAT_ATTR_BYTES: - counters[index] = - switch_counters[SWITCH_METER_STATS_GREEEN].num_bytes + - switch_counters[SWITCH_METER_STATS_YELLOW].num_bytes + - switch_counters[SWITCH_METER_STATS_RED].num_bytes; - break; - case SAI_POLICER_STAT_GREEN_PACKETS: - counters[index] = - switch_counters[SWITCH_METER_STATS_GREEEN].num_packets; - break; - case SAI_POLICER_STAT_GREEN_BYTES: - counters[index] = - switch_counters[SWITCH_METER_STATS_GREEEN].num_bytes; - break; - case SAI_POLICER_STAT_YELLOW_PACKETS: - counters[index] = - switch_counters[SWITCH_METER_STATS_YELLOW].num_packets; - break; - case SAI_POLICER_STAT_YELLOW_BYTES: - counters[index] = - switch_counters[SWITCH_METER_STATS_YELLOW].num_bytes; - break; - case SAI_POLICER_STAT_RED_PACKETS: - counters[index] = - switch_counters[SWITCH_METER_STATS_RED].num_packets; - break; - case SAI_POLICER_STAT_RED_BYTES: - counters[index] = - switch_counters[SWITCH_METER_STATS_RED].num_bytes; - break; - default: - break; - } +static sai_status_t switch_meter_counters_to_sai_meter_counters( + _In_ uint32_t number_of_counters, + _In_ const sai_policer_stat_counter_t *counter_ids, + _In_ switch_counter_t *switch_counters, + _Out_ uint64_t *counters) { + uint32_t index = 0; + for (index = 0; index < number_of_counters; index++) { + switch (counter_ids[index]) { + case SAI_POLICER_STAT_PACKETS: + counters[index] = + switch_counters[SWITCH_METER_STATS_GREEEN].num_packets + + switch_counters[SWITCH_METER_STATS_YELLOW].num_packets + + switch_counters[SWITCH_METER_STATS_RED].num_packets; + break; + case SAI_POLICER_STAT_ATTR_BYTES: + counters[index] = switch_counters[SWITCH_METER_STATS_GREEEN].num_bytes + + switch_counters[SWITCH_METER_STATS_YELLOW].num_bytes + + switch_counters[SWITCH_METER_STATS_RED].num_bytes; + break; + case SAI_POLICER_STAT_GREEN_PACKETS: + counters[index] = + switch_counters[SWITCH_METER_STATS_GREEEN].num_packets; + break; + case SAI_POLICER_STAT_GREEN_BYTES: + counters[index] = switch_counters[SWITCH_METER_STATS_GREEEN].num_bytes; + break; + case SAI_POLICER_STAT_YELLOW_PACKETS: + counters[index] = + switch_counters[SWITCH_METER_STATS_YELLOW].num_packets; + break; + case SAI_POLICER_STAT_YELLOW_BYTES: + counters[index] = switch_counters[SWITCH_METER_STATS_YELLOW].num_bytes; + break; + case SAI_POLICER_STAT_RED_PACKETS: + counters[index] = switch_counters[SWITCH_METER_STATS_RED].num_packets; + break; + case SAI_POLICER_STAT_RED_BYTES: + counters[index] = switch_counters[SWITCH_METER_STATS_RED].num_bytes; + break; + default: + break; } - return SAI_STATUS_SUCCESS; + } + return SAI_STATUS_SUCCESS; } sai_status_t sai_get_policer_statistics( _In_ sai_object_id_t policer_id, _In_ const sai_policer_stat_counter_t *counter_ids, _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) -{ - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_counter_t *switch_counters = NULL; - switch_meter_stats_t *meter_stat_ids = NULL; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - uint32_t index = 0; - - switch_counters = SAI_MALLOC(sizeof(switch_counter_t) * SWITCH_METER_STATS_MAX); - if (!switch_counters) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to get meter stats %lx: %s", - policer_id, sai_status_to_string(status)); - return status; - } - - meter_stat_ids = SAI_MALLOC(sizeof(switch_meter_stats_t) * SWITCH_METER_STATS_MAX); - if (!meter_stat_ids) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to get meter stats %lx: %s", - policer_id, sai_status_to_string(status)); - SAI_FREE(switch_counters); - return status; - } - - for (index = 0; index < SWITCH_METER_STATS_MAX; index++) { - meter_stat_ids[index] = index; - } - - switch_status = switch_api_meter_stats_get( - device, - policer_id, - SWITCH_METER_STATS_MAX, - meter_stat_ids, - switch_counters); - status = sai_switch_status_to_sai_status(switch_status); - - if (status != SWITCH_STATUS_SUCCESS) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to get meter stats %lx: %s", - policer_id, sai_status_to_string(status)); - SAI_FREE(meter_stat_ids); - SAI_FREE(switch_counters); - return status; - } - - switch_meter_counters_to_sai_meter_counters( - number_of_counters, - counter_ids, - switch_counters, - counters); - + _Out_ uint64_t *counters) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_counter_t *switch_counters = NULL; + switch_meter_stats_t *meter_stat_ids = NULL; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + uint32_t index = 0; + + switch_counters = + SAI_MALLOC(sizeof(switch_counter_t) * SWITCH_METER_STATS_MAX); + if (!switch_counters) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to get meter stats %lx: %s", + policer_id, + sai_status_to_string(status)); + return status; + } + + meter_stat_ids = + SAI_MALLOC(sizeof(switch_meter_stats_t) * SWITCH_METER_STATS_MAX); + if (!meter_stat_ids) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to get meter stats %lx: %s", + policer_id, + sai_status_to_string(status)); + SAI_FREE(switch_counters); + return status; + } + + for (index = 0; index < SWITCH_METER_STATS_MAX; index++) { + meter_stat_ids[index] = index; + } + + switch_status = switch_api_meter_stats_get(device, + policer_id, + SWITCH_METER_STATS_MAX, + meter_stat_ids, + switch_counters); + status = sai_switch_status_to_sai_status(switch_status); + + if (status != SWITCH_STATUS_SUCCESS) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to get meter stats %lx: %s", + policer_id, + sai_status_to_string(status)); SAI_FREE(meter_stat_ids); SAI_FREE(switch_counters); + return status; + } + + switch_meter_counters_to_sai_meter_counters( + number_of_counters, counter_ids, switch_counters, counters); + + SAI_FREE(meter_stat_ids); + SAI_FREE(switch_counters); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Policer methods table retrieved with sai_api_query() */ sai_policer_api_t policer_api = { - .create_policer = sai_create_policer, - .remove_policer = sai_remove_policer, - .set_policer_attribute = sai_set_policer_attribute, - .get_policer_attribute = sai_get_policer_attribute, - .get_policer_statistics = sai_get_policer_statistics -}; + .create_policer = sai_create_policer, + .remove_policer = sai_remove_policer, + .set_policer_attribute = sai_set_policer_attribute, + .get_policer_attribute = sai_get_policer_attribute, + .get_policer_statistics = sai_get_policer_statistics}; sai_status_t sai_policer_initialize(sai_api_service_t *sai_api_service) { - sai_api_service->policer_api = policer_api; - return SAI_STATUS_SUCCESS; + sai_api_service->policer_api = policer_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiport.c b/switchsai/src/saiport.c index 9502d73..242fdea 100644 --- a/switchsai/src/saiport.c +++ b/switchsai/src/saiport.c @@ -17,6 +17,7 @@ limitations under the License. #include #include "saiinternal.h" #include +#include static sai_api_t api_id = SAI_API_PORT; @@ -32,42 +33,122 @@ static sai_api_t api_id = SAI_API_PORT; * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_port_attribute( - _In_ sai_object_id_t port_id, - _In_ const sai_attribute_t *attr) { +sai_status_t sai_set_port_attribute(_In_ sai_object_id_t port_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + 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_port_speed_t port_speed; + bool trust = FALSE; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_handle_t vlan_handle = SWITCH_API_INVALID_HANDLE; + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); + switch (attr->id) { + case SAI_PORT_ATTR_PORT_VLAN_ID: + switch_status = switch_api_vlan_id_to_handle_get( + (switch_vlan_t)attr->value.u16, &vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to get vlan %d: %s", + sai_status_to_string(status)); return status; - } + } + /* TBD: Default BD */ + break; - switch (attr->id) { - case SAI_PORT_ATTR_PORT_VLAN_ID: - switch_status = switch_api_vlan_id_to_handle_get((switch_vlan_t) attr->value.u16, &vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to get vlan %d: %s", - sai_status_to_string(status)); - return status; - } - /* TBD: Default BD */ - - break; - default: - break; - } + case SAI_PORT_ATTR_QOS_DEFAULT_TC: + switch_status = + switch_api_port_tc_default_set(device, port_id, attr->value.u8); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set default tc for port %d: %s", + sai_status_to_string(status)); + return status; + } + break; + case SAI_PORT_ATTR_GLOBAL_FLOW_CONTROL: + // need for disabling ports on shutdown + break; + case SAI_PORT_ATTR_INGRESS_FILTERING: + // need to enable ingress filtering + break; + case SAI_PORT_ATTR_SPEED: + if ((status = sai_port_speed_to_switch_port_speed( + attr->value.u32, &port_speed)) != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("bad port speed for port %d speed: %s", + (port_id & 0xFFFF), + sai_status_to_string(status)); + return status; + } + switch_status = + switch_api_port_speed_set(device, + (switch_port_t)(port_id & 0xFFFF), + (switch_port_speed_t)attr->value.u8); + if ((status = sai_switch_status_to_sai_status(switch_status)) != + SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set port %d speed: %s", + (port_id & 0xFFFF), + sai_status_to_string(status)); + return status; + } + case SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP: + case SAI_PORT_ATTR_QOS_DSCP_TO_COLOR_MAP: + trust = attr->value.oid != 0 ? TRUE : FALSE; + switch_status = switch_api_port_trust_dscp_set(device, port_id, trust); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set dscp trust for port %d: %s", + sai_status_to_string(status)); + return status; + } + switch_status = switch_api_port_qos_group_ingress_set( + device, port_id, attr->value.oid); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set ingress qos handle for port %d: %s", + sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + break; - return (sai_status_t) status; + case SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP: + case SAI_PORT_ATTR_QOS_TC_TO_PRIORITY_GROUP_MAP: + switch_status = + switch_api_port_qos_group_tc_set(device, port_id, attr->value.oid); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set ingress tc handle for port %d: %s", + sai_status_to_string(status)); + return status; + } + break; + + case SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP: + case SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP: + switch_status = switch_api_port_qos_group_egress_set( + device, port_id, attr->value.oid); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set egress qos handle for port %d: %s", + sai_status_to_string(status)); + return status; + } + break; + + default: + break; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -83,25 +164,91 @@ sai_status_t sai_set_port_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_port_attribute( - _In_ sai_object_id_t port_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { +sai_status_t sai_get_port_attribute(_In_ sai_object_id_t port_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + unsigned int i = 0; + sai_attribute_t *attr = attr_list; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_ENTER(); + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; + for (i = 0, attr = attr_list; i < attr_count; i++, attr++) { + switch (attr->id) { + case SAI_PORT_ATTR_TYPE: { + switch_api_capability_t api_switch_info; + switch_api_capability_get(device, &api_switch_info); + if (api_switch_info.port_list[64] == port_id) + attr->value.s32 = SAI_PORT_TYPE_CPU; + else + attr->value.s32 = SAI_PORT_TYPE_LOGICAL; + status = sai_switch_status_to_sai_status(switch_status); + } break; + + case SAI_PORT_ATTR_HW_LANE_LIST: + attr->value.u32list.count = 1; + attr->value.u32list.list[0] = port_id & 0xFFFF; + status = sai_switch_status_to_sai_status(switch_status); + break; + + case SAI_PORT_ATTR_SUPPORTED_BREAKOUT_MODE: + attr->value.s32list.count = 1; + attr->value.s32list.list[0] = SAI_PORT_BREAKOUT_MODE_1_LANE; + status = sai_switch_status_to_sai_status(switch_status); + break; + + case SAI_PORT_ATTR_CURRENT_BREAKOUT_MODE: + attr->value.s32 = SAI_PORT_BREAKOUT_MODE_1_LANE; + status = sai_switch_status_to_sai_status(switch_status); + break; + case SAI_PORT_ATTR_OPER_STATUS: + switch_status = switch_api_port_state_get( + device, (switch_port_t)(port_id & 0xFFFF), &(attr->value.booldata)); + if ((status = sai_switch_status_to_sai_status(switch_status)) != + SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to get port %d oper state: %s", + (port_id & 0xFFFF), + sai_status_to_string(status)); + return status; + } + status = sai_switch_port_enabled_to_sai_oper_status(attr); + attr->value.s32 = SAI_PORT_OPER_STATUS_UP; + status = sai_switch_status_to_sai_status(switch_status); + break; + case SAI_PORT_ATTR_SPEED: + switch_status = + switch_api_port_speed_get(device, + (switch_port_t)(port_id & 0xFFFF), + (switch_port_speed_t *)&attr->value.u8); + if ((status = sai_switch_status_to_sai_status(switch_status)) != + SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to get port %d speed: %s", + (port_id & 0xFFFF), + sai_status_to_string(status)); + return status; + } + attr->value.u32 = 40000; // SAI_PORT_SPEED_FORTY_GIG; + break; + case SAI_PORT_ATTR_SUPPORTED_SPEED: + // TODO: implement this, should return list of supported port speeds + attr->value.u32list.count = 0; + break; + default: + status = SAI_STATUS_NOT_SUPPORTED; + break; } + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -117,33 +264,29 @@ sai_status_t sai_get_port_attribute( * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error -*/ -sai_status_t sai_get_port_stats( - _In_ sai_object_id_t port_id, - _In_ const sai_port_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) { - - SAI_LOG_ENTER(); +*/ +sai_status_t sai_get_port_stats(_In_ sai_object_id_t port_id, + _In_ const sai_port_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t *counters) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Port methods table retrieved with sai_api_query() */ -sai_port_api_t port_api = { - .set_port_attribute = sai_set_port_attribute, - .get_port_attribute = sai_get_port_attribute, - .get_port_stats = sai_get_port_stats -}; +sai_port_api_t port_api = {.set_port_attribute = sai_set_port_attribute, + .get_port_attribute = sai_get_port_attribute, + .get_port_stats = sai_get_port_stats}; sai_status_t sai_port_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing port"); - sai_api_service->port_api = port_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing port"); + sai_api_service->port_api = port_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiqosmaps.c b/switchsai/src/saiqosmaps.c new file mode 100644 index 0000000..6529fd4 --- /dev/null +++ b/switchsai/src/saiqosmaps.c @@ -0,0 +1,334 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "saiinternal.h" +#include + +static sai_api_t api_id = SAI_API_QOS_MAPS; + +static sai_status_t sai_qos_map_type_to_switch_qos_map_type( + sai_qos_map_type_t qos_map_type, + switch_direction_t *direction, + switch_qos_map_ingress_t *ingress_qos_map_type, + switch_qos_map_egress_t *egress_qos_map_type) { + sai_status_t status = SAI_STATUS_SUCCESS; + + *ingress_qos_map_type = SWITCH_QOS_MAP_INGRESS_NONE; + *egress_qos_map_type = SWITCH_QOS_MAP_EGRESS_NONE; + + switch (qos_map_type) { + case SAI_QOS_MAP_DOT1P_TO_TC: + *ingress_qos_map_type = SWITCH_QOS_MAP_INGRESS_PCP_TO_TC; + *direction = SWITCH_API_DIRECTION_INGRESS; + break; + case SAI_QOS_MAP_DOT1P_TO_COLOR: + *ingress_qos_map_type = SWITCH_QOS_MAP_INGRESS_PCP_TO_COLOR; + *direction = SWITCH_API_DIRECTION_INGRESS; + break; + case SAI_QOS_MAP_DSCP_TO_TC: + *ingress_qos_map_type = SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC; + *direction = SWITCH_API_DIRECTION_INGRESS; + break; + case SAI_QOS_MAP_DSCP_TO_COLOR: + *ingress_qos_map_type = SWITCH_QOS_MAP_INGRESS_DSCP_TO_COLOR; + *direction = SWITCH_API_DIRECTION_INGRESS; + break; + case SAI_QOS_MAP_TC_TO_QUEUE: + *ingress_qos_map_type = SWITCH_QOS_MAP_INGRESS_TC_TO_QUEUE; + *direction = SWITCH_API_DIRECTION_INGRESS; + break; + case SAI_QOS_MAP_TC_AND_COLOR_TO_DSCP: + *egress_qos_map_type = SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_DSCP; + *direction = SWITCH_API_DIRECTION_EGRESS; + break; + case SAI_QOS_MAP_TC_AND_COLOR_TO_DOT1P: + *egress_qos_map_type = SWITCH_QOS_MAP_EGRESS_TC_AND_COLOR_TO_PCP; + *direction = SWITCH_API_DIRECTION_EGRESS; + break; + case SAI_QOS_MAP_TC_TO_PRIORITY_GROUP: + case SAI_QOS_MAP_PFC_PRIORITY_TO_QUEUE: + default: + status = SAI_STATUS_NOT_SUPPORTED; + break; + } + + return status; +} + +static switch_color_t sai_color_to_switch_color(sai_packet_color_t color) { + switch (color) { + case SAI_PACKET_COLOR_GREEN: + return SWITCH_COLOR_GREEN; + case SAI_PACKET_COLOR_YELLOW: + return SWITCH_COLOR_YELLOW; + case SAI_PACKET_COLOR_RED: + return SWITCH_COLOR_RED; + default: + return SWITCH_COLOR_GREEN; + } +} + +static void sai_qos_map_to_switch_qos_map(sai_qos_map_type_t qos_map_type, + sai_qos_map_t *qos_map, + switch_qos_map_t *switch_qos_map) { + switch (qos_map_type) { + case SAI_QOS_MAP_DOT1P_TO_TC: + switch_qos_map->pcp = qos_map->key.dot1p; + switch_qos_map->tc = qos_map->value.tc; + break; + case SAI_QOS_MAP_DOT1P_TO_COLOR: + switch_qos_map->pcp = qos_map->key.dot1p; + switch_qos_map->color = sai_color_to_switch_color(qos_map->value.color); + break; + case SAI_QOS_MAP_DSCP_TO_TC: + switch_qos_map->dscp = qos_map->key.dscp; + switch_qos_map->tc = qos_map->value.tc; + break; + case SAI_QOS_MAP_DSCP_TO_COLOR: + switch_qos_map->dscp = qos_map->key.dscp; + switch_qos_map->color = sai_color_to_switch_color(qos_map->value.color); + break; + case SAI_QOS_MAP_TC_TO_QUEUE: + switch_qos_map->tc = qos_map->key.tc; + switch_qos_map->qid = qos_map->value.queue_index; + break; + case SAI_QOS_MAP_TC_AND_COLOR_TO_DSCP: + switch_qos_map->tc = qos_map->key.tc; + switch_qos_map->color = sai_color_to_switch_color(qos_map->key.color); + switch_qos_map->dscp = qos_map->value.dscp; + break; + case SAI_QOS_MAP_TC_AND_COLOR_TO_DOT1P: + switch_qos_map->tc = qos_map->key.tc; + switch_qos_map->color = sai_color_to_switch_color(qos_map->key.color); + switch_qos_map->pcp = qos_map->value.dot1p; + break; + default: + break; + } +} + +static sai_status_t sai_qos_map_attribute_parse( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + _Out_ switch_direction_t *direction, + _Out_ switch_qos_map_ingress_t *ingress_qos_map_type, + _Out_ switch_qos_map_egress_t *egress_qos_map_type, + _Out_ uint32_t *num_entries, + _Out_ switch_qos_map_t **switch_qos_map_list) { + const sai_attribute_t *attribute; + uint32_t i = 0, j = 0; + sai_status_t status = SAI_STATUS_SUCCESS; + sai_qos_map_t *qos_map = NULL; + switch_qos_map_t *switch_qos_map = NULL; + sai_qos_map_type_t qos_map_type = 0; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_QOS_MAP_ATTR_TYPE: + status = sai_qos_map_type_to_switch_qos_map_type(attribute->value.u32, + direction, + ingress_qos_map_type, + egress_qos_map_type); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("qos map attribute parse failed %s", + sai_status_to_string(status)); + return status; + } + qos_map_type = attribute->value.u32; + break; + case SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST: + *num_entries = attribute->value.qosmap.count; + *switch_qos_map_list = + SAI_MALLOC(sizeof(switch_qos_map_t) * (*num_entries)); + if (!(*switch_qos_map_list)) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("memory allocation failed for qos map %s", + sai_status_to_string(status)); + return status; + } + + memset(*switch_qos_map_list, + 0x0, + sizeof(switch_qos_map_t) * (*num_entries)); + for (j = 0; j < (*num_entries); j++) { + qos_map = &attribute->value.qosmap.list[j]; + switch_qos_map = &(*switch_qos_map_list)[j]; + sai_qos_map_to_switch_qos_map(qos_map_type, qos_map, switch_qos_map); + } + break; + default: + break; + } + } + + return status; +} + +/** + * @brief Create Qos Map + * + * @param[out] qos_map_id Qos Map Id + * @param[in] attr_count number of attributes + * @param[in] attr_list array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_create_qos_map(_Out_ sai_object_id_t *qos_map_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + uint32_t num_entries = 0; + switch_qos_map_t *switch_qos_map_list = NULL; + switch_direction_t direction = 0; + switch_qos_map_ingress_t ingress_qos_map_type = 0; + switch_qos_map_egress_t egress_qos_map_type = 0; + + status = sai_qos_map_attribute_parse(attr_count, + attr_list, + &direction, + &ingress_qos_map_type, + &egress_qos_map_type, + &num_entries, + &switch_qos_map_list); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("qos map attribute parse failed %s", + sai_status_to_string(status)); + return status; + } + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + *qos_map_id = switch_api_qos_map_ingress_create( + device, ingress_qos_map_type, num_entries, switch_qos_map_list); + } else { + *qos_map_id = switch_api_qos_map_egress_create( + device, egress_qos_map_type, num_entries, switch_qos_map_list); + } + + status = (*qos_map_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create qos map group: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Remove Qos Map + * + * @param[in] qos_map_id Qos Map id to be removed. + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_qos_map(_In_ sai_object_id_t qos_map_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(qos_map_id) == SAI_OBJECT_TYPE_QOS_MAPS); + + status = switch_api_qos_map_ingress_delete(device, qos_map_id); + if (status != SWITCH_STATUS_SUCCESS && + status != SWITCH_STATUS_INVALID_HANDLE) { + SAI_LOG_ERROR("failed to remove ingress qos map %s", + sai_status_to_string(status)); + return status; + } + + status = switch_api_qos_map_egress_delete(device, qos_map_id); + if (status != SWITCH_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove egress qos map %s", + sai_status_to_string(status)); + return status; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Set attributes for qos map + * + * @param[in] qos_map_id Qos Map Id + * @param[in] attr attribute to set + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ + +sai_status_t sai_set_qos_map_attribute(_In_ sai_object_id_t qos_map_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(qos_map_id) == SAI_OBJECT_TYPE_QOS_MAPS); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Get attrbutes of qos map + * + * @param[in] qos_map_id map id + * @param[in] attr_count number of attributes + * @param[inout] attr_list array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ + +sai_status_t sai_get_qos_map_attribute(_In_ sai_object_id_t qos_map_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(qos_map_id) == SAI_OBJECT_TYPE_QOS_MAPS); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/* +* Qos maps methods table retrieved with sai_api_query() +*/ +sai_qos_map_api_t qos_api = { + .create_qos_map = sai_create_qos_map, + .remove_qos_map = sai_remove_qos_map, + .set_qos_map_attribute = sai_set_qos_map_attribute, + .get_qos_map_attribute = sai_get_qos_map_attribute}; + +sai_status_t sai_qos_map_initialize(sai_api_service_t *sai_api_service) { + SAI_LOG_DEBUG("Initializing qos map"); + sai_api_service->qos_api = qos_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saiqueue.c b/switchsai/src/saiqueue.c new file mode 100644 index 0000000..9b00275 --- /dev/null +++ b/switchsai/src/saiqueue.c @@ -0,0 +1,147 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "saiinternal.h" +#include + +static sai_api_t api_id = SAI_API_QUEUE; + +/** + * @brief Set attribute to Queue + * @param[in] queue_id queue id to set the attribute + * @param[in] attr attribute to set + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_queue_attribute(_In_ sai_object_id_t queue_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(queue_id) == SAI_OBJECT_TYPE_QUEUE); + + switch (attr->id) { + case SAI_QUEUE_ATTR_BUFFER_PROFILE_ID: + switch_status = switch_api_queue_buffer_profile_set( + device, queue_id, attr->value.oid); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set buffer profile for queue:%s", + sai_status_to_string(status)); + } + break; + case SAI_QUEUE_ATTR_WRED_PROFILE_ID: + case SAI_QUEUE_ATTR_SCHEDULER_PROFILE_ID: + status = SWITCH_STATUS_NOT_SUPPORTED; + break; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Get attribute to Queue + * @param[in] queue_id queue id to set the attribute + * @param[in] attr_count number of attributes + * @param[inout] attr_list Array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_get_queue_attribute(_In_ sai_object_id_t queue_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(queue_id) == SAI_OBJECT_TYPE_QUEUE); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Get queue statistics counters. + * + * @param[in] queue_id Queue id + * @param[in] counter_ids specifies the array of counter ids + * @param[in] number_of_counters number of counters in the array + * @param[out] counters array of resulting counter values. + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_get_queue_stats( + _In_ sai_object_id_t queue_id, + _In_ const sai_queue_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t *counters) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(queue_id) == SAI_OBJECT_TYPE_QUEUE); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Clear queue statistics counters. + * + * @param[in] queue_id Queue id + * @param[in] counter_ids specifies the array of counter ids + * @param[in] number_of_counters number of counters in the array + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_clear_queue_stats( + _In_ sai_object_id_t queue_id, + _In_ const sai_queue_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(queue_id) == SAI_OBJECT_TYPE_QUEUE); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/* +* Queue methods table retrieved with sai_api_query() +*/ +sai_queue_api_t queue_api = {.set_queue_attribute = sai_set_queue_attribute, + .get_queue_attribute = sai_get_queue_attribute, + .get_queue_stats = sai_get_queue_stats}; + +sai_status_t sai_queue_initialize(sai_api_service_t *sai_api_service) { + SAI_LOG_DEBUG("Initializing queue map"); + sai_api_service->queue_api = queue_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/sairoute.c b/switchsai/src/sairoute.c index 34d7f1b..7015f36 100644 --- a/switchsai/src/sairoute.c +++ b/switchsai/src/sairoute.c @@ -22,57 +22,59 @@ limitations under the License. static sai_api_t api_id = SAI_API_ROUTE; static void sai_route_entry_to_string( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _Out_ char *entry_string) { - int count = 0; - int len = 0; - count = snprintf(entry_string, - SAI_MAX_ENTRY_STRING_LEN, - "route: vrf %lx", - unicast_route_entry->vr_id); - sai_ipprefix_to_string(unicast_route_entry->destination, - SAI_MAX_ENTRY_STRING_LEN - count, - entry_string + count, &len); - return; + _In_ const sai_unicast_route_entry_t *unicast_route_entry, + _Out_ char *entry_string) { + int count = 0; + int len = 0; + count = snprintf(entry_string, + SAI_MAX_ENTRY_STRING_LEN, + "route: vrf %" PRIx64 "", + unicast_route_entry->vr_id); + sai_ipprefix_to_string(unicast_route_entry->destination, + SAI_MAX_ENTRY_STRING_LEN - count, + entry_string + count, + &len); + return; } static void sai_route_entry_parse( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _Out_ switch_handle_t *vrf_handle, - _Out_ switch_ip_addr_t *ip_addr) { - const sai_ip_prefix_t *sai_ip_prefix; - - SAI_ASSERT(sai_object_type_query(unicast_route_entry->vr_id) == - SAI_OBJECT_TYPE_VIRTUAL_ROUTER); - *vrf_handle = (switch_handle_t) unicast_route_entry->vr_id; - - memset(ip_addr, 0, sizeof(switch_ip_addr_t)); - sai_ip_prefix = &unicast_route_entry->destination; - sai_ip_prefix_to_switch_ip_addr(sai_ip_prefix, ip_addr); + _In_ const sai_unicast_route_entry_t *unicast_route_entry, + _Out_ switch_handle_t *vrf_handle, + _Out_ switch_ip_addr_t *ip_addr) { + const sai_ip_prefix_t *sai_ip_prefix; + + SAI_ASSERT(sai_object_type_query(unicast_route_entry->vr_id) == + SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + *vrf_handle = (switch_handle_t)unicast_route_entry->vr_id; + + memset(ip_addr, 0, sizeof(switch_ip_addr_t)); + sai_ip_prefix = &unicast_route_entry->destination; + sai_ip_prefix_to_switch_ip_addr(sai_ip_prefix, ip_addr); } static void sai_route_entry_attribute_parse( - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list, - switch_handle_t *nhop_handle, - int *action, int *pri) { - const sai_attribute_t *attribute; - uint32_t index = 0; - - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_ROUTE_ATTR_NEXT_HOP_ID: - *nhop_handle = (switch_handle_t) attribute->value.oid; - break; - case SAI_ROUTE_ATTR_TRAP_PRIORITY: - *pri = attribute->value.u8; - break; - case SAI_ROUTE_ATTR_PACKET_ACTION: - *action = attribute->value.s32; - break; - } + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + switch_handle_t *nhop_handle, + int *action, + int *pri) { + const sai_attribute_t *attribute; + uint32_t index = 0; + + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_ROUTE_ATTR_NEXT_HOP_ID: + *nhop_handle = (switch_handle_t)attribute->value.oid; + break; + case SAI_ROUTE_ATTR_TRAP_PRIORITY: + *pri = attribute->value.u8; + break; + case SAI_ROUTE_ATTR_PACKET_ACTION: + *action = attribute->value.s32; + break; } + } } /* @@ -87,66 +89,71 @@ static void sai_route_entry_attribute_parse( * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error -* +* * Note: IP prefix/mask expected in Network Byte Order. -* +* */ sai_status_t sai_create_route_entry( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_ip_addr_t ip_addr; - switch_handle_t nhop_handle = 0; - switch_handle_t vrf_handle = 0; - char entry_string[SAI_MAX_ENTRY_STRING_LEN]; - int action=-1, pri=-1; - - if (!unicast_route_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null unicast entry: %s", - sai_status_to_string(status)); - return status; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - sai_route_entry_parse(unicast_route_entry, &vrf_handle, &ip_addr); - sai_route_entry_attribute_parse(attr_count, attr_list, &nhop_handle, &action, &pri); - - sai_route_entry_to_string(unicast_route_entry, entry_string); - - if(!nhop_handle && action != -1) { - switch(action) { - case SAI_PACKET_ACTION_DROP: - nhop_handle = switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_NULL_DROP); - break; - case SAI_PACKET_ACTION_FORWARD: - break; - case SAI_PACKET_ACTION_TRAP: - nhop_handle = switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); - break; - default: - break; - } - } - if (nhop_handle) { - switch_status = switch_api_l3_route_add(device, vrf_handle, &ip_addr, nhop_handle); - status = sai_switch_status_to_sai_status(switch_status); + _In_ const sai_unicast_route_entry_t *unicast_route_entry, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_ip_addr_t ip_addr; + switch_handle_t nhop_handle = 0; + switch_handle_t vrf_handle = 0; + char entry_string[SAI_MAX_ENTRY_STRING_LEN]; + int action = -1, pri = -1; + + if (!unicast_route_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null unicast entry: %s", sai_status_to_string(status)); + return status; + } + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + sai_route_entry_parse(unicast_route_entry, &vrf_handle, &ip_addr); + sai_route_entry_attribute_parse( + attr_count, attr_list, &nhop_handle, &action, &pri); + + if (sai_object_type_query(nhop_handle) == SAI_OBJECT_TYPE_ROUTER_INTERFACE) { + nhop_handle = 0; + action = SAI_PACKET_ACTION_TRAP; + } + + sai_route_entry_to_string(unicast_route_entry, entry_string); + + if (!nhop_handle && action != -1) { + switch (action) { + case SAI_PACKET_ACTION_DROP: + nhop_handle = + switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_NULL_DROP); + break; + case SAI_PACKET_ACTION_FORWARD: + break; + case SAI_PACKET_ACTION_TRAP: + nhop_handle = switch_api_cpu_nhop_get(SWITCH_HOSTIF_REASON_CODE_GLEAN); + break; + default: + break; } + } + if (nhop_handle) { + switch_status = + switch_api_l3_route_add(device, vrf_handle, &ip_addr, nhop_handle); + status = sai_switch_status_to_sai_status(switch_status); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -163,35 +170,34 @@ sai_status_t sai_create_route_entry( * Note: IP prefix/mask expected in Network Byte Order. */ sai_status_t sai_remove_route_entry( - _In_ const sai_unicast_route_entry_t* unicast_route_entry) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_ip_addr_t ip_addr; - switch_handle_t vrf_handle = 0; - switch_handle_t nhop_handle = 0; - - if (!unicast_route_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null unicast entry: %s", - sai_status_to_string(status)); - return status; - } - - sai_route_entry_parse(unicast_route_entry, &vrf_handle, &ip_addr); - switch_status = switch_api_l3_route_delete(device, vrf_handle, &ip_addr, nhop_handle); - status = sai_switch_status_to_sai_status(switch_status); - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove route entry: %s", - sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + _In_ const sai_unicast_route_entry_t *unicast_route_entry) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_ip_addr_t ip_addr; + switch_handle_t vrf_handle = 0; + switch_handle_t nhop_handle = 0; + + if (!unicast_route_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null unicast entry: %s", sai_status_to_string(status)); + return status; + } + + sai_route_entry_parse(unicast_route_entry, &vrf_handle, &ip_addr); + switch_status = + switch_api_l3_route_delete(device, vrf_handle, &ip_addr, nhop_handle); + status = sai_switch_status_to_sai_status(switch_status); + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove route entry: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -207,30 +213,27 @@ sai_status_t sai_remove_route_entry( * Failure status code on error */ sai_status_t sai_set_route_entry_attribute( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _In_ const sai_attribute_t *attr) { + _In_ const sai_unicast_route_entry_t *unicast_route_entry, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!unicast_route_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null unicast entry: %s", sai_status_to_string(status)); + return status; + } - if (!unicast_route_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null unicast entry: %s", - sai_status_to_string(status)); - return status; - } - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -247,45 +250,42 @@ sai_status_t sai_set_route_entry_attribute( * Failure status code on error */ sai_status_t sai_get_route_entry_attribute( - _In_ const sai_unicast_route_entry_t* unicast_route_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { + _In_ const sai_unicast_route_entry_t *unicast_route_entry, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!unicast_route_entry) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null unicast entry: %s", sai_status_to_string(status)); + return status; + } - if (!unicast_route_entry) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null unicast entry: %s", - sai_status_to_string(status)); - return status; - } - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Router entry methods table retrieved with sai_api_query() */ sai_route_api_t route_api = { - .create_route = sai_create_route_entry, - .remove_route = sai_remove_route_entry, - .set_route_attribute = sai_set_route_entry_attribute, - .get_route_attribute = sai_get_route_entry_attribute, + .create_route = sai_create_route_entry, + .remove_route = sai_remove_route_entry, + .set_route_attribute = sai_set_route_entry_attribute, + .get_route_attribute = sai_get_route_entry_attribute, }; sai_status_t sai_route_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing route"); - sai_api_service->route_api = route_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing route"); + sai_api_service->route_api = route_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/sairouter.c b/switchsai/src/sairouter.c index b517b33..7891072 100644 --- a/switchsai/src/sairouter.c +++ b/switchsai/src/sairouter.c @@ -20,75 +20,70 @@ limitations under the License. static sai_api_t api_id = SAI_API_VIRTUAL_ROUTER; -static void sai_vrf_entry_attribute_parse( - uint32_t attr_count, - const sai_attribute_t *attr_list) { - - const sai_attribute_t *attribute; - uint32_t i = 0; - - for (i = 0; i < attr_count; i++) { - attribute = &attr_list[i]; - switch (attribute->id) { - case SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE: - break; - case SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V6_STATE: - break; - case SAI_VIRTUAL_ROUTER_ATTR_SRC_MAC_ADDRESS: - break; - default: - break; - } +static void sai_vrf_entry_attribute_parse(uint32_t attr_count, + const sai_attribute_t *attr_list) { + const sai_attribute_t *attribute; + uint32_t i = 0; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V4_STATE: + break; + case SAI_VIRTUAL_ROUTER_ATTR_ADMIN_V6_STATE: + break; + case SAI_VIRTUAL_ROUTER_ATTR_SRC_MAC_ADDRESS: + break; + default: + break; } + } } /* * Routine Description: * Create virtual router -* +* * Arguments: * [out] vr_id - virtual router id * [in] attr_count - number of attributes * [in] attr_list - array of attributes -* +* * Return Values: * - SAI_STATUS_SUCCESS on success -* - SAI_STATUS_ADDR_NOT_FOUND if neither SAI_SWITCH_ATTR_SRC_MAC_ADDRESS nor +* - SAI_STATUS_ADDR_NOT_FOUND if neither SAI_SWITCH_ATTR_SRC_MAC_ADDRESS nor * SAI_VIRTUAL_ROUTER_ATTR_SRC_MAC_ADDRESS is set. */ sai_status_t sai_create_virtual_router_entry( - _Out_ sai_object_id_t *vr_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); + _Out_ sai_object_id_t *vr_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_vrf_id_t vrf_id = 1; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_vrf_id_t vrf_id = 1; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - sai_vrf_entry_attribute_parse(attr_count, attr_list); + sai_vrf_entry_attribute_parse(attr_count, attr_list); - *vr_id = (sai_object_id_t) switch_api_vrf_create(device, vrf_id); + *vr_id = (sai_object_id_t)switch_api_vrf_create(device, vrf_id); - status = (*vr_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; + status = (*vr_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create virtual router entry : %s", - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create virtual router entry : %s", + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -102,26 +97,25 @@ sai_status_t sai_create_virtual_router_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_virtual_router_entry( - _In_ sai_object_id_t vr_id) { +sai_status_t sai_remove_virtual_router_entry(_In_ sai_object_id_t vr_id) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); - SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + switch_status = switch_api_vrf_delete(device, vr_id); + status = sai_switch_status_to_sai_status(switch_status); - switch_status = switch_api_vrf_delete(device, vr_id); - status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove virtual router entry %lx : %s", + vr_id, + sai_status_to_string(status)); + } - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove virtual router entry %lx : %s", - vr_id, sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - return (sai_status_t) status; + SAI_LOG_EXIT(); + return (sai_status_t)status; } /* @@ -137,25 +131,22 @@ sai_status_t sai_remove_virtual_router_entry( * Failure status code on error */ sai_status_t sai_set_virtual_router_entry_attribute( - _In_ sai_object_id_t vr_id, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); + _In_ sai_object_id_t vr_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -172,40 +163,37 @@ sai_status_t sai_set_virtual_router_entry_attribute( * Failure status code on error */ sai_status_t sai_get_virtual_router_entry_attribute( - _In_ sai_object_id_t vr_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { + _In_ sai_object_id_t vr_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Virtual router methods table retrieved with sai_api_query() */ sai_virtual_router_api_t vr_api = { - .create_virtual_router = sai_create_virtual_router_entry, - .remove_virtual_router = sai_remove_virtual_router_entry, - .set_virtual_router_attribute = sai_set_virtual_router_entry_attribute, - .get_virtual_router_attribute = sai_get_virtual_router_entry_attribute -}; + .create_virtual_router = sai_create_virtual_router_entry, + .remove_virtual_router = sai_remove_virtual_router_entry, + .set_virtual_router_attribute = sai_set_virtual_router_entry_attribute, + .get_virtual_router_attribute = sai_get_virtual_router_entry_attribute}; sai_status_t sai_virtual_router_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing virtual router"); - sai_api_service->vr_api = vr_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing virtual router"); + sai_api_service->vr_api = vr_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/sairouterintf.c b/switchsai/src/sairouterintf.c index 4f7d364..f73c9f2 100644 --- a/switchsai/src/sairouterintf.c +++ b/switchsai/src/sairouterintf.c @@ -21,21 +21,20 @@ limitations under the License. static sai_api_t api_id = SAI_API_ROUTER_INTERFACE; -static switch_urpf_mode_t -sai_to_switch_urpf_mode(uint8_t sai_urpf_mode) { - switch_urpf_mode_t switch_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; - switch (sai_urpf_mode) { - case SAI_URPF_MODE_NONE: - switch_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; - break; - case SAI_URPF_MODE_STRICT: - switch_urpf_mode = SWITCH_API_RPF_CHECK_STRICT; - break; - case SAI_URPF_MODE_LOOSE: - switch_urpf_mode = SWITCH_API_RPF_CHECK_LOOSE; - break; - } - return switch_urpf_mode; +static switch_urpf_mode_t sai_to_switch_urpf_mode(uint8_t sai_urpf_mode) { + switch_urpf_mode_t switch_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; + switch (sai_urpf_mode) { + case SAI_URPF_MODE_NONE: + switch_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; + break; + case SAI_URPF_MODE_STRICT: + switch_urpf_mode = SWITCH_API_RPF_CHECK_STRICT; + break; + case SAI_URPF_MODE_LOOSE: + switch_urpf_mode = SWITCH_API_RPF_CHECK_LOOSE; + break; + } + return switch_urpf_mode; } /* @@ -52,95 +51,95 @@ sai_to_switch_urpf_mode(uint8_t sai_urpf_mode) { * Failure status code on error */ sai_status_t sai_create_router_interface( - _Out_ sai_object_id_t* rif_id, - _In_ uint32_t attr_count, - _In_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_api_interface_info_t intf_info; - const sai_attribute_t *attribute; - sai_router_interface_type_t sai_intf_type; - uint32_t index = 0; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - memset(&intf_info, 0, sizeof(switch_api_interface_info_t)); - intf_info.ipv4_unicast_enabled = true; - intf_info.ipv6_unicast_enabled = true; - intf_info.ipv4_multicast_enabled = false; - intf_info.ipv6_multicast_enabled = false; - intf_info.ipv4_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; - intf_info.ipv6_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; - for (index = 0; index < attr_count; index++) { - attribute = &attr_list[index]; - switch (attribute->id) { - case SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID: - SAI_ASSERT(sai_object_type_query(attribute->value.oid) == - SAI_OBJECT_TYPE_VIRTUAL_ROUTER); - intf_info.vrf_handle = (switch_handle_t) attribute->value.oid; - break; - case SAI_ROUTER_INTERFACE_ATTR_TYPE: - sai_intf_type = attribute->value.s32; - break; - case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: - SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_PORT); - intf_info.type = SWITCH_API_INTERFACE_L3; - intf_info.u.port_lag_handle = attribute->value.oid; - break; - case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: - SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_VLAN); - intf_info.type = SWITCH_API_INTERFACE_L3_VLAN; - intf_info.u.vlan_id = attribute->value.u16; - break; - case SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS: - intf_info.mac_valid = TRUE; - memcpy(&intf_info.mac, &attribute->value.mac, 6); - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: - intf_info.ipv4_unicast_enabled = attribute->value.booldata; - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: - intf_info.ipv6_unicast_enabled = attribute->value.booldata; - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE: - intf_info.ipv4_multicast_enabled = attribute->value.booldata; - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE: - intf_info.ipv6_multicast_enabled = attribute->value.booldata; - break; - case SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE: - intf_info.ipv4_urpf_mode = - 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.s32); - break; - default: - return SAI_STATUS_INVALID_PARAMETER; - } + _Out_ sai_object_id_t *rif_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_api_interface_info_t intf_info; + const sai_attribute_t *attribute; + sai_router_interface_type_t sai_intf_type = -1; + uint32_t index = 0; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + memset(&intf_info, 0, sizeof(switch_api_interface_info_t)); + intf_info.ipv4_unicast_enabled = true; + intf_info.ipv6_unicast_enabled = true; + intf_info.ipv4_multicast_enabled = false; + intf_info.ipv6_multicast_enabled = false; + intf_info.ipv4_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; + intf_info.ipv6_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID: + SAI_ASSERT(sai_object_type_query(attribute->value.oid) == + SAI_OBJECT_TYPE_VIRTUAL_ROUTER); + intf_info.vrf_handle = (switch_handle_t)attribute->value.oid; + break; + case SAI_ROUTER_INTERFACE_ATTR_TYPE: + sai_intf_type = attribute->value.s32; + break; + case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: + SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_PORT); + intf_info.type = SWITCH_API_INTERFACE_L3; + intf_info.u.port_lag_handle = attribute->value.oid; + break; + case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: + SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_VLAN); + intf_info.type = SWITCH_API_INTERFACE_L3_VLAN; + intf_info.u.vlan_id = attribute->value.u16; + break; + case SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS: + intf_info.mac_valid = TRUE; + memcpy(&intf_info.mac, &attribute->value.mac, 6); + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: + intf_info.ipv4_unicast_enabled = attribute->value.booldata; + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: + intf_info.ipv6_unicast_enabled = attribute->value.booldata; + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE: + intf_info.ipv4_multicast_enabled = attribute->value.booldata; + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE: + intf_info.ipv6_multicast_enabled = attribute->value.booldata; + break; + case SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE: + intf_info.ipv4_urpf_mode = + 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.s32); + break; + case SAI_ROUTER_INTERFACE_ATTR_MTU: + // TODO: + break; + default: + return SAI_STATUS_INVALID_PARAMETER; } + } - *rif_id = (sai_object_id_t) switch_api_interface_create(device, &intf_info); - status = (*rif_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; + *rif_id = (sai_object_id_t)switch_api_interface_create(device, &intf_info); + status = (*rif_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create router interface: %s", - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create router interface: %s", + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -154,27 +153,25 @@ sai_status_t sai_create_router_interface( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_router_interface( - _In_ sai_object_id_t rif_id) { - - SAI_LOG_ENTER(); +sai_status_t sai_remove_router_interface(_In_ sai_object_id_t rif_id) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); + SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); - switch_status = switch_api_interface_delete(device, (switch_handle_t)rif_id); - status = sai_switch_status_to_sai_status(switch_status); + switch_status = switch_api_interface_delete(device, (switch_handle_t)rif_id); + status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove router interface: %s", - sai_status_to_string(status)); - } + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove router interface: %s", + sai_status_to_string(status)); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -190,56 +187,53 @@ sai_status_t sai_remove_router_interface( * Failure status code on error */ sai_status_t sai_set_router_interface_attribute( - _In_ sai_object_id_t rif_id, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); + _In_ sai_object_id_t rif_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - - SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); - - switch (attr->id) { - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: - switch_status = switch_api_interface_ipv4_unicast_enabled_set( - rif_id, attr->value.booldata); - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: - switch_status = switch_api_interface_ipv6_unicast_enabled_set( - rif_id, attr->value.booldata); - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE: - switch_status = switch_api_interface_ipv4_multicast_enabled_set( - rif_id, attr->value.booldata); - break; - case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE: - switch_status = switch_api_interface_ipv6_multicast_enabled_set( - rif_id, attr->value.booldata); - 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.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.s32)); - break; - default: - return SAI_STATUS_INVALID_PARAMETER; - } - - SAI_LOG_EXIT(); - - status = sai_switch_status_to_sai_status(switch_status); + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); return status; + } + + SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); + + switch (attr->id) { + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: + switch_status = switch_api_interface_ipv4_unicast_enabled_set( + rif_id, attr->value.booldata); + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: + switch_status = switch_api_interface_ipv6_unicast_enabled_set( + rif_id, attr->value.booldata); + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE: + switch_status = switch_api_interface_ipv4_multicast_enabled_set( + rif_id, attr->value.booldata); + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE: + switch_status = switch_api_interface_ipv6_multicast_enabled_set( + rif_id, attr->value.booldata); + 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.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.s32)); + break; + default: + return SAI_STATUS_INVALID_PARAMETER; + } + + SAI_LOG_EXIT(); + + status = sai_switch_status_to_sai_status(switch_status); + return status; } /* @@ -256,40 +250,92 @@ sai_status_t sai_set_router_interface_attribute( * Failure status code on error */ sai_status_t sai_get_router_interface_attribute( - _In_ sai_object_id_t rif_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { + _In_ sai_object_id_t rif_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + + uint32_t index; + uint64_t value; + switch_status_t switch_status = -1; + sai_attribute_t *attribute; + for (index = 0; index < attr_count; index++) { + attribute = &attr_list[index]; + switch (attribute->id) { + case SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID: + switch_status = switch_api_interface_attribute_get( + (switch_handle_t)rif_id, SWITCH_INTF_ATTR_VRF, &value); + attribute->value.oid = value; + break; + case SAI_ROUTER_INTERFACE_ATTR_TYPE: + break; + case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: + switch_status = switch_api_interface_attribute_get( + (switch_handle_t)rif_id, SWITCH_INTF_ATTR_PORT_ID, &value); + attribute->value.oid = value; + break; + case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: + switch_status = switch_api_interface_attribute_get( + (switch_handle_t)rif_id, SWITCH_INTF_ATTR_VLAN_ID, &value); + attribute->value.u16 = value; + break; + case SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS: + switch_status = switch_api_interface_attribute_get( + (switch_handle_t)rif_id, SWITCH_INTF_ATTR_RMAC_ADDR, &value); + memcpy(attribute->value.mac, (uint8_t *)&value, sizeof(sai_mac_t)); + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: + switch_status = switch_api_interface_attribute_get( + (switch_handle_t)rif_id, SWITCH_INTF_ATTR_V4_UNICAST, &value); + attribute->value.booldata = value; + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: + switch_status = switch_api_interface_attribute_get( + (switch_handle_t)rif_id, SWITCH_INTF_ATTR_V6_UNICAST, &value); + attribute->value.booldata = value; + break; + case SAI_ROUTER_INTERFACE_ATTR_MTU: + // return the default for now + attribute->value.u32 = 1514; + break; + default: + return SAI_STATUS_INVALID_PARAMETER; + } - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; + if ((status = sai_switch_status_to_sai_status(switch_status)) != + SAI_STATUS_SUCCESS) { + return status; } + } - SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); + SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * Routing interface methods table retrieved with sai_api_query() */ sai_router_interface_api_t rif_api = { - .create_router_interface = sai_create_router_interface, - .remove_router_interface = sai_remove_router_interface, - .set_router_interface_attribute = sai_set_router_interface_attribute, - .get_router_interface_attribute = sai_get_router_interface_attribute, + .create_router_interface = sai_create_router_interface, + .remove_router_interface = sai_remove_router_interface, + .set_router_interface_attribute = sai_set_router_interface_attribute, + .get_router_interface_attribute = sai_get_router_interface_attribute, }; -sai_status_t sai_router_interface_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing router interface"); - sai_api_service->rif_api = rif_api; - return SAI_STATUS_SUCCESS; +sai_status_t sai_router_interface_initialize( + sai_api_service_t *sai_api_service) { + SAI_LOG_DEBUG("Initializing router interface"); + sai_api_service->rif_api = rif_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saischeduler.c b/switchsai/src/saischeduler.c new file mode 100644 index 0000000..8a6bdfa --- /dev/null +++ b/switchsai/src/saischeduler.c @@ -0,0 +1,186 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "saiinternal.h" +#include + +static sai_api_t api_id = SAI_API_SCHEDULER; + +static void sai_scheduler_attribute_parse( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list, + switch_scheduler_info_t *scheduler_info) { + const sai_attribute_t *attribute; + uint32_t i = 0; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_SCHEDULER_ATTR_SCHEDULING_ALGORITHM: + break; + case SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT: + scheduler_info->weight = attribute->value.u8; + break; + case SAI_SCHEDULER_ATTR_SHAPER_TYPE: + if (attribute->value.u32 == SAI_METER_TYPE_PACKETS) { + scheduler_info->shaper_type = SWITCH_METER_TYPE_PACKETS; + } else { + scheduler_info->shaper_type = SWITCH_METER_TYPE_BYTES; + } + break; + case SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_RATE: + scheduler_info->min_rate = attribute->value.u64; + break; + case SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_BURST_RATE: + scheduler_info->min_burst_size = attribute->value.u64; + break; + case SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_RATE: + scheduler_info->max_rate = attribute->value.u64; + break; + case SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_BURST_RATE: + scheduler_info->max_burst_size = attribute->value.u64; + break; + default: + break; + } + } +} + +/** + * @brief Create Scheduler Profile + * + * @param[out] scheduler_id Scheduler id + * @param[in] attr_count number of attributes + * @param[in] attr_list array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_create_scheduler_profile( + _Out_ sai_object_id_t *scheduler_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_scheduler_info_t scheduler_info; + + memset(&scheduler_info, 0x0, sizeof(scheduler_info)); + sai_scheduler_attribute_parse(attr_count, attr_list, &scheduler_info); + + *scheduler_id = switch_api_scheduler_create(device, &scheduler_info); + + status = (*scheduler_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create scheduler: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Remove Scheduler profile + * + * @param[in] scheduler_id Scheduler id + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_scheduler_profile(_In_ sai_object_id_t scheduler_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_id) == SAI_OBJECT_TYPE_SCHEDULER); + + status = switch_api_scheduler_delete(device, scheduler_id); + if (status != SWITCH_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove scheduler: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Set Scheduler Attribute + * + * @param[in] scheduler_id Scheduler id + * @param[in] attr attribute to set + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_scheduler_attribute(_In_ sai_object_id_t scheduler_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_id) == SAI_OBJECT_TYPE_SCHEDULER); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Get Scheduler attribute + * + * @param[in] scheduler_id - scheduler id + * @param[in] attr_count - number of attributes + * @param[inout] attr_list - array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ + +sai_status_t sai_get_scheduler_attribute(_In_ sai_object_id_t scheduler_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_id) == SAI_OBJECT_TYPE_SCHEDULER); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/* +* Scheduler methods table retrieved with sai_api_query() +*/ +sai_scheduler_api_t scheduler_api = { + .create_scheduler_profile = sai_create_scheduler_profile, + .remove_scheduler_profile = sai_remove_scheduler_profile, + .set_scheduler_attribute = sai_set_scheduler_attribute, + .get_scheduler_attribute = sai_get_scheduler_attribute}; + +sai_status_t sai_scheduler_initialize(sai_api_service_t *sai_api_service) { + SAI_LOG_DEBUG("Initializing scheulder"); + sai_api_service->scheduler_api = scheduler_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saischedulergroup.c b/switchsai/src/saischedulergroup.c new file mode 100644 index 0000000..87c64de --- /dev/null +++ b/switchsai/src/saischedulergroup.c @@ -0,0 +1,216 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "saiinternal.h" + +static sai_api_t api_id = SAI_API_SCHEDULER_GROUP; + +static void sai_scheduler_group_attribute_parse( + _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { + const sai_attribute_t *attribute; + uint32_t i = 0; + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT: + break; + case SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST: + break; + case SAI_SCHEDULER_GROUP_ATTR_PORT_ID: + break; + case SAI_SCHEDULER_GROUP_ATTR_LEVEL: + break; + case SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID: + break; + } + } +} + +/** + * @brief Create Scheduler group + * + * @param[out] scheduler_group_id Scheudler group id + * @param[in] attr_count number of attributes + * @param[in] attr_list array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_create_scheduler_group( + _Out_ sai_object_id_t *scheduler_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + sai_scheduler_group_attribute_parse(attr_count, attr_list); + + status = (*scheduler_group_id == SWITCH_API_INVALID_HANDLE) + ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create scheduler group: %s", + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Remove Scheduler group + * + * @param[in] scheduler_group_id Scheudler group id + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_scheduler_group(_In_ sai_object_id_t + scheduler_group_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_group_id) == + SAI_OBJECT_TYPE_SCHEDULER_GROUP); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} +/** + * @brief Set Scheduler group Attribute + * + * @param[in] scheduler_group_id Scheudler group id + * @param[in] attr attribute to set + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_scheduler_group_attribute( + _In_ sai_object_id_t scheduler_group_id, _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_group_id) == + SAI_OBJECT_TYPE_SCHEDULER_GROUP); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} +/** + * @brief Get Scheduler Group attribute + * + * @param[in] scheduler_group_id - scheduler group id + * @param[in] attr_count - number of attributes + * @param[inout] attr_list - array of attributes + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ + +sai_status_t sai_get_scheduler_group_attribute( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_group_id) == + SAI_OBJECT_TYPE_SCHEDULER_GROUP); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Add Child queue/group objects to scheduler group + * + * @param[in] scheduler_group_id Scheduler group id. + * @param[in] child_count number of child count + * @param[in] child_objects array of child objects + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_add_child_object_to_group( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t child_count, + _In_ const sai_object_id_t *child_objects) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_group_id) == + SAI_OBJECT_TYPE_SCHEDULER_GROUP); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * @brief Remove Child queue/group objects from scheduler group + * + * @param[in] scheduler_group_id Scheduler group id. + * @param[in] child_count number of child count + * @param[in] child_objects array of child objects + * + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_child_object_from_group( + _In_ sai_object_id_t scheduler_group_id, + _In_ uint32_t child_count, + _In_ const sai_object_id_t *child_objects) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(scheduler_group_id) == + SAI_OBJECT_TYPE_SCHEDULER_GROUP); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/* +* Scheduler Group methods table retrieved with sai_api_query() +*/ +sai_scheduler_group_api_t scheduler_group_api = { + .create_scheduler_group = sai_create_scheduler_group, + .remove_scheduler_group = sai_remove_scheduler_group, + .set_scheduler_group_attribute = sai_set_scheduler_group_attribute, + .get_scheduler_group_attribute = sai_get_scheduler_group_attribute, + .add_child_object_to_group = sai_add_child_object_to_group, + .remove_child_object_from_group = sai_remove_child_object_from_group}; + +sai_status_t sai_scheduler_group_initialize( + sai_api_service_t *sai_api_service) { + SAI_LOG_DEBUG("Initializing scheulder group"); + sai_api_service->scheduler_group_api = scheduler_group_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saistp.c b/switchsai/src/saistp.c index 4217859..fb9a8c3 100644 --- a/switchsai/src/saistp.c +++ b/switchsai/src/saistp.c @@ -30,81 +30,79 @@ static sai_api_t api_id = SAI_API_STP; * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_create_stp_entry( - _Out_ sai_object_id_t *stp_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - const sai_attribute_t *attribute; - const sai_vlan_list_t *vlans; - sai_vlan_id_t vlan_id = 0; - uint32_t index1 = 0, index2 = 0; - switch_handle_t *vlan_handle; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", +sai_status_t sai_create_stp_entry(_Out_ sai_object_id_t *stp_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + const sai_attribute_t *attribute; + const sai_vlan_list_t *vlans; + sai_vlan_id_t vlan_id = 0; + uint32_t index1 = 0, index2 = 0; + switch_handle_t *vlan_handle; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + *stp_id = (sai_object_id_t)switch_api_stp_group_create(device, 0); + + status = (*stp_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create stp entry: %s", + sai_status_to_string(status)); + return status; + } + + for (index1 = 0; index1 < attr_count; index1++) { + attribute = &attr_list[index1]; + if (attribute->id == SAI_STP_ATTR_VLAN_LIST) { + vlans = &attribute->value.vlanlist; + + vlan_handle = + (switch_handle_t *)SAI_MALLOC(sizeof(switch_handle_t) * vlans->count); + if (!vlan_handle) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to create stp entry : %s", sai_status_to_string(status)); return status; - } - - *stp_id = (sai_object_id_t) switch_api_stp_group_create(device, 0); - - status = (*stp_id == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create stp entry: %s", + } + + for (index2 = 0; index2 < vlans->count; index2++) { + vlan_id = vlans->list[index2]; + switch_status = + switch_api_vlan_id_to_handle_get(vlan_id, &vlan_handle[index2]); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_FREE(vlan_handle); + SAI_LOG_ERROR("failed to add ports to vlan %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + } + switch_status = switch_api_stp_group_vlans_add( + device, *stp_id, vlans->count, vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + SAI_FREE(vlan_handle); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to add ports to vlan %d: %s", + vlan_id, sai_status_to_string(status)); return status; + } } + } - for (index1 = 0; index1 < attr_count; index1++) { - attribute = &attr_list[index1]; - if (attribute->id == SAI_STP_ATTR_VLAN_LIST) { - vlans = &attribute->value.vlanlist; - - vlan_handle = (switch_handle_t *) SAI_MALLOC(sizeof(switch_handle_t) * vlans->vlan_count); - if (!vlan_handle) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to create stp entry : %s", - sai_status_to_string(status)); - return status; - } - - for (index2 = 0; index2 < vlans->vlan_count; index2++) { - vlan_id = vlans->vlan_list[index2]; - switch_status = switch_api_vlan_id_to_handle_get(vlan_id, - &vlan_handle[index2]); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_FREE(vlan_handle); - SAI_LOG_ERROR("failed to add ports to vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - } - switch_status = switch_api_stp_group_vlans_add(device, *stp_id, - vlans->vlan_count, - vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - SAI_FREE(vlan_handle); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to add ports to vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - } - } - - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -114,26 +112,25 @@ sai_status_t sai_create_stp_entry( * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_remove_stp_entry( - _In_ sai_object_id_t stp_id) { +sai_status_t sai_remove_stp_entry(_In_ sai_object_id_t stp_id) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); - SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); + switch_status = switch_api_stp_group_delete(device, (switch_handle_t)stp_id); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to remove stp entry %lx: %s", + stp_id, + sai_status_to_string(status)); + } - switch_status = switch_api_stp_group_delete(device, (switch_handle_t)stp_id); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove stp entry %lx: %s", - stp_id, sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -145,26 +142,23 @@ sai_status_t sai_remove_stp_entry( * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_set_stp_entry_attribute( - _In_ sai_object_id_t stp_id, - _In_ const sai_attribute_t *attr) { +sai_status_t sai_set_stp_entry_attribute(_In_ sai_object_id_t stp_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); + SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /** @@ -176,27 +170,24 @@ sai_status_t sai_set_stp_entry_attribute( * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_get_stp_entry_attribute( - _In_ sai_object_id_t stp_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { +sai_status_t sai_get_stp_entry_attribute(_In_ sai_object_id_t stp_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); + SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return SAI_STATUS_SUCCESS; + return SAI_STATUS_SUCCESS; } /** @@ -207,42 +198,41 @@ sai_status_t sai_get_stp_entry_attribute( * @return SAI_STATUS_SUCCESS if operation is successful otherwise a different * error code is returned. */ -sai_status_t sai_set_stp_port_state( - _In_ sai_object_id_t stp_id, - _In_ sai_object_id_t port_id, - _In_ sai_port_stp_port_state_t stp_port_state) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_stp_state_t switch_stp_state = SWITCH_PORT_STP_STATE_NONE; - - SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); - - switch (stp_port_state) { - case SAI_PORT_STP_STATE_LEARNING: - switch_stp_state = SWITCH_PORT_STP_STATE_LEARNING; - break; - case SAI_PORT_STP_STATE_FORWARDING: - switch_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; - break; - case SAI_PORT_STP_STATE_BLOCKING: - switch_stp_state = SWITCH_PORT_STP_STATE_BLOCKING; - break; - } - switch_status = switch_api_stp_port_state_set(device, stp_id, - port_id, - switch_stp_state); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to set stp port state %lx: %s", - stp_id, sai_status_to_string(status)); - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_set_stp_port_state(_In_ sai_object_id_t stp_id, + _In_ sai_object_id_t port_id, + _In_ sai_port_stp_port_state_t + stp_port_state) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_stp_state_t switch_stp_state = SWITCH_PORT_STP_STATE_NONE; + + SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); + + switch (stp_port_state) { + case SAI_PORT_STP_STATE_LEARNING: + switch_stp_state = SWITCH_PORT_STP_STATE_LEARNING; + break; + case SAI_PORT_STP_STATE_FORWARDING: + switch_stp_state = SWITCH_PORT_STP_STATE_FORWARDING; + break; + case SAI_PORT_STP_STATE_BLOCKING: + switch_stp_state = SWITCH_PORT_STP_STATE_BLOCKING; + break; + } + switch_status = + switch_api_stp_port_state_set(device, stp_id, port_id, switch_stp_state); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set stp port state %lx: %s", + stp_id, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /** @@ -255,61 +245,58 @@ sai_status_t sai_set_stp_port_state( * error code is returned. */ sai_status_t sai_get_stp_port_state( - _In_ sai_object_id_t stp_id, - _In_ sai_object_id_t port_id, - _Out_ sai_port_stp_port_state_t *stp_port_state) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_stp_state_t switch_stp_state = SWITCH_PORT_STP_STATE_NONE; - - SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); - - switch_status = switch_api_stp_port_state_get(device, stp_id, - port_id, - &switch_stp_state); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to set stp port state %lx: %s", - stp_id, sai_status_to_string(status)); - return status; - } - - switch (switch_stp_state) { - case SWITCH_PORT_STP_STATE_LEARNING: - *stp_port_state = SAI_PORT_STP_STATE_LEARNING; - break; - case SWITCH_PORT_STP_STATE_FORWARDING: - *stp_port_state = SAI_PORT_STP_STATE_FORWARDING; - break; - case SWITCH_PORT_STP_STATE_BLOCKING: - *stp_port_state = SAI_PORT_STP_STATE_BLOCKING; - break; - default: - *stp_port_state = 0; - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + _In_ sai_object_id_t stp_id, + _In_ sai_object_id_t port_id, + _Out_ sai_port_stp_port_state_t *stp_port_state) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_stp_state_t switch_stp_state = SWITCH_PORT_STP_STATE_NONE; + + SAI_ASSERT(sai_object_type_query(stp_id) == SAI_OBJECT_TYPE_STP_INSTANCE); + + switch_status = + switch_api_stp_port_state_get(device, stp_id, port_id, &switch_stp_state); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to set stp port state %lx: %s", + stp_id, + sai_status_to_string(status)); + return status; + } + + switch (switch_stp_state) { + case SWITCH_PORT_STP_STATE_LEARNING: + *stp_port_state = SAI_PORT_STP_STATE_LEARNING; + break; + case SWITCH_PORT_STP_STATE_FORWARDING: + *stp_port_state = SAI_PORT_STP_STATE_FORWARDING; + break; + case SWITCH_PORT_STP_STATE_BLOCKING: + *stp_port_state = SAI_PORT_STP_STATE_BLOCKING; + break; + default: + *stp_port_state = 0; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /** * @brief STP method table retrieved with sai_api_query() */ -sai_stp_api_t stp_api = { - .create_stp = sai_create_stp_entry, - .remove_stp = sai_remove_stp_entry, - .set_stp_attribute = sai_set_stp_entry_attribute, - .get_stp_attribute = sai_get_stp_entry_attribute, - .set_stp_port_state = sai_set_stp_port_state, - .get_stp_port_state = sai_get_stp_port_state -}; +sai_stp_api_t stp_api = {.create_stp = sai_create_stp_entry, + .remove_stp = sai_remove_stp_entry, + .set_stp_attribute = sai_set_stp_entry_attribute, + .get_stp_attribute = sai_get_stp_entry_attribute, + .set_stp_port_state = sai_set_stp_port_state, + .get_stp_port_state = sai_get_stp_port_state}; sai_status_t sai_stp_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing spanning tree"); - sai_api_service->stp_api = stp_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing spanning tree"); + sai_api_service->stp_api = stp_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiswitch.c b/switchsai/src/saiswitch.c index 5fbac83..4086649 100644 --- a/switchsai/src/saiswitch.c +++ b/switchsai/src/saiswitch.c @@ -23,52 +23,49 @@ static sai_api_t api_id = SAI_API_SWITCH; sai_switch_notification_t sai_switch_notifications; sai_status_t sai_initialize_switch( - _In_ sai_switch_profile_id_t profile_id, - _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char* switch_hardware_id, - _In_reads_opt_z_(SAI_MAX_FIRMWARE_PATH_NAME_LEN) char* firmware_path_name, - _In_ sai_switch_notification_t* switch_notifications) { + _In_ sai_switch_profile_id_t profile_id, + _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char *switch_hardware_id, + _In_reads_opt_z_(SAI_MAX_FIRMWARE_PATH_NAME_LEN) char *firmware_path_name, + _In_ sai_switch_notification_t *switch_notifications) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + if (!switch_notifications) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null switch notifications: %s", + sai_status_to_string(status)); + return status; + } - if (!switch_notifications) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null switch notifications: %s", - sai_status_to_string(status)); - return status; - } - - memcpy(&sai_switch_notifications, switch_notifications, sizeof(sai_switch_notification_t)); + memcpy(&sai_switch_notifications, + switch_notifications, + sizeof(sai_switch_notification_t)); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } -void sai_shutdown_switch( - _In_ bool warm_restart_hint) { -} +void sai_shutdown_switch(_In_ bool warm_restart_hint) {} sai_status_t sai_connect_switch( - _In_ sai_switch_profile_id_t profile_id, - _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char* switch_hardware_id, - _In_ sai_switch_notification_t* switch_notifications) { + _In_ sai_switch_profile_id_t profile_id, + _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char *switch_hardware_id, + _In_ sai_switch_notification_t *switch_notifications) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); + sai_status_t status = SAI_STATUS_SUCCESS; - sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); - - return (sai_status_t) status; -} - -void sai_disconnect_switch(void) { + return (sai_status_t)status; } +void sai_disconnect_switch(void) {} static int mac_set = 0; +static unsigned char def_mac[6] = {0x00, 0x01, 0x04, 0x06, 0x08, 0x03}; /* * Routine Description: * Set switch attribute value @@ -80,32 +77,30 @@ static int mac_set = 0; * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_switch_attribute( - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_api_capability_t api_switch_info; - - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } - - switch (attr->id) { - case SAI_SWITCH_ATTR_SRC_MAC_ADDRESS: - memcpy(&api_switch_info.switch_mac, &attr->value.mac, 6); - mac_set = 1; - break; - } - switch_api_capability_set(device, &api_switch_info); - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_set_switch_attribute(_In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_api_capability_t api_switch_info; + + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + + memset(&api_switch_info, 0x0, sizeof(api_switch_info)); + switch (attr->id) { + case SAI_SWITCH_ATTR_SRC_MAC_ADDRESS: + memcpy(&api_switch_info.switch_mac, &attr->value.mac, 6); + mac_set = 1; + break; + } + switch_api_capability_set(device, &api_switch_info); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -120,83 +115,84 @@ sai_status_t sai_set_switch_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_switch_attribute( - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - uint32_t index1 = 0, index2 = 0; - sai_object_list_t *objlist = NULL; - switch_api_capability_t api_switch_info; - sai_attribute_t attribute; - - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } - - switch_api_capability_get(device, &api_switch_info); - for (index1 = 0; index1 < attr_count; index1++) { - attribute = attr_list[index1]; - switch (attribute.id) { - case SAI_SWITCH_ATTR_PORT_NUMBER: - attr_list->value.u32 = api_switch_info.max_ports; - break; - case SAI_SWITCH_ATTR_PORT_LIST: - objlist = &attr_list->value.objlist; - objlist->count = api_switch_info.max_ports; - for (index2 = 0; index2 < objlist->count; index2++) { - objlist->list[index2] = api_switch_info.port_list[index2]; - } - break; - case SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_ALGORITHM: - case SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_SEED: - case SAI_SWITCH_ATTR_LAG_HASH_IPV4: - case SAI_SWITCH_ATTR_LAG_HASH_IPV4_IN_IPV4: - break; - case SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM: - case SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_SEED: - case SAI_SWITCH_ATTR_ECMP_HASH_IPV4: - case SAI_SWITCH_ATTR_ECMP_HASH_IPV4_IN_IPV4: - break; - case SAI_SWITCH_ATTR_MAX_VIRTUAL_ROUTERS: - break; - case SAI_SWITCH_ATTR_DEFAULT_STP_INST_ID: - break; - case SAI_SWITCH_ATTR_SRC_MAC_ADDRESS: - memcpy(attribute.value.mac, &api_switch_info.switch_mac, 6); - if(!mac_set) - return SAI_STATUS_FAILURE; - break; - case SAI_SWITCH_ATTR_CPU_PORT: - attr_list->value.oid = api_switch_info.port_list[64]; - break; +sai_status_t sai_get_switch_attribute(_In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + uint32_t index1 = 0, index2 = 0; + sai_object_list_t *objlist = NULL; + switch_api_capability_t api_switch_info; + sai_attribute_t attribute; + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + switch_api_capability_get(device, &api_switch_info); + for (index1 = 0; index1 < attr_count; index1++) { + attribute = attr_list[index1]; + switch (attribute.id) { + case SAI_SWITCH_ATTR_PORT_NUMBER: + attr_list->value.u32 = api_switch_info.max_ports; + break; + case SAI_SWITCH_ATTR_PORT_LIST: + objlist = &attr_list->value.objlist; + objlist->count = api_switch_info.max_ports; + for (index2 = 0; index2 < objlist->count; index2++) { + objlist->list[index2] = api_switch_info.port_list[index2]; + } + break; + case SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_ALGORITHM: + case SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_SEED: + case SAI_SWITCH_ATTR_LAG_HASH_IPV4: + case SAI_SWITCH_ATTR_LAG_HASH_IPV4_IN_IPV4: + break; + case SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM: + case SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_SEED: + case SAI_SWITCH_ATTR_ECMP_HASH_IPV4: + case SAI_SWITCH_ATTR_ECMP_HASH_IPV4_IN_IPV4: + break; + case SAI_SWITCH_ATTR_MAX_VIRTUAL_ROUTERS: + break; + case SAI_SWITCH_ATTR_DEFAULT_STP_INST_ID: + break; + case SAI_SWITCH_ATTR_SRC_MAC_ADDRESS: + if (!mac_set) { + memcpy(&api_switch_info.switch_mac, def_mac, 6); + mac_set = 1; } + memcpy(attribute.value.mac, &api_switch_info.switch_mac, 6); + break; + case SAI_SWITCH_ATTR_CPU_PORT: + attr_list->value.oid = api_switch_info.port_list[64]; + break; + case SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID: + attr_list->value.oid = switch_api_default_vrf_internal(); + break; } + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* -* Switch method table retrieved with sai_api_query() +* Switch method table retrieved with sai_api_query() */ sai_switch_api_t switch_api = { - .initialize_switch = sai_initialize_switch, - .shutdown_switch = sai_shutdown_switch, - .connect_switch = sai_connect_switch, - .disconnect_switch = sai_disconnect_switch, - .set_switch_attribute = sai_set_switch_attribute, - .get_switch_attribute = sai_get_switch_attribute -}; + .initialize_switch = sai_initialize_switch, + .shutdown_switch = sai_shutdown_switch, + .connect_switch = sai_connect_switch, + .disconnect_switch = sai_disconnect_switch, + .set_switch_attribute = sai_set_switch_attribute, + .get_switch_attribute = sai_get_switch_attribute}; sai_status_t sai_switch_initialize(sai_api_service_t *sai_api_service) { - SAI_LOG_DEBUG("Initializing switch"); - sai_api_service->switch_api = switch_api; - return SAI_STATUS_SUCCESS; + SAI_LOG_DEBUG("Initializing switch"); + sai_api_service->switch_api = switch_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiudf.c b/switchsai/src/saiudf.c new file mode 100644 index 0000000..98ed7b9 --- /dev/null +++ b/switchsai/src/saiudf.c @@ -0,0 +1,106 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include +#include + +#include "saiinternal.h" + +// Unused for now +/* static sai_api_t api_id = SAI_API_UDF; */ + +sai_status_t sai_create_udf(_Out_ sai_object_id_t *udf_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_remove_udf(_In_ sai_object_id_t udf_id) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_set_udf_attribute(_In_ sai_object_id_t udf_id, + _In_ const sai_attribute_t *attr) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_get_udf_attribute(_In_ sai_object_id_t udf_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_create_udf_match(_Out_ sai_object_id_t *udf_match_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_remove_udf_match(_In_ sai_object_id_t udf_match_id) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_set_udf_match_attribute(_In_ sai_object_id_t udf_match_id, + _In_ const sai_attribute_t *attr) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_get_udf_match_attribute(_In_ sai_object_id_t udf_match_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_create_udf_group(_Out_ sai_object_id_t *udf_group_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_remove_udf_group(_In_ sai_object_id_t udf_group_id) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_set_udf_group_attribute(_In_ sai_object_id_t udf_group_id, + _In_ const sai_attribute_t *attr) { + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_get_udf_group_attribute(_In_ sai_object_id_t udf_group_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + return SAI_STATUS_SUCCESS; +} + +sai_udf_api_t udf_api = { + .create_udf = sai_create_udf, + .remove_udf = sai_remove_udf, + .set_udf_attribute = sai_set_udf_attribute, + .get_udf_attribute = sai_get_udf_attribute, + .create_udf_match = sai_create_udf_match, + .remove_udf_match = sai_remove_udf_match, + .set_udf_match_attribute = sai_set_udf_match_attribute, + .get_udf_match_attribute = sai_get_udf_match_attribute, + .create_udf_group = sai_create_udf_group, + .remove_udf_group = sai_remove_udf_group, + .set_udf_group_attribute = sai_set_udf_group_attribute, + .get_udf_group_attribute = sai_get_udf_group_attribute, +}; + +sai_status_t sai_udf_initialize(sai_api_service_t *sai_api_service) { + sai_api_service->udf_api = udf_api; + return SAI_STATUS_SUCCESS; +} diff --git a/switchsai/src/saiutils.c b/switchsai/src/saiutils.c index 0e8aecf..5e08016 100644 --- a/switchsai/src/saiutils.c +++ b/switchsai/src/saiutils.c @@ -16,265 +16,316 @@ limitations under the License. #include "saiinternal.h" -char *sai_status_to_string( - _In_ const sai_status_t status) { - switch (status) { - case SAI_STATUS_INVALID_PARAMETER: - return "invalid parameter"; - case SAI_STATUS_NO_MEMORY: - return "no memory"; - case SAI_STATUS_FAILURE: - return "unknown failure"; - default: - return "unknown failure"; - } -} +// maps from SAI types to switchapi types -sai_status_t sai_switch_status_to_sai_status( - _In_ const switch_status_t status) { - switch (status) { - case SWITCH_STATUS_SUCCESS: - return SAI_STATUS_SUCCESS; - case SWITCH_STATUS_FAILURE: - return SWITCH_STATUS_FAILURE; - case SWITCH_STATUS_INVALID_PARAMETER: - return SAI_STATUS_INVALID_PARAMETER; - case SWITCH_STATUS_NO_MEMORY: - return SAI_STATUS_NO_MEMORY; - default: - return SAI_STATUS_FAILURE; - } +char *sai_status_to_string(_In_ const sai_status_t status) { + switch (status) { + case SAI_STATUS_INVALID_PARAMETER: + return "invalid parameter"; + case SAI_STATUS_NO_MEMORY: + return "no memory"; + case SAI_STATUS_FAILURE: + return "unknown failure"; + default: + return "unknown failure"; + } } -char * sai_object_type_to_string( - _In_ sai_object_type_t object_type) { - if (object_type > SAI_OBJECT_TYPE_MAX) { - return "invalid object"; - } +char *sai_object_type_to_string(_In_ sai_object_type_t object_type) { + if (object_type > SAI_OBJECT_TYPE_MAX) { + return "invalid object"; + } - switch (object_type) { - case SAI_OBJECT_TYPE_NULL: - return "null object"; - case SAI_OBJECT_TYPE_PORT: - return "port object"; - case SAI_OBJECT_TYPE_LAG: - return "lag object"; - case SAI_OBJECT_TYPE_VIRTUAL_ROUTER: - return "virtual router object"; - case SAI_OBJECT_TYPE_NEXT_HOP: - return "nexthop object"; - case SAI_OBJECT_TYPE_NEXT_HOP_GROUP: - return "nexthop group object"; - case SAI_OBJECT_TYPE_ROUTER_INTERFACE: - return "router interface object"; - case SAI_OBJECT_TYPE_ACL_TABLE: - return "acl table object"; - case SAI_OBJECT_TYPE_ACL_ENTRY: - return "acl entry object"; - case SAI_OBJECT_TYPE_ACL_COUNTER: - return "acl counter object"; - case SAI_OBJECT_TYPE_HOST_INTERFACE: - return "host interface object"; - case SAI_OBJECT_TYPE_MIRROR: - return "mirror object"; - case SAI_OBJECT_TYPE_SAMPLEPACKET: - return "sample packet object"; - case SAI_OBJECT_TYPE_STP_INSTANCE: - return "stp instance object"; - case SAI_OBJECT_TYPE_TRAP_GROUP: - return "trap group object"; - case SAI_OBJECT_TYPE_ACL_TABLE_GROUP: - return "acl table group object"; - case SAI_OBJECT_TYPE_POLICER: - return "policer object"; - case SAI_OBJECT_TYPE_WRED: - return "wred object"; - case SAI_OBJECT_TYPE_QOS_MAPS: - return "qos maps object"; - case SAI_OBJECT_TYPE_QUEUE: - return "queue object"; - case SAI_OBJECT_TYPE_SCHEDULER: - return "scheduler object"; - case SAI_OBJECT_TYPE_SCHEDULER_GROUP: - return "scheduler group object"; - default: - return "invalid object"; - } + switch (object_type) { + case SAI_OBJECT_TYPE_NULL: + return "null object"; + case SAI_OBJECT_TYPE_PORT: + return "port object"; + case SAI_OBJECT_TYPE_LAG: + return "lag object"; + case SAI_OBJECT_TYPE_VIRTUAL_ROUTER: + return "virtual router object"; + case SAI_OBJECT_TYPE_NEXT_HOP: + return "nexthop object"; + case SAI_OBJECT_TYPE_NEXT_HOP_GROUP: + return "nexthop group object"; + case SAI_OBJECT_TYPE_ROUTER_INTERFACE: + return "router interface object"; + case SAI_OBJECT_TYPE_ACL_TABLE: + return "acl table object"; + case SAI_OBJECT_TYPE_ACL_ENTRY: + return "acl entry object"; + case SAI_OBJECT_TYPE_ACL_COUNTER: + return "acl counter object"; + case SAI_OBJECT_TYPE_HOST_INTERFACE: + return "host interface object"; + case SAI_OBJECT_TYPE_MIRROR: + return "mirror object"; + case SAI_OBJECT_TYPE_SAMPLEPACKET: + return "sample packet object"; + case SAI_OBJECT_TYPE_STP_INSTANCE: + return "stp instance object"; + case SAI_OBJECT_TYPE_TRAP_GROUP: + return "trap group object"; + case SAI_OBJECT_TYPE_ACL_TABLE_GROUP: + return "acl table group object"; + case SAI_OBJECT_TYPE_POLICER: + return "policer object"; + case SAI_OBJECT_TYPE_WRED: + return "wred object"; + case SAI_OBJECT_TYPE_QOS_MAPS: + return "qos maps object"; + case SAI_OBJECT_TYPE_QUEUE: + return "queue object"; + case SAI_OBJECT_TYPE_SCHEDULER: + return "scheduler object"; + case SAI_OBJECT_TYPE_SCHEDULER_GROUP: + return "scheduler group object"; + default: + return "invalid object"; + } } -sai_status_t sai_ipv4_prefix_length( - _In_ sai_ip4_t ip4, - _Out_ uint32_t *prefix_length) { - int x = 0; - *prefix_length = 0; - while (ip4) { - x = ip4 & 0x1; - if (x) (*prefix_length)++; - ip4 = ip4 >> 1; - } - return SAI_STATUS_SUCCESS; +sai_status_t sai_ipv4_prefix_length(_In_ sai_ip4_t ip4, + _Out_ uint32_t *prefix_length) { + int x = 0; + *prefix_length = 0; + while (ip4) { + x = ip4 & 0x1; + if (x) (*prefix_length)++; + ip4 = ip4 >> 1; + } + return SAI_STATUS_SUCCESS; } -sai_status_t sai_ipv6_prefix_length( - _In_ const sai_ip6_t ip6, - _Out_ uint32_t *prefix_length) { - int i = 0, x = 0; - sai_ip6_t ip6_temp; - memcpy(ip6_temp, ip6, 16); - *prefix_length = 0; - for (i = 0; i < 16; i++) { - if (ip6_temp[i] == 0xFF) { - *prefix_length += 8; - } else { - while (ip6_temp[i]) { - x = ip6_temp[i] & 0x1; - if (x) (*prefix_length)++; - ip6_temp[i] = ip6_temp[i] >> 1; - } - } +sai_status_t sai_ipv6_prefix_length(_In_ const sai_ip6_t ip6, + _Out_ uint32_t *prefix_length) { + int i = 0, x = 0; + sai_ip6_t ip6_temp; + memcpy(ip6_temp, ip6, 16); + *prefix_length = 0; + for (i = 0; i < 16; i++) { + if (ip6_temp[i] == 0xFF) { + *prefix_length += 8; + } else { + while (ip6_temp[i]) { + x = ip6_temp[i] & 0x1; + if (x) (*prefix_length)++; + ip6_temp[i] = ip6_temp[i] >> 1; + } } - return SAI_STATUS_SUCCESS; + } + return SAI_STATUS_SUCCESS; } sai_status_t sai_ip_prefix_to_switch_ip_addr( - const _In_ sai_ip_prefix_t *sai_ip_addr, - _Out_ switch_ip_addr_t *ip_addr) { - if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV4) { - ip_addr->type = SWITCH_API_IP_ADDR_V4; - ip_addr->ip.v4addr = ntohl(sai_ip_addr->addr.ip4); - sai_ipv4_prefix_length(ntohl(sai_ip_addr->mask.ip4), &ip_addr->prefix_len); - } else if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV6) { - ip_addr->type = SWITCH_API_IP_ADDR_V6; - memcpy(ip_addr->ip.v6addr, sai_ip_addr->addr.ip6, 16); - sai_ipv6_prefix_length(sai_ip_addr->mask.ip6, &ip_addr->prefix_len); - } - return SAI_STATUS_SUCCESS; + const _In_ sai_ip_prefix_t *sai_ip_addr, _Out_ switch_ip_addr_t *ip_addr) { + if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV4) { + ip_addr->type = SWITCH_API_IP_ADDR_V4; + ip_addr->ip.v4addr = ntohl(sai_ip_addr->addr.ip4); + sai_ipv4_prefix_length(ntohl(sai_ip_addr->mask.ip4), &ip_addr->prefix_len); + } else if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV6) { + ip_addr->type = SWITCH_API_IP_ADDR_V6; + memcpy(ip_addr->ip.v6addr, sai_ip_addr->addr.ip6, 16); + sai_ipv6_prefix_length(sai_ip_addr->mask.ip6, &ip_addr->prefix_len); + } + return SAI_STATUS_SUCCESS; } sai_status_t sai_ip_addr_to_switch_ip_addr( - const _In_ sai_ip_address_t *sai_ip_addr, - _Out_ switch_ip_addr_t *ip_addr) { - if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV4) { - ip_addr->type = SWITCH_API_IP_ADDR_V4; - ip_addr->ip.v4addr = ntohl(sai_ip_addr->addr.ip4); - ip_addr->prefix_len = 32; - } else if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV6) { - ip_addr->type = SWITCH_API_IP_ADDR_V6; - memcpy(ip_addr->ip.v6addr, sai_ip_addr->addr.ip6, 16); - ip_addr->prefix_len = 128; - } - return SAI_STATUS_SUCCESS; + const _In_ sai_ip_address_t *sai_ip_addr, _Out_ switch_ip_addr_t *ip_addr) { + if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV4) { + ip_addr->type = SWITCH_API_IP_ADDR_V4; + ip_addr->ip.v4addr = ntohl(sai_ip_addr->addr.ip4); + ip_addr->prefix_len = 32; + } else if (sai_ip_addr->addr_family == SAI_IP_ADDR_FAMILY_IPV6) { + ip_addr->type = SWITCH_API_IP_ADDR_V6; + memcpy(ip_addr->ip.v6addr, sai_ip_addr->addr.ip6, 16); + ip_addr->prefix_len = 128; + } + return SAI_STATUS_SUCCESS; } -sai_status_t sai_ipv4_to_string( - _In_ sai_ip4_t ip4, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length) -{ - inet_ntop(AF_INET, &ip4, entry_string, max_length); - *entry_length = (int)strlen(entry_string); - return SAI_STATUS_SUCCESS; +sai_status_t sai_ipv4_to_string(_In_ sai_ip4_t ip4, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length) { + inet_ntop(AF_INET, &ip4, entry_string, max_length); + *entry_length = (int)strlen(entry_string); + return SAI_STATUS_SUCCESS; } -sai_status_t sai_ipv6_to_string( - _In_ sai_ip6_t ip6, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length) -{ - inet_ntop(AF_INET6, &ip6, entry_string, max_length); - *entry_length = (int) strlen(entry_string); - return SAI_STATUS_SUCCESS; +sai_status_t sai_ipv6_to_string(_In_ sai_ip6_t ip6, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length) { + inet_ntop(AF_INET6, &ip6, entry_string, max_length); + *entry_length = (int)strlen(entry_string); + return SAI_STATUS_SUCCESS; } -sai_status_t sai_ipaddress_to_string( - _In_ sai_ip_address_t ip_addr, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length) -{ - if (ip_addr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) { - sai_ipv4_to_string(ip_addr.addr.ip4, max_length, entry_string, entry_length); - } else if (ip_addr.addr_family == SAI_IP_ADDR_FAMILY_IPV6) { - sai_ipv6_to_string(ip_addr.addr.ip6, max_length, entry_string, entry_length); - } else { - snprintf(entry_string, max_length, "Invalid addr family %d", ip_addr.addr_family); - return SAI_STATUS_INVALID_PARAMETER; - } - return SAI_STATUS_SUCCESS; +sai_status_t sai_ipaddress_to_string(_In_ sai_ip_address_t ip_addr, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length) { + if (ip_addr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) { + sai_ipv4_to_string( + ip_addr.addr.ip4, max_length, entry_string, entry_length); + } else if (ip_addr.addr_family == SAI_IP_ADDR_FAMILY_IPV6) { + sai_ipv6_to_string( + ip_addr.addr.ip6, max_length, entry_string, entry_length); + } else { + snprintf(entry_string, + max_length, + "Invalid addr family %d", + ip_addr.addr_family); + return SAI_STATUS_INVALID_PARAMETER; + } + return SAI_STATUS_SUCCESS; } -sai_status_t sai_ipprefix_to_string( - _In_ sai_ip_prefix_t ip_prefix, - _In_ uint32_t max_length, - _Out_ char *entry_string, - _Out_ int *entry_length) -{ - int len = 0; - uint32_t pos = 0; +sai_status_t sai_ipprefix_to_string(_In_ sai_ip_prefix_t ip_prefix, + _In_ uint32_t max_length, + _Out_ char *entry_string, + _Out_ int *entry_length) { + int len = 0; + uint32_t pos = 0; - if (ip_prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV4) { - sai_ipv4_to_string(ip_prefix.addr.ip4, max_length, entry_string, &len); - pos += len; - if (pos > max_length) { - *entry_length = max_length; - return SAI_STATUS_SUCCESS; - } - pos += snprintf(entry_string + pos, max_length - pos, "/"); - if (pos > max_length) { - *entry_length = max_length; - return SAI_STATUS_SUCCESS; - } - sai_ipv4_to_string(ip_prefix.mask.ip4, max_length - pos, - entry_string + pos, &len); - pos += len; - if (pos > max_length) { - *entry_length = max_length; - return SAI_STATUS_SUCCESS; - } - } else if (ip_prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV6) { - sai_ipv6_to_string(ip_prefix.addr.ip6, max_length, entry_string, &len); - pos += len; - if (pos > max_length) { - *entry_length = max_length; - return SAI_STATUS_SUCCESS; - } - pos += snprintf(entry_string + pos, max_length - pos, "/"); - if (pos > max_length) { - *entry_length = max_length; - return SAI_STATUS_SUCCESS; - } - sai_ipv6_to_string(ip_prefix.mask.ip6, max_length - pos, - entry_string + pos, &len); - pos += len; - if (pos > max_length) { - *entry_length = max_length; - return SAI_STATUS_SUCCESS; - } - } else { - snprintf(entry_string, max_length, "Invalid addr family %d", - ip_prefix.addr_family); - return SAI_STATUS_INVALID_PARAMETER; + if (ip_prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV4) { + sai_ipv4_to_string(ip_prefix.addr.ip4, max_length, entry_string, &len); + pos += len; + if (pos > max_length) { + *entry_length = max_length; + return SAI_STATUS_SUCCESS; + } + pos += snprintf(entry_string + pos, max_length - pos, "/"); + if (pos > max_length) { + *entry_length = max_length; + return SAI_STATUS_SUCCESS; + } + sai_ipv4_to_string( + ip_prefix.mask.ip4, max_length - pos, entry_string + pos, &len); + pos += len; + if (pos > max_length) { + *entry_length = max_length; + return SAI_STATUS_SUCCESS; } + } else if (ip_prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV6) { + sai_ipv6_to_string(ip_prefix.addr.ip6, max_length, entry_string, &len); + pos += len; + if (pos > max_length) { + *entry_length = max_length; + return SAI_STATUS_SUCCESS; + } + pos += snprintf(entry_string + pos, max_length - pos, "/"); + if (pos > max_length) { + *entry_length = max_length; + return SAI_STATUS_SUCCESS; + } + sai_ipv6_to_string( + ip_prefix.mask.ip6, max_length - pos, entry_string + pos, &len); + pos += len; + if (pos > max_length) { + *entry_length = max_length; + return SAI_STATUS_SUCCESS; + } + } else { + snprintf(entry_string, + max_length, + "Invalid addr family %d", + ip_prefix.addr_family); + return SAI_STATUS_INVALID_PARAMETER; + } - *entry_length = pos; - return SAI_STATUS_SUCCESS; + *entry_length = pos; + return SAI_STATUS_SUCCESS; } -switch_acl_action_t -sai_packet_action_to_switch_packet_action( - _In_ sai_packet_action_t action) { - switch (action) { - case SAI_PACKET_ACTION_DROP: - return SWITCH_ACL_ACTION_DROP; - case SAI_PACKET_ACTION_FORWARD: - return SWITCH_ACL_ACTION_PERMIT; - case SAI_PACKET_ACTION_TRAP: - return SWITCH_ACL_ACTION_REDIRECT_TO_CPU; - case SAI_PACKET_ACTION_LOG: - return SWITCH_ACL_ACTION_LOG; - default: - return SWITCH_ACL_ACTION_NOP; - } +sai_status_t sai_port_speed_to_switch_port_speed( + uint32_t sai_port_speed, _Out_ switch_port_speed_t *switch_port_speed) { + // speeds are in mbps + switch (sai_port_speed) { + case 1000: + *switch_port_speed = SWITCH_API_PORT_SPEED_1G; + break; + case 10000: + *switch_port_speed = SWITCH_API_PORT_SPEED_10G; + break; + case 25000: + *switch_port_speed = SWITCH_API_PORT_SPEED_25G; + break; + case 40000: + *switch_port_speed = SWITCH_API_PORT_SPEED_40G; + break; + case 50000: + *switch_port_speed = SWITCH_API_PORT_SPEED_50G; + break; + case 100000: + *switch_port_speed = SWITCH_API_PORT_SPEED_100G; + break; + default: + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +switch_acl_action_t sai_packet_action_to_switch_packet_action( + _In_ sai_packet_action_t action) { + switch (action) { + case SAI_PACKET_ACTION_DROP: + return SWITCH_ACL_ACTION_DROP; + case SAI_PACKET_ACTION_FORWARD: + return SWITCH_ACL_ACTION_PERMIT; + case SAI_PACKET_ACTION_TRAP: + return SWITCH_ACL_ACTION_REDIRECT_TO_CPU; + case SAI_PACKET_ACTION_LOG: + return SWITCH_ACL_ACTION_LOG; + default: + return SWITCH_ACL_ACTION_NOP; + } +} + +// maps from switchapi types to SAI types + +sai_status_t sai_switch_ip_addr_to_sai_ip_addr( + _Out_ sai_ip_address_t *sai_ip_addr, const _In_ switch_ip_addr_t *ip_addr) { + if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { + sai_ip_addr->addr_family = SAI_IP_ADDR_FAMILY_IPV4; + sai_ip_addr->addr.ip4 = htonl(ip_addr->ip.v4addr); + } else if (ip_addr->type == SWITCH_API_IP_ADDR_V6) { + sai_ip_addr->addr_family = SAI_IP_ADDR_FAMILY_IPV6; + memcpy(sai_ip_addr->addr.ip6, ip_addr->ip.v6addr, 16); + } + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_switch_port_enabled_to_sai_oper_status( + _In_ _Out_ sai_attribute_t *attr) { + switch ((int)attr->value.booldata) { + case 1: + attr->value.u8 = SAI_PORT_OPER_STATUS_UP; + break; + case 0: + attr->value.u8 = SAI_PORT_OPER_STATUS_DOWN; + break; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t sai_switch_status_to_sai_status(_In_ const switch_status_t + status) { + switch (status) { + case SWITCH_STATUS_SUCCESS: + return SAI_STATUS_SUCCESS; + case SWITCH_STATUS_FAILURE: + return SWITCH_STATUS_FAILURE; + case SWITCH_STATUS_INVALID_PARAMETER: + return SAI_STATUS_INVALID_PARAMETER; + case SWITCH_STATUS_NO_MEMORY: + return SAI_STATUS_NO_MEMORY; + default: + return SAI_STATUS_FAILURE; + } } diff --git a/switchsai/src/saivlan.c b/switchsai/src/saivlan.c index 1febfa5..8db0f93 100644 --- a/switchsai/src/saivlan.c +++ b/switchsai/src/saivlan.c @@ -17,6 +17,8 @@ limitations under the License. #include #include "saiinternal.h" #include +#include +#include static sai_api_t api_id = SAI_API_VLAN; @@ -31,37 +33,33 @@ static sai_api_t api_id = SAI_API_VLAN; * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_create_vlan_entry( - _In_ sai_vlan_id_t vlan_id) { - - SAI_LOG_ENTER(); - - switch_handle_t vlan_handle = SWITCH_API_INVALID_HANDLE; - - sai_status_t status = SAI_STATUS_SUCCESS; - vlan_handle = switch_api_vlan_create(device, (switch_vlan_t) vlan_id); - - status = (vlan_handle == SWITCH_API_INVALID_HANDLE) ? - SAI_STATUS_FAILURE : - SAI_STATUS_SUCCESS; - - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to create vlan %d: %s", - vlan_id, sai_status_to_string(status)); - } else { - /* enable IGMP and MLD snooping by default */ - switch_status_t switch_status; - switch_status = switch_api_vlan_igmp_snooping_enabled_set( - vlan_handle, true); - assert(switch_status == SWITCH_STATUS_SUCCESS); - switch_status = switch_api_vlan_mld_snooping_enabled_set( - vlan_handle, true); - assert(switch_status == SWITCH_STATUS_SUCCESS); - } +sai_status_t sai_create_vlan_entry(_In_ sai_vlan_id_t vlan_id) { + SAI_LOG_ENTER(); + + switch_handle_t vlan_handle = SWITCH_API_INVALID_HANDLE; + + sai_status_t status = SAI_STATUS_SUCCESS; + vlan_handle = switch_api_vlan_create(device, (switch_vlan_t)vlan_id); + + status = (vlan_handle == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE + : SAI_STATUS_SUCCESS; + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR( + "failed to create vlan %d: %s", vlan_id, sai_status_to_string(status)); + } else { + /* enable IGMP and MLD snooping by default */ + switch_status_t switch_status; + switch_status = + switch_api_vlan_igmp_snooping_enabled_set(vlan_handle, true); + assert(switch_status == SWITCH_STATUS_SUCCESS); + switch_status = switch_api_vlan_mld_snooping_enabled_set(vlan_handle, true); + assert(switch_status == SWITCH_STATUS_SUCCESS); + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -75,35 +73,33 @@ sai_status_t sai_create_vlan_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_remove_vlan_entry( - _In_ sai_vlan_id_t vlan_id) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_handle_t vlan_handle = 0; - - switch_status = switch_api_vlan_id_to_handle_get((switch_vlan_t) vlan_id, - &vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - - switch_status = switch_api_vlan_delete(device, vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to remove vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - - SAI_LOG_EXIT(); - - return (sai_status_t) status; +sai_status_t sai_remove_vlan_entry(_In_ sai_vlan_id_t vlan_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_handle_t vlan_handle = 0; + + switch_status = + switch_api_vlan_id_to_handle_get((switch_vlan_t)vlan_id, &vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR( + "failed to remove vlan %d: %s", vlan_id, sai_status_to_string(status)); + return status; + } + + switch_status = switch_api_vlan_delete(device, vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR( + "failed to remove vlan %d: %s", vlan_id, sai_status_to_string(status)); + return status; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* @@ -118,24 +114,21 @@ sai_status_t sai_remove_vlan_entry( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_set_vlan_entry_attribute( - _In_ sai_vlan_id_t vlan_id, - _In_ const sai_attribute_t *attr) { - - SAI_LOG_ENTER(); +sai_status_t sai_set_vlan_entry_attribute(_In_ sai_vlan_id_t vlan_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute: %s", - sai_status_to_string(status)); - return status; - } + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -151,25 +144,22 @@ sai_status_t sai_set_vlan_entry_attribute( * SAI_STATUS_SUCCESS on success * Failure status code on error */ -sai_status_t sai_get_vlan_entry_attribute( - _In_ sai_vlan_id_t vlan_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) { - - SAI_LOG_ENTER(); +sai_status_t sai_get_vlan_entry_attribute(_In_ sai_vlan_id_t vlan_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - if (!attr_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null attribute list: %s", - sai_status_to_string(status)); - return status; - } + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* @@ -184,207 +174,245 @@ sai_status_t sai_get_vlan_entry_attribute( * Failure status code on error */ sai_status_t sai_remove_all_vlans(void) { + SAI_LOG_ENTER(); - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; + sai_status_t status = SAI_STATUS_SUCCESS; - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* -* Routine Description: -* Add Port to VLAN -* -* Arguments: -* [in] vlan_id - VLAN id -* [in] port_count - number of ports -* [in] port_list - pointer to membership structures -* -* Return Values: -* SAI_STATUS_SUCCESS on success -* Failure status code on error + \brief Create VLAN Member + \param[out] vlan_member_id VLAN member ID + \param[in] attr_count number of attributes + \param[in] attr_list array of attributes + \return Success: SAI_STATUS_SUCCESS + Failure: failure status code on error */ -sai_status_t sai_add_ports_to_vlan( - _In_ sai_vlan_id_t vlan_id, - _In_ uint32_t port_count, - _In_ const sai_vlan_port_t* port_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_handle_t vlan_handle = 0; - switch_vlan_port_t *switch_port_list; - uint32_t index = 0; - - if (!port_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null port list: %s", - sai_status_to_string(status)); - return status; - } - - switch_status = switch_api_vlan_id_to_handle_get((switch_vlan_t) vlan_id, &vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to add ports to vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; +sai_status_t sai_create_vlan_member(_Out_ sai_object_id_t *vlan_member_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_ENTER(); + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_handle_t vlan_handle = 0; + switch_vlan_port_t switch_port; + unsigned int index = 0; + sai_vlan_tagging_mode_t tag_mode = SAI_VLAN_PORT_UNTAGGED; + unsigned short vlan_id = 0; + switch_handle_t port_id = 0; + + memset(vlan_member_id, 0, sizeof(sai_object_id_t)); + memset(&switch_port, 0, sizeof(switch_port)); + for (index = 0; index < attr_count; index++) { + switch (attr_list[index].id) { + case SAI_VLAN_MEMBER_ATTR_VLAN_ID: + vlan_id = attr_list[index].value.u16; + break; + case SAI_VLAN_MEMBER_ATTR_PORT_ID: + port_id = (switch_handle_t)attr_list[index].value.oid; + break; + case SAI_VLAN_MEMBER_ATTR_TAGGING_MODE: + tag_mode = attr_list[index].value.s32; + break; + default: + // NEED error checking here! + break; } - - switch_port_list = (switch_vlan_port_t *) SAI_MALLOC(sizeof(switch_vlan_port_t) * port_count); - if (!switch_port_list) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to add ports to vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - - for (index = 0; index < port_count; index++) { - switch_port_list[index].handle = (switch_handle_t) port_list[index].port_id; - switch_port_list[index].tagging_mode = (switch_vlan_tagging_mode_t) port_list[index].tagging_mode; - } - switch_status = switch_api_vlan_ports_add(device, vlan_handle, port_count, switch_port_list); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_FREE(switch_port_list); - SAI_LOG_ERROR("failed to add ports to vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - - SAI_FREE(switch_port_list); - - SAI_LOG_EXIT(); - - return (sai_status_t) status; + } + + switch_status = + switch_api_vlan_id_to_handle_get((switch_vlan_t)vlan_id, &vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to add ports to vlan %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + + switch_port.handle = port_id; + switch_port.tagging_mode = tag_mode; + 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 ports to vlan %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + + // make it from port and vlan (no storage of handle) + *vlan_member_id = 0 | (port_id & 0xFFF) | (vlan_id << 12) | + (SWITCH_HANDLE_TYPE_VLAN_MEMBER << HANDLE_TYPE_SHIFT); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } /* -* Routine Description: -* Remove Port from VLAN -* -* Arguments: -* [in] vlan_id - VLAN id -* [in] port_count - number of ports -* [in] port_list - pointer to membership structures -* -* Return Values: -* SAI_STATUS_SUCCESS on success -* Failure status code on error + \brief Remove VLAN Member + \param[in] vlan_member_id VLAN member ID + \return Success: SAI_STATUS_SUCCESS + Failure: failure status code on error */ -sai_status_t sai_remove_ports_from_vlan( - _In_ sai_vlan_id_t vlan_id, - _In_ uint32_t port_count, - _In_ const sai_vlan_port_t* port_list) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - switch_handle_t vlan_handle = 0; - switch_vlan_port_t *switch_port_list; - uint32_t index = 0; - - if (!port_list) { - status = SAI_STATUS_INVALID_PARAMETER; - SAI_LOG_ERROR("null port list: %s", - sai_status_to_string(status)); - return status; - } +sai_status_t sai_remove_vlan_member(_In_ sai_object_id_t vlan_member_id) { + sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_ENTER(); + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_handle_t vlan_handle = 0; + switch_vlan_port_t switch_port; + // sai_vlan_tagging_mode_t tag_mode=SAI_VLAN_PORT_UNTAGGED; + unsigned short vlan_id; + + memset(&switch_port, 0, sizeof(switch_port)); + // check the OID for handle type? + switch_port.handle = + id_to_handle(SWITCH_HANDLE_TYPE_PORT, (vlan_member_id & 0xFFF)); + vlan_id = (vlan_member_id >> 12) & 0xFFF; + switch_status = + switch_api_vlan_id_to_handle_get((switch_vlan_t)vlan_id, &vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to del port from vlan (no VLAN) %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + + switch_status = + switch_api_vlan_ports_remove(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 del ports from vlan %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} - switch_status = switch_api_vlan_id_to_handle_get((switch_vlan_t) vlan_id, &vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to rremove ports from vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } +/* + \brief Set VLAN Member Attribute + \param[in] vlan_member_id VLAN member ID + \param[in] attr attribute structure containing ID and value + \return Success: SAI_STATUS_SUCCESS + Failure: failure status code on error +*/ +sai_status_t sai_set_vlan_member_attribute(_In_ sai_object_id_t vlan_member_id, + _In_ const sai_attribute_t *attr) { + sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_ENTER(); - switch_port_list = (switch_vlan_port_t *) SAI_MALLOC(sizeof(switch_vlan_port_t) * port_count); - if (!switch_port_list) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to remove ports from vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } + SAI_LOG_EXIT(); - for (index = 0; index < port_count; index++) { - switch_port_list[index].handle = (switch_handle_t) port_list[index].port_id; - switch_port_list[index].tagging_mode = (switch_vlan_tagging_mode_t) port_list[index].tagging_mode; - } + return (sai_status_t)status; +} - switch_status = switch_api_vlan_ports_remove(device, vlan_handle, port_count, switch_port_list); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_FREE(switch_port_list); - SAI_LOG_ERROR("failed to add ports to vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } +/* + \brief Get VLAN Member Attribute + \param[in] vlan_member_id VLAN member ID + \param[in] attr_count number of attributes + \param[in,out] attr_list list of attribute structures containing ID and + value + \return Success: SAI_STATUS_SUCCESS + Failure: failure status code on error +*/ +sai_status_t sai_get_vlan_member_attribute(_In_ sai_object_id_t vlan_member_id, + _In_ const uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { + sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_ENTER(); - SAI_FREE(switch_port_list); + SAI_LOG_EXIT(); - SAI_LOG_EXIT(); + return (sai_status_t)status; +} - return (sai_status_t) status; +/** + * Routine Description: + * @brief Clear vlan statistics counters. + * + * Arguments: + * @param[in] vlan_id - vlan id + * @param[in] counter_ids - specifies the array of counter ids + * @param[in] number_of_counters - number of counters in the array + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_clear_vlan_stats( + _In_ sai_vlan_id_t vlan_id, + _In_ const sai_vlan_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters) { + sai_status_t status = SAI_STATUS_SUCCESS; + SAI_LOG_ENTER(); + + SAI_LOG_EXIT(); + + return (sai_status_t)status; } -static sai_status_t -switch_vlan_counters_to_sai_vlan_counters( - _In_ uint32_t number_of_counters, - _In_ const sai_vlan_stat_counter_t *counter_ids, - _In_ switch_counter_t *switch_counters, - _Out_ uint64_t *counters) { - uint32_t index = 0; - for (index = 0; index < number_of_counters; index++) { - switch (counter_ids[index]) { - case SAI_VLAN_STAT_IN_OCTETS: - counters[index] = - switch_counters[SWITCH_VLAN_STATS_IN_UCAST].num_bytes + - switch_counters[SWITCH_VLAN_STATS_IN_MCAST].num_bytes + - switch_counters[SWITCH_VLAN_STATS_IN_BCAST].num_bytes; - break; - case SAI_VLAN_STAT_IN_UCAST_PKTS: - counters[index] = - switch_counters[SWITCH_VLAN_STATS_IN_UCAST].num_packets; - break; - case SAI_VLAN_STAT_IN_NON_UCAST_PKTS: - counters[index] = - switch_counters[SWITCH_VLAN_STATS_IN_MCAST].num_packets + - switch_counters[SWITCH_VLAN_STATS_IN_BCAST].num_packets; - break; - case SAI_VLAN_STAT_IN_DISCARDS: - case SAI_VLAN_STAT_IN_ERRORS: - case SAI_VLAN_STAT_IN_UNKNOWN_PROTOS: - counters[index] = 0; - break; - case SAI_VLAN_STAT_OUT_OCTETS: - counters[index] = - switch_counters[SWITCH_VLAN_STATS_OUT_UCAST].num_bytes + - switch_counters[SWITCH_VLAN_STATS_OUT_MCAST].num_bytes + - switch_counters[SWITCH_VLAN_STATS_OUT_BCAST].num_bytes; - break; - case SAI_VLAN_STAT_OUT_UCAST_PKTS: - counters[index] = - switch_counters[SWITCH_VLAN_STATS_OUT_UCAST].num_packets; - break; - case SAI_VLAN_STAT_OUT_NON_UCAST_PKTS: - counters[index] = - switch_counters[SWITCH_VLAN_STATS_OUT_MCAST].num_packets + - switch_counters[SWITCH_VLAN_STATS_OUT_BCAST].num_packets; - break; - case SAI_VLAN_STAT_OUT_DISCARDS: - case SAI_VLAN_STAT_OUT_ERRORS: - case SAI_VLAN_STAT_OUT_QLEN: - counters[index] = 0; - break; - } +static sai_status_t switch_vlan_counters_to_sai_vlan_counters( + _In_ uint32_t number_of_counters, + _In_ const sai_vlan_stat_counter_t *counter_ids, + _In_ switch_counter_t *switch_counters, + _Out_ uint64_t *counters) { + uint32_t index = 0; + for (index = 0; index < number_of_counters; index++) { + switch (counter_ids[index]) { + case SAI_VLAN_STAT_IN_OCTETS: + counters[index] = switch_counters[SWITCH_BD_STATS_IN_UCAST].num_bytes + + switch_counters[SWITCH_BD_STATS_IN_MCAST].num_bytes + + switch_counters[SWITCH_BD_STATS_IN_BCAST].num_bytes; + break; + case SAI_VLAN_STAT_IN_UCAST_PKTS: + counters[index] = switch_counters[SWITCH_BD_STATS_IN_UCAST].num_packets; + break; + case SAI_VLAN_STAT_IN_NON_UCAST_PKTS: + counters[index] = + switch_counters[SWITCH_BD_STATS_IN_MCAST].num_packets + + switch_counters[SWITCH_BD_STATS_IN_BCAST].num_packets; + break; + case SAI_VLAN_STAT_IN_DISCARDS: + case SAI_VLAN_STAT_IN_ERRORS: + case SAI_VLAN_STAT_IN_UNKNOWN_PROTOS: + counters[index] = 0; + break; + case SAI_VLAN_STAT_OUT_OCTETS: + counters[index] = switch_counters[SWITCH_BD_STATS_OUT_UCAST].num_bytes + + switch_counters[SWITCH_BD_STATS_OUT_MCAST].num_bytes + + switch_counters[SWITCH_BD_STATS_OUT_BCAST].num_bytes; + break; + case SAI_VLAN_STAT_OUT_UCAST_PKTS: + counters[index] = + switch_counters[SWITCH_BD_STATS_OUT_UCAST].num_packets; + break; + case SAI_VLAN_STAT_OUT_NON_UCAST_PKTS: + counters[index] = + switch_counters[SWITCH_BD_STATS_OUT_MCAST].num_packets + + switch_counters[SWITCH_BD_STATS_OUT_BCAST].num_packets; + break; + case SAI_VLAN_STAT_OUT_DISCARDS: + case SAI_VLAN_STAT_OUT_ERRORS: + case SAI_VLAN_STAT_OUT_QLEN: + counters[index] = 0; + break; + case SAI_VLAN_STAT_IN_PACKETS: + case SAI_VLAN_STAT_OUT_PACKETS: + SAI_LOG_WARN("Unsupported attribute"); + break; } - return SAI_STATUS_SUCCESS; + } + return SAI_STATUS_SUCCESS; } /* @@ -400,97 +428,95 @@ switch_vlan_counters_to_sai_vlan_counters( * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error -*/ -sai_status_t sai_get_vlan_stats( - _In_ sai_vlan_id_t vlan_id, - _In_ const sai_vlan_stat_counter_t *counter_ids, - _In_ uint32_t number_of_counters, - _Out_ uint64_t* counters) { - - SAI_LOG_ENTER(); - - sai_status_t status = SAI_STATUS_SUCCESS; - switch_counter_t *switch_counters = NULL; - switch_vlan_stats_t *vlan_stat_ids = NULL; - switch_handle_t vlan_handle = 0; - switch_status_t switch_status = SWITCH_STATUS_SUCCESS; - uint32_t index = 0; - - switch_status = switch_api_vlan_id_to_handle_get((switch_vlan_t) vlan_id, &vlan_handle); - status = sai_switch_status_to_sai_status(switch_status); - if (status != SAI_STATUS_SUCCESS) { - SAI_LOG_ERROR("failed to rremove ports from vlan %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - - switch_counters = SAI_MALLOC(sizeof(switch_counter_t) * SWITCH_VLAN_STATS_MAX); - if (!switch_counters) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to get vlan stats %d: %s", - vlan_id, sai_status_to_string(status)); - return status; - } - - vlan_stat_ids = SAI_MALLOC(sizeof(switch_vlan_stats_t) * SWITCH_VLAN_STATS_MAX); - if (!vlan_stat_ids) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to get vlan stats %d: %s", - vlan_id, sai_status_to_string(status)); - SAI_FREE(switch_counters); - return status; - } - - for (index = 0; index < SWITCH_VLAN_STATS_MAX; index++) { - vlan_stat_ids[index] = index; - } - - switch_status = switch_api_vlan_stats_get( - device, - vlan_handle, - SWITCH_VLAN_STATS_MAX, - vlan_stat_ids, - switch_counters); - status = sai_switch_status_to_sai_status(switch_status); - - if (status != SWITCH_STATUS_SUCCESS) { - status = SAI_STATUS_NO_MEMORY; - SAI_LOG_ERROR("failed to get vlan stats %d: %s", - vlan_id, sai_status_to_string(status)); - SAI_FREE(vlan_stat_ids); - SAI_FREE(switch_counters); - return status; - } - - switch_vlan_counters_to_sai_vlan_counters( - number_of_counters, - counter_ids, - switch_counters, - counters); - +*/ +sai_status_t sai_get_vlan_stats(_In_ sai_vlan_id_t vlan_id, + _In_ const sai_vlan_stat_counter_t *counter_ids, + _In_ uint32_t number_of_counters, + _Out_ uint64_t *counters) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_counter_t *switch_counters = NULL; + switch_bd_stats_id_t *vlan_stat_ids = NULL; + switch_handle_t vlan_handle = 0; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + uint32_t index = 0; + + switch_status = + switch_api_vlan_id_to_handle_get((switch_vlan_t)vlan_id, &vlan_handle); + status = sai_switch_status_to_sai_status(switch_status); + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to rremove ports from vlan %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + + switch_counters = SAI_MALLOC(sizeof(switch_counter_t) * SWITCH_BD_STATS_MAX); + if (!switch_counters) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to get vlan stats %d: %s", + vlan_id, + sai_status_to_string(status)); + return status; + } + + vlan_stat_ids = + SAI_MALLOC(sizeof(switch_bd_stats_id_t) * SWITCH_BD_STATS_MAX); + if (!vlan_stat_ids) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to get vlan stats %d: %s", + vlan_id, + sai_status_to_string(status)); + SAI_FREE(switch_counters); + return status; + } + + for (index = 0; index < SWITCH_BD_STATS_MAX; index++) { + vlan_stat_ids[index] = index; + } + + switch_status = switch_api_vlan_stats_get( + device, vlan_handle, SWITCH_BD_STATS_MAX, vlan_stat_ids, switch_counters); + status = sai_switch_status_to_sai_status(switch_status); + + if (status != SWITCH_STATUS_SUCCESS) { + status = SAI_STATUS_NO_MEMORY; + SAI_LOG_ERROR("failed to get vlan stats %d: %s", + vlan_id, + sai_status_to_string(status)); SAI_FREE(vlan_stat_ids); SAI_FREE(switch_counters); + return status; + } + + switch_vlan_counters_to_sai_vlan_counters( + number_of_counters, counter_ids, switch_counters, counters); + + SAI_FREE(vlan_stat_ids); + SAI_FREE(switch_counters); - SAI_LOG_EXIT(); + SAI_LOG_EXIT(); - return (sai_status_t) status; + return (sai_status_t)status; } /* * VLAN methods table retrieved with sai_api_query() */ sai_vlan_api_t vlan_api = { - .create_vlan = sai_create_vlan_entry, - .remove_vlan = sai_remove_vlan_entry, - .set_vlan_attribute = sai_set_vlan_entry_attribute, - .get_vlan_attribute = sai_get_vlan_entry_attribute, - .add_ports_to_vlan = sai_add_ports_to_vlan, - .remove_ports_from_vlan = sai_remove_ports_from_vlan, - .remove_all_vlans = sai_remove_all_vlans, - .get_vlan_stats = sai_get_vlan_stats -}; + .create_vlan = sai_create_vlan_entry, + .remove_vlan = sai_remove_vlan_entry, + .set_vlan_attribute = sai_set_vlan_entry_attribute, + .get_vlan_attribute = sai_get_vlan_entry_attribute, + .create_vlan_member = sai_create_vlan_member, + .remove_vlan_member = sai_remove_vlan_member, + .set_vlan_member_attribute = sai_set_vlan_member_attribute, + .get_vlan_member_attribute = sai_get_vlan_member_attribute, + .get_vlan_stats = sai_get_vlan_stats, + .clear_vlan_stats = sai_clear_vlan_stats}; sai_status_t sai_vlan_initialize(sai_api_service_t *sai_api_service) { - sai_api_service->vlan_api = vlan_api; - return SAI_STATUS_SUCCESS; + sai_api_service->vlan_api = vlan_api; + return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/switch_sai.thrift b/switchsai/src/switch_sai.thrift index 0696e63..6c0ee5c 100644 --- a/switchsai/src/switch_sai.thrift +++ b/switchsai/src/switch_sai.thrift @@ -118,6 +118,21 @@ struct sai_thrift_acl_action_data_t { 2: sai_thrift_acl_parameter_t parameter; } +struct sai_thrift_qos_map_params_t { + 1: byte tc; + 2: byte dscp; + 3: byte dot1p; + 4: byte prio; + 5: byte pg; + 6: byte queue_index; + 7: i32 color; +} + +struct sai_thrift_qos_map_list_t { + 1: list key; + 2: list data; +} + union sai_thrift_attribute_value_t { 1: bool booldata; 2: string chardata; @@ -138,6 +153,7 @@ union sai_thrift_attribute_value_t { 17: sai_thrift_vlan_list_t vlanlist; 18: sai_thrift_acl_field_data_t aclfield; 19: sai_thrift_acl_action_data_t aclaction; + 20: sai_thrift_qos_map_list_t qosmap; } struct sai_thrift_attribute_t { @@ -145,6 +161,11 @@ struct sai_thrift_attribute_t { 2: sai_thrift_attribute_value_t value; } +struct sai_thrift_get_response_t { + 1: sai_thrift_status_t status; + 2: list attributes; +} + struct sai_thrift_unicast_route_entry_t { 1: sai_thrift_object_id_t vr_id; 2: sai_thrift_ip_prefix_t destination; @@ -172,8 +193,8 @@ service switch_sai_rpc { //vlan API sai_thrift_status_t sai_thrift_create_vlan(1: sai_thrift_vlan_id_t vlan_id); sai_thrift_status_t sai_thrift_delete_vlan(1: sai_thrift_vlan_id_t vlan_id); - sai_thrift_status_t sai_thrift_add_ports_to_vlan(1: sai_thrift_vlan_id_t vlan_id, 2: list thrift_port_list); - sai_thrift_status_t sai_thrift_remove_ports_from_vlan(1: sai_thrift_vlan_id_t vlan_id, 2: list thrift_port_list); + sai_thrift_object_id_t sai_thrift_create_vlan_member(1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_remove_vlan_member(1: sai_thrift_object_id_t vlan_member_id); list sai_thrift_get_vlan_stats( 1: sai_thrift_vlan_id_t vlan_id, 2: list counter_ids, @@ -190,10 +211,14 @@ service switch_sai_rpc { //router interface API sai_thrift_object_id_t sai_thrift_create_router_interface(1: list thrift_attr_list); sai_thrift_status_t sai_thrift_remove_router_interface(1: sai_thrift_object_id_t rif_id); + sai_thrift_get_response_t sai_thrift_get_router_interface_attribute(1: sai_thrift_object_id_t rif_id, + 2: i32 attr_count, 3: list thrift_attr_list); //next hop API sai_thrift_object_id_t sai_thrift_create_next_hop(1: list thrift_attr_list); sai_thrift_status_t sai_thrift_remove_next_hop(1: sai_thrift_object_id_t next_hop_id); + sai_thrift_get_response_t sai_thrift_get_next_hop_attribute(1: sai_thrift_object_id_t next_hop_id, 2: i32 attr_count, 3: list thrift_attr_list); + sai_thrift_status_t sai_thrift_set_next_hop_attribute(1: sai_thrift_object_id_t next_hop_id, 2: list single_attribute); //next hop group API sai_thrift_object_id_t sai_thrift_create_next_hop_group(1: list thrift_attr_list); @@ -253,4 +278,46 @@ service switch_sai_rpc { list sai_thrift_get_policer_stats( 1: sai_thrift_object_id_t policer_id, 2: list counter_ids) + + //Buffer API + sai_thrift_object_id_t sai_thrift_create_buffer_pool( + 1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_remove_buffer_pool( + 1: sai_thrift_object_id_t pool_id); + sai_thrift_object_id_t sai_thrift_create_buffer_profile( + 1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_remove_buffer_profile( + 1: sai_thrift_object_id_t buffer_profile_id); + sai_thrift_status_t sai_thrift_set_ingress_priority_group_attribute( + 1: sai_thrift_object_id_t ingress_pg_id, + 2: sai_thrift_attribute_t thrift_attr); + + //Scheduler API + sai_thrift_object_id_t sai_thrift_create_scheduler_profile( + 1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_remove_scheduler_profile( + 1: sai_thrift_object_id_t scheduler_id); + + //Scheduler Group API + sai_thrift_object_id_t sai_thrift_create_scheduler_group( + 1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_remove_scheduler_group( + 1: sai_thrift_object_id_t scheduler_group_id); + sai_thrift_status_t sai_thrift_add_child_object_to_group( + 1: sai_thrift_object_id_t scheduler_group_id, + 2: list thrift_child_objects); + sai_thrift_status_t sai_thrift_remove_child_object_from_group( + 1: sai_thrift_object_id_t scheduler_group_id, + 2: list thrift_child_objects); + + //Qos Maps + sai_thrift_object_id_t sai_thrift_create_qos_map( + 1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_remove_qos_map( + 1: sai_thrift_object_id_t qos_map_id); + + //Queue + sai_thrift_status_t sai_thrift_set_queue_attribute( + 1: sai_thrift_object_id_t queue_id, + 2: sai_thrift_attribute_t thrift_attr); } diff --git a/switchsai/src/switch_sai_rpc_server.cpp b/switchsai/src/switch_sai_rpc_server.cpp index dffdb29..acbffc7 100644 --- a/switchsai/src/switch_sai_rpc_server.cpp +++ b/switchsai/src/switch_sai_rpc_server.cpp @@ -113,6 +113,14 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return; } + void sai_v4_ip_to_thrift_string(std::string s, unsigned int *m) { + return; + } + + void sai_to_v6_ip_thrift_string(std::string s, unsigned char *v6_ip) { + return; + } + void sai_thrift_parse_object_id_list(const std::vector & thrift_object_id_list, sai_object_id_t *object_id_list) { std::vector::const_iterator it = thrift_object_id_list.begin(); for(uint32_t i = 0; i < thrift_object_id_list.size(); i++, it++) { @@ -120,13 +128,25 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { } } - void sai_thrift_parse_vlan_port_id_list(const std::vector & thrift_port_list, sai_vlan_port_t *port_list) { - std::vector::const_iterator it = thrift_port_list.begin(); - sai_thrift_vlan_port_t thrift_vlan_port; - for(uint32_t i = 0; i < thrift_port_list.size(); i++, it++) { - thrift_vlan_port = (sai_thrift_vlan_port_t)*it; - port_list[i].port_id = thrift_vlan_port.port_id; - port_list[i].tagging_mode = (sai_vlan_tagging_mode_t) thrift_vlan_port.tagging_mode; + void sai_thrift_parse_vlan_member_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_VLAN_MEMBER_ATTR_VLAN_ID: + attr_list[i].value.u16 = attribute.value.u16; + break; + case SAI_VLAN_MEMBER_ATTR_PORT_ID: + attr_list[i].value.oid = attribute.value.oid; + break; + case SAI_VLAN_MEMBER_ATTR_TAGGING_MODE: + attr_list[i].value.s32 = attribute.value.s32; + break; + default: + break; + } } } @@ -139,6 +159,15 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { } } + void sai_thrift_deparse_ip_address(sai_thrift_ip_address_t &thrift_ip_address, sai_ip_address_t *ip_address) { + thrift_ip_address.addr_family = (sai_thrift_ip_addr_family_t) ip_address->addr_family; + if ((sai_ip_addr_family_t)thrift_ip_address.addr_family == SAI_IP_ADDR_FAMILY_IPV4) { + sai_v4_ip_to_thrift_string(thrift_ip_address.addr.ip4, &ip_address->addr.ip4); + } else { + sai_to_v6_ip_thrift_string(thrift_ip_address.addr.ip6, ip_address->addr.ip6); + } + } + void sai_thrift_parse_ip_prefix(const sai_thrift_ip_prefix_t &thrift_ip_prefix, sai_ip_prefix_t *ip_prefix) { ip_prefix->addr_family = (sai_ip_addr_family_t) thrift_ip_prefix.addr_family; if ((sai_ip_addr_family_t)thrift_ip_prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV4) { @@ -175,6 +204,16 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { case SAI_PORT_ATTR_PORT_VLAN_ID: attr_list[i].value.u16 = attribute.value.u16; break; + case SAI_PORT_ATTR_QOS_DOT1P_TO_TC_MAP: + case SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP: + case SAI_PORT_ATTR_QOS_DOT1P_TO_COLOR_MAP: + case SAI_PORT_ATTR_QOS_DSCP_TO_COLOR_MAP: + case SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP: + case SAI_PORT_ATTR_QOS_TC_TO_PRIORITY_GROUP_MAP: + case SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP: + case SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP: + attr_list[i].value.oid = attribute.value.oid; + break; default: break; } @@ -297,6 +336,37 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { } } + void sai_thrift_deparse_router_interface_attributes(std::vector &out_attr_list, + const std::vector &in_attr_list, sai_attribute_t *attr_list) { + std::vector::const_iterator it = in_attr_list.begin(); + sai_thrift_attribute_t attribute; + for(uint32_t i = 0; i < in_attr_list.size(); i++, it++) { + attribute = (sai_thrift_attribute_t)*it; + switch (attr_list[i].id) { + case SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID: + case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: + attribute.value.oid = attr_list[i].value.oid; + break; + case SAI_ROUTER_INTERFACE_ATTR_TYPE: + attribute.value.s32 = attr_list[i].value.s32; + break; + case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: + attribute.value.u16 = attr_list[i].value.u16; + break; + case SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS: +// sai_thrift_string_to_mac(attribute.value.mac, attr_list[i].value.mac); + break; + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: + case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: + attribute.value.booldata = attr_list[i].value.booldata; + break; + default: + break; + } + out_attr_list.push_back(attribute); + } + } + void sai_thrift_parse_next_hop_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; @@ -317,6 +387,26 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { } } + void sai_thrift_deparse_next_hop_attributes(std::vector &out_attr_list, const std::vector &in_attr_list, sai_attribute_t *attr_list) { + std::vector::const_iterator it = in_attr_list.begin(); + sai_thrift_attribute_t attribute; + for(uint32_t i = 0; i < in_attr_list.size(); i++, it++) { + attribute = (sai_thrift_attribute_t)*it; + switch (attr_list[i].id) { + case SAI_NEXT_HOP_ATTR_TYPE: + attribute.value.s32 = attr_list[i].value.s32; + break; + case SAI_NEXT_HOP_ATTR_IP: + sai_thrift_deparse_ip_address(attribute.value.ipaddr, &attr_list[i].value.ipaddr); + break; + case SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID: + attribute.value.oid = attr_list[i].value.oid; + break; + } + out_attr_list.push_back(attribute); + } + } + void sai_thrift_parse_next_hop_group_attributes(const std::vector &thrift_attr_list, sai_attribute_t *attr_list, sai_object_id_t **nhop_list) { std::vector::const_iterator it1 = thrift_attr_list.begin(); sai_thrift_attribute_t attribute; @@ -397,8 +487,8 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { for (uint32_t j = 0; j < attribute.value.vlanlist.vlan_list.size(); j++, *it2++) { *vlan_list[j] = (sai_vlan_id_t) *it2; } - attr_list[i].value.vlanlist.vlan_count = attribute.value.vlanlist.vlan_count; - attr_list[i].value.vlanlist.vlan_list = *vlan_list; + attr_list[i].value.vlanlist.count = attribute.value.vlanlist.vlan_count; + attr_list[i].value.vlanlist.list = *vlan_list; break; } } @@ -448,8 +538,8 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { case SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE: attr_list[i].value.u32 = attribute.value.u32; break; - case SAI_HOSTIF_TRAP_GROUP_ATTR_PRIO: - attr_list[i].value.u32 = attribute.value.u32; + case SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER: + attr_list[i].value.oid = attribute.value.oid; break; } } @@ -588,35 +678,31 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return status; } - int32_t sai_thrift_add_ports_to_vlan(const sai_thrift_vlan_id_t vlan_id, const std::vector & thrift_port_list) { - printf("sai_thrift_add_ports_to_vlan\n"); + sai_thrift_object_id_t sai_thrift_create_vlan_member(const std::vector & thrift_attr_list) { + printf("sai_thrift_create_vlan_member\n"); sai_status_t status = SAI_STATUS_SUCCESS; sai_vlan_api_t *vlan_api; + sai_object_id_t vlan_member_id = 0; status = sai_api_query(SAI_API_VLAN, (void **) &vlan_api); if (status != SAI_STATUS_SUCCESS) { return status; } - sai_vlan_port_t *port_list = (sai_vlan_port_t *) malloc(sizeof(sai_vlan_port_t) * thrift_port_list.size()); - sai_thrift_parse_vlan_port_id_list(thrift_port_list, port_list); - uint32_t port_count = thrift_port_list.size(); - status = vlan_api->add_ports_to_vlan(vlan_id, port_count, port_list); - free(port_list); - return status; + uint32_t attr_count = thrift_attr_list.size(); + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_vlan_member_attributes(thrift_attr_list, attr_list); + status = vlan_api->create_vlan_member(&vlan_member_id, attr_count, attr_list); + return vlan_member_id; } - int32_t sai_thrift_remove_ports_from_vlan(const sai_thrift_vlan_id_t vlan_id, const std::vector & thrift_port_list) { - printf("sai_thrift_remove_ports_from_vlan\n"); + sai_thrift_status_t sai_thrift_remove_vlan_member(const sai_thrift_object_id_t vlan_member_id) { + printf("sai_thrift_remove_vlan_member\n"); sai_status_t status = SAI_STATUS_SUCCESS; sai_vlan_api_t *vlan_api; status = sai_api_query(SAI_API_VLAN, (void **) &vlan_api); if (status != SAI_STATUS_SUCCESS) { return status; } - sai_vlan_port_t *port_list = (sai_vlan_port_t *) malloc(sizeof(sai_vlan_port_t) * thrift_port_list.size()); - sai_thrift_parse_vlan_port_id_list(thrift_port_list, port_list); - uint32_t port_count = thrift_port_list.size(); - status = vlan_api->remove_ports_from_vlan(vlan_id, port_count, port_list); - free(port_list); + status = vlan_api->remove_vlan_member(vlan_member_id); return status; } @@ -741,6 +827,24 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return status; } + void sai_thrift_get_router_interface_attribute(sai_thrift_get_response_t& _return, const sai_thrift_object_id_t rif_id, + const int32_t attr_count, const std::vector & thrift_attr_list) { + printf("sai_thrift_get_router_interface_attribute\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_router_interface_api_t *rif_api; + status = sai_api_query(SAI_API_ROUTER_INTERFACE, (void **) &rif_api); + if (status != SAI_STATUS_SUCCESS) { + _return.status = status;; + return; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_router_interface_attributes(thrift_attr_list, attr_list); + status = rif_api->get_router_interface_attribute(rif_id, attr_count, attr_list); + _return.status; + + sai_thrift_deparse_router_interface_attributes(_return.attributes, thrift_attr_list, attr_list); + } + sai_thrift_object_id_t sai_thrift_create_next_hop(const std::vector & thrift_attr_list) { printf("sai_thrift_create_next_hop\n"); sai_status_t status = SAI_STATUS_SUCCESS; @@ -769,6 +873,44 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return status; } + void sai_thrift_get_next_hop_attribute(sai_thrift_get_response_t & _return, const sai_thrift_object_id_t next_hop_id, + const int32_t attr_count, const std::vector & thrift_attr_list) { + printf("sai_thrift_get_next_hop_attribute\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_next_hop_api_t *nhop_api; + status = sai_api_query(SAI_API_NEXT_HOP, (void **) &nhop_api); + if (status != SAI_STATUS_SUCCESS) { + _return.status = status; + return; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_next_hop_attributes(thrift_attr_list, attr_list); + + status = nhop_api->get_next_hop_attribute(next_hop_id, attr_count, attr_list); + _return.status = status; + + sai_thrift_deparse_next_hop_attributes(_return.attributes, thrift_attr_list, attr_list); + } + + sai_thrift_status_t sai_thrift_set_next_hop_attribute(const sai_thrift_object_id_t next_hop_id, const std::vector & single_attribute) { + printf("sai_thrift_set_next_hop_attribute\n"); + + // ensure singleton list + assert(single_attribute.size() == 1); + + sai_status_t status = SAI_STATUS_SUCCESS; + sai_next_hop_api_t *nhop_api; + status = sai_api_query(SAI_API_NEXT_HOP, (void **) &nhop_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * single_attribute.size()); + sai_thrift_parse_next_hop_attributes(single_attribute, attr_list); + + status = nhop_api->set_next_hop_attribute(next_hop_id, attr_list); + return status; + } + sai_thrift_object_id_t sai_thrift_create_next_hop_group(const std::vector & thrift_attr_list) { printf("sai_thrift_create_next_hop_group\n"); sai_status_t status = SAI_STATUS_SUCCESS; @@ -955,6 +1097,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { sai_neighbor_api_t *neighbor_api; status = sai_api_query(SAI_API_NEIGHBOR, (void **) &neighbor_api); sai_neighbor_entry_t neighbor_entry; + memset(&neighbor_entry, 0, sizeof(neighbor_entry)); if (status != SAI_STATUS_SUCCESS) { return status; } @@ -972,6 +1115,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { sai_status_t status = SAI_STATUS_SUCCESS; sai_neighbor_api_t *neighbor_api; sai_neighbor_entry_t neighbor_entry; + memset(&neighbor_entry, 0, sizeof(neighbor_entry)); status = sai_api_query(SAI_API_NEIGHBOR, (void **) &neighbor_api); if (status != SAI_STATUS_SUCCESS) { return status; @@ -1101,7 +1245,14 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { sai_thrift_status_t sai_thrift_remove_hostif_trap(const sai_thrift_hostif_trap_id_t trap_id) { printf("sai_thrift_remove_hostif_trap\n"); - return 0; + sai_status_t status = SAI_STATUS_SUCCESS; + sai_hostif_api_t *hostif_api = NULL; + status = sai_api_query(SAI_API_HOST_INTERFACE, (void **) &hostif_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = hostif_api->set_trap_attribute((sai_hostif_trap_id_t) trap_id, NULL); + return status; } sai_thrift_status_t sai_thrift_set_hostif_trap(const sai_thrift_hostif_trap_id_t trap_id, const sai_thrift_attribute_t& thrift_attr) { @@ -1508,6 +1659,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { sai_thrift_parse_mirror_session_attributes(thrift_attr_list, attr_list); uint32_t attr_count = thrift_attr_list.size(); mirror_api->create_mirror_session(&session_id, attr_count, attr_list); + free(attr_list); return session_id; } @@ -1577,6 +1729,7 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { sai_thrift_parse_policer_attributes(thrift_attr_list, attr_list); uint32_t attr_count = thrift_attr_list.size(); policer_api->create_policer(&policer_id, attr_count, attr_list); + free(attr_list); return policer_id; } @@ -1625,6 +1778,432 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return; } + void sai_thrift_parse_buffer_pool_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_BUFFER_POOL_ATTR_SHARED_SIZE: + attr_list[i].value.u32 = attribute.value.u32; + break; + case SAI_BUFFER_POOL_ATTR_TYPE: + attr_list[i].value.u8 = attribute.value.u8; + break; + case SAI_BUFFER_POOL_ATTR_SIZE: + attr_list[i].value.u32 = attribute.value.u32; + break; + case SAI_BUFFER_POOL_ATTR_TH_MODE: + attr_list[i].value.u8 = attribute.value.u8; + break; + } + } + } + + sai_thrift_object_id_t sai_thrift_create_buffer_pool(const std::vector & thrift_attr_list) { + printf("sai_thrift_create_buffer_pool\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_buffer_api_t *buffer_api; + sai_object_id_t pool_id = 0; + status = sai_api_query(SAI_API_BUFFERS, (void **) &buffer_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_buffer_pool_attributes(thrift_attr_list, attr_list); + uint32_t attr_count = thrift_attr_list.size(); + buffer_api->create_buffer_pool(&pool_id, attr_count, attr_list); + free(attr_list); + return pool_id; + } + + sai_thrift_status_t sai_thrift_remove_buffer_pool(const sai_thrift_object_id_t pool_id) { + printf("sai_thrift_remove_buffer_pool\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_buffer_api_t *buffer_api; + status = sai_api_query(SAI_API_BUFFERS, (void **) &buffer_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = buffer_api->remove_buffer_pool(pool_id); + return status; + } + + void sai_thrift_parse_buffer_profile_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_BUFFER_PROFILE_ATTR_POOL_ID: + attr_list[i].value.u64 = attribute.value.u64; + break; + case SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE: + attr_list[i].value.u32 = attribute.value.u32; + break; + case SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH: + attr_list[i].value.u8 = attribute.value.u8; + break; + case SAI_BUFFER_PROFILE_ATTR_SHARED_STATIC_TH: + attr_list[i].value.u32 = attribute.value.u32; + break; + case SAI_BUFFER_PROFILE_ATTR_XOFF_TH: + attr_list[i].value.u32 = attribute.value.u32; + break; + case SAI_BUFFER_PROFILE_ATTR_XON_TH: + attr_list[i].value.u32 = attribute.value.u32; + break; + } + } + } + + sai_thrift_object_id_t sai_thrift_create_buffer_profile(const std::vector & thrift_attr_list) { + printf("sai_thrift_create_buffer_profile\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_buffer_api_t *buffer_api; + sai_object_id_t buffer_profile_id = 0; + status = sai_api_query(SAI_API_BUFFERS, (void **) &buffer_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_buffer_profile_attributes(thrift_attr_list, attr_list); + uint32_t attr_count = thrift_attr_list.size(); + buffer_api->create_buffer_profile(&buffer_profile_id, attr_count, attr_list); + free(attr_list); + return buffer_profile_id; + } + + sai_thrift_status_t sai_thrift_remove_buffer_profile(const sai_thrift_object_id_t buffer_profile_id) { + printf("sai_thrift_remove_buffer_profile\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_buffer_api_t *buffer_api; + status = sai_api_query(SAI_API_BUFFERS, (void **) &buffer_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = buffer_api->remove_buffer_profile(buffer_profile_id); + return status; + } + + sai_thrift_status_t sai_thrift_set_ingress_priority_group_attribute( + const sai_thrift_object_id_t ingress_pg_id, + const sai_thrift_attribute_t& thrift_attr) { + printf("sai_thrift_set_ingress_priority_group_attribute\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_buffer_api_t *buffer_api; + status = sai_api_query(SAI_API_BUFFERS, (void **) &buffer_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t attr; + memset(&attr, 0x0, sizeof(sai_attribute_t)); + attr.id = thrift_attr.id; + attr.value.oid = thrift_attr.value.oid; + + status = buffer_api->set_ingress_priority_group_attr(ingress_pg_id, &attr); + return status; + } + + void sai_thrift_parse_scheduler_profile_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_SCHEDULER_ATTR_SCHEDULING_ALGORITHM: + attr_list[i].value.u8 = attribute.value.u8; + break; + case SAI_SCHEDULER_ATTR_SCHEDULING_WEIGHT: + attr_list[i].value.u8 = attribute.value.u8; + break; + case SAI_SCHEDULER_ATTR_SHAPER_TYPE: + attr_list[i].value.u8 = attribute.value.u8; + break; + case SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_RATE: + attr_list[i].value.u64 = attribute.value.u64; + break; + case SAI_SCHEDULER_ATTR_MIN_BANDWIDTH_BURST_RATE: + attr_list[i].value.u64 = attribute.value.u64; + break; + case SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_RATE: + attr_list[i].value.u64 = attribute.value.u64; + break; + case SAI_SCHEDULER_ATTR_MAX_BANDWIDTH_BURST_RATE: + attr_list[i].value.u64 = attribute.value.u64; + break; + default: + break; + } + } + } + + sai_thrift_object_id_t sai_thrift_create_scheduler_profile( + const std::vector & thrift_attr_list) { + printf("sai_thrift_create_scheduler_profile\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_scheduler_api_t *scheduler_api; + sai_object_id_t scheduler_id = 0; + status = sai_api_query(SAI_API_SCHEDULER, (void **) &scheduler_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_scheduler_profile_attributes(thrift_attr_list, attr_list); + uint32_t attr_count = thrift_attr_list.size(); + scheduler_api->create_scheduler_profile(&scheduler_id, attr_count, attr_list); + free(attr_list); + return scheduler_id; + } + + sai_thrift_status_t sai_thrift_remove_scheduler_profile( + const sai_thrift_object_id_t scheduler_id) { + printf("sai_thrift_remove_scheduler_profile\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_scheduler_api_t *scheduler_api; + status = sai_api_query(SAI_API_SCHEDULER, (void **) &scheduler_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = scheduler_api->remove_scheduler_profile(scheduler_id); + return status; + } + + void sai_thrift_parse_scheduler_group_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_SCHEDULER_GROUP_ATTR_CHILD_COUNT: + attr_list[i].value.u32 = attribute.value.u32; + break; + case SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST: + break; + case SAI_SCHEDULER_GROUP_ATTR_PORT_ID: + attr_list[i].value.oid = attribute.value.oid; + break; + case SAI_SCHEDULER_GROUP_ATTR_LEVEL: + attr_list[i].value.u8 = attribute.value.u8; + break; + case SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID: + attr_list[i].value.oid = attribute.value.oid; + break; + } + } + } + + sai_thrift_object_id_t sai_thrift_create_scheduler_group( + const std::vector & thrift_attr_list) { + printf("sai_thrift_create_scheduler_group\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_scheduler_group_api_t *scheduler_group_api; + sai_object_id_t scheduler_group_id = 0; + status = sai_api_query(SAI_API_SCHEDULER_GROUP, (void **) &scheduler_group_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_scheduler_group_attributes(thrift_attr_list, attr_list); + uint32_t attr_count = thrift_attr_list.size(); + scheduler_group_api->create_scheduler_group(&scheduler_group_id, attr_count, attr_list); + free(attr_list); + return scheduler_group_id; + } + + sai_thrift_status_t sai_thrift_remove_scheduler_group( + const sai_thrift_object_id_t scheduler_group_id) { + printf("sai_thrift_remove_scheduler_group\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_scheduler_group_api_t *scheduler_group_api; + status = sai_api_query(SAI_API_SCHEDULER_GROUP, (void **) &scheduler_group_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = scheduler_group_api->remove_scheduler_group(scheduler_group_id); + return status; + } + + sai_thrift_status_t sai_thrift_add_child_object_to_group( + const sai_thrift_object_id_t scheduler_group_id, + const std::vector & thrift_child_objects) { + printf("sai_thrift_add_child_object_to_group\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_scheduler_group_api_t *scheduler_group_api; + sai_object_id_t *child_objects; + status = sai_api_query(SAI_API_SCHEDULER_GROUP, (void **) &scheduler_group_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + child_objects = (sai_object_id_t *) malloc(sizeof(sai_object_id_t) * thrift_child_objects.size()); + std::vector::const_iterator it2 = thrift_child_objects.begin(); + for (uint32_t j = 0; j < thrift_child_objects.size(); j++, *it2++) { + child_objects[j] = (sai_object_id_t) *it2; + } + uint32_t attr_count = thrift_child_objects.size(); + status = scheduler_group_api->add_child_object_to_group( + scheduler_group_id, + attr_count, + child_objects); + free(child_objects); + return status; + } + + sai_thrift_status_t sai_thrift_remove_child_object_from_group( + const sai_thrift_object_id_t scheduler_group_id, + const std::vector & thrift_child_objects) { + printf("sai_thrift_remove_child_object_from_group\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_scheduler_group_api_t *scheduler_group_api; + sai_object_id_t *child_objects; + status = sai_api_query(SAI_API_SCHEDULER_GROUP, (void **) &scheduler_group_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + child_objects = (sai_object_id_t *) malloc(sizeof(sai_object_id_t) * thrift_child_objects.size()); + std::vector::const_iterator it2 = thrift_child_objects.begin(); + for (uint32_t j = 0; j < thrift_child_objects.size(); j++, *it2++) { + child_objects[j] = (sai_object_id_t) *it2; + } + uint32_t attr_count = thrift_child_objects.size(); + status = scheduler_group_api->remove_child_object_from_group( + scheduler_group_id, + attr_count, + child_objects); + free(child_objects); + return status; + } + + void sai_thrift_parse_qos_map_attributes( + const std::vector &thrift_attr_list, + sai_attribute_t *attr_list, + sai_qos_map_t **qos_map_list) { + std::vector::const_iterator it = thrift_attr_list.begin(); + sai_thrift_attribute_t attribute; + sai_qos_map_type_t qos_map_type = (sai_qos_map_type_t) 0; + 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_QOS_MAP_ATTR_TYPE: + attr_list[i].value.s32 = attribute.value.s32; + qos_map_type = (sai_qos_map_type_t) attribute.value.s32; + break; + case SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST: + attr_list[i].value.qosmap.list = (sai_qos_map_t *) malloc(attribute.value.qosmap.key.size() * sizeof(sai_qos_map_t)); + attr_list[i].value.qosmap.count = attribute.value.qosmap.key.size(); + *qos_map_list = attr_list[i].value.qosmap.list; + memset(attr_list[i].value.qosmap.list, 0x0, attribute.value.qosmap.key.size() * sizeof(sai_qos_map_t)); + std::vector::const_iterator it1 = attribute.value.qosmap.key.begin(); + std::vector::const_iterator it2 = attribute.value.qosmap.data.begin(); + for (uint32_t j = 0; j < attribute.value.qosmap.key.size(); j++, it1++, it2++) { + sai_qos_map_params_t *key = &attr_list[i].value.qosmap.list[j].key; + sai_qos_map_params_t *data = &attr_list[i].value.qosmap.list[j].value; + const sai_thrift_qos_map_params_t thrift_key = (sai_thrift_qos_map_params_t) *it1; + const sai_thrift_qos_map_params_t thrift_data = (sai_thrift_qos_map_params_t) *it2; + + switch (qos_map_type) { + case SAI_QOS_MAP_DOT1P_TO_TC: + key->dot1p = thrift_key.dot1p; + data->tc = thrift_data.tc; + break; + case SAI_QOS_MAP_DOT1P_TO_COLOR: + key->dot1p = thrift_key.dot1p; + data->color = (sai_packet_color_t) thrift_data.color; + break; + case SAI_QOS_MAP_DSCP_TO_TC: + key->dscp = thrift_key.dscp; + data->tc = thrift_data.tc; + break; + case SAI_QOS_MAP_DSCP_TO_COLOR: + key->dscp = thrift_key.dscp; + data->color = (sai_packet_color_t) thrift_data.color; + break; + case SAI_QOS_MAP_TC_TO_QUEUE: + key->tc = thrift_key.tc; + data->queue_index = thrift_data.queue_index; + break; + case SAI_QOS_MAP_TC_AND_COLOR_TO_DSCP: + key->tc = thrift_key.tc; + key->color = (sai_packet_color_t) thrift_key.color; + data->dscp = thrift_data.dscp; + break; + case SAI_QOS_MAP_TC_AND_COLOR_TO_DOT1P: + key->tc = thrift_key.tc; + key->color = (sai_packet_color_t) thrift_key.color; + data->dot1p = thrift_data.dot1p; + break; + default: + break; + } + } + break; + } + } + } + + sai_thrift_object_id_t sai_thrift_create_qos_map( + const std::vector & thrift_attr_list) { + printf("sai_thrift_create_qos_map\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_qos_map_api_t *qos_api; + sai_object_id_t qos_map_id = 0; + sai_qos_map_t *qos_map_list = NULL; + status = sai_api_query(SAI_API_QOS_MAPS, (void **) &qos_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_parse_qos_map_attributes(thrift_attr_list, attr_list, &qos_map_list); + uint32_t attr_count = thrift_attr_list.size(); + qos_api->create_qos_map(&qos_map_id, attr_count, attr_list); + if (qos_map_list) { + free(qos_map_list); + } + free(attr_list); + return qos_map_id; + } + + sai_thrift_status_t sai_thrift_remove_qos_map( + const sai_thrift_object_id_t qos_map_id) { + printf("sai_thrift_remove_qos_map\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_qos_map_api_t *qos_api; + status = sai_api_query(SAI_API_QOS_MAPS, (void **) &qos_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = qos_api->remove_qos_map(qos_map_id); + return status; + } + + sai_thrift_status_t sai_thrift_set_queue_attribute( + const sai_thrift_object_id_t queue_id, + const sai_thrift_attribute_t& thrift_attr) { + printf("sai_thrift_set_queue_attribute\n"); + sai_status_t status = SAI_STATUS_SUCCESS; + sai_queue_api_t *queue_api; + status = sai_api_query(SAI_API_QUEUE, (void **) &queue_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + + sai_attribute_t attr; + memset(&attr, 0x0, sizeof(sai_attribute_t)); + attr.id = thrift_attr.id; + attr.value.oid = thrift_attr.value.oid; + status = queue_api->set_queue_attribute(queue_id, &attr); + return status; + } + }; static void * switch_sai_thrift_rpc_server_thread(void *arg) { diff --git a/switchsai/submodules/.clang-format b/switchsai/submodules/.clang-format new file mode 100644 index 0000000..ac2aa81 --- /dev/null +++ b/switchsai/submodules/.clang-format @@ -0,0 +1,3 @@ +--- +DisableFormat : true +... diff --git a/tests/ptf-tests/api-tests/switch.py b/tests/ptf-tests/api-tests/switch.py index c00a293..4c705af 100644 --- a/tests/ptf-tests/api-tests/switch.py +++ b/tests/ptf-tests/api-tests/switch.py @@ -34,6 +34,7 @@ import os from switch_api_thrift.ttypes import * +from switch_api_thrift.switch_api_headers import * this_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.join(this_dir, '..')) @@ -55,11 +56,11 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -70,15 +71,13 @@ def runTest(self): self.client.switcht_api_mac_table_entry_create(device, vlan, '00:11:11:11:11:11', 2, if2) self.client.switcht_api_mac_table_entry_create(device, vlan, '00:22:22:22:22:22', 2, if1) - pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + pkt = simple_udp_packet(eth_dst='00:11:11:11:11:11', eth_src='00:22:22:22:22:22', ip_dst='10.0.0.1', - ip_id=101, ip_ttl=64) - exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + exp_pkt = simple_udp_packet(eth_dst='00:11:11:11:11:11', eth_src='00:22:22:22:22:22', ip_dst='10.0.0.1', - ip_id=101, ip_ttl=64) try: @@ -107,11 +106,11 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=3, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=3, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -163,11 +162,11 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=3, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -217,11 +216,11 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=3, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -270,15 +269,15 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -336,15 +335,15 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -410,15 +409,15 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -484,15 +483,15 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -557,15 +556,15 @@ def runTest(self): self.client.switcht_api_vlan_learning_enabled_set(vlan, 0) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -613,16 +612,16 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) lag = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[5]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[6]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[7]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[8]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[7]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[8]) iu2 = interface_union(port_lag_handle = lag) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -662,7 +661,7 @@ def runTest(self): print 'L2LagTest:', count for i in range(0, 4): - self.assertTrue((count[i] >= ((max_itrs / 4) * 0.9)), + 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', @@ -694,10 +693,10 @@ def runTest(self): self.client.switcht_api_vlan_ports_remove(device, vlan, vlan_port1) self.client.switcht_api_vlan_ports_remove(device, vlan, vlan_port2) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[5]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[6]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[7]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[8]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[7]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[8]) self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) @@ -717,11 +716,11 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -798,22 +797,22 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -853,7 +852,6 @@ def runTest(self): ############################################################################### @group('l3') @group('ipv4') -@group('maxsizes') class L3IPv4SubIntfHostTest(api_base_tests.ThriftInterfaceDataPlane): def runTest(self): print @@ -967,30 +965,30 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_PORT_VLAN, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + 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=SWITCH_API_NEIGHBOR_RW_TYPE_L3) 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) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + 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=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip4, nhop2) @@ -1070,28 +1068,28 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='11.0.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key1 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) - neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:22:22:22:22:22', ip_addr=i_ip4, rw_type=1) + neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:22:22:22:22:22', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) self.client.switcht_api_l3_route_add(device, vrf, i_ip4, nhop1) @@ -1115,7 +1113,7 @@ def runTest(self): nhop_key2 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) - neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip4, rw_type=1) + neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) self.client.switcht_api_l3_route_add(device, vrf, i_ip4, nhop2) @@ -1171,22 +1169,22 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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.0', prefix_length=24) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.0', prefix_length=24) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -1223,10 +1221,193 @@ def runTest(self): self.client.switcht_api_router_mac_group_delete(device, rmac) self.client.switcht_api_vrf_delete(device, vrf) +############################################################################### +@group('l3') +@group('ipv4') +class L3IPv4LookupTest(api_base_tests.ThriftInterfaceDataPlane): + def testLookup(self, vrf, ip_key, exp_nhop): + result_nhop = self.client.switcht_api_l3_route_lookup(device, vrf, ip_key) + self.assertTrue(result_nhop == exp_nhop) + + def runTest(self): + print + print "IPv4 FIB lookup test -- both exact match and LPM -- in switchAPI." + print "The lookup is purely done in control plane (switchAPI), not using dataplane tables." + + self.client.switcht_api_init(device) + vrf = self.client.switcht_api_vrf_create(device, 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=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) + + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + + ip_default = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='0.0.0.0', prefix_length=0) + ip_classA = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.0', prefix_length=8) + ip_classB = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.0.0', prefix_length=16) + ip_classB23 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.0', prefix_length=23) + ip_classC = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.0', prefix_length=24) + ip_host = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.10', prefix_length=32) + + nhop_default = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_classA = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_classB = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_classB23 = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_classC = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_host = self.client.switcht_api_nhop_create(device, nhop_key) + + try: + self.client.switcht_api_l3_route_add(device, vrf, ip_default, nhop_default) + self.testLookup(vrf, ip_host, nhop_default) + + self.client.switcht_api_l3_route_add(device, vrf, ip_classA, nhop_classA) + self.testLookup(vrf, ip_host, nhop_classA) + + self.client.switcht_api_l3_route_add(device, vrf, ip_classB, nhop_classB) + self.testLookup(vrf, ip_host, nhop_classB) + + self.client.switcht_api_l3_route_add(device, vrf, ip_classB23, nhop_classB23) + self.testLookup(vrf, ip_host, nhop_classB23) + + self.client.switcht_api_l3_route_add(device, vrf, ip_classC, nhop_classC) + self.testLookup(vrf, ip_host, nhop_classC) + + self.client.switcht_api_l3_route_add(device, vrf, ip_host, nhop_host) + self.testLookup(vrf, ip_host, nhop_host) + + self.client.switcht_api_l3_route_delete(device, vrf, ip_host, nhop_host) + self.testLookup(vrf, ip_host, nhop_classC) + + ip_host2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='20.10.10.10', prefix_length=32) + self.testLookup(vrf, ip_host2, nhop_default) + + finally: + # clean up + self.client.switcht_api_l3_route_delete(device, vrf, ip_classC, nhop_classC) + self.client.switcht_api_l3_route_delete(device, vrf, ip_classB23, nhop_classB23) + self.client.switcht_api_l3_route_delete(device, vrf, ip_classB, nhop_classB) + self.client.switcht_api_l3_route_delete(device, vrf, ip_classA, nhop_classA) + self.client.switcht_api_l3_route_delete(device, vrf, ip_default, nhop_default) + + self.client.switcht_api_nhop_delete(device, nhop_default) + self.client.switcht_api_nhop_delete(device, nhop_classA) + self.client.switcht_api_nhop_delete(device, nhop_classB) + self.client.switcht_api_nhop_delete(device, nhop_classB23) + self.client.switcht_api_nhop_delete(device, nhop_classC) + self.client.switcht_api_nhop_delete(device, nhop_host) + + + 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('ipv6') +class L3IPv6LookupTest(api_base_tests.ThriftInterfaceDataPlane): + def testLookup(self, vrf, ip_key, exp_nhop): + result_nhop = self.client.switcht_api_l3_route_lookup(device, vrf, ip_key) + self.assertTrue(result_nhop == exp_nhop) + + def runTest(self): + print + print "IPv6 FIB lookup test -- both exact match and LPM -- in switchAPI." + print "The lookup is purely done in control plane (switchAPI), not using dataplane tables." + + self.client.switcht_api_init(device) + vrf = self.client.switcht_api_vrf_create(device, 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=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V6, ipaddr='2000::2', prefix_length=120) + self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V6, ipaddr='3000::2', prefix_length=120) + self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) + + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + + ip_default = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='::', prefix_length=0) + ip_p8 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000::', prefix_length=8) + ip_p16 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000:10::0', prefix_length=16) + ip_host = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000:10::10', prefix_length=128) + + nhop_default = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_p8 = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_p16 = self.client.switcht_api_nhop_create(device, nhop_key) + nhop_host = self.client.switcht_api_nhop_create(device, nhop_key) + + try: + self.client.switcht_api_l3_route_add(device, vrf, ip_default, nhop_default) + self.testLookup(vrf, ip_host, nhop_default) + + self.client.switcht_api_l3_route_add(device, vrf, ip_p8, nhop_p8) + self.testLookup(vrf, ip_host, nhop_p8) + + self.client.switcht_api_l3_route_add(device, vrf, ip_p16, nhop_p16) + self.testLookup(vrf, ip_host, nhop_p16) + + self.client.switcht_api_l3_route_add(device, vrf, ip_host, nhop_host) + self.testLookup(vrf, ip_host, nhop_host) + + self.client.switcht_api_l3_route_delete(device, vrf, ip_host, nhop_host) + self.testLookup(vrf, ip_host, nhop_p16) + + ip_host2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='4000:10:10:10:10:10:10:10:10:10:10:10:10:10:10:10', prefix_length=128) + self.testLookup(vrf, ip_host2, nhop_default) + + finally: + # clean up + self.client.switcht_api_l3_route_delete(device, vrf, ip_p16, nhop_p16) + self.client.switcht_api_l3_route_delete(device, vrf, ip_p8, nhop_p8) + self.client.switcht_api_l3_route_delete(device, vrf, ip_default, nhop_default) + + self.client.switcht_api_nhop_delete(device, nhop_default) + self.client.switcht_api_nhop_delete(device, nhop_p8) + self.client.switcht_api_nhop_delete(device, nhop_p16) + self.client.switcht_api_nhop_delete(device, nhop_host) + + + 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('ipv6') +@group('maxsizes') class L3IPv6HostTest(api_base_tests.ThriftInterfaceDataPlane): def runTest(self): print @@ -1238,22 +1419,22 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='2000::2', prefix_length=120) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000::2', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='3000::2', prefix_length=120) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000::2', prefix_length=120) 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=1, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99aa', prefix_length=128) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99aa', prefix_length=128) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -1303,22 +1484,22 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='2000::2', prefix_length=120) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000::2', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='3000::2', prefix_length=120) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000::2', prefix_length=120) 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=1, ipaddr='3000::0', prefix_length=120) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000::0', prefix_length=120) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:99:99:99:99:99', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:99:99:99:99:99', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -1367,33 +1548,33 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='11.0.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key1 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) - neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip4, rw_type=1) + neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) nhop_key2 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) - neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=i_ip4, rw_type=1) + neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) ecmp = self.client.switcht_api_l3_ecmp_create(device) @@ -1489,33 +1670,33 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='2000:1:1:0:0:0:0:1', prefix_length=120) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='3000:1:1:0:0:0:0:1', prefix_length=120) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=1, ipaddr='4000:1:1:0:0:0:0:1', prefix_length=120) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='4000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) - i_ip4 = switcht_ip_addr_t(addr_type=1, ipaddr='5000:1:1:0:0:0:0:1', prefix_length=128) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='5000:1:1:0:0:0:0:1', prefix_length=128) nhop_key1 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) - neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip4, rw_type=1) + neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) nhop_key2 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) - neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=i_ip4, rw_type=1) + neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) ecmp = self.client.switcht_api_l3_ecmp_create(device) @@ -1613,63 +1794,63 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, 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=vrf, rmac_handle=rmac) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) 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=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) iu3 = interface_union(port_lag_handle = swports[2]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='11.0.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(port_lag_handle = swports[3]) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='12.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) iu5 = interface_union(port_lag_handle = swports[4]) - i_info5 = switcht_interface_info_t(device=0, type=4, u=iu5, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info5 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu5, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if5 = self.client.switcht_api_interface_create(device, i_info5) - i_ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='13.0.0.2', prefix_length=16) + i_ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='13.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if5, vrf, i_ip5) nhop_key1 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) - n_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.100', prefix_length=32) - neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=n_ip1, rw_type=1) + n_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.100', prefix_length=32) + neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=n_ip1, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) nhop_key2 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) - n_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='11.0.0.100', prefix_length=32) - neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=n_ip2, rw_type=1) + n_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.0.0.100', prefix_length=32) + neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=n_ip2, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) nhop_key3 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop3 = self.client.switcht_api_nhop_create(device, nhop_key3) - n_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='12.0.0.101', prefix_length=32) - neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=nhop3, interface_handle=if2, mac_addr='00:11:22:33:44:57', ip_addr=n_ip3, rw_type=1) + n_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.0.0.101', prefix_length=32) + neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=nhop3, interface_handle=if2, mac_addr='00:11:22:33:44:57', ip_addr=n_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) nhop_key4 = switcht_nhop_key_t(intf_handle=if5, ip_addr_valid=0) nhop4 = self.client.switcht_api_nhop_create(device, nhop_key4) - n_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='13.0.0.101', prefix_length=32) - neighbor_entry4 = switcht_neighbor_info_t(nhop_handle=nhop4, interface_handle=if3, mac_addr='00:11:22:33:44:58', ip_addr=n_ip4, rw_type=1) + n_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='13.0.0.101', prefix_length=32) + neighbor_entry4 = switcht_neighbor_info_t(nhop_handle=nhop4, interface_handle=if3, mac_addr='00:11:22:33:44:58', ip_addr=n_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) ecmp = self.client.switcht_api_l3_ecmp_create(device) self.client.switcht_api_l3_ecmp_member_add(device, ecmp, 4, [nhop1, nhop2, nhop3, nhop4]) - r_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.0.0', prefix_length=16) + r_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.0.0', prefix_length=16) self.client.switcht_api_l3_route_add(device, vrf, r_ip, ecmp) try: @@ -1782,59 +1963,59 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='1000:1:1:0:0:0:0:1', prefix_length=120) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='1000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='2000:1:1:0:0:0:0:1', prefix_length=120) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=1, ipaddr='3000:1:1:0:0:0:0:1', prefix_length=120) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(port_lag_handle = swports[4]) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=1, ipaddr='4000:1:1:0:0:0:0:1', prefix_length=120) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='4000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) iu5 = interface_union(port_lag_handle = swports[5]) - i_info5 = switcht_interface_info_t(device=0, type=4, u=iu5, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info5 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu5, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if5 = self.client.switcht_api_interface_create(device, i_info5) - i_ip5 = switcht_ip_addr_t(addr_type=1, ipaddr='5000:1:1:0:0:0:0:1', prefix_length=120) + i_ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='5000:1:1:0:0:0:0:1', prefix_length=120) self.client.switcht_api_l3_interface_address_add(device, if5, vrf, i_ip5) nhop_key1 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) - neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip2, rw_type=1) + neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip2, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) nhop_key2 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) - neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=i_ip3, rw_type=1) + neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) nhop_key3 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop3 = self.client.switcht_api_nhop_create(device, nhop_key3) - neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=nhop3, interface_handle=if4, mac_addr='00:11:22:33:44:57', ip_addr=i_ip4, rw_type=1) + neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=nhop3, interface_handle=if4, mac_addr='00:11:22:33:44:57', ip_addr=i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) nhop_key4 = switcht_nhop_key_t(intf_handle=if5, ip_addr_valid=0) nhop4 = self.client.switcht_api_nhop_create(device, nhop_key4) - neighbor_entry4 = switcht_neighbor_info_t(nhop_handle=nhop4, interface_handle=if5, mac_addr='00:11:22:33:44:58', ip_addr=i_ip5, rw_type=1) + neighbor_entry4 = switcht_neighbor_info_t(nhop_handle=nhop4, interface_handle=if5, mac_addr='00:11:22:33:44:58', ip_addr=i_ip5, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) ecmp = self.client.switcht_api_l3_ecmp_create(device) self.client.switcht_api_l3_ecmp_member_add(device, ecmp, 4, [nhop1, nhop2, nhop3, nhop4]) - r_ip = switcht_ip_addr_t(addr_type=1, ipaddr='6000:1:1:0:0:0:0:0', prefix_length=64) + r_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='6000:1:1:0:0:0:0:0', prefix_length=64) self.client.switcht_api_l3_route_add(device, vrf, r_ip, ecmp) try: @@ -1899,7 +2080,7 @@ def runTest(self): print "Count = %s" % str(count) for i in range(0, 4): - self.assertTrue((count[i] >= ((max_itrs / 4) * 0.75)), + self.assertTrue((count[i] >= ((max_itrs / 4) * 0.50)), "Not all paths are equally balanced") finally: self.client.switcht_api_l3_route_delete(device, vrf, r_ip, ecmp) @@ -1950,24 +2131,24 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) lag = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[2]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) iu2 = interface_union(port_lag_handle = lag) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0,vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -1996,8 +2177,8 @@ def runTest(self): 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_lag_member_delete(device, lag_handle=lag, side=0, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) @@ -2009,9 +2190,8 @@ def runTest(self): ############################################################################### -@group('l2') @group('l3') -@group('ipv4') +@group('ipv6') class L3IPv6LagTest(api_base_tests.ThriftInterfaceDataPlane): def runTest(self): print @@ -2022,25 +2202,25 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='5001::10', prefix_length=128) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='5001::10', prefix_length=128) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) lag = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[2]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0,vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=1, ipaddr='4001::10', prefix_length=128) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='4001::10', prefix_length=128) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) - i_ip3 = switcht_ip_addr_t(addr_type=1, ipaddr='4001::1', prefix_length=128) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='4001::1', prefix_length=128) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:88:88:88:88:88', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:88:88:88:88:88', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -2067,9 +2247,9 @@ def runTest(self): 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_lag_member_delete(device, lag_handle=lag, side=0, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) @@ -2095,67 +2275,67 @@ def runTest(self): 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, + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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', + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag1) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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.2.2', prefix_length=16) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.2.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[5]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[6]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) iu3 = interface_union(port_lag_handle = lag2) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.3.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.3.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(port_lag_handle = swports[7]) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.4.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.4.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) - i_ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='10.100.0.0', + i_ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.100.0.0', prefix_length=16) nhop_key1 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if2, mac_addr='00:11:22:33:44:55', - ip_addr=i_ip5, rw_type=1) + ip_addr=i_ip5, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) nhop_key2 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if3, mac_addr='00:11:22:33:44:56', - ip_addr=i_ip5, rw_type=1) + ip_addr=i_ip5, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) nhop_key3 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop3 = self.client.switcht_api_nhop_create(device, nhop_key3) neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=nhop3, interface_handle=if4, mac_addr='00:11:22:33:44:57', - ip_addr=i_ip5, rw_type=1) + ip_addr=i_ip5, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) ecmp = self.client.switcht_api_l3_ecmp_create(device) @@ -2231,15 +2411,15 @@ def runTest(self): self.client.switcht_api_neighbor_entry_remove(device, neighbor3) self.client.switcht_api_nhop_delete(device, nhop3) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) self.client.switcht_api_l3_interface_address_delete(device, if1, vrf, i_ip1) @@ -2274,41 +2454,41 @@ def runTest(self): 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, v4_urpf_mode=1) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_urpf_mode=1) 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) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_urpf_mode=2) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_urpf_mode=2) 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) # add neighbor 192.168.0.1 - i_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.1', prefix_length=32) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.1', prefix_length=32) nhop_key1 = switcht_nhop_key_t(intf_handle=if1, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) - neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if1, mac_addr='00:11:22:33:44:55', ip_addr=i_ip1, rw_type=1) + neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if1, mac_addr='00:11:22:33:44:55', ip_addr=i_ip1, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) # add neighbor 10.0.0.2 - i_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=32) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=32) nhop_key2 = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) - neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if2, mac_addr='00:11:22:33:44:56', ip_addr=i_ip2, rw_type=1) + neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if2, mac_addr='00:11:22:33:44:56', ip_addr=i_ip2, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) # Add a static route 10.10/16 --> if1 - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.0.0', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.0.0', prefix_length=16) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop1) # Add a static route 10.11/16 --> if2 - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.11.0.0', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.11.0.0', prefix_length=16) self.client.switcht_api_l3_route_add(device, vrf, i_ip4, nhop2) # Add a static route 10.13/16 --> if1 - i_ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='10.13.0.0', prefix_length=16) + i_ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.13.0.0', prefix_length=16) self.client.switcht_api_l3_route_add(device, vrf, i_ip5, nhop1) # send the test packet(s) @@ -2429,15 +2609,15 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -2547,29 +2727,29 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) 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) - iu4 = switcht_tunnel_info_t(encap_mode = 0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -2582,7 +2762,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -2668,31 +2848,31 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) ipv6_src_addr = '1234:5678:9abc:def0:1234:5678:9abc:def0' ipv6_dst_addr = '1111:2222:3333:4444:5555:6666:7777:8888' - src_ip = switcht_ip_addr_t(addr_type=1, ipaddr=ipv6_src_addr, prefix_length=128) - dst_ip = switcht_ip_addr_t(addr_type=1, ipaddr=ipv6_dst_addr, prefix_length=128) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr=ipv6_src_addr, prefix_length=128) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr=ipv6_dst_addr, prefix_length=128) udp_tcp = switcht_udp_tcp_t(udp = udp) #encap_type 3 is vxlan - encap_info = switcht_encap_info_t(encap_type=3) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) 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) - iu4 = switcht_tunnel_info_t(encap_mode = 0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -2705,7 +2885,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=8) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV6_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -2770,31 +2950,31 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) ipv6_src_addr = '1234:5678:9abc:def0:1234:5678:9abc:def0' ipv6_dst_addr = '1111:2222:3333:4444:5555:6666:7777:8888' - src_ip = switcht_ip_addr_t(addr_type=1, ipaddr=ipv6_src_addr, prefix_length=128) - dst_ip = switcht_ip_addr_t(addr_type=1, ipaddr=ipv6_dst_addr, prefix_length=128) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr=ipv6_src_addr, prefix_length=128) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr=ipv6_dst_addr, prefix_length=128) udp_tcp = switcht_udp_tcp_t(udp = udp) #encap_type 3 is vxlan - encap_info = switcht_encap_info_t(encap_type=3) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) 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) - iu4 = switcht_tunnel_info_t(encap_mode = 0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -2807,7 +2987,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=8) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV6_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -2829,7 +3009,7 @@ def runTest(self): ipv6_dst=ipv6_dst_addr, ipv6_src=ipv6_src_addr, ipv6_hlim=64, - udp_sport=46064, + udp_sport=0xf0b3, with_udp_chksum=False, vxlan_vni=0x1234, inner_frame=pkt) @@ -2890,27 +3070,27 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface - 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) - encap_info = switcht_encap_info_t(encap_type=5) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_NVGRE) ip_encap = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip, dst_ip=dst_ip, ttl=60, proto=47, gre_proto=0x6558) 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=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -2923,7 +3103,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -3006,26 +3186,26 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) nvgre = switcht_nvgre_id_t(tnid=0x1234) bt = switcht_bridge_type(nvgre_info=nvgre) - encap_info = switcht_encap_info_t(encap_type=5, u=bt) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_NVGRE, u=bt) ip_encap = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip, dst_ip=dst_ip, ttl=60, proto=47, gre_proto=0x6558) 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=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3038,7 +3218,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -3124,35 +3304,35 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) 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) - encap_info = switcht_encap_info_t(encap_type=3) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3165,7 +3345,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -3239,11 +3419,11 @@ def runTest(self): self.client.switcht_api_logical_network_member_remove(device, ln1, if4) self.client.switcht_api_logical_network_delete(device, ln1) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_tunnel_interface_delete(device, if4) self.client.switcht_api_interface_delete(device, if1) @@ -3271,29 +3451,29 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=6081) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) 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) - encap_info = switcht_encap_info_t(encap_type=6) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3306,7 +3486,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -3395,35 +3575,35 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=6081) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) 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) - encap_info = switcht_encap_info_t(encap_type=6) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3436,7 +3616,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -3511,11 +3691,11 @@ def runTest(self): self.client.switcht_api_logical_network_member_remove(device, ln1, if4) self.client.switcht_api_logical_network_delete(device, ln1) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_tunnel_interface_delete(device, if4) self.client.switcht_api_interface_delete(device, if1) @@ -3543,33 +3723,33 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) ip_encap = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip, dst_ip=dst_ip, ttl=60, proto=47, gre_proto=0x6558) tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) - encap_info = switcht_encap_info_t(encap_type=5) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_NVGRE) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3582,7 +3762,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -3654,11 +3834,11 @@ def runTest(self): self.client.switcht_api_logical_network_member_remove(device, ln1, if4) self.client.switcht_api_logical_network_delete(device, ln1) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_tunnel_interface_delete(device, if4) self.client.switcht_api_interface_delete(device, if1) @@ -3682,15 +3862,15 @@ def runTest(self): vrf = self.client.switcht_api_vrf_create(device, 2) 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_PORT_VLAN, 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=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) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_PORT_VLAN, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) - lognet_info = switcht_logical_network_t(type=4, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) self.client.switcht_api_logical_network_member_add(device, ln1, if1) @@ -3760,40 +3940,40 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a geneve tunnel interface udp3 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp3 = switcht_udp_tcp_t(udp = udp3) ip_encap3 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip3, dst_ip=dst_ip3, ttl=60, proto=17, u=udp_tcp3) tunnel_encap3 = switcht_tunnel_encap_t(ip_encap=ip_encap3) - encap_info3 = switcht_encap_info_t(encap_type=6) - iu3 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) + encap_info3 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) # Create a vxlan tunnel interface udp4 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp4 = switcht_udp_tcp_t(udp = udp4) ip_encap4 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip4, dst_ip=dst_ip4, ttl=60, proto=17, u=udp_tcp4) tunnel_encap4 = switcht_tunnel_encap_t(ip_encap=ip_encap4) - encap_info4 = switcht_encap_info_t(encap_type=3) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) + encap_info4 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3806,7 +3986,7 @@ def runTest(self): interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3) @@ -3818,7 +3998,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4) @@ -3941,46 +4121,46 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a geneve tunnel interface udp3 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp3 = switcht_udp_tcp_t(udp = udp3) ip_encap3 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip3, dst_ip=dst_ip3, ttl=60, proto=17, u=udp_tcp3) tunnel_encap3 = switcht_tunnel_encap_t(ip_encap=ip_encap3) - encap_info3 = switcht_encap_info_t(encap_type=6) - iu3 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) + encap_info3 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) # Create a vxlan tunnel interface udp4 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp4 = switcht_udp_tcp_t(udp = udp4) ip_encap4 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip4, dst_ip=dst_ip4, ttl=60, proto=17, u=udp_tcp4) tunnel_encap4 = switcht_tunnel_encap_t(ip_encap=ip_encap4) - encap_info4 = switcht_encap_info_t(encap_type=3) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) + encap_info4 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -3993,7 +4173,7 @@ def runTest(self): interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3) @@ -4005,7 +4185,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4) @@ -4112,12 +4292,12 @@ def runTest(self): self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) self.client.switcht_api_lag_delete(device, lag1) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_lag_delete(device, lag2) self.client.switcht_api_router_mac_delete(device, rmac, '00:77:66:55:44:33') @@ -4139,28 +4319,28 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) vxlan = switcht_vxlan_id_t(vnid=0x1234) bt = switcht_bridge_type(vxlan_info=vxlan) - encap_info = switcht_encap_info_t(encap_type=3, u=bt) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt) 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) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -4173,7 +4353,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -4262,35 +4442,35 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) vxlan = switcht_vxlan_id_t(vnid=0x1234) bt = switcht_bridge_type(vxlan_info=vxlan) - encap_info = switcht_encap_info_t(encap_type=3, u=bt) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt) 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) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -4303,7 +4483,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -4378,11 +4558,11 @@ def runTest(self): self.client.switcht_api_logical_network_member_remove(device, ln1, if4) self.client.switcht_api_logical_network_delete(device, ln1) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_tunnel_interface_delete(device, if4) self.client.switcht_api_interface_delete(device, if1) @@ -4410,41 +4590,41 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a geneve tunnel interface udp3 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp3 = switcht_udp_tcp_t(udp = udp3) geneve3 = switcht_geneve_id_t(vni=0x4321) bt3 = switcht_bridge_type(geneve_info=geneve3) - encap_info3 = switcht_encap_info_t(encap_type=6, u=bt3) + encap_info3 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE, u=bt3) ip_encap3 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip3, dst_ip=dst_ip3, ttl=60, proto=17, u=udp_tcp3) tunnel_encap3 = switcht_tunnel_encap_t(ip_encap=ip_encap3) - iu3 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) # Create a vxlan tunnel interface udp4 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp4 = switcht_udp_tcp_t(udp = udp4) vxlan4 = switcht_vxlan_id_t(vnid=0x1234) bt4 = switcht_bridge_type(vxlan_info=vxlan4) - encap_info4 = switcht_encap_info_t(encap_type=3, u=bt4) + encap_info4 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt4) ip_encap4 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip4, dst_ip=dst_ip4, ttl=60, proto=17, u=udp_tcp4) tunnel_encap4 = switcht_tunnel_encap_t(ip_encap=ip_encap4) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -4457,7 +4637,7 @@ def runTest(self): interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3) @@ -4469,7 +4649,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4) @@ -4589,47 +4769,47 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a geneve tunnel interface udp3 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp3 = switcht_udp_tcp_t(udp = udp3) geneve3 = switcht_geneve_id_t(vni=0x4321) bt3 = switcht_bridge_type(geneve_info=geneve3) - encap_info3 = switcht_encap_info_t(encap_type=6, u=bt3) + encap_info3 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE, u=bt3) ip_encap3 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip3, dst_ip=dst_ip3, ttl=60, proto=17, u=udp_tcp3) tunnel_encap3 = switcht_tunnel_encap_t(ip_encap=ip_encap3) - iu3 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap3, encap_info=encap_info3, out_if=if1) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) # Create a vxlan tunnel interface udp4 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp4 = switcht_udp_tcp_t(udp = udp4) vxlan4 = switcht_vxlan_id_t(vnid=0x1234) bt4 = switcht_bridge_type(vxlan_info=vxlan4) - encap_info4 = switcht_encap_info_t(encap_type=3, u=bt4) + encap_info4 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt4) ip_encap4 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip4, dst_ip=dst_ip4, ttl=60, proto=17, u=udp_tcp4) tunnel_encap4 = switcht_tunnel_encap_t(ip_encap=ip_encap4) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) #add L2 port to LN @@ -4642,7 +4822,7 @@ def runTest(self): interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=src_ip3) @@ -4654,7 +4834,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=src_ip4) @@ -4766,11 +4946,11 @@ def runTest(self): self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_lag_delete(device, lag1) self.client.switcht_api_lag_delete(device, lag2) @@ -4795,34 +4975,34 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) #encap_type 3 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a tunnel interface flags = switcht_interface_flags(flood_enabled=1) udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) - encap_info = switcht_encap_info_t(encap_type=3) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) 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) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if3, flags=flags) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if3, flags=flags) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) nhop_key1 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) @@ -4837,7 +5017,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -4925,51 +5105,51 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) 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) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, 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) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) 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) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) self.client.switcht_api_logical_network_member_add(device, ln1, if4) - i_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key1 = switcht_nhop_key_t(intf_handle=if1, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, interface_handle=if1, mac_addr='00:33:33:33:33:33', ip_addr=i_ip1, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) - i_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='20.20.20.1', prefix_length=32) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='20.20.20.1', prefix_length=32) nhop_key2 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop2 = self.client.switcht_api_nhop_create(device, nhop_key2) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=nhop2, interface_handle=if4, mac_addr='00:44:44:44:44:44', ip_addr=i_ip2, - rw_type=1, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:55:55:55:55:55', ip_addr=src_ip) @@ -5066,20 +5246,23 @@ def runTest(self): vlan = self.client.switcht_api_vlan_create(device, 10) self.client.switcht_api_vlan_aging_interval_set(vlan, 60000) + default_learn_timeout = 500 + learn_timeout_in_ms = 5000 + iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) iu4 = interface_union(port_lag_handle = swports[4]) - i_info4 = switcht_interface_info_t(device=0, type=2, u=iu4, mac='00:77:66:55:44:33', label=0) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu4, mac='00:77:66:55:44:33', label=0) if4 = self.client.switcht_api_interface_create(device, i_info4) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -5103,11 +5286,11 @@ def runTest(self): ip_ttl=0) send_packet(self, port, str(pkt)) - time.sleep(3) + time.sleep(int(learn_timeout_in_ms/1000) + 2) try: - for src_port in range (1, 5): - for dst_port in range (1, 5): + for dst_port in range (1, 5): + for src_port in range (1, 5): for mac_offset in range (1, 9): if src_port == dst_port: continue @@ -5120,7 +5303,9 @@ def runTest(self): ip_id=108, ip_ttl=64) send_packet(self, src_port, str(pkt)) - verify_packets(self, pkt, [dst_port]) + verify_packet(self, pkt, dst_port) + + verify_no_other_packets(self) finally: self.client.switcht_api_mac_table_entries_delete_all(device) @@ -5151,24 +5336,24 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf, rmac_handle=rmac) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf, rmac_handle=rmac) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) mpls_tag1 = switcht_mpls_t(label=0xabcde, exp=0x5, ttl=0x30, bos=0) mpls_tag2 = switcht_mpls_t(label=0x54321, exp=0x2, ttl=0x40, bos=1) pop_info=switcht_mpls_pop_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(pop_info=pop_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=0, mpls_mode=2, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_POP, mpls_mode=SWITCH_API_MPLS_TERMINATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu3 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) self.client.switcht_api_logical_network_member_add(device, ln1, if1) @@ -5227,24 +5412,24 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf, rmac_handle=rmac) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf, rmac_handle=rmac) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) mpls_tag1 = switcht_mpls_t(label=0xabcde, exp=0x5, ttl=0x30, bos=0) mpls_tag2 = switcht_mpls_t(label=0x54321, exp=0x2, ttl=0x40, bos=1) push_info=switcht_mpls_push_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(push_info=push_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=1, mpls_mode=0, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_PUSH, mpls_mode=SWITCH_API_MPLS_INITIATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu3 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) self.client.switcht_api_logical_network_member_add(device, ln1, if1) @@ -5256,7 +5441,7 @@ def runTest(self): #neighbor type 5 is push l2vpn neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, - neigh_type=5, + neigh_type=SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN, interface_handle= if3, mpls_label=0, header_count=2) @@ -5321,14 +5506,14 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf, rmac_handle=rmac) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf, rmac_handle=rmac) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) self.client.switcht_api_logical_network_member_add(device, ln1, if1) @@ -5341,11 +5526,17 @@ def runTest(self): inner_tag = switcht_mpls_t(label=0x54321, exp=0x2, ttl=0x40, bos=1) swap_info=switcht_mpls_swap_t(old_tag=old_mpls_tag, new_tag=new_mpls_tag) mpls_info = switcht_mpls_info_t(swap_info=swap_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=2, mpls_mode=1, u=mpls_info, nhop_handle=nhop1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_SWAP, mpls_mode=SWITCH_API_MPLS_TRANSIT, u=mpls_info, nhop_handle=nhop1) self.client.switcht_api_mpls_tunnel_transit_create(device, mpls_encap) #neighbor type 2 is swap l2vpn - neighbor_entry1 = switcht_neighbor_info_t(neigh_type=2, nhop_handle=nhop1, interface_handle=if2, mac_addr='00:44:44:44:44:44', mpls_label=0x98765, rw_type=0) + neighbor_entry1 = switcht_neighbor_info_t( + neigh_type=SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN, + nhop_handle=nhop1, + interface_handle=if2, + mac_addr='00:44:44:44:44:44', + mpls_label=0x98765, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) try: @@ -5402,36 +5593,36 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) ln_flags = switcht_ln_flags(ipv4_unicast_enabled=1) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf, rmac_handle=rmac, flags=ln_flags) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf, rmac_handle=rmac, flags=ln_flags) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) mpls_tag1 = switcht_mpls_t(label=0xabcde, exp=0x5, ttl=0x30, bos=0) mpls_tag2 = switcht_mpls_t(label=0x54321, exp=0x2, ttl=0x40, bos=1) pop_info=switcht_mpls_pop_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(pop_info=pop_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=1, mpls_action=0, mpls_mode=2, u=mpls_info, bd_handle=ln1, vrf_handle=vrf) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_IPV4_MPLS, mpls_action=SWITCH_API_MPLS_ACTION_POP, mpls_mode=SWITCH_API_MPLS_TERMINATE, u=mpls_info, bd_handle=ln1, vrf_handle=vrf) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu3 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) self.client.switcht_api_logical_network_member_add(device, ln1, if1) self.client.switcht_api_logical_network_member_add(device, ln1, if3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='20.20.20.1', prefix_length=32) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='20.20.20.1', prefix_length=32) nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) nhop = self.client.switcht_api_nhop_create(device, nhop_key) - neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:33:33:33:33:33', ip_addr=i_ip3, rw_type=1) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, interface_handle=if2, mac_addr='00:33:33:33:33:33', ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) @@ -5490,41 +5681,41 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf, rmac_handle=rmac) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf, rmac_handle=rmac) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) mpls_tag1 = switcht_mpls_t(label=0xabcde, exp=0x5, ttl=0x30, bos=0) mpls_tag2 = switcht_mpls_t(label=0x54321, exp=0x2, ttl=0x40, bos=1) push_info=switcht_mpls_push_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(push_info=push_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=1, mpls_action=1, mpls_mode=0, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_IPV4_MPLS, mpls_action=SWITCH_API_MPLS_ACTION_PUSH, mpls_mode=SWITCH_API_MPLS_INITIATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu3 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if1, flags=flags) if3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) self.client.switcht_api_logical_network_member_add(device, ln1, if1) self.client.switcht_api_logical_network_member_add(device, ln1, if3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='20.20.20.1', prefix_length=32) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='20.20.20.1', prefix_length=32) nhop_key1 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop1 = self.client.switcht_api_nhop_create(device, nhop_key1) #neighbor type 6 is push l3vpn neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=nhop1, - neigh_type=6, + neigh_type=SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN, interface_handle=if3, mpls_label=0, header_count=2, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if3, mac_addr='00:44:44:44:44:44') neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) @@ -5591,45 +5782,45 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a geneve tunnel interface udp4 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp4 = switcht_udp_tcp_t(udp = udp4) geneve4 = switcht_geneve_id_t(vni=0x4321) bt4 = switcht_bridge_type(geneve_info=geneve4) - encap_info4 = switcht_encap_info_t(encap_type=6, u=bt4) + encap_info4 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE, u=bt4) ip_encap4 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip4, dst_ip=dst_ip4, ttl=60, proto=17, u=udp_tcp4) tunnel_encap4 = switcht_tunnel_encap_t(ip_encap=ip_encap4) - iu4 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if1) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap4, encap_info=encap_info4, out_if=if1) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) # Create a vxlan tunnel interface udp5 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp5 = switcht_udp_tcp_t(udp = udp5) vxlan5 = switcht_vxlan_id_t(vnid=0x1234) bt5 = switcht_bridge_type(vxlan_info=vxlan5) - encap_info5 = switcht_encap_info_t(encap_type=3, u=bt5) + encap_info5 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt5) ip_encap5 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip5, dst_ip=dst_ip5, ttl=60, proto=17, u=udp_tcp5) tunnel_encap5 = switcht_tunnel_encap_t(ip_encap=ip_encap5) - iu5 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap5, encap_info=encap_info5, out_if=if2) + iu5 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap5, encap_info=encap_info5, out_if=if2) if5 = self.client.switcht_api_tunnel_interface_create(device, 0, iu5) #Create a mpls push interface @@ -5637,10 +5828,10 @@ def runTest(self): mpls_tag2 = switcht_mpls_t(label=0xbbbbb, exp=0x2, ttl=0x40, bos=1) push_info=switcht_mpls_push_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(push_info=push_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=1, mpls_mode=0, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_PUSH, mpls_mode=SWITCH_API_MPLS_INITIATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu6 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) + iu6 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) if6 = self.client.switcht_api_tunnel_interface_create(device, 0, iu6) #Create a mpls pop interface @@ -5648,10 +5839,10 @@ def runTest(self): mpls_tag2 = switcht_mpls_t(label=0xddddd, exp=0x2, ttl=0x40, bos=1) pop_info=switcht_mpls_pop_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(pop_info=pop_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=0, mpls_mode=2, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_POP, mpls_mode=SWITCH_API_MPLS_TERMINATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu7 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) + iu7 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) if7 = self.client.switcht_api_tunnel_interface_create(device, 0, iu7) #add L2 port to LN @@ -5666,7 +5857,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip4, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor4 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry4) neighbor_entry1 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip4) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) @@ -5677,7 +5868,7 @@ def runTest(self): interface_handle=if5, mac_addr='00:44:44:44:44:44', ip_addr=src_ip5, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor5 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry5) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if5, mac_addr='00:44:44:44:44:44', ip_addr=src_ip5) neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry2) @@ -5685,7 +5876,13 @@ def runTest(self): #neighbor type 5 is push l2vpn nhop_key6 = switcht_nhop_key_t(intf_handle=if6, ip_addr_valid=0) nhop6 = self.client.switcht_api_nhop_create(device, nhop_key6) - neighbor_entry6 = switcht_neighbor_info_t(nhop_handle=nhop6, neigh_type=5, interface_handle= if6, mpls_label=0, header_count=2, rw_type=0) + neighbor_entry6 = switcht_neighbor_info_t( + nhop_handle=nhop6, + neigh_type=SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN, + interface_handle= if6, + mpls_label=0, + header_count=2, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2) neighbor6 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry6) neighbor_entry3 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if6, mac_addr='00:55:55:55:55:55') neighbor3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry3) @@ -5823,7 +6020,7 @@ def runTest(self): send_packet(self, swports[1], str(geneve_pkt)) verify_packets(self, mpls_pkt, [swports[3]]) - print "Sending packet from Mpls port %d" % swports[3], " to Geneve port %d" % swports[1], "" + print "Sending packet from Mpls port %d" % swports[3], "to Geneve port %d" % swports[1], "" pkt = simple_tcp_packet(eth_dst='00:aa:aa:aa:aa:aa', eth_src='00:cc:cc:cc:cc:cc', ip_dst='10.10.10.1', @@ -5836,7 +6033,7 @@ def runTest(self): eth_src='00:55:55:55:55:55', mpls_tags=mpls_tags, inner_frame=pkt) - udp_sport = entropy_hash(pkt, layer='ether') + udp_sport = entropy_hash(pkt) geneve_pkt = simple_geneve_packet( eth_dst='00:33:33:33:33:33', eth_src='00:77:66:55:44:33', @@ -5898,32 +6095,32 @@ def runTest(self): self.client.switcht_api_vlan_learning_enabled_set(vlan, 0) lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu1 = interface_union(port_lag_handle = lag1) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) lag2 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu2 = interface_union(port_lag_handle = lag2) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) lag3 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag3, side=0, port=swports[5]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag3, side=0, port=swports[6]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag3, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag3, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) iu3 = interface_union(port_lag_handle = lag3) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) iu4 = interface_union(port_lag_handle = swports[7]) - i_info4 = switcht_interface_info_t(device=0, type=2, u=iu4, mac='00:77:66:55:44:33', label=0) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu4, mac='00:77:66:55:44:33', label=0) if4 = self.client.switcht_api_interface_create(device, i_info4) iu5 = interface_union(port_lag_handle = swports[8]) - i_info5 = switcht_interface_info_t(device=0, type=2, u=iu5, mac='00:77:66:55:44:33', label=0) + i_info5 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu5, mac='00:77:66:55:44:33', label=0) if5 = self.client.switcht_api_interface_create(device, i_info5) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -5986,12 +6183,12 @@ def runTest(self): self.client.switcht_api_interface_delete(device, if4) self.client.switcht_api_interface_delete(device, if5) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[2]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=0, port=swports[4]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag3, side=0, port=swports[5]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag3, side=0, port=swports[6]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag2, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag3, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag3, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) self.client.switcht_api_lag_delete(device, lag1) self.client.switcht_api_lag_delete(device, lag2) @@ -6015,60 +6212,60 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) iu4 = interface_union(port_lag_handle = swports[4]) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if4 = self.client.switcht_api_interface_create(device, i_info4) lag1 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[5]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=0, port=swports[6]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) iu5 = interface_union(port_lag_handle = lag1) - i_info5 = switcht_interface_info_t(device=0, type=2, u=iu5, mac='00:77:66:55:44:33', label=0) + i_info5 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu5, mac='00:77:66:55:44:33', label=0) if5 = self.client.switcht_api_interface_create(device, i_info5) iu7 = interface_union(port_lag_handle = swports[7]) - i_info7 = switcht_interface_info_t(device=0, type=2, u=iu7, mac='00:77:66:55:44:33', label=0) + i_info7 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu7, mac='00:77:66:55:44:33', label=0) if7 = self.client.switcht_api_interface_create(device, i_info7) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) # Create a geneve tunnel interface udp11 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip11 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip11 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip11 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip11 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp11 = switcht_udp_tcp_t(udp = udp11) geneve11 = switcht_geneve_id_t(vni=0x4321) bt11 = switcht_bridge_type(geneve_info=geneve11) - encap_info11 = switcht_encap_info_t(encap_type=6, u=bt11) + encap_info11 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE, u=bt11) ip_encap11 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip11, dst_ip=dst_ip11, ttl=60, proto=17, u=udp_tcp11) tunnel_encap11 = switcht_tunnel_encap_t(ip_encap=ip_encap11) - iu11 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap11, encap_info=encap_info11, out_if=if1) + iu11 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap11, encap_info=encap_info11, out_if=if1) if11 = self.client.switcht_api_tunnel_interface_create(device, 0, iu11) # Create a vxlan tunnel interface udp21 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip21 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip21 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp21 = switcht_udp_tcp_t(udp = udp21) vxlan21 = switcht_vxlan_id_t(vnid=0x1234) bt21 = switcht_bridge_type(vxlan_info=vxlan21) - encap_info21 = switcht_encap_info_t(encap_type=3, u=bt21) + encap_info21 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt21) ip_encap21 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip21, dst_ip=dst_ip21, ttl=60, proto=17, u=udp_tcp21) tunnel_encap21 = switcht_tunnel_encap_t(ip_encap=ip_encap21) - iu21 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap21, encap_info=encap_info21, out_if=if2) + iu21 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap21, encap_info=encap_info21, out_if=if2) if21 = self.client.switcht_api_tunnel_interface_create(device, 0, iu21) #Create a mpls push interface @@ -6076,10 +6273,10 @@ def runTest(self): mpls_tag2 = switcht_mpls_t(label=0xbbbbb, exp=0x2, ttl=0x40, bos=1) push_info=switcht_mpls_push_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(push_info=push_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=1, mpls_mode=0, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_PUSH, mpls_mode=SWITCH_API_MPLS_INITIATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu31 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) + iu31 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) if31 = self.client.switcht_api_tunnel_interface_create(device, 0, iu31) #Create a mpls pop interface @@ -6087,21 +6284,21 @@ def runTest(self): mpls_tag2 = switcht_mpls_t(label=0xddddd, exp=0x2, ttl=0x40, bos=1) pop_info=switcht_mpls_pop_t(tag=[mpls_tag1, mpls_tag2], count=2) mpls_info = switcht_mpls_info_t(pop_info=pop_info) - mpls_encap = switcht_mpls_encap_t(mpls_type=0, mpls_action=0, mpls_mode=2, u=mpls_info, bd_handle=ln1) + mpls_encap = switcht_mpls_encap_t(mpls_type=SWITCH_API_MPLS_TYPE_EOMPLS, mpls_action=SWITCH_API_MPLS_ACTION_POP, mpls_mode=SWITCH_API_MPLS_TERMINATE, u=mpls_info, bd_handle=ln1) tunnel_encap = switcht_tunnel_encap_t(mpls_encap=mpls_encap) flags=switcht_interface_flags(flood_enabled=0, core_intf=0) - iu32 = switcht_tunnel_info_t(encap_mode=1, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) + iu32 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_MPLS, tunnel_encap=tunnel_encap, out_if=if3, flags=flags) if32 = self.client.switcht_api_tunnel_interface_create(device, 0, iu32) # Create a nvgre tunnel interface - src_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='3.3.3.1', prefix_length=32) - dst_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='3.3.3.3', prefix_length=32) + src_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='3.3.3.1', prefix_length=32) + dst_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='3.3.3.3', prefix_length=32) nvgre41 = switcht_nvgre_id_t(tnid=0x4545) bt41 = switcht_bridge_type(nvgre_info=nvgre41) - encap_info41 = switcht_encap_info_t(encap_type=5, u=bt41) + encap_info41 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_NVGRE, u=bt41) ip_encap41 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip41, dst_ip=dst_ip41, ttl=60, proto=47, gre_proto=0x6558) tunnel_encap41 = switcht_tunnel_encap_t(ip_encap=ip_encap41) - iu41 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap41, encap_info=encap_info41, out_if=if4) + iu41 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap41, encap_info=encap_info41, out_if=if4) if41 = self.client.switcht_api_tunnel_interface_create(device, 0, iu41) #add L2 port to LN @@ -6119,7 +6316,7 @@ def runTest(self): interface_handle=if11, mac_addr='00:33:33:33:33:33', ip_addr=src_ip11, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor11 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry11) neighbor_entry12 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if11, mac_addr='00:33:33:33:33:33', ip_addr=src_ip11) neighbor12 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry12) @@ -6130,7 +6327,7 @@ def runTest(self): interface_handle=if21, mac_addr='00:44:44:44:44:44', ip_addr=src_ip21, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor21 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry21) neighbor_entry22 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if21, mac_addr='00:44:44:44:44:44', ip_addr=src_ip21) neighbor22 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry22) @@ -6138,7 +6335,13 @@ def runTest(self): #neighbor type 5 is push l2vpn nhop_key31 = switcht_nhop_key_t(intf_handle=if31, ip_addr_valid=0) nhop31 = self.client.switcht_api_nhop_create(device, nhop_key31) - neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, neigh_type=5, interface_handle= if31, mpls_label=0, header_count=2, rw_type=0) + neighbor_entry31 = switcht_neighbor_info_t( + nhop_handle=nhop31, + neigh_type=SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN, + interface_handle= if31, + mpls_label=0, + header_count=2, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) neighbor_entry32 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if31, mac_addr='00:55:55:55:55:55') neighbor32 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry32) @@ -6149,7 +6352,7 @@ def runTest(self): interface_handle=if41, mac_addr='00:66:66:66:66:66', ip_addr=src_ip41, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if41, mac_addr='00:66:66:66:66:66', ip_addr=src_ip41) neighbor42 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry42) @@ -6301,7 +6504,7 @@ def runTest(self): eth_src='00:55:55:55:55:55', mpls_tags=mpls_tags, inner_frame=pkt) - udp_sport = entropy_hash(pkt, layer='ether') + udp_sport = entropy_hash(pkt) geneve_pkt = simple_geneve_packet( eth_dst='00:33:33:33:33:33', eth_src='00:77:66:55:44:33', @@ -6474,7 +6677,7 @@ def runTest(self): send_packet(self, swports[4], str(nvgre_pkt)) verify_packets(self, mpls_pkt, [swports[3]]) - print "Sending packet from Mpls port %d" % swports[3], " to Nvgre port %d" % swports[4], "" + print "Sending packet from Mpls port %d" % swports[3], "to Nvgre port %d" % swports[4], "" pkt = simple_tcp_packet(eth_dst='00:04:00:00:00:41', eth_src='00:03:00:00:00:31', ip_dst='10.10.10.1', @@ -6487,7 +6690,7 @@ def runTest(self): eth_src='00:55:55:55:55:55', mpls_tags=mpls_tags, inner_frame=pkt) - nvgre_flowid = entropy_hash(pkt, layer='ether') & 0xFF + nvgre_flowid = entropy_hash(pkt) & 0xFF nvgre_pkt = simple_nvgre_packet( eth_dst='00:66:66:66:66:66', eth_src='00:77:66:55:44:33', @@ -6602,8 +6805,8 @@ def runTest(self): self.client.switcht_api_tunnel_interface_delete(device, if32) self.client.switcht_api_tunnel_interface_delete(device, if41) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[5]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=0, port=swports[6]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[5]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag1, side=SWITCH_API_DIRECTION_BOTH, port=swports[6]) self.client.switcht_api_lag_delete(device, lag1) self.client.switcht_api_interface_delete(device, if1) @@ -6631,15 +6834,15 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) # Create a logical network (LN) @@ -6648,7 +6851,7 @@ def runTest(self): encap = switcht_encap_info_t(u=bt) #encap_type 4 is vxlan - lognet_info = switcht_logical_network_t(type=4, encap_info=encap, + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=10000, vrf=vrf, flags=ln_flags) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) @@ -6656,13 +6859,13 @@ def runTest(self): # Create a tunnel interface flags = switcht_interface_flags(flood_enabled=1) udp = switcht_udp_t(src_port=1234, dst_port=4789) - 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) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) - encap_info = switcht_encap_info_t(encap_type=3) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) 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) - iu4 = switcht_tunnel_info_t(encap_mode = 0, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2, flags=flags) + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=if2, flags=flags) if4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) nhop_key1 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) @@ -6677,7 +6880,7 @@ def runTest(self): interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if4, mac_addr='00:33:33:33:33:33', ip_addr=src_ip) @@ -6748,6 +6951,7 @@ def runTest(self): self.client.switcht_api_tunnel_interface_delete(device, if4) self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) + self.client.switcht_api_interface_delete(device, if3) 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) @@ -6765,11 +6969,11 @@ def runTest(self): self.client.switcht_api_vlan_stats_enable(device, vlan) iu1 = interface_union(port_lag_handle = swports[1]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -6857,72 +7061,72 @@ def runTest(self): 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) # Create a logical network (LN) - lognet_info = switcht_logical_network_t(type=5, age_interval=1800, vrf=vrf) + lognet_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, age_interval=1800, vrf=vrf) ln1 = self.client.switcht_api_logical_network_create(device, lognet_info) flags = switcht_interface_flags(flood_enabled=1) # Create a geneve tunnel interface udp11 = switcht_udp_t(src_port=1234, dst_port=6081) - src_ip11 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', prefix_length=32) - dst_ip11 = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', prefix_length=32) + src_ip11 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) + dst_ip11 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp11 = switcht_udp_tcp_t(udp = udp11) geneve11 = switcht_geneve_id_t(vni=0x4321) bt11 = switcht_bridge_type(geneve_info=geneve11) - encap_info11 = switcht_encap_info_t(encap_type=6, u=bt11) + encap_info11 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GENEVE, u=bt11) ip_encap11 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip11, dst_ip=dst_ip11, ttl=60, proto=17, u=udp_tcp11) tunnel_encap11 = switcht_tunnel_encap_t(ip_encap=ip_encap11) - iu11 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap11, encap_info=encap_info11, out_if=if1, flags=flags) + iu11 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap11, encap_info=encap_info11, out_if=if1, flags=flags) if11 = self.client.switcht_api_tunnel_interface_create(device, 0, iu11) # Create a vxlan tunnel interface udp21 = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip21 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.1', prefix_length=32) - dst_ip21 = switcht_ip_addr_t(addr_type=0, ipaddr='2.2.2.3', prefix_length=32) + src_ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.1', prefix_length=32) + dst_ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='2.2.2.3', prefix_length=32) udp_tcp21 = switcht_udp_tcp_t(udp = udp21) vxlan21 = switcht_vxlan_id_t(vnid=0x1234) bt21 = switcht_bridge_type(vxlan_info=vxlan21) - encap_info21 = switcht_encap_info_t(encap_type=3, u=bt21) + encap_info21 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt21) ip_encap21 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip21, dst_ip=dst_ip21, ttl=60, proto=17, u=udp_tcp21) tunnel_encap21 = switcht_tunnel_encap_t(ip_encap=ip_encap21) - iu21 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap21, encap_info=encap_info21, out_if=if2, flags=flags) + iu21 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap21, encap_info=encap_info21, out_if=if2, flags=flags) if21 = self.client.switcht_api_tunnel_interface_create(device, 0, iu21) # Create a nvgre tunnel interface - src_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='3.3.3.1', prefix_length=32) - dst_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='3.3.3.3', prefix_length=32) + src_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='3.3.3.1', prefix_length=32) + dst_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='3.3.3.3', prefix_length=32) nvgre31 = switcht_nvgre_id_t(tnid=0x4545) bt31 = switcht_bridge_type(nvgre_info=nvgre31) - encap_info31 = switcht_encap_info_t(encap_type=5, u=bt31) + encap_info31 = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_NVGRE, u=bt31) ip_encap31 = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip31, dst_ip=dst_ip31, ttl=60, proto=47, gre_proto=0x6558) tunnel_encap31 = switcht_tunnel_encap_t(ip_encap=ip_encap31) - iu31 = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap31, encap_info=encap_info31, out_if=if3, flags=flags) + iu31 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap31, encap_info=encap_info31, out_if=if3, flags=flags) if31 = self.client.switcht_api_tunnel_interface_create(device, 0, iu31) pv4 = switcht_port_vlan_t(port_lag_handle=swports[4], vlan_id=10) iu4 = interface_union(port_vlan = pv4) - i_info4 = switcht_interface_info_t(device=0, type=9, u=iu4, mac='00:77:66:55:44:33', label=0) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_PORT_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0) if4 = self.client.switcht_api_interface_create(device, i_info4) pv5 = switcht_port_vlan_t(port_lag_handle=swports[5], vlan_id=20) iu5 = interface_union(port_vlan = pv5) - i_info5 = switcht_interface_info_t(device=0, type=9, u=iu5, mac='00:77:66:55:44:33', label=0) + i_info5 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_PORT_VLAN, u=iu5, mac='00:77:66:55:44:33', label=0) if5 = self.client.switcht_api_interface_create(device, i_info5) iu6 = interface_union(port_lag_handle = swports[6]) - i_info6 = switcht_interface_info_t(device=0, type=2, u=iu6, mac='00:77:66:55:44:33', label=0) + i_info6 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu6, mac='00:77:66:55:44:33', label=0) if6 = self.client.switcht_api_interface_create(device, i_info6) nhop_key11 = switcht_nhop_key_t(intf_handle=if11, ip_addr_valid=0) @@ -6943,7 +7147,7 @@ def runTest(self): interface_handle=if11, mac_addr='00:11:11:11:11:11', ip_addr=src_ip11, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor11 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry11) neighbor_entry12 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if11, mac_addr='00:11:11:11:11:11', ip_addr=src_ip11) neighbor12 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry12) @@ -6952,7 +7156,7 @@ def runTest(self): interface_handle=if21, mac_addr='00:22:22:22:22:22', ip_addr=src_ip21, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor21 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry21) neighbor_entry22 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if21, mac_addr='00:22:22:22:22:22', ip_addr=src_ip21) neighbor22 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry22) @@ -6961,7 +7165,7 @@ def runTest(self): interface_handle=if31, mac_addr='00:33:33:33:33:33', ip_addr=src_ip31, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) neighbor_entry32 = switcht_neighbor_info_t(nhop_handle=0, interface_handle=if31, mac_addr='00:33:33:33:33:33:33', ip_addr=src_ip31) neighbor32 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry32) @@ -7085,11 +7289,11 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -7101,38 +7305,38 @@ def runTest(self): self.client.switcht_api_mac_table_entry_create(device, vlan, '00:22:22:22:22:22', 2, if2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # Add a static route - i_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key41 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop41 = self.client.switcht_api_nhop_create(device, nhop_key41) - neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=1) + neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) self.client.switcht_api_l3_route_add(device, vrf, i_ip41, nhop41) - i_ip42 = switcht_ip_addr_t(addr_type=0, ipaddr='11.11.11.1', prefix_length=32) + i_ip42 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.11.11.1', prefix_length=32) nhop_key42 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop42 = self.client.switcht_api_nhop_create(device, nhop_key42) - neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=1) + neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor42 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry42) self.client.switcht_api_l3_route_add(device, vrf, i_ip42, nhop42) - i_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='12.12.12.1', prefix_length=32) + i_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.12.12.1', prefix_length=32) nhop_key31 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop31 = self.client.switcht_api_nhop_create(device, nhop_key31) - neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=1) + neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) self.client.switcht_api_l3_route_add(device, vrf, i_ip31, nhop31) @@ -7243,11 +7447,11 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -7259,38 +7463,38 @@ def runTest(self): self.client.switcht_api_mac_table_entry_create(device, vlan, '00:22:22:22:22:22', 2, if2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=1, ipaddr='2000::2', prefix_length=128) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000::2', prefix_length=128) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='3000::2', prefix_length=128) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='3000::2', prefix_length=128) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # Add a static route - i_ip41 = switcht_ip_addr_t(addr_type=1, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99aa', prefix_length=128) + i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99aa', prefix_length=128) nhop_key41 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop41 = self.client.switcht_api_nhop_create(device, nhop_key41) - neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=1) + neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) self.client.switcht_api_l3_route_add(device, vrf, i_ip41, nhop41) - i_ip42 = switcht_ip_addr_t(addr_type=1, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99bb', prefix_length=128) + i_ip42 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99bb', prefix_length=128) nhop_key42 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop42 = self.client.switcht_api_nhop_create(device, nhop_key42) - neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=1) + neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor42 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry42) self.client.switcht_api_l3_route_add(device, vrf, i_ip42, nhop42) - i_ip31 = switcht_ip_addr_t(addr_type=1, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99cc', prefix_length=128) + i_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='1234:5678:9abc:def0:4422:1133:5577:99cc', prefix_length=128) nhop_key31 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop31 = self.client.switcht_api_nhop_create(device, nhop_key31) - neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=1) + neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) self.client.switcht_api_l3_route_add(device, vrf, i_ip31, nhop31) @@ -7393,11 +7597,11 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -7406,38 +7610,38 @@ def runTest(self): self.client.switcht_api_vlan_ports_add(device, vlan, vlan_port2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # Add a static route - i_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key41 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop41 = self.client.switcht_api_nhop_create(device, nhop_key41) - neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=1) + neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) self.client.switcht_api_l3_route_add(device, vrf, i_ip41, nhop41) - i_ip42 = switcht_ip_addr_t(addr_type=0, ipaddr='11.11.11.1', prefix_length=32) + i_ip42 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.11.11.1', prefix_length=32) nhop_key42 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop42 = self.client.switcht_api_nhop_create(device, nhop_key42) - neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=1) + neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor42 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry42) self.client.switcht_api_l3_route_add(device, vrf, i_ip42, nhop42) - i_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='12.12.12.1', prefix_length=32) + i_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.12.12.1', prefix_length=32) nhop_key31 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop31 = self.client.switcht_api_nhop_create(device, nhop_key31) - neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=1) + neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) self.client.switcht_api_l3_route_add(device, vrf, i_ip31, nhop31) @@ -7549,15 +7753,15 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, mac='00:77:66:55:44:33', label=0) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) if3 = self.client.switcht_api_interface_create(device, i_info3) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -7568,11 +7772,11 @@ def runTest(self): self.client.switcht_api_vlan_ports_add(device, vlan, vlan_port3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # send the test packet(s) @@ -7643,17 +7847,17 @@ def runTest(self): self.client.switcht_api_router_mac_add(device, rmac, '00:77:66:55:44:33') lag12 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag12, side=0, port=swports[1]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag12, side=0, port=swports[2]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag12, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag12, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) iu12 = interface_union(port_lag_handle = lag12) - i_info12 = switcht_interface_info_t(device=0, type=2, u=iu12, mac='00:77:66:55:44:33', label=0) + i_info12 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu12, mac='00:77:66:55:44:33', label=0) if12 = self.client.switcht_api_interface_create(device, i_info12) lag34 = self.client.switcht_api_lag_create(device) - self.client.switcht_api_lag_member_add(device, lag_handle=lag34, side=0, port=swports[3]) - self.client.switcht_api_lag_member_add(device, lag_handle=lag34, side=0, port=swports[4]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag34, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=lag34, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) iu34 = interface_union(port_lag_handle = lag34) - i_info34 = switcht_interface_info_t(device=0, type=2, u=iu34, mac='00:77:66:55:44:33', label=0) + i_info34 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu34, mac='00:77:66:55:44:33', label=0) if34 = self.client.switcht_api_interface_create(device, i_info34) vlan_port1 = switcht_vlan_port_t(handle=if12, tagging_mode=0) @@ -7662,30 +7866,30 @@ def runTest(self): self.client.switcht_api_vlan_ports_add(device, vlan, vlan_port2) iu1 = interface_union(vlan_id = 10) - i_info1 = switcht_interface_info_t(device=0, type=5, u=iu1, mac='00:77:66:55:44:33', + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if1 = self.client.switcht_api_interface_create(device, i_info1) - i_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='100.0.0.2', prefix_length=32) + i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='100.0.0.2', prefix_length=32) self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[5]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0,vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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='200.0.0.2', prefix_length=32) + i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='200.0.0.2', prefix_length=32) self.client.switcht_api_l3_interface_address_add(device, if2, vrf, i_ip2) - i_ip11 = switcht_ip_addr_t(addr_type=0, ipaddr='11.11.11.1', prefix_length=32) + i_ip11 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.11.11.1', prefix_length=32) nhop_key11 = switcht_nhop_key_t(intf_handle=if1, ip_addr_valid=0) nhop11 = self.client.switcht_api_nhop_create(device, nhop_key11) - neighbor_entry11 = switcht_neighbor_info_t(nhop_handle=nhop11, interface_handle=if1, mac_addr='00:11:11:11:11:11', ip_addr=i_ip11, rw_type=1) + neighbor_entry11 = switcht_neighbor_info_t(nhop_handle=nhop11, interface_handle=if1, mac_addr='00:11:11:11:11:11', ip_addr=i_ip11, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor11 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry11) self.client.switcht_api_l3_route_add(device, vrf, i_ip11, nhop11) - i_ip12 = switcht_ip_addr_t(addr_type=0, ipaddr='12.12.12.1', prefix_length=32) + i_ip12 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.12.12.1', prefix_length=32) nhop_key12 = switcht_nhop_key_t(intf_handle=if1, ip_addr_valid=0) nhop12 = self.client.switcht_api_nhop_create(device, nhop_key12) - neighbor_entry12 = switcht_neighbor_info_t(nhop_handle=nhop12, interface_handle=if1, mac_addr='00:12:12:12:12:12', ip_addr=i_ip12, rw_type=1) + neighbor_entry12 = switcht_neighbor_info_t(nhop_handle=nhop12, interface_handle=if1, mac_addr='00:12:12:12:12:12', ip_addr=i_ip12, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor12 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry12) self.client.switcht_api_l3_route_add(device, vrf, i_ip12, nhop12) @@ -7749,12 +7953,12 @@ def runTest(self): self.client.switcht_api_interface_delete(device, if1) self.client.switcht_api_interface_delete(device, if2) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag12, side=0, port=swports[1]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag12, side=0, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag12, side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag12, side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) self.client.switcht_api_interface_delete(device, if12) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag34, side=0, port=swports[3]) - self.client.switcht_api_lag_member_delete(device, lag_handle=lag34, side=0, port=swports[4]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag34, side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=lag34, side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) self.client.switcht_api_interface_delete(device, if34) self.client.switcht_api_lag_delete(device, lag12) @@ -7782,11 +7986,11 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=3, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -7798,38 +8002,38 @@ def runTest(self): self.client.switcht_api_mac_table_entry_create(device, vlan, '00:22:22:22:22:22', 2, if2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # Add a static route - i_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key41 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop41 = self.client.switcht_api_nhop_create(device, nhop_key41) - neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=1) + neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) self.client.switcht_api_l3_route_add(device, vrf, i_ip41, nhop41) - i_ip42 = switcht_ip_addr_t(addr_type=0, ipaddr='11.11.11.1', prefix_length=32) + i_ip42 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.11.11.1', prefix_length=32) nhop_key42 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop42 = self.client.switcht_api_nhop_create(device, nhop_key42) - neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=1) + neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor42 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry42) self.client.switcht_api_l3_route_add(device, vrf, i_ip42, nhop42) - i_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='12.12.12.1', prefix_length=32) + i_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.12.12.1', prefix_length=32) nhop_key31 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop31 = self.client.switcht_api_nhop_create(device, nhop_key31) - neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=1) + neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) self.client.switcht_api_l3_route_add(device, vrf, i_ip31, nhop31) @@ -7959,11 +8163,11 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -7974,29 +8178,29 @@ def runTest(self): self.client.switcht_api_mac_table_entry_create(device, vlan, '00:22:22:22:22:22', 2, if2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # Add a static route - i_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key41 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop41 = self.client.switcht_api_nhop_create(device, nhop_key41) self.client.switcht_api_l3_route_add(device, vrf, i_ip41, nhop41) - i_ip42 = switcht_ip_addr_t(addr_type=0, ipaddr='11.11.11.1', prefix_length=32) + i_ip42 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='11.11.11.1', prefix_length=32) nhop_key42 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop42 = self.client.switcht_api_nhop_create(device, nhop_key42) - neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=1) + neighbor_entry42 = switcht_neighbor_info_t(nhop_handle=nhop42, interface_handle=if4, mac_addr='00:22:22:22:22:22', ip_addr=i_ip42, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor42 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry42) self.client.switcht_api_l3_route_add(device, vrf, i_ip42, nhop42) @@ -8010,7 +8214,7 @@ def runTest(self): ip_ttl=64) exp_pkt1 = simple_cpu_packet(ingress_port = 3, ingress_ifindex = 4, - reason_code = 0, + reason_code = 0x217, ingress_bd = 3, inner_pkt = pkt) exp_pkt2 = simple_tcp_packet( @@ -8031,7 +8235,7 @@ def runTest(self): send_packet(self, swports[3], str(pkt)) verify_packets(self, exp_pkt1, [cpu_port]) - neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=1) + neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) print "Sending packet l3 port %d" % swports[3], "to vlan interface port %d" % swports[1] @@ -8105,11 +8309,11 @@ def setUp(self): # vlan 10, with two ports 0 and 1 self.vlan = self.client.switcht_api_vlan_create(device, 10) iu1 = interface_union(port_lag_handle = swports[0]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) 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=2, u=iu2, + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) self.if2 = self.client.switcht_api_interface_create(device, i_info2) self.vlan_port1 = switcht_vlan_port_t(handle=self.if1, tagging_mode=0) @@ -8125,12 +8329,12 @@ def setUp(self): # logical network with one native 2 and one tunnel interface 3 iu3 = interface_union(port_lag_handle = swports[2]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) self.if3 = self.client.switcht_api_interface_create(device, i_info3) iu4 = interface_union(port_lag_handle = swports[3]) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac) @@ -8139,24 +8343,24 @@ def setUp(self): # Create a logical network (LN) bt = switcht_bridge_type(tunnel_vni=0x1234) encap = switcht_encap_info_t(u=bt) - ln_info = switcht_logical_network_t(type=4, encap_info=encap, + ln_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=self.vrf) self.ln1 = self.client.switcht_api_logical_network_create(device, ln_info) # Create a tunnel interface udp = switcht_udp_t(src_port=1234, dst_port=4789) - src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.1', + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.1', prefix_length=32) - dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='1.1.1.3', + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='1.1.1.3', prefix_length=32) udp_tcp = switcht_udp_tcp_t(udp = udp) - encap_info = switcht_encap_info_t(encap_type=3) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN) ip_encap = switcht_ip_encap_t(vrf=self.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) - iu5 = switcht_tunnel_info_t(encap_mode = 0, tunnel_encap=tunnel_encap, + iu5 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=self.if4) self.if5 = self.client.switcht_api_tunnel_interface_create(device, 0, iu5) @@ -8173,7 +8377,7 @@ def setUp(self): interface_handle=self.if5, mac_addr='00:33:33:33:33:33', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) self.neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, @@ -8652,11 +8856,11 @@ def runTest(self): 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=2, u=iu1, mac='00:77:66:55:44:33', label=0) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) if1 = self.client.switcht_api_interface_create(device, i_info1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=2, u=iu2, mac='00:77:66:55:44:33', label=0) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu2, mac='00:77:66:55:44:33', label=0) if2 = self.client.switcht_api_interface_create(device, i_info2) vlan_port1 = switcht_vlan_port_t(handle=if1, tagging_mode=0) @@ -8665,31 +8869,31 @@ def runTest(self): self.client.switcht_api_vlan_ports_add(device, vlan, vlan_port2) iu3 = interface_union(port_lag_handle = swports[3]) - i_info3 = switcht_interface_info_t(device=0, type=4, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu3, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if3 = self.client.switcht_api_interface_create(device, i_info3) - i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', prefix_length=16) + i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if3, vrf, i_ip3) iu4 = interface_union(vlan_id = 10) - i_info4 = switcht_interface_info_t(device=0, type=5, u=iu4, mac='00:77:66:55:44:33', + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac, v4_unicast_enabled=1, v6_unicast_enabled=1) if4 = self.client.switcht_api_interface_create(device, i_info4) - i_ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', prefix_length=16) + i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(device, if4, vrf, i_ip4) # Add a static route - i_ip41 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', prefix_length=32) + i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key41 = switcht_nhop_key_t(intf_handle=if4, ip_addr_valid=0) nhop41 = self.client.switcht_api_nhop_create(device, nhop_key41) - neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=1) + neighbor_entry41 = switcht_neighbor_info_t(nhop_handle=nhop41, interface_handle=if4, mac_addr='00:11:11:11:11:11', ip_addr=i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor41 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry41) self.client.switcht_api_l3_route_add(device, vrf, i_ip41, nhop41) - i_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='12.12.12.1', prefix_length=32) + i_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='12.12.12.1', prefix_length=32) nhop_key31 = switcht_nhop_key_t(intf_handle=if3, ip_addr_valid=0) nhop31 = self.client.switcht_api_nhop_create(device, nhop_key31) - neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=1) + neighbor_entry31 = switcht_neighbor_info_t(nhop_handle=nhop31, interface_handle=if3, mac_addr='00:33:33:33:33:33', ip_addr=i_ip31, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor31 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry31) self.client.switcht_api_l3_route_add(device, vrf, i_ip31, nhop31) @@ -8746,8 +8950,7 @@ def runTest(self): ip_ttl=63) print "Sending packet vlan interface port %d" % swports[2], " to l3 port %d" % swports[3] send_packet(self, swports[2], str(pkt)) - verify_packets(self, exp_pkt, [swports[3]]) - + verify_packet(self, exp_pkt, swports[3]) time.sleep(3) pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', @@ -8763,6 +8966,7 @@ def runTest(self): ip_src='192.168.0.1', ip_id=105, ip_ttl=63) + print "Sending packet l3 port %d" % swports[3], " to vlan interface port %d" % swports[2] send_packet(self, swports[3], str(pkt)) verify_packets(self, exp_pkt, [swports[2]]) @@ -8813,14 +9017,14 @@ def setUp(self): # create two l3 interfaces iu1 = interface_union(port_lag_handle = swports[0]) - i_info1 = switcht_interface_info_t(device=0, type=4, u=iu1, + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) - self.i_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='192.168.0.2', + self.i_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', prefix_length=16) - self.i_ip11 = switcht_ip_addr_t(addr_type=1, ipaddr='2000::2', + self.i_ip11 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000::2', prefix_length=64) self.client.switcht_api_l3_interface_address_add(device, self.if1, self.vrf, @@ -8829,67 +9033,67 @@ def setUp(self): self.vrf, self.i_ip11) iu2 = interface_union(port_lag_handle = swports[1]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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) - self.i_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.0.2', + self.i_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.0.2', prefix_length=16) - self.i_ip21 = switcht_ip_addr_t(addr_type=1, ipaddr='3000::2', + self.i_ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000::2', prefix_length=64) self.client.switcht_api_l3_interface_address_add(device, self.if2, self.vrf, self.i_ip2) # add ipv4 static routes - self.i_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='10.10.10.1', + self.i_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', prefix_length=32) nhop_key = switcht_nhop_key_t(intf_handle=self.if2, 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.if2, mac_addr='00:11:22:33:44:55', - ip_addr=self.i_ip3, rw_type=1) + ip_addr=self.i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) self.neighbor1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, self.vrf, self.i_ip3, self.nhop1) - self.i_ip31 = switcht_ip_addr_t(addr_type=0, ipaddr='10.20.10.1', + self.i_ip31 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.20.10.1', prefix_length=32) nhop_key = switcht_nhop_key_t(intf_handle=self.if1, ip_addr_valid=0) self.nhop11 = self.client.switcht_api_nhop_create(device, nhop_key) neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop11, interface_handle=self.if1, mac_addr='00:11:22:33:44:66', - ip_addr=self.i_ip31, rw_type=1) + ip_addr=self.i_ip31, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) self.neighbor11 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, self.vrf, self.i_ip31, self.nhop11) # add an ipv6 static route - self.i_ip4 = switcht_ip_addr_t(addr_type=1, + self.i_ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3000::3', prefix_length=64) nhop_key = switcht_nhop_key_t(intf_handle=self.if2, 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.if2, mac_addr='00:11:22:33:44:55', - ip_addr=self.i_ip4, rw_type=1) + ip_addr=self.i_ip4, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) self.neighbor2 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, self.vrf, self.i_ip4, self.nhop2) - self.i_ip41 = switcht_ip_addr_t(addr_type=1, + self.i_ip41 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000::3', prefix_length=64) nhop_key = switcht_nhop_key_t(intf_handle=self.if1, ip_addr_valid=0) self.nhop21 = self.client.switcht_api_nhop_create(device, nhop_key) neighbor_entry = switcht_neighbor_info_t(nhop_handle=self.nhop21, interface_handle=self.if2, mac_addr='00:11:22:33:44:77', - ip_addr=self.i_ip41, rw_type=1) + ip_addr=self.i_ip41, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) self.neighbor21 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) self.client.switcht_api_l3_route_add(device, self.vrf, self.i_ip41, @@ -8935,7 +9139,7 @@ def runTest(self): ip_ttl=1) cpu_pkt = simple_cpu_packet(ingress_port=swports[0], ingress_ifindex=1, - reason_code=0x1d, + reason_code=0x212, ingress_bd=0x02, inner_pkt=pkt) send_packet(self, swports[0], str(pkt)) @@ -8949,7 +9153,7 @@ def runTest(self): ipv6_hlim=1) cpu_pkt = simple_cpu_packet(ingress_port=swports[0], ingress_ifindex=1, - reason_code=0x1d, + reason_code=0x212, ingress_bd=0x02, inner_pkt=pkt) send_packet(self, swports[0], str(pkt)) @@ -8964,7 +9168,7 @@ def runTest(self): ip_ttl=63) cpu_pkt = simple_cpu_packet(ingress_port=swports[0], ingress_ifindex=1, - reason_code=0x104, + reason_code=0x215, ingress_bd=0x02, inner_pkt=pkt) exp_pkt = simple_tcp_packet(eth_dst='00:11:22:33:44:66', @@ -8985,7 +9189,7 @@ def runTest(self): ipv6_hlim=64) cpu_pkt = simple_cpu_packet(ingress_port=swports[0], ingress_ifindex=1, - reason_code=0x104, + reason_code=0x215, ingress_bd=0x02, inner_pkt=pkt) exp_pkt = simple_tcpv6_packet(eth_dst='00:11:22:33:44:77', @@ -9005,7 +9209,7 @@ def runTest(self): ipv6_hlim=64) cpu_pkt = simple_cpu_packet(ingress_port=swports[0], ingress_ifindex=1, - reason_code=0x105, + reason_code=0x216, ingress_bd=0x02, inner_pkt=pkt) send_packet(self, swports[0], str(pkt)) @@ -9047,6 +9251,116 @@ def tearDown(self): api_base_tests.ThriftInterfaceDataPlane.tearDown(self) + +############################################################################### +@group('l3') +@group('ipv4') +class L3IPv4MtuTest(api_base_tests.ThriftInterfaceDataPlane): + def runTest(self): + print + print "Skipping L3IPv4MtuTest" + return + 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=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', + prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, if1, + vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V4, 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=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', + prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + nhop = self.client.switcht_api_nhop_create(device, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, + interface_handle=if2, + mac_addr='00:11:22:33:44:55', + ip_addr=i_ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + neighbor = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + self.client.switcht_api_l3_route_add(device, vrf, i_ip3, nhop) + + # 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, + pktlen=128) + 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, + ip_ttl=63, + pktlen=128) + 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:22:22:22:22:22', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64, + pktlen=523+14) + 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, + ip_ttl=63, + pktlen=523+14) + cpu_pkt = simple_cpu_packet(ingress_port=swports[1], + ingress_ifindex=2, + reason_code=0x1c, + ingress_bd=0x02, + inner_pkt=exp_pkt) + send_packet(self, swports[1], str(pkt)) + verify_packets(self, cpu_pkt, [cpu_port]) + finally: + self.client.switcht_api_neighbor_entry_remove(device, neighbor) + self.client.switcht_api_l3_route_delete(device, vrf, i_ip3, nhop) + self.client.switcht_api_nhop_delete(device, nhop) + + 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('tunnel') class IPinIPTest(api_base_tests.ThriftInterfaceDataPlane): @@ -9062,29 +9376,29 @@ def setUp(self): '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, + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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, + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, 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', + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.100.1.1', prefix_length=32) - dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.200.1.3', + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.200.1.3', prefix_length=32) - encap_info = switcht_encap_info_t(encap_type=4) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GRE) 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, + iu3 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=self.if2) self.ift1 = self.client.switcht_api_tunnel_interface_create(device, 0, iu3) @@ -9095,7 +9409,7 @@ def setUp(self): 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) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) self.neigh1 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, @@ -9106,15 +9420,15 @@ def setUp(self): neighbor_entry) # Create an GRE IPv6 tunnel interface (encap_type = 4) - src_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::1', + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3ffe::1', prefix_length=128) - dst_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::2', + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3ffe::2', prefix_length=128) - encap_info = switcht_encap_info_t(encap_type=4) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_GRE) 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, + iu4 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=self.if2) self.ift2 = self.client.switcht_api_tunnel_interface_create(device, 0, iu4) @@ -9125,7 +9439,7 @@ def setUp(self): 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) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3, neigh_type=SWITCH_API_NEIGHBOR_IPV6_TUNNEL) self.neigh3 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, @@ -9136,15 +9450,15 @@ def setUp(self): neighbor_entry) # Create an IPv4 tunnel interface (encap_type = 8) - src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.100.1.1', + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.100.1.1', prefix_length=32) - dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.200.1.3', + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.200.1.3', prefix_length=32) - encap_info = switcht_encap_info_t(encap_type=8) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_IPIP) 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, + iu5 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=self.if2) self.ift3 = self.client.switcht_api_tunnel_interface_create(device, 0, iu5) @@ -9155,7 +9469,7 @@ def setUp(self): 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) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3, neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) self.neigh5 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, @@ -9166,15 +9480,15 @@ def setUp(self): neighbor_entry) # Create an IPv6 tunnel interface (encap_type = 8) - src_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::1', + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3ffe::1', prefix_length=128) - dst_ip = switcht_ip_addr_t(addr_type=1, ipaddr='3ffe::2', + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='3ffe::2', prefix_length=128) - encap_info = switcht_encap_info_t(encap_type=8) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_IPIP) 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, + iu6 = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=self.if2) self.ift4 = self.client.switcht_api_tunnel_interface_create(device, 0, iu6) @@ -9185,7 +9499,7 @@ def setUp(self): 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) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3, neigh_type=SWITCH_API_NEIGHBOR_IPV6_TUNNEL) self.neigh7 = self.client.switcht_api_neighbor_entry_add(device, neighbor_entry) neighbor_entry = switcht_neighbor_info_t(nhop_handle=0, @@ -9196,45 +9510,45 @@ def setUp(self): 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', + self.ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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', + self.ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, 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', + self.ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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', + self.ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, 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', + self.ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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', + self.ip6 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, 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', + self.ip7 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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', + self.ip8 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2ffe::4', prefix_length=128) self.client.switcht_api_l3_route_add(device, self.vrf, self.ip8, self.nhop4) @@ -9243,7 +9557,7 @@ def setUp(self): 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, + ln_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_BASIC, encap_info=encap, age_interval=1800, vrf=self.vrf, rmac_handle=self.rmac, flags=ln_flags) @@ -9260,17 +9574,17 @@ def setUp(self): 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) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3, neigh_type=SWITCH_API_NEIGHBOR_NONE) 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', + self.ip9 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, 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', + self.ip10 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V6, ipaddr='2000::1', prefix_length=128) self.client.switcht_api_l3_route_add(device, self.vrf, self.ip10, self.nhop5) @@ -9679,3 +9993,690 @@ def runTest(self): self.client.switcht_api_router_mac_group_delete(device, self.rmac) self.client.switcht_api_vrf_delete(device, self.vrf) + +############################################################################### +@group('cpu') +@group('maxsizes') +class CpuTxTest(api_base_tests.ThriftInterfaceDataPlane): + def setUp(self): + print + print 'Configuring devices for CPU Tx 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') + + # create l3 interface + iu = interface_union(port_lag_handle = swports[0]) + info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu, + 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, info) + self.ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.1.1', + prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, self.if1, + self.vrf, self.ip1) + + # create l3 vlan interface + self.vlan = self.client.switcht_api_vlan_create(device, 10) + + self.lag1 = self.client.switcht_api_lag_create(device) + self.client.switcht_api_lag_member_add(device, lag_handle=self.lag1, + side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_add(device, lag_handle=self.lag1, + side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + iu = interface_union(port_lag_handle=self.lag1) + info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu, + mac='00:77:66:55:44:33', label=0) + self.if2 = self.client.switcht_api_interface_create(device, info) + + self.lag2 = self.client.switcht_api_lag_create(device) + self.client.switcht_api_lag_member_add(device, lag_handle=self.lag2, + side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_add(device, lag_handle=self.lag2, + side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) + iu = interface_union(port_lag_handle=self.lag2) + info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu, + mac='00:77:66:55:44:33', label=0) + self.if3 = self.client.switcht_api_interface_create(device, info) + + self.vlan_port1 = switcht_vlan_port_t(handle=self.if2, tagging_mode=0) + self.vlan_port2 = switcht_vlan_port_t(handle=self.if3, tagging_mode=0) + self.client.switcht_api_vlan_ports_add(device, self.vlan, + self.vlan_port1) + self.client.switcht_api_vlan_ports_add(device, self.vlan, + self.vlan_port2) + + iu = interface_union(vlan_id=10) + info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu, + mac='00:77:66:55:44:33', + label=0, vrf_handle=self.vrf, + rmac_handle=self.rmac, + v4_unicast_enabled=1, + v6_unicast_enabled=1) + self.if4 = self.client.switcht_api_interface_create(device, info) + self.ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.2.1', + prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, self.if4, + self.vrf, self.ip2) + + self.client.switcht_api_mac_table_entry_create(device, self.vlan, + '00:11:11:11:11:11', 2, + self.if2) + self.client.switcht_api_mac_table_entry_create(device, self.vlan, + '00:22:22:22:22:22', 2, + self.if3) + + # add ipv4 static routes + self.ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', + prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=self.if4, 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.if4, + mac_addr='00:11:11:11:11:11', + ip_addr=self.ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + self.neighbor1 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + self.client.switcht_api_l3_route_add(device, self.vrf, self.ip3, + self.nhop1) + + def runTest(self): + pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:66:66:66:66:66', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64) + cpu_pkt = simple_cpu_packet(dst_device=0, + dst_port_or_group=swports[2], + ingress_ifindex=0, + ingress_port=0, + ingress_bd=0, + tx_bypass=True, + reason_code=0xFFFF, + inner_pkt=pkt) + print "Sending packet from cpu port %d" % swports[cpu_port] + send_packet(self, swports[cpu_port], str(cpu_pkt)) + verify_packets(self, pkt, [swports[2]]) + + pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:66:66:66:66:66', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64, + dl_vlan_enable=True, + vlan_vid=self.vlan & 0xFFF, + pktlen=100) + cpu_pkt = simple_cpu_packet(dst_device=0, + dst_port_or_group=0, + ingress_ifindex=0, + ingress_port=0, + ingress_bd=0, + tx_bypass=False, + reason_code=0, + inner_pkt=pkt) + exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:66:66:66:66:66', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64, + pktlen=96) + print "Sending packet from cpu port %d" % swports[cpu_port] + send_packet(self, swports[cpu_port], str(cpu_pkt)) + verify_packets_any(self, exp_pkt, [swports[1], swports[2]]) + + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:66:66:66:66:66', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64, + dl_vlan_enable=True, + vlan_vid=self.vlan & 0xFFF, + pktlen=100) + cpu_pkt = simple_cpu_packet(dst_device=0, + dst_port_or_group=0, + ingress_ifindex=0, + ingress_port=0, + ingress_bd=0, + tx_bypass=False, + reason_code=0x0020, + inner_pkt=pkt) + exp_pkt = simple_tcp_packet(eth_src='00:77:66:55:44:33', + eth_dst='00:11:11:11:11:11', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=63, + pktlen=96) + print "Sending packet from cpu port %d" % swports[cpu_port] + send_packet(self, swports[cpu_port], str(cpu_pkt)) + verify_packets_any(self, exp_pkt, [swports[1], swports[2]]) + + def tearDown(self): + self.client.switcht_api_neighbor_entry_remove(device, self.neighbor1) + self.client.switcht_api_l3_route_delete(device, self.vrf, self.ip3, + self.nhop1) + self.client.switcht_api_nhop_delete(device, self.nhop1) + + self.client.switcht_api_mac_table_entries_delete_all(device) + + self.client.switcht_api_l3_interface_address_delete(device, self.if1, + self.vrf, + self.ip1) + self.client.switcht_api_l3_interface_address_delete(device, self.if4, + self.vrf, + self.ip2) + + self.client.switcht_api_vlan_ports_remove(device, self.vlan, + self.vlan_port1) + self.client.switcht_api_vlan_ports_remove(device, self.vlan, + self.vlan_port2) + + self.client.switcht_api_lag_member_delete(device, lag_handle=self.lag1, + side=SWITCH_API_DIRECTION_BOTH, port=swports[1]) + self.client.switcht_api_lag_member_delete(device, lag_handle=self.lag1, + side=SWITCH_API_DIRECTION_BOTH, port=swports[2]) + self.client.switcht_api_lag_member_delete(device, lag_handle=self.lag2, + side=SWITCH_API_DIRECTION_BOTH, port=swports[3]) + self.client.switcht_api_lag_member_delete(device, lag_handle=self.lag2, + side=SWITCH_API_DIRECTION_BOTH, port=swports[4]) + + self.client.switcht_api_interface_delete(device, self.if1) + self.client.switcht_api_interface_delete(device, self.if2) + self.client.switcht_api_interface_delete(device, self.if3) + self.client.switcht_api_interface_delete(device, self.if4) + + self.client.switcht_api_lag_delete(device, self.lag1) + self.client.switcht_api_lag_delete(device, self.lag2) + + self.client.switcht_api_vlan_delete(device, self.vlan) + 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) + + api_base_tests.ThriftInterfaceDataPlane.tearDown(self) + + + +############################################################################### +@group('nat') +class NatTest(api_base_tests.ThriftInterfaceDataPlane): + def setUp(self): + print + print 'Configuring devices for NAT 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') + + # create l3 inside interface + iu = interface_union(port_lag_handle = swports[1]) + info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu, + mac='00:77:66:55:44:33', label=0, + vrf_handle=self.vrf, + rmac_handle=self.rmac, + nat_mode=SWITCH_NAT_MODE_INNER) + self.if1 = self.client.switcht_api_interface_create(device, info) + self.ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.1.1', + prefix_length=24) + self.client.switcht_api_l3_interface_address_add(device, self.if1, + self.vrf, self.ip1) + + # create l3 outside interface + iu = interface_union(port_lag_handle = swports[2]) + info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu, + mac='00:77:66:55:44:33', label=0, + vrf_handle=self.vrf, + rmac_handle=self.rmac, + nat_mode=SWITCH_NAT_MODE_OUTER) + self.if2 = self.client.switcht_api_interface_create(device, info) + self.ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.2.1', + prefix_length=24) + self.client.switcht_api_l3_interface_address_add(device, self.if2, + self.vrf, self.ip2) + + # add ipv4 static route + self.ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.10.10.1', + prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=self.if2, 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.if2, + mac_addr='00:22:22:22:22:22', + ip_addr=self.ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + self.neighbor1 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + self.client.switcht_api_l3_route_add(device, self.vrf, self.ip3, + self.nhop1) + + # create nexthop for dst NAT + nhop_key = switcht_nhop_key_t(intf_handle=self.if1, 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.if1, + mac_addr='00:11:11:11:11:11', + ip_addr=self.ip3, rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + self.neighbor2 = self.client.switcht_api_neighbor_entry_add(device, + neighbor_entry) + + # create NAT ACL (permit all) + self.acl = self.client.switcht_api_acl_list_create(device, 0) + kvp = [] + acl_priority = 10 + action = 2 + action_params = switcht_acl_action_params_t() + opt_action_params = switcht_acl_opt_action_params_t() + self.ace = self.client.switcht_api_acl_ip_rule_create( + device, self.acl, acl_priority, len(kvp), kvp, action, + action_params, opt_action_params) + self.client.switcht_api_acl_reference(device, self.acl, self.if1) + self.client.switcht_api_acl_reference(device, self.acl, self.if2) + + # create NAT bindings + self.nat = [] + nat_bindings = [ + [self.vrf, 0, 0, + '192.168.0.1', 0x0, '0.0.0.0', 0x0, 6, + '172.16.55.56', 0x0, '0.0.0.0', 0x0], + [self.vrf, self.nhop2, 1, + '0.0.0.0', 0x0, '172.16.55.56', 0x0, 6, + '0.0.0.0', 0x0, '192.168.0.1', 0x0], + [self.vrf, self.nhop1, 2, + '192.168.0.2', 0x0, '10.10.10.2', 0x0, 6, + '172.16.55.57', 0x0, '10.100.1.2', 0x0], + [self.vrf, 0, 6, + '192.168.0.1', 0x1289, '0.0.0.0', 0x0, 6, + '172.16.55.55', 0x3456, '0.0.0.0', 0x0], + [self.vrf, self.nhop2, 7, + '0.0.0.0', 0x0, '172.16.55.55', 0x3456, 6, + '0.0.0.0', 0x0, '192.168.0.1', 0x1289], + [self.vrf, self.nhop1, 8, + '192.168.0.2', 0x789a, '10.10.10.2', 0xabcd, 6, + '172.16.55.58', 0x5678, '10.100.1.3', 0x3489], + ] + for b in nat_bindings: + vrf_h = b[0] + nhop_h = b[1] + nat_type = b[2] + sip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr=b[3], + prefix_length=32) + sport = b[4] + dip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr=b[5], + prefix_length=0) + dport = b[6] + proto = b[7] + rw_sip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr=b[8], + prefix_length=32) + rw_sport = b[9] + rw_dip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr=b[10], + prefix_length=0) + rw_dport = b[11] + nb = switcht_nat_info_t(nat_rw_type=nat_type, + src_ip=sip, dst_ip=dip, src_port=sport, + dst_port=dport, protocol=proto, + rw_src_ip=rw_sip, rw_dst_ip=rw_dip, + rw_src_port=rw_sport,rw_dst_port=rw_dport, + vrf_handle=vrf_h, nhop_handle=nhop_h) + self.client.switcht_api_nat_create(device, nb) + self.nat.append(nb) + + def runTest(self): + skip_checksum_validation = False + + + print "Verifying Source NAT (ip and port)" + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:11:11:11:11:11', + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_id=105, + ip_ttl=64, + tcp_sport=0x1289) + exp_pkt = simple_tcp_packet(eth_dst='00:22:22:22:22:22', + eth_src='00:77:66:55:44:33', + ip_dst='10.10.10.1', + ip_src='172.16.55.55', + ip_id=105, + ip_ttl=63, + tcp_sport=0x3456) + send_packet(self, swports[3], str(exp_pkt)) + return + + send_packet(self, swports[1], str(pkt)) + if (skip_checksum_validation): + exp_pkt = ptf.mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(TCP, 'chksum') + verify_packets(self, exp_pkt, [swports[2]]) + + print "Verifying Source NAT (ip)" + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:11:11:11:11:11', + 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:22:22:22:22:22', + eth_src='00:77:66:55:44:33', + ip_dst='10.10.10.1', + ip_src='172.16.55.56', + ip_id=105, + ip_ttl=63) + send_packet(self, swports[1], str(pkt)) + if (skip_checksum_validation): + exp_pkt = ptf.mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(TCP, 'chksum') + verify_packets(self, exp_pkt, [swports[2]]) + + print "Verifying Destination NAT (ip and port)" + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:22:22:22:22:22', + ip_dst='172.16.55.55', + ip_src='10.10.10.1', + ip_id=105, + ip_ttl=64, + tcp_dport=0x3456) + exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:77:66:55:44:33', + ip_dst='192.168.0.1', + ip_src='10.10.10.1', + ip_id=105, + ip_ttl=63, + tcp_dport=0x1289) + send_packet(self, swports[2], str(pkt)) + if (skip_checksum_validation): + exp_pkt = ptf.mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(TCP, 'chksum') + verify_packets(self, exp_pkt, [swports[1]]) + + print "Verifying Destination NAT (ip)" + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:22:22:22:22:22', + ip_dst='172.16.55.56', + ip_src='10.10.10.1', + ip_id=105, + ip_ttl=64) + exp_pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', + eth_src='00:77:66:55:44:33', + ip_dst='192.168.0.1', + ip_src='10.10.10.1', + ip_id=105, + ip_ttl=63) + send_packet(self, swports[2], str(pkt)) + if (skip_checksum_validation): + exp_pkt = ptf.mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(TCP, 'chksum') + verify_packets(self, exp_pkt, [swports[1]]) + + print "Verifying Twice NAT (ip and port)" + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:11:11:11:11:11', + ip_dst='10.10.10.2', + ip_src='192.168.0.2', + ip_id=105, + ip_ttl=64, + tcp_sport=0x789a, + tcp_dport=0xabcd) + exp_pkt = simple_tcp_packet(eth_dst='00:22:22:22:22:22', + eth_src='00:77:66:55:44:33', + ip_dst='10.100.1.3', + ip_src='172.16.55.58', + ip_id=105, + ip_ttl=63, + tcp_sport=0x5678, + tcp_dport=0x3489) + send_packet(self, swports[1], str(pkt)) + if (skip_checksum_validation): + exp_pkt = ptf.mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(TCP, 'chksum') + verify_packets(self, exp_pkt, [swports[2]]) + + print "Verifying Twice NAT (ip)" + pkt = simple_tcp_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:11:11:11:11:11', + ip_dst='10.10.10.2', + ip_src='192.168.0.2', + ip_id=105, + ip_ttl=64) + exp_pkt = simple_tcp_packet(eth_dst='00:22:22:22:22:22', + eth_src='00:77:66:55:44:33', + ip_dst='10.100.1.2', + ip_src='172.16.55.57', + ip_id=105, + ip_ttl=63) + send_packet(self, swports[1], str(pkt)) + if (skip_checksum_validation): + exp_pkt = ptf.mask.Mask(exp_pkt) + exp_pkt.set_do_not_care_scapy(TCP, 'chksum') + verify_packets(self, exp_pkt, [swports[2]]) + + def tearDown(self): + self.client.switcht_api_l3_route_delete(device, self.vrf, self.ip3, + self.nhop1) + self.client.switcht_api_neighbor_entry_remove(device, self.neighbor1) + self.client.switcht_api_neighbor_entry_remove(device, self.neighbor2) + self.client.switcht_api_nhop_delete(device, self.nhop1) + self.client.switcht_api_nhop_delete(device, self.nhop2) + + for n in self.nat: + self.client.switcht_api_nat_delete(device, n) + + self.client.switcht_api_mac_table_entries_delete_all(device) + + self.client.switcht_api_l3_interface_address_delete(device, self.if1, + self.vrf, + self.ip1) + self.client.switcht_api_l3_interface_address_delete(device, self.if2, + self.vrf, + self.ip2) + + self.client.switcht_api_acl_remove(device, self.acl, self.if1) + self.client.switcht_api_acl_remove(device, self.acl, self.if2) + self.client.switcht_api_acl_rule_delete(device, self.acl, self.ace) + self.client.switcht_api_acl_list_delete(device, self.acl) + + 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) + api_base_tests.ThriftInterfaceDataPlane.tearDown(self) + +############################################################################### +class HostIfTest(api_base_tests.ThriftInterfaceDataPlane): + def runTest(self): + print + 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=SWITCH_API_INTERFACE_L3, 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=SWITCH_API_IP_ADDR_V4, ipaddr='192.168.0.2', + prefix_length=16) + self.client.switcht_api_l3_interface_address_add(device, if1, vrf, i_ip1) + + hostif_group1 = switcht_hostif_group_t(queue_id=1, priority=1000) + hostif_group_id1 = self.client.switcht_api_hostif_group_create(device, hostif_group1) + + hostif_group2 = switcht_hostif_group_t(queue_id=2, priority=2000) + hostif_group_id2 = self.client.switcht_api_hostif_group_create(device, hostif_group2) + + try: + print 'Installing hostif reason codes Arp Request/Resp, OSPF, PIM, IGMP and STP' + arp_req_rcode_info = switcht_api_hostif_rcode_info_t( + reason_code = SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST, + action=SWITCH_ACL_ACTION_COPY_TO_CPU, + hostif_group_id=hostif_group_id1) + self.client.switcht_api_hostif_reason_code_create(device, arp_req_rcode_info) + + arp_resp_rcode_info = switcht_api_hostif_rcode_info_t( + reason_code = SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE, + action=SWITCH_ACL_ACTION_REDIRECT_TO_CPU, + hostif_group_id=hostif_group_id1) + self.client.switcht_api_hostif_reason_code_create(device, arp_resp_rcode_info) + + ospf_rcode_info = switcht_api_hostif_rcode_info_t( + reason_code = SWITCH_HOSTIF_REASON_CODE_OSPF, + action=SWITCH_ACL_ACTION_COPY_TO_CPU, + hostif_group_id=hostif_group_id2) + self.client.switcht_api_hostif_reason_code_create(device, ospf_rcode_info) + + igmp_v2_rcode_info = switcht_api_hostif_rcode_info_t( + reason_code = SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT, + action=SWITCH_ACL_ACTION_COPY_TO_CPU, + hostif_group_id=hostif_group_id2) + self.client.switcht_api_hostif_reason_code_create(device, igmp_v2_rcode_info) + + pim_rcode_info = switcht_api_hostif_rcode_info_t( + reason_code = SWITCH_HOSTIF_REASON_CODE_PIM, + action=SWITCH_ACL_ACTION_COPY_TO_CPU, + hostif_group_id=hostif_group_id2) + self.client.switcht_api_hostif_reason_code_create(device, pim_rcode_info) + + stp_rcode_info = switcht_api_hostif_rcode_info_t( + reason_code = SWITCH_HOSTIF_REASON_CODE_STP, + action=SWITCH_ACL_ACTION_REDIRECT_TO_CPU, + hostif_group_id=hostif_group_id2) + self.client.switcht_api_hostif_reason_code_create(device, stp_rcode_info) + + pkt = simple_arp_packet(arp_op=1, pktlen=100) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending ARP request broadcast' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_arp_packet(arp_op=2, eth_dst='00:77:66:55:44:33', pktlen=100) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending ARP response' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.5') + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_OSPF, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending OSPF packet destined to 224.0.0.5' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.6') + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_OSPF, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending OSPF packet destined to 224.0.0.6' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=2) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending IGMP v2 report' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=103) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_PIM, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending PIM packet' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_eth_packet(eth_dst='01:80:C2:00:00:00', pktlen=100) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=SWITCH_HOSTIF_REASON_CODE_STP, + ingress_bd=2, + inner_pkt = pkt) + print 'Sending STP packet' + send_packet(self, swports[1], str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + print 'Deleting hostif reason codes Arp Request/Resp, OSPF, PIM, IGMP and STP' + self.client.switcht_api_hostif_reason_code_delete(device, SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST) + self.client.switcht_api_hostif_reason_code_delete(device, SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE) + self.client.switcht_api_hostif_reason_code_delete(device, SWITCH_HOSTIF_REASON_CODE_OSPF) + self.client.switcht_api_hostif_reason_code_delete(device, SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT) + self.client.switcht_api_hostif_reason_code_delete(device, SWITCH_HOSTIF_REASON_CODE_PIM) + self.client.switcht_api_hostif_reason_code_delete(device, SWITCH_HOSTIF_REASON_CODE_STP) + + print 'Sending ARP request broadcast' + pkt = simple_arp_packet(arp_op=1, pktlen=100) + send_packet(self, swports[1], str(pkt)) + + print 'Sending OSPF packet destined to 224.0.0.5' + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.5') + send_packet(self, swports[1], str(pkt)) + + print 'Sending OSPF packet destined to 224.0.0.6' + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.6') + send_packet(self, swports[1], str(pkt)) + + print 'Sending IGMP v2 report' + pkt = simple_ip_packet(ip_proto=2) + send_packet(self, swports[1], str(pkt)) + + print 'Sending PIM packet' + pkt = simple_ip_packet(ip_proto=103) + send_packet(self, swports[1], str(pkt)) + + print 'Sending STP packet' + pkt = simple_eth_packet(eth_dst='01:80:C2:00:00:00', pktlen=100) + send_packet(self, swports[1], str(pkt)) + + verify_no_other_packets(self, timeout=1) + + finally: + + self.client.switcht_api_hostif_group_delete(device, hostif_group_id1) + self.client.switcht_api_hostif_group_delete(device, hostif_group_id2) + + self.client.switcht_api_l3_interface_address_delete(device, if1, vrf, i_ip1) + + self.client.switcht_api_interface_delete(device, if1) + self.client.switcht_api_router_mac_delete(device, rmac, '00:77:66:55:44:33') + self.client.switcht_api_vrf_delete(device, vrf) diff --git a/tests/ptf-tests/api-tests/switch_acl.py b/tests/ptf-tests/api-tests/switch_acl.py index 953c80b..2323543 100644 --- a/tests/ptf-tests/api-tests/switch_acl.py +++ b/tests/ptf-tests/api-tests/switch_acl.py @@ -33,6 +33,7 @@ import os from switch_api_thrift.ttypes import * +from switch_api_thrift.switch_api_headers import * from erspan3 import * @@ -54,13 +55,13 @@ def runTest(self): self.client.switcht_api_router_mac_add(0, 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if1 = self.client.switcht_api_interface_create(0, i_info1) i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if2 = self.client.switcht_api_interface_create(0, i_info2) i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) @@ -73,7 +74,7 @@ def runTest(self): interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) @@ -104,7 +105,7 @@ def runTest(self): kvp = [] kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) kvp_mask = switcht_acl_value_t(value_num=int("ffffffff", 16)) - kvp.append(switcht_acl_key_value_pair_t(1, kvp_val, kvp_mask)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val, kvp_mask)) action = 1 action_params = switcht_acl_action_params_t(redirect = switcht_acl_action_redirect(handle = 0)) opt_action_params = switcht_acl_opt_action_params_t() @@ -156,13 +157,13 @@ def runTest(self): self.client.switcht_api_router_mac_add(0, 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if1 = self.client.switcht_api_interface_create(0, i_info1) i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if2 = self.client.switcht_api_interface_create(0, i_info2) i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) @@ -175,7 +176,7 @@ def runTest(self): interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) @@ -214,7 +215,7 @@ def runTest(self): kvp = [] kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) kvp_mask = switcht_acl_value_t(value_num=int("ffffffff", 16)) - kvp.append(switcht_acl_key_value_pair_t(1, kvp_val, kvp_mask)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val, kvp_mask)) action = 9 action_params = switcht_acl_action_params_t() opt_action_params = switcht_acl_opt_action_params_t(mirror_handle=mirror1) @@ -303,13 +304,13 @@ def runTest(self): self.client.switcht_api_router_mac_add(0, 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if1 = self.client.switcht_api_interface_create(0, i_info1) i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if2 = self.client.switcht_api_interface_create(0, i_info2) i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) @@ -322,7 +323,7 @@ def runTest(self): interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) @@ -357,11 +358,11 @@ def runTest(self): kvp = [] 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_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_SRC, kvp_val, kvp_mask)) #kvp.append(switcht_acl_egr_key_value_pair_t(field=0, value=2, mask=-1)) kvp_val = switcht_acl_value_t(value_num=0) kvp_mask = switcht_acl_value_t(value_num=0xff) - kvp.append(switcht_acl_key_value_pair_t(1, kvp_val, kvp_mask)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val, kvp_mask)) #kvp.append(switcht_acl_egr_key_value_pair_t(field=1, value=0, mask=-1)) action = 1 action_params = switcht_acl_action_params_t() @@ -427,13 +428,13 @@ def runTest(self): self.client.switcht_api_router_mac_add(0, 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if1 = self.client.switcht_api_interface_create(0, i_info1) i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if2 = self.client.switcht_api_interface_create(0, i_info2) i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) @@ -446,7 +447,7 @@ def runTest(self): interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) @@ -468,14 +469,14 @@ def runTest(self): ip_ttl=63) iu4 = interface_union(port_lag_handle = 4) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, mac='00:44:44:44:44:44', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:44:44:44:44:44', label=0, vrf_handle=vrf, rmac_handle=rmac) if4 = self.client.switcht_api_interface_create(0, i_info4) i_ip4 = switcht_ip_addr_t(ipaddr='10.0.0.4', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if4, vrf, i_ip4) # Create an ERSPAN tunnel interface - src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='4.4.4.1', prefix_length=32) - dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='4.4.4.3', prefix_length=32) + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='4.4.4.1', prefix_length=32) + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='4.4.4.3', prefix_length=32) encap_info = switcht_encap_info_t(encap_type=7) ip_encap = switcht_ip_encap_t(vrf=vrf, src_ip=src_ip, dst_ip=dst_ip, ttl=60, proto=47) tunnel_encap = switcht_tunnel_encap_t(ip_encap=ip_encap) @@ -497,7 +498,8 @@ def runTest(self): interface_handle=ift, mac_addr='00:44:44:44:44:44', ip_addr=src_ip, - rw_type=0, neigh_type=7) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L2, + neigh_type=SWITCH_API_NEIGHBOR_IPV4_TUNNEL) neighbor1 = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry1) neighbor_entry2 = switcht_neighbor_info_t(nhop_handle=0, @@ -507,9 +509,10 @@ def runTest(self): neighbor2 = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry2) # create a mirror session - minfo1 = switcht_mirror_info_t(session_id=85, direction=1, - egress_port=swports[4], mirror_type=3, - session_type=0, + minfo1 = switcht_mirror_info_t(session_id=85, direction=SWITCH_API_DIRECTION_INGRESS, + egress_port=swports[4], + mirror_type=SWITCH_MIRROR_TYPE_ENHANCED_REMOTE, + session_type=SWITCH_MIRROR_SESSION_TYPE_SIMPLE, cos=0, max_pkt_len=0, ttl=0, enable=1, nhop_handle=nhop1) mirror1 = self.client.switcht_api_mirror_session_create(0, minfo1) @@ -520,7 +523,7 @@ def runTest(self): kvp = [] kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) kvp_mask = switcht_acl_value_t(value_num=int("ffffffff", 16)) - kvp.append(switcht_acl_key_value_pair_t(1, kvp_val, kvp_mask)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val, kvp_mask)) action = 9 action_params = switcht_acl_action_params_t() opt_action_params = switcht_acl_opt_action_params_t(mirror_handle=mirror1) @@ -583,7 +586,6 @@ def runTest(self): self.client.switcht_api_router_mac_group_delete(0, rmac) self.client.switcht_api_vrf_delete(0, vrf) - ############################################################################### @group('acl') class IPAclStatsTest(api_base_tests.ThriftInterfaceDataPlane): @@ -597,13 +599,13 @@ def runTest(self): self.client.switcht_api_router_mac_add(0, 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) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if1 = self.client.switcht_api_interface_create(0, i_info1) i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) iu2 = interface_union(port_lag_handle = swports[2]) - i_info2 = switcht_interface_info_t(device=0, type=4, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) if2 = self.client.switcht_api_interface_create(0, i_info2) i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) @@ -616,7 +618,7 @@ def runTest(self): interface_handle=if2, mac_addr='00:11:22:33:44:55', ip_addr=i_ip3, - rw_type=1) + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) @@ -626,7 +628,7 @@ def runTest(self): kvp = [] kvp_val1 = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) kvp_mask1 = switcht_acl_value_t(value_num=int("ffffffff", 16)) - kvp.append(switcht_acl_key_value_pair_t(1, kvp_val1, kvp_mask1)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val1, kvp_mask1)) action = 2 action_params = switcht_acl_action_params_t(redirect = switcht_acl_action_redirect(handle = 0)) opt_action_params = switcht_acl_opt_action_params_t(counter_handle = counter) @@ -636,7 +638,7 @@ def runTest(self): kvp = [] kvp_val2 = switcht_acl_value_t(value_num=int("0a0a0a02", 16)) kvp_mask2 = switcht_acl_value_t(value_num=int("ffffffff", 16)) - kvp.append(switcht_acl_key_value_pair_t(1, kvp_val2, kvp_mask2)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val2, kvp_mask2)) action = 1 action_params = switcht_acl_action_params_t(redirect = switcht_acl_action_redirect(handle = 0)) opt_action_params = switcht_acl_opt_action_params_t(counter_handle = counter) @@ -697,7 +699,7 @@ def runTest(self): num_bytes += pktlen num_packets += 1 - verify_no_other_packets(self, timeout=10) + verify_no_other_packets(self, timeout=30) stats = self.client.switcht_api_acl_stats_get(0, counter) print stats self.assertEqual(stats.num_packets, num_packets) diff --git a/tests/ptf-tests/api-tests/switch_mcast.py b/tests/ptf-tests/api-tests/switch_mcast.py index 362ef4b..2f2f014 100644 --- a/tests/ptf-tests/api-tests/switch_mcast.py +++ b/tests/ptf-tests/api-tests/switch_mcast.py @@ -18,6 +18,7 @@ from ptf.thriftutils import * from switch_api_thrift.ttypes import * +from switch_api_thrift.switch_api_headers import * this_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.join(this_dir, '..')) @@ -57,7 +58,7 @@ def setUp(self): # port 0: access port in vlan 10 iu1 = interface_union(port_lag_handle=swports[0]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) self.if1 = self.client.switcht_api_interface_create(device, i_info1) self.pv1 = switcht_vlan_port_t(handle=self.if1, tagging_mode=0) @@ -65,7 +66,7 @@ def setUp(self): # port 1: trunk port; allowed vlans: 10, 100, 200 iu2 = interface_union(port_lag_handle=swports[1]) - i_info2 = switcht_interface_info_t(device=0, type=3, u=iu2, + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu2, mac='00:77:66:55:44:33', label=0) self.if2 = self.client.switcht_api_interface_create(device, i_info2) self.pv2 = switcht_vlan_port_t(handle=self.if2, tagging_mode=0) @@ -75,7 +76,7 @@ def setUp(self): # port 2: access port in vlan 100 iu3 = interface_union(port_lag_handle=swports[2]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) self.if3 = self.client.switcht_api_interface_create(device, i_info3) self.pv3 = switcht_vlan_port_t(handle=self.if3, tagging_mode=0) @@ -83,35 +84,35 @@ def setUp(self): # port 3: routed port iu4 = interface_union(port_lag_handle = swports[3]) - i_info4 = switcht_interface_info_t(device=0, type=4, u=iu4, + i_info4 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu4, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, v4_multicast_enabled=1, v6_multicast_enabled=1) self.if4 = self.client.switcht_api_interface_create(device, i_info4) - self.ip4 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.250.1', + self.ip4 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.250.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if4, self.vrf, self.ip4) # port 4: routed port iu5 = interface_union(port_lag_handle = swports[4]) - i_info5 = switcht_interface_info_t(device=0, type=4, u=iu5, + i_info5 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu5, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, v4_multicast_enabled=1, v6_multicast_enabled=1) self.if5 = self.client.switcht_api_interface_create(device, i_info5) - self.ip5 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.251.1', + self.ip5 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.251.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if5, self.vrf, self.ip5) # port 5: trunk port; allowed vlans: 10, 100, 200 iu6 = interface_union(port_lag_handle=swports[5]) - i_info6 = switcht_interface_info_t(device=0, type=3, u=iu6, + i_info6 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu6, mac='00:77:66:55:44:33', label=0) self.if6 = self.client.switcht_api_interface_create(device, i_info6) self.pv6 = switcht_vlan_port_t(handle=self.if6, tagging_mode=0) @@ -121,7 +122,7 @@ def setUp(self): # port 6: trunk port; allowed vlans: 10, 100, 200 iu7 = interface_union(port_lag_handle=swports[6]) - i_info7 = switcht_interface_info_t(device=0, type=3, u=iu7, + i_info7 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu7, mac='00:77:66:55:44:33', label=0) self.if7 = self.client.switcht_api_interface_create(device, i_info7) self.pv7 = switcht_vlan_port_t(handle=self.if7, tagging_mode=0) @@ -131,7 +132,7 @@ def setUp(self): # port 7: trunk port; allowed vlans: 10, 100, 200 iu8 = interface_union(port_lag_handle=swports[7]) - i_info8 = switcht_interface_info_t(device=0, type=3, u=iu8, + i_info8 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu8, mac='00:77:66:55:44:33', label=0) self.if8 = self.client.switcht_api_interface_create(device, i_info8) self.pv8 = switcht_vlan_port_t(handle=self.if8, tagging_mode=0) @@ -141,7 +142,7 @@ def setUp(self): # Create L3 virtual interface for vlan 10 iu = interface_union(vlan_id=10) - i_info = switcht_interface_info_t(device=0, type=5, u=iu, + i_info = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3_VLAN, u=iu, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, @@ -150,14 +151,16 @@ def setUp(self): v4_multicast_enabled=1, v6_multicast_enabled=1) self.if20 = self.client.switcht_api_interface_create(device, i_info) - self.ip20 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.10.1', + self.ip20 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.10.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if20, self.vrf, self.ip20) # Create L3 virtual interface for vlan 100 iu = interface_union(vlan_id=100) - i_info = switcht_interface_info_t(device=0, type=5, u=iu, + i_info = switcht_interface_info_t(device=0, + type=SWITCH_API_INTERFACE_L3_VLAN, + u=iu, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, @@ -166,14 +169,16 @@ def setUp(self): v4_multicast_enabled=1, v6_multicast_enabled=1) self.if21 = self.client.switcht_api_interface_create(device, i_info) - self.ip21 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.100.1', + self.ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.100.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if21, self.vrf, self.ip21) # Create L3 virtual interface for vlan 200 iu = interface_union(vlan_id=200) - i_info = switcht_interface_info_t(device=0, type=5, u=iu, + i_info = switcht_interface_info_t(device=0, + type=SWITCH_API_INTERFACE_L3_VLAN, + u=iu, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, @@ -182,7 +187,7 @@ def setUp(self): v4_multicast_enabled=1, v6_multicast_enabled=1) self.if22 = self.client.switcht_api_interface_create(device, i_info) - self.ip22 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.200.1', + self.ip22 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.200.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if22, self.vrf, self.ip22) @@ -190,7 +195,8 @@ def setUp(self): # logical network ln_flags = switcht_ln_flags(ipv4_unicast_enabled=1, ipv4_multicast_enabled=1) - ln_info = switcht_logical_network_t(type=5, age_interval=1800, + ln_info = switcht_logical_network_t(type=SWITCH_LOGICAL_NETWORK_TYPE_ENCAP_ENHANCED, + age_interval=1800, vrf=self.vrf, rmac_handle=self.rmac, flags=ln_flags) @@ -199,19 +205,20 @@ def setUp(self): # tunnel interface udp = switcht_udp_t(src_port=0, dst_port=4789) - src_ip = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.10.1', + src_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.10.1', prefix_length=32) - dst_ip = switcht_ip_addr_t(addr_type=0, ipaddr='235.0.2.2', + dst_ip = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='235.0.2.2', prefix_length=32) vxlan = switcht_vxlan_id_t(vnid=0x5768) bt = switcht_bridge_type(vxlan_info=vxlan) - encap_info = switcht_encap_info_t(encap_type=3, u=bt) + encap_info = switcht_encap_info_t(encap_type=SWITCH_API_ENCAP_TYPE_VXLAN, u=bt) udp_tcp = switcht_udp_tcp_t(udp=udp) ip_encap = switcht_ip_encap_t(vrf=self.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) - iu = switcht_tunnel_info_t(encap_mode=0, tunnel_encap=tunnel_encap, + iu = switcht_tunnel_info_t(encap_mode=SWITCH_API_TUNNEL_ENCAP_MODE_IP, + tunnel_encap=tunnel_encap, encap_info=encap_info, out_if=self.if5) self.tif1 = self.client.switcht_api_tunnel_interface_create(device, 0, iu) @@ -268,9 +275,9 @@ def setUp(self): self.route_ports) # create a ip multicast route (10.0.10.5,230.1.1.5) - self.msrc_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.10.5', + self.msrc_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.10.5', prefix_length=32) - self.mgrp_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='230.1.1.5', + self.mgrp_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='230.1.1.5', prefix_length=32) rpflist = [ self.vlan1 ] self.client.switcht_api_multicast_mroute_add(device, self.mch1, @@ -280,9 +287,9 @@ def setUp(self): rpflist, len(rpflist)) # create (outer) ip multicast route (*,235.0.2.2) - self.msrc_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='0.0.0.0', + self.msrc_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='0.0.0.0', prefix_length=0) - self.mgrp_ip2 = switcht_ip_addr_t(addr_type=0, ipaddr='235.0.2.2', + self.mgrp_ip2 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='235.0.2.2', prefix_length=32) rpflist = [ self.if5 ] self.client.switcht_api_multicast_mroute_add(device, 0, @@ -292,9 +299,9 @@ def setUp(self): rpflist, len(rpflist)) # create (inner) ip multicast route (*,230.1.1.6) - self.msrc_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='0.0.0.0', + self.msrc_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='0.0.0.0', prefix_length=0) - self.mgrp_ip3 = switcht_ip_addr_t(addr_type=0, ipaddr='230.1.1.6', + self.mgrp_ip3 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='230.1.1.6', prefix_length=32) rpflist = [ self.ln1 ] self.client.switcht_api_multicast_mroute_add(device, self.mch1, @@ -451,7 +458,7 @@ def runTest(self): p2 = [swports[2], [pkt1]] p5 = [swports[5], [pkt]] p7 = [swports[7], [pkt]] - p64 = [swports[64], [cpu_pkt]] + p64 = [swports[cpu_port], [cpu_pkt]] verify_multiple_packets_on_ports(self, [p1, p2, p5, p7, p64]) print "IPv4 multicast (tunneled packet)" @@ -638,7 +645,7 @@ def setUp(self): # port 0: access port in vlan 10 iu1 = interface_union(port_lag_handle=swports[0]) - i_info1 = switcht_interface_info_t(device=0, type=2, u=iu1, + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu1, mac='00:77:66:55:44:33', label=0) self.if1 = self.client.switcht_api_interface_create(device, i_info1) self.pv1 = switcht_vlan_port_t(handle=self.if1, tagging_mode=0) @@ -646,7 +653,7 @@ def setUp(self): # port 1: trunk port; allowed vlans: 10, 100, 200 iu2 = interface_union(port_lag_handle=swports[1]) - i_info2 = switcht_interface_info_t(device=0, type=3, u=iu2, + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu2, mac='00:77:66:55:44:33', label=0) self.if2 = self.client.switcht_api_interface_create(device, i_info2) self.pv2 = switcht_vlan_port_t(handle=self.if2, tagging_mode=0) @@ -656,7 +663,7 @@ def setUp(self): # port 2: access port in vlan 100 iu3 = interface_union(port_lag_handle=swports[2]) - i_info3 = switcht_interface_info_t(device=0, type=2, u=iu3, + i_info3 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_ACCESS, u=iu3, mac='00:77:66:55:44:33', label=0) self.if3 = self.client.switcht_api_interface_create(device, i_info3) self.pv3 = switcht_vlan_port_t(handle=self.if3, tagging_mode=0) @@ -664,7 +671,7 @@ def setUp(self): # port 5: trunk port; allowed vlans: 10, 100, 200 iu6 = interface_union(port_lag_handle=swports[5]) - i_info6 = switcht_interface_info_t(device=0, type=3, u=iu6, + i_info6 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu6, mac='00:77:66:55:44:33', label=0) self.if6 = self.client.switcht_api_interface_create(device, i_info6) self.pv6 = switcht_vlan_port_t(handle=self.if6, tagging_mode=0) @@ -674,7 +681,7 @@ def setUp(self): # port 6: trunk port; allowed vlans: 10, 100, 200 iu7 = interface_union(port_lag_handle=swports[6]) - i_info7 = switcht_interface_info_t(device=0, type=3, u=iu7, + i_info7 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu7, mac='00:77:66:55:44:33', label=0) self.if7 = self.client.switcht_api_interface_create(device, i_info7) self.pv7 = switcht_vlan_port_t(handle=self.if7, tagging_mode=0) @@ -684,7 +691,7 @@ def setUp(self): # port 7: trunk port; allowed vlans: 10, 100, 200 iu8 = interface_union(port_lag_handle=swports[7]) - i_info8 = switcht_interface_info_t(device=0, type=3, u=iu8, + i_info8 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L2_VLAN_TRUNK, u=iu8, mac='00:77:66:55:44:33', label=0) self.if8 = self.client.switcht_api_interface_create(device, i_info8) self.pv8 = switcht_vlan_port_t(handle=self.if8, tagging_mode=0) @@ -694,7 +701,9 @@ def setUp(self): # Create L3 virtual interface for vlan 10 iu = interface_union(vlan_id=10) - i_info = switcht_interface_info_t(device=0, type=5, u=iu, + i_info = switcht_interface_info_t(device=0, + type=SWITCH_API_INTERFACE_L3_VLAN, + u=iu, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, @@ -703,14 +712,16 @@ def setUp(self): v4_multicast_enabled=1, v6_multicast_enabled=1) self.if20 = self.client.switcht_api_interface_create(device, i_info) - self.ip20 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.10.1', + self.ip20 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.10.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if20, self.vrf, self.ip20) # Create L3 virtual interface for vlan 100 iu = interface_union(vlan_id=100) - i_info = switcht_interface_info_t(device=0, type=5, u=iu, + i_info = switcht_interface_info_t(device=0, + type=SWITCH_API_INTERFACE_L3_VLAN, + u=iu, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, @@ -719,14 +730,16 @@ def setUp(self): v4_multicast_enabled=1, v6_multicast_enabled=1) self.if21 = self.client.switcht_api_interface_create(device, i_info) - self.ip21 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.100.1', + self.ip21 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.100.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if21, self.vrf, self.ip21) # Create L3 virtual interface for vlan 200 iu = interface_union(vlan_id=200) - i_info = switcht_interface_info_t(device=0, type=5, u=iu, + i_info = switcht_interface_info_t(device=0, + type=SWITCH_API_INTERFACE_L3_VLAN, + u=iu, mac='00:77:66:55:44:33', label=0, vrf_handle=self.vrf, rmac_handle=self.rmac, @@ -735,7 +748,7 @@ def setUp(self): v4_multicast_enabled=1, v6_multicast_enabled=1) self.if22 = self.client.switcht_api_interface_create(device, i_info) - self.ip22 = switcht_ip_addr_t(addr_type=0, ipaddr='10.0.200.1', + self.ip22 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='10.0.200.1', prefix_length=24) self.client.switcht_api_l3_interface_address_add(device, self.if22, self.vrf, self.ip22) @@ -774,9 +787,9 @@ def setUp(self): self.route_ports) # create a ip multicast route (*,230.1.1.5) - self.msrc_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='0.0.0.0', + self.msrc_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='0.0.0.0', prefix_length=0) - self.mgrp_ip1 = switcht_ip_addr_t(addr_type=0, ipaddr='230.1.1.5', + self.mgrp_ip1 = switcht_ip_addr_t(addr_type=SWITCH_API_IP_ADDR_V4, ipaddr='230.1.1.5', prefix_length=32) rpid = [ ~0x0002 & 0xFFFF ] self.client.switcht_api_multicast_mroute_add(device, self.mch1, diff --git a/tests/ptf-tests/api-tests/switch_qos.py b/tests/ptf-tests/api-tests/switch_qos.py new file mode 100644 index 0000000..f805be4 --- /dev/null +++ b/tests/ptf-tests/api-tests/switch_qos.py @@ -0,0 +1,164 @@ +""" +Thrift API interface ACL tests +""" + +import switch_api_thrift + +import time +import sys +import logging + +import unittest +import random +import pdb + +import ptf.dataplane as dataplane +import api_base_tests + +from ptf.testutils import * +from ptf.thriftutils import * + + +import os + +from switch_api_thrift.ttypes import * +from switch_api_thrift.switch_api_headers import * + +from erspan3 import * + +this_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(os.path.join(this_dir, '..')) +from common.utils import * + +device=0 +cpu_port=64 +swports = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] +invalid_hdl = -1 + +############################################################################### +@group('qos') +class L3IPv4QosDscpRewriteTest(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])" + self.client.switcht_api_init(0) + vrf = self.client.switcht_api_vrf_create(0, 1) + + rmac = self.client.switcht_api_router_mac_group_create(0) + self.client.switcht_api_router_mac_add(0, rmac, '00:77:66:55:44:33') + + iu1 = interface_union(port_lag_handle = swports[1]) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if1 = self.client.switcht_api_interface_create(0, i_info1) + i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if2 = self.client.switcht_api_interface_create(0, i_info2) + i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) + + # Add a static route + i_ip3 = switcht_ip_addr_t(ipaddr='10.10.10.1', prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + nhop = self.client.switcht_api_nhop_create(0, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, + interface_handle=if2, + mac_addr='00:11:22:33:44:55', + ip_addr=i_ip3, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) + self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) + + qos_map1 = switcht_qos_map_t(dscp=1, tc=11) + qos_map2 = switcht_qos_map_t(dscp=2, tc=12) + qos_map3 = switcht_qos_map_t(dscp=3, tc=13) + qos_map4 = switcht_qos_map_t(dscp=4, tc=14) + ingress_qos_map_list = [qos_map1, qos_map2, qos_map3, qos_map4] + ingress_qos_handle = self.client.switcht_api_qos_map_ingress_create( + device=0, + qos_map_type=SWITCH_QOS_MAP_INGRESS_DSCP_TO_TC, + qos_map=ingress_qos_map_list) + + qos_map5 = switcht_qos_map_t(tc=11, icos=1) + qos_map6 = switcht_qos_map_t(tc=12, icos=2) + qos_map7 = switcht_qos_map_t(tc=13, icos=3) + qos_map8 = switcht_qos_map_t(tc=14, icos=4) + tc_qos_map_list = [qos_map5, qos_map6, qos_map7, qos_map8] + tc_qos_handle = self.client.switcht_api_qos_map_ingress_create( + device=0, + qos_map_type=SWITCH_QOS_MAP_INGRESS_TC_TO_ICOS, + qos_map=tc_qos_map_list) + + qos_map9 = switcht_qos_map_t(tc=11, dscp=10) + qos_map10 = switcht_qos_map_t(tc=12, icos=20) + qos_map11 = switcht_qos_map_t(tc=13, icos=30) + qos_map12 = switcht_qos_map_t(tc=14, icos=40) + egress_qos_map_list = [qos_map9, qos_map10, qos_map11, qos_map12] + egress_qos_handle = self.client.switcht_api_qos_map_egress_create( + device=0, + qos_map_type=SWITCH_QOS_MAP_EGRESS_TC_TO_DSCP, + qos_map=egress_qos_map_list) + + self.client.switcht_api_port_qos_group_ingress_set(device=0, port_handle=1, qos_handle=ingress_qos_handle) + self.client.switcht_api_port_qos_group_tc_set(device=0, port_handle=1, qos_handle=tc_qos_handle) + self.client.switcht_api_port_qos_group_egress_set(device=0, port_handle=1, qos_handle=egress_qos_handle) + self.client.switcht_api_port_trust_dscp_set(device=0, port_handle=1, trust_dscp=True) + + self.client.switcht_api_port_qos_group_ingress_set(device=0, port_handle=2, qos_handle=ingress_qos_handle) + self.client.switcht_api_port_qos_group_tc_set(device=0, port_handle=2, qos_handle=tc_qos_handle) + self.client.switcht_api_port_qos_group_egress_set(device=0, port_handle=2, qos_handle=egress_qos_handle) + self.client.switcht_api_port_trust_dscp_set(device=0, port_handle=2, trust_dscp=True) + + # send the test packet(s) + # send the test packet(s) + 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_tos=1, + ip_ttl=64) + send_packet(self, swports[1], str(pkt)) + + 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, + ip_tos=10, + ip_ttl=63) + verify_packets(self, exp_pkt, [swports[2]]) + + #cleanup + self.client.switcht_api_port_qos_group_ingress_set(device=0, port_handle=1, qos_handle=0) + self.client.switcht_api_port_qos_group_tc_set(device=0, port_handle=1, qos_handle=0) + self.client.switcht_api_port_qos_group_egress_set(device=0, port_handle=1, qos_handle=0) + self.client.switcht_api_port_trust_dscp_set(device=0, port_handle=1, trust_dscp=False) + + self.client.switcht_api_port_qos_group_ingress_set(device=0, port_handle=2, qos_handle=0) + self.client.switcht_api_port_qos_group_tc_set(device=0, port_handle=2, qos_handle=0) + self.client.switcht_api_port_qos_group_egress_set(device=0, port_handle=2, qos_handle=0) + self.client.switcht_api_port_trust_dscp_set(device=0, port_handle=2, trust_dscp=False) + + self.client.switcht_api_qos_map_ingress_delete(device=0, qos_map_handle=ingress_qos_handle) + self.client.switcht_api_qos_map_ingress_delete(device=0, qos_map_handle=tc_qos_handle) + self.client.switcht_api_qos_map_egress_delete(device=0, qos_map_handle=egress_qos_handle) + + self.client.switcht_api_neighbor_entry_remove(0, neighbor) + self.client.switcht_api_nhop_delete(0, nhop) + self.client.switcht_api_l3_route_delete(0, vrf, i_ip3, if2) + + self.client.switcht_api_l3_interface_address_delete(0, if1, vrf, i_ip1) + self.client.switcht_api_l3_interface_address_delete(0, if2, vrf, i_ip2) + + self.client.switcht_api_interface_delete(0, if1) + self.client.switcht_api_interface_delete(0, if2) + + self.client.switcht_api_router_mac_delete(0, rmac, '00:77:66:55:44:33') + self.client.switcht_api_router_mac_group_delete(0, rmac) + self.client.switcht_api_vrf_delete(0, vrf) + +############################################################################### diff --git a/tests/ptf-tests/api-tests/switch_sflow.py b/tests/ptf-tests/api-tests/switch_sflow.py index 784e7c2..882e411 100644 --- a/tests/ptf-tests/api-tests/switch_sflow.py +++ b/tests/ptf-tests/api-tests/switch_sflow.py @@ -62,7 +62,7 @@ def runTest(self): collector_type = 0, #CPU egress_port_hdl = cpu_port); sf_hdl = self.client.switcht_api_sflow_session_create(device, sflow_info1) - print "hdl = ", sf_hdl + print "hdl = ", sf_hdl assert(sf_hdl == invalid_hdl) # delete 2 sessions, create 2 sessions @@ -175,8 +175,9 @@ def runTest(self): ingress_ifindex = 2, ingress_bd = 2, ingress_port = 1, - reason_code=0x106, - sflow_sid=sflow_sid, + reason_code=0x4, + sflow_sid=sflow_sid, + sflow_egress_port=3, inner_pkt=pkt) for i in range(0,1): @@ -184,6 +185,17 @@ def runTest(self): verify_packet(self, exp_pkt, swports[2]) verify_packet(self, exp_pkt_sflow, cpu_port) + print "Get sflow session sample pool count" + stats = self.client.switcht_api_sflow_session_sample_count_get(0, sflow1, flow_hdl1) + self.assertEqual(stats.num_packets, 1) + print stats + + print "Reset sflow session sample pool count" + self.client.switcht_api_sflow_session_sample_count_reset(0, sflow1, flow_hdl1) + stats = self.client.switcht_api_sflow_session_sample_count_get(0, sflow1, flow_hdl1) + self.assertEqual(stats.num_packets, 0) + print stats + print "Detach sflow Session" self.client.switcht_api_sflow_session_detach(device, sflow1, flow_hdl1) # make sure pkts are not sent to cpu anymore diff --git a/tests/ptf-tests/common/pd_utils.py b/tests/ptf-tests/common/pd_utils.py index e744b24..aa77333 100644 --- a/tests/ptf-tests/common/pd_utils.py +++ b/tests/ptf-tests/common/pd_utils.py @@ -9,6 +9,7 @@ default_entries = {} stats_enabled = 1 +nat_enabled = 1 def port_to_pipe(port): return port >> 7 @@ -86,7 +87,6 @@ def populate_default_fabric_entries(client, sess_hdl, dev_tgt, ipv6_enabled=0, client.ip_acl_set_default_action_nop(sess_hdl, dev_tgt) client.ipv4_racl_set_default_action_nop(sess_hdl, dev_tgt) client.egress_acl_set_default_action_nop(sess_hdl, dev_tgt) - client.qos_set_default_action_nop(sess_hdl, dev_tgt) client.validate_packet_set_default_action_nop(sess_hdl, dev_tgt) if tunnel_enabled: client.outer_rmac_set_default_action_on_miss(sess_hdl, dev_tgt) @@ -105,16 +105,16 @@ def populate_default_fabric_entries(client, sess_hdl, dev_tgt, ipv6_enabled=0, client.ipv6_acl_set_default_action_nop(sess_hdl, dev_tgt) client.ipv6_racl_set_default_action_nop(sess_hdl, dev_tgt) match_spec = dc_compute_ipv4_hashes_match_spec_t( - ingress_metadata_drop_flag=0) + ethernet_valid=1) client.compute_ipv4_hashes_table_add_with_compute_lkp_ipv4_hash( sess_hdl, dev_tgt, match_spec) if ipv6_enabled == 1: match_spec = dc_compute_ipv6_hashes_match_spec_t( - ingress_metadata_drop_flag=0) + ethernet_valid=1) client.compute_ipv6_hashes_table_add_with_compute_lkp_ipv6_hash( sess_hdl, dev_tgt, match_spec) match_spec = dc_compute_non_ip_hashes_match_spec_t( - ingress_metadata_drop_flag=0) + ethernet_valid=1) client.compute_non_ip_hashes_table_add_with_compute_lkp_non_ip_hash( sess_hdl, dev_tgt, match_spec) client.egress_vni_set_default_action_nop(sess_hdl, dev_tgt) @@ -130,6 +130,11 @@ def populate_default_fabric_entries(client, sess_hdl, dev_tgt, ipv6_enabled=0, if stats_enabled: client.ingress_bd_stats_set_default_action_update_ingress_bd_stats( sess_hdl, dev_tgt) + if nat_enabled: + client.nat_twice_set_default_action_on_miss(sess_hdl, dev_tgt) + client.nat_dst_set_default_action_on_miss(sess_hdl, dev_tgt) + client.nat_src_set_default_action_on_miss(sess_hdl, dev_tgt) + client.nat_flow_set_default_action_nop(sess_hdl, dev_tgt) def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, acl_enabled, tunnel_enabled, multicast_enabled, int_enabled): @@ -176,11 +181,11 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, client.storm_control_stats_set_default_action_nop( sess_hdl, dev_tgt) meter_spec = dc_bytes_meter_spec_t( - cir_kbps=0, - cburst_kbits=0, - pir_kbps=0, - pburst_kbits=0, - color_aware=False) + cir_kbps=0, + cburst_kbits=0, + pir_kbps=0, + pburst_kbits=0, + color_aware=False) client.meter_index_set_default_action_nop( sess_hdl, dev_tgt, meter_spec) client.meter_action_set_default_action_meter_permit( @@ -192,7 +197,7 @@ 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) + action_spec = dc_egress_port_type_normal_action_spec_t(action_ifindex=0, action_qos_group=0) client.egress_port_mapping_set_default_action_egress_port_type_normal( sess_hdl, dev_tgt, action_spec) client.mtu_set_default_action_mtu_miss( @@ -212,6 +217,18 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) client.system_acl_set_default_action_nop( sess_hdl, dev_tgt) + client.adjust_lkp_fields_set_default_action_non_ip_lkp( + sess_hdl, dev_tgt) + match_spec = dc_adjust_lkp_fields_match_spec_t(ipv4_valid=1, ipv6_valid=0) + client.adjust_lkp_fields_table_add_with_ipv4_lkp( + sess_hdl, dev_tgt, match_spec) + match_spec = dc_adjust_lkp_fields_match_spec_t(ipv4_valid=0, ipv6_valid=1) + client.adjust_lkp_fields_table_add_with_ipv6_lkp( + sess_hdl, dev_tgt, match_spec) + client.sflow_ingress_set_default_action_nop( + sess_hdl, dev_tgt) + client.sflow_ing_take_sample_set_default_action_nop( + sess_hdl, dev_tgt) if acl_enabled: client.ip_acl_set_default_action_nop( @@ -220,8 +237,6 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) client.egress_acl_set_default_action_nop( sess_hdl, dev_tgt) - client.qos_set_default_action_nop( - sess_hdl, dev_tgt) client.acl_stats_set_default_action_acl_stats_update( sess_hdl, dev_tgt) if tunnel_enabled: @@ -233,8 +248,6 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) client.tunnel_mtu_set_default_action_tunnel_mtu_miss( sess_hdl, dev_tgt) - client.tunnel_miss_set_default_action_tunnel_lookup_miss( - sess_hdl, dev_tgt) client.egress_bd_map_set_default_action_nop( sess_hdl, dev_tgt) if ipv6_enabled and tunnel_enabled: @@ -249,9 +262,10 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) if multicast_enabled: - client.outer_ipv4_multicast_set_default_action_on_miss( + if tunnel_enabled: + client.outer_ipv4_multicast_set_default_action_on_miss( sess_hdl, dev_tgt) - client.outer_ipv4_multicast_star_g_set_default_action_nop( + client.outer_ipv4_multicast_star_g_set_default_action_nop( sess_hdl, dev_tgt) client.ipv4_multicast_bridge_set_default_action_on_miss( sess_hdl, dev_tgt) @@ -262,9 +276,10 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, client.ipv4_multicast_route_star_g_set_default_action_multicast_route_star_g_miss( sess_hdl, dev_tgt) if ipv6_enabled: - client.outer_ipv6_multicast_set_default_action_on_miss( + if tunnel_enabled: + client.outer_ipv6_multicast_set_default_action_on_miss( sess_hdl, dev_tgt) - client.outer_ipv6_multicast_star_g_set_default_action_nop( + client.outer_ipv6_multicast_star_g_set_default_action_nop( sess_hdl, dev_tgt) client.ipv6_multicast_bridge_set_default_action_on_miss( sess_hdl, dev_tgt) @@ -275,6 +290,15 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, client.ipv6_multicast_route_star_g_set_default_action_multicast_route_star_g_miss( sess_hdl, dev_tgt) + client.egress_qos_map_set_default_action_nop( + sess_hdl, dev_tgt) + client.ingress_qos_map_dscp_set_default_action_nop( + sess_hdl, dev_tgt) + client.ingress_qos_map_pcp_set_default_action_nop( + sess_hdl, dev_tgt) + client.traffic_class_set_default_action_nop( + sess_hdl, dev_tgt) + if stats_enabled: client.ingress_bd_stats_set_default_action_update_ingress_bd_stats( sess_hdl, dev_tgt) @@ -292,6 +316,12 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, dev_tgt) client.int_outer_encap_set_default_action_nop(sess_hdl, dev_tgt) + if nat_enabled: + client.nat_twice_set_default_action_on_miss(sess_hdl, dev_tgt) + client.nat_dst_set_default_action_on_miss(sess_hdl, dev_tgt) + client.nat_src_set_default_action_on_miss(sess_hdl, dev_tgt) + client.nat_flow_set_default_action_nop(sess_hdl, dev_tgt) + def delete_default_entries(client, sess_hdl, dev_id): return @@ -316,6 +346,8 @@ def populate_init_fabric_entries(client, sess_hdl, dev_tgt, inner_rmac_group, l3_metadata_rmac_hit_mask=1, l3_metadata_fib_hit=1, l3_metadata_fib_hit_mask=1, + nat_metadata_nat_hit=0, + nat_metadata_nat_hit_mask=0, l2_metadata_lkp_pkt_type=0, l2_metadata_lkp_pkt_type_mask=0, l3_metadata_lkp_ip_type=0, @@ -346,6 +378,8 @@ def populate_init_fabric_entries(client, sess_hdl, dev_tgt, inner_rmac_group, l3_metadata_rmac_hit_mask=0, l3_metadata_fib_hit=0, l3_metadata_fib_hit_mask=0, + nat_metadata_nat_hit=0, + nat_metadata_nat_hit_mask=0, l2_metadata_lkp_pkt_type=0, l2_metadata_lkp_pkt_type_mask=0, l3_metadata_lkp_ip_type=0, @@ -441,6 +475,8 @@ def populate_init_entries(client, sess_hdl, dev_tgt, rewrite_index, rmac, l3_metadata_fib_hit_mask=1, l3_metadata_rmac_hit=0, l3_metadata_rmac_hit_mask=0, + nat_metadata_nat_hit=0, + nat_metadata_nat_hit_mask=0, l2_metadata_lkp_pkt_type=0, l2_metadata_lkp_pkt_type_mask=0, l3_metadata_lkp_ip_type=0, @@ -472,6 +508,8 @@ def populate_init_entries(client, sess_hdl, dev_tgt, rewrite_index, rmac, l3_metadata_fib_hit_mask=0, l3_metadata_rmac_hit=0, l3_metadata_rmac_hit_mask=0, + nat_metadata_nat_hit=0, + nat_metadata_nat_hit_mask=0, l2_metadata_lkp_pkt_type=0, l2_metadata_lkp_pkt_type_mask=0, l3_metadata_lkp_ip_type=0, @@ -541,7 +579,7 @@ def populate_init_entries(client, sess_hdl, dev_tgt, rewrite_index, rmac, #Add default outer rmac entry match_spec = dc_outer_rmac_match_spec_t( l3_metadata_rmac_group=outer_rmac_group, - l2_metadata_lkp_mac_da=macAddr_to_string(rmac)) + ethernet_dstAddr=macAddr_to_string(rmac)) ret.append(client.outer_rmac_table_add_with_outer_rmac_hit( sess_hdl, dev_tgt, match_spec)) @@ -586,11 +624,20 @@ def program_ports(client, sess_hdl, dev_tgt, port_count): standard_metadata_ingress_port=count) action_spec = dc_set_ifindex_action_spec_t( action_ifindex=count, - action_if_label=count, action_port_type=0) port_hdl = client.ingress_port_mapping_table_add_with_set_ifindex( sess_hdl, dev_tgt, match_spec, action_spec) + action_spec = dc_set_ingress_port_properties_action_spec_t( + action_if_label=count, + action_qos_group=0, + action_tc_qos_group=0, + action_tc=0, + action_color=0, + action_trust_dscp=0, + action_trust_pcp=0) + port2_hdl = client.ingress_port_properties_table_add_with_set_ingress_port_properties( + sess_hdl, dev_tgt, match_spec, action_spec) action_spec = dc_set_lag_port_action_spec_t( action_port=count) @@ -605,13 +652,16 @@ def program_ports(client, sess_hdl, dev_tgt, port_count): 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) + action_spec = dc_egress_port_type_normal_action_spec_t( + action_ifindex=count, + action_qos_group=0) 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}) + ret.append({ 'port': port_hdl, 'port2': port2_hdl, 'mbr' : mbr_hdl, + 'lag' : lag_hdl, 'egress' : egress_hdl}) count = count + 1 return ret @@ -624,12 +674,22 @@ def program_emulation_ports(client, sess_hdl, dev_tgt, port_count): standard_metadata_ingress_port=count) action_spec = dc_set_ifindex_action_spec_t( action_ifindex=count+1, - action_if_label=count, action_port_type=0) port_hdl = client.ingress_port_mapping_table_add_with_set_ifindex( sess_hdl, dev_tgt, match_spec, action_spec) + action_spec = dc_set_ingress_port_properties_action_spec_t( + action_if_label=count, + action_qos_group=0, + action_tc_qos_group=0, + action_tc=0, + action_color=0, + action_trust_dscp=0, + action_trust_pcp=0) + port2_hdl = client.ingress_port_properties_table_add_with_set_ingress_port_properties( + sess_hdl, dev_tgt, match_spec, action_spec) + action_spec = dc_set_lag_port_action_spec_t( action_port=count) mbr_hdl = client.lag_action_profile_add_member_with_set_lag_port( @@ -643,13 +703,16 @@ def program_emulation_ports(client, sess_hdl, dev_tgt, port_count): match_spec, mbr_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) + action_spec = dc_egress_port_type_normal_action_spec_t( + action_ifindex=count, + action_qos_group=0) 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}) + ret.append({ 'port': port_hdl, 'port2': port2_hdl, 'mbr' : mbr_hdl, + 'lag' : lag_hdl, 'egress' : egress_hdl}) count = count + 1 return ret @@ -661,7 +724,8 @@ def add_ports(client, sess_hdl, dev_tgt, port_list, port_type, l2xid): match_spec = dc_ingress_port_mapping_match_spec_t( standard_metadata_ingress_port=i) action_spec = dc_set_ifindex_action_spec_t( - action_ifindex=ifindex, action_if_label=0, + action_ifindex=ifindex, + action_if_label=0, action_port_type=port_type) client.ingress_port_mapping_table_add_with_set_ifindex( sess_hdl, dev_tgt, match_spec, action_spec) @@ -676,7 +740,9 @@ 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) + action_spec = dc_egress_port_type_normal_action_spec_t( + action_ifindex=count, + action_qos_group=0) client.egress_port_mapping_table_add_with_egress_port_type_normal( sess_hdl, dev_tgt, match_spec, action_spec) elif port_type == PortType.Fabric: @@ -696,6 +762,8 @@ 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.ingress_port_properties_table_delete( + sess_hdl, dev, ret_list[count]['port2']) client.egress_port_mapping_table_delete( sess_hdl, dev, ret_list[count]['egress']) @@ -766,7 +834,7 @@ def program_vlan(client, sess_hdl, dev_tgt, vrf, inner_rmac_group, def program_egress_bd_map(client, sess_hdl, dev_tgt, smac_index, vlan): match_spec = dc_egress_bd_map_match_spec_t(egress_metadata_bd=vlan) action_spec = dc_set_egress_bd_properties_action_spec_t( - action_smac_idx=smac_index) + action_smac_idx=smac_index, action_nat_mode=0) client.egress_bd_map_table_add_with_set_egress_bd_properties( sess_hdl, dev_tgt, match_spec, action_spec) @@ -1131,7 +1199,7 @@ def program_tunnel_ipv4_src_vtep(client, sess_hdl, dev_tgt, vrf, src_ip, #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_srcAddr=src_ip, tunnel_metadata_ingress_tunnel_type=tunnel_type) action_spec = dc_src_vtep_hit_action_spec_t( action_ifindex=ifindex) @@ -1150,7 +1218,7 @@ def program_tunnel_ipv4_dst_vtep(client, sess_hdl, dev_tgt, vrf, dst_ip, #Ingress Tunnel Decap - dest vtep entry match_spec = dc_ipv4_dest_vtep_match_spec_t( l3_metadata_vrf=vrf, - ipv4_metadata_lkp_ipv4_da=dst_ip, + ipv4_dstAddr=dst_ip, tunnel_metadata_ingress_tunnel_type=tunnel_type) hdl = client.ipv4_dest_vtep_table_add_with_set_tunnel_termination_flag( sess_hdl, dev_tgt, @@ -1346,7 +1414,8 @@ def program_egress_bd_properties(client, sess_hdl, dev_tgt, bd, rewrite_index): match_spec = dc_egress_bd_map_match_spec_t( egress_metadata_bd=bd) action_spec = dc_set_egress_bd_properties_action_spec_t( - action_smac_idx=rewrite_index) + action_smac_idx=rewrite_index, + action_nat_mode=0) hdl = client.egress_bd_map_table_add_with_set_egress_bd_properties( sess_hdl, dev_tgt, match_spec, action_spec) return hdl diff --git a/tests/ptf-tests/common/sai_utils.py b/tests/ptf-tests/common/sai_utils.py index 4079053..de1953f 100644 --- a/tests/ptf-tests/common/sai_utils.py +++ b/tests/ptf-tests/common/sai_utils.py @@ -39,6 +39,20 @@ port_list = [] table_attr_list = [] +def sai_thrift_create_vlan_member(client, vlan_id, port, tagging_mode): + attribute1_value = sai_thrift_attribute_value_t(u16=vlan_id) + attribute1 = sai_thrift_attribute_t(id=SAI_VLAN_MEMBER_ATTR_VLAN_ID, + value=attribute1_value) + attribute2_value = sai_thrift_attribute_value_t(oid=port) + attribute2 = sai_thrift_attribute_t(id=SAI_VLAN_MEMBER_ATTR_PORT_ID, + value=attribute2_value) + attribute3_value = sai_thrift_attribute_value_t(s32=tagging_mode) + attribute3 = sai_thrift_attribute_t(id=SAI_VLAN_MEMBER_ATTR_TAGGING_MODE, + value=attribute3_value) + attr_list = [attribute1, attribute2, attribute3] + vlan_member = client.sai_thrift_create_vlan_member(thrift_attr_list=attr_list) + return vlan_member + 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 @@ -246,12 +260,12 @@ def sai_thrift_create_stp_entry(client, vlan_list): stp_id = client.sai_thrift_create_stp_entry(stp_attr_list) return stp_id -def sai_thrift_create_hostif_trap_group(client, queue_id, priority): - attribute1_value = sai_thrift_attribute_value_t(u32=priority) - attribute1 = sai_thrift_attribute_t(id=SAI_HOSTIF_TRAP_GROUP_ATTR_PRIO, +def sai_thrift_create_hostif_trap_group(client, queue_id, policer_id): + attribute1_value = sai_thrift_attribute_value_t(u32=queue_id) + attribute1 = sai_thrift_attribute_t(id=SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE, value=attribute1_value) - attribute2_value = sai_thrift_attribute_value_t(u32=queue_id) - attribute2 = sai_thrift_attribute_t(id=SAI_HOSTIF_TRAP_GROUP_ATTR_QUEUE, + attribute2_value = sai_thrift_attribute_value_t(oid=policer_id) + attribute2 = sai_thrift_attribute_t(id=SAI_HOSTIF_TRAP_GROUP_ATTR_POLICER, value=attribute2_value) attr_list = [attribute1, attribute2] trap_group_id = client.sai_thrift_create_hostif_trap_group(thrift_attr_list=attr_list) @@ -571,6 +585,7 @@ def sai_thrift_get_vlan_stats(client, vlan_id, ingress=True, egress=True): counter_ids = [] if ingress: counter_ids.append(SAI_VLAN_STAT_IN_OCTETS) + counter_ids.append(SAI_VLAN_STAT_IN_PACKETS) counter_ids.append(SAI_VLAN_STAT_IN_UCAST_PKTS) counter_ids.append(SAI_VLAN_STAT_IN_NON_UCAST_PKTS) counter_ids.append(SAI_VLAN_STAT_IN_DISCARDS) @@ -578,6 +593,7 @@ def sai_thrift_get_vlan_stats(client, vlan_id, ingress=True, egress=True): counter_ids.append(SAI_VLAN_STAT_IN_UNKNOWN_PROTOS) if egress: counter_ids.append(SAI_VLAN_STAT_OUT_OCTETS) + counter_ids.append(SAI_VLAN_STAT_OUT_PACKETS) counter_ids.append(SAI_VLAN_STAT_OUT_UCAST_PKTS) counter_ids.append(SAI_VLAN_STAT_OUT_NON_UCAST_PKTS) counter_ids.append(SAI_VLAN_STAT_OUT_DISCARDS) @@ -714,3 +730,85 @@ def sai_thrift_get_policer_stats(client, policer_id): attr_value_list = client.sai_thrift_get_policer_stats(policer_id, attr_list) return attr_value_list + +def sai_thrift_create_qos_map(client, map_type, key_list, data_list): + qos_map_key_list = [] + qos_map_data_list = [] + attr_list = [] + + attribute1_value = sai_thrift_attribute_value_t(s32=map_type) + attribute1 = sai_thrift_attribute_t(id=SAI_QOS_MAP_ATTR_TYPE, + value=attribute1_value) + attr_list.append(attribute1) + + if (map_type == SAI_QOS_MAP_DOT1P_TO_TC): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(dot1p=i) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(tc=j) + qos_map_data_list.append(qos_map_data) + elif (map_type == SAI_QOS_MAP_DSCP_TO_TC): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(dscp=i) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(tc=j) + qos_map_data_list.append(qos_map_data) + elif (map_type == SAI_QOS_MAP_DOT1P_TO_COLOR): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(dot1p=i) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(color=j) + qos_map_data_list.append(qos_map_data) + elif (map_type == SAI_QOS_MAP_DSCP_TO_COLOR): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(dscp=i) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(color=j) + qos_map_data_list.append(qos_map_data) + elif (map_type == SAI_QOS_MAP_TC_TO_QUEUE): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(tc=i) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(queue_index=j) + qos_map_data_list.append(qos_map_data) + elif (map_type == SAI_QOS_MAP_TC_AND_COLOR_TO_DOT1P): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(tc=i[0], color=i[1]) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(dot1p=j) + qos_map_data_list.append(qos_map_data) + elif (map_type == SAI_QOS_MAP_TC_AND_COLOR_TO_DSCP): + for i in key_list: + qos_map_key = sai_thrift_qos_map_params_t(tc=i[0], color=i[1]) + qos_map_key_list.append(qos_map_key) + for j in data_list: + qos_map_data = sai_thrift_qos_map_params_t(dscp=j) + qos_map_data_list.append(qos_map_data) + + qos_map_list = sai_thrift_qos_map_list_t(key=qos_map_key_list, data=qos_map_data_list) + attribute2_value = sai_thrift_attribute_value_t(qosmap=qos_map_list) + attribute2 = sai_thrift_attribute_t(id=SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST, + value=attribute2_value) + attr_list.append(attribute2) + + qos_map_id = client.sai_thrift_create_qos_map(attr_list) + return qos_map_id + +def sai_thrift_set_port_attribute(client, port_id, id, value): + if (id == SAI_PORT_ATTR_QOS_DOT1P_TO_TC_MAP or + id == SAI_PORT_ATTR_QOS_DOT1P_TO_COLOR_MAP or + id == SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP or + id == SAI_PORT_ATTR_QOS_DSCP_TO_COLOR_MAP or + id == SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP or + id == SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP or + id == SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP): + attribute_value = sai_thrift_attribute_value_t(oid=value) + attribute = sai_thrift_attribute_t(id=id, value=attribute_value) + client.sai_thrift_set_port_attribute(port_id, attribute) + diff --git a/tests/ptf-tests/common/utils.py b/tests/ptf-tests/common/utils.py index 02d591e..cd6e912 100644 --- a/tests/ptf-tests/common/utils.py +++ b/tests/ptf-tests/common/utils.py @@ -88,6 +88,7 @@ class FabricCpuSflowHeader(Packet): name = "Fabric Cpu Sflow Header" fields_desc = [ XShortField("sflow_sid", 0), + XShortField("sflow_egress_port", 0), ] class FabricPayloadHeader(Packet): @@ -137,6 +138,7 @@ def simple_cpu_packet(header_version = 0, ingress_port = 1, reason_code = 0, sflow_sid = 0, + sflow_egress_port = 0, inner_pkt = None): ether = Ether(str(inner_pkt)) @@ -165,7 +167,7 @@ def simple_cpu_packet(header_version = 0, pkt = (str(ether)[:14]) / fabric_header / fabric_cpu_header if sflow_sid: - pkt = pkt / FabricCpuSflowHeader(sflow_sid = sflow_sid) + pkt = pkt / FabricCpuSflowHeader(sflow_sid = sflow_sid, sflow_egress_port = sflow_egress_port) pkt = pkt / fabric_payload_header @@ -314,6 +316,7 @@ def entropy_hash(pkt, layer='ipv4'): buf = '' else: buf = '' - h = socket.htons(crc16_regular(buff.decode('hex'))) + # h = socket.htons(crc16_regular(buff.decode('hex'))) + h = crc16_regular(buff.decode('hex')) return h diff --git a/tests/ptf-tests/pd-tests/pd_base_tests.py b/tests/ptf-tests/pd-tests/pd_base_tests.py new file mode 100644 index 0000000..333bdda --- /dev/null +++ b/tests/ptf-tests/pd-tests/pd_base_tests.py @@ -0,0 +1,75 @@ +""" +Base classes for PD test cases + +Tests will usually inherit from one of these classes to have the controller +and/or dataplane automatically set up. +""" + +import importlib + +import ptf +from ptf.base_tests import BaseTest +from ptf import config +import ptf.testutils as testutils + +################################################################ +# +# Thrift interface base tests +# +################################################################ + +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol +from thrift.protocol import TMultiplexedProtocol + +class ThriftInterface(BaseTest): + def __init__(self, p4_name): + BaseTest.__init__(self) + self.p4_name = p4_name + self.p4_client_module = importlib.import_module(".".join(["p4_pd_rpc", p4_name])) + self.mc_client_module = importlib.import_module(".".join(["mc_pd_rpc", "mc"])) + self.conn_mgr_client_module = importlib.import_module(".".join(["conn_mgr_pd_rpc", "conn_mgr"])) + + def setUp(self): + BaseTest.setUp(self) + + # Set up thrift client and contact server + self.transport = TSocket.TSocket('localhost', 9090) + self.transport = TTransport.TBufferedTransport(self.transport) + bprotocol = TBinaryProtocol.TBinaryProtocol(self.transport) + + self.mc_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "mc") + self.conn_mgr_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, "conn_mgr") + self.p4_protocol = TMultiplexedProtocol.TMultiplexedProtocol(bprotocol, self.p4_name) + + self.client = self.p4_client_module.Client(self.p4_protocol) + self.mc = self.mc_client_module.Client(self.mc_protocol) + self.conn_mgr = self.conn_mgr_client_module.Client(self.conn_mgr_protocol) + self.transport.open() + + def tearDown(self): + if config["log_dir"] != None: + self.dataplane.stop_pcap() + BaseTest.tearDown(self) + self.transport.close() + +class ThriftInterfaceDataPlane(ThriftInterface): + """ + Root class that sets up the thrift interface and dataplane + """ + def __init__(self, p4_name): + ThriftInterface.__init__(self, p4_name) + + def setUp(self): + ThriftInterface.setUp(self) + self.dataplane = ptf.dataplane_instance + self.dataplane.flush() + if config["log_dir"] != None: + filename = os.path.join(config["log_dir"], str(self)) + ".pcap" + self.dataplane.start_pcap(filename) + + def tearDown(self): + if config["log_dir"] != None: + self.dataplane.stop_pcap() + ThriftInterface.tearDown(self) diff --git a/tests/ptf-tests/pd-tests/switch.py b/tests/ptf-tests/pd-tests/switch.py index 3b60365..3039f33 100644 --- a/tests/ptf-tests/pd-tests/switch.py +++ b/tests/ptf-tests/pd-tests/switch.py @@ -63,7 +63,7 @@ def __init__(self): pd_base_tests.ThriftInterfaceDataPlane.__init__(self, "dc") def runTest(self): - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -148,7 +148,7 @@ def __init__(self): def runTest(self): print - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -270,7 +270,7 @@ def runTest(self): print "ipv6 not enabled" return - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -399,7 +399,7 @@ def runTest(self): print "tunnel not enabled" return - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -533,7 +533,6 @@ def runTest(self): try: send_packet(self, 1, str(pkt1)) verify_packets(self, vxlan_pkt1, [2]) - send_packet(self, 2, str(vxlan_pkt2)) verify_packets(self, pkt2, [1]) finally: @@ -583,7 +582,7 @@ def runTest(self): if tunnel_enabled == 0: print "tunnel not enabled" return - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -789,7 +788,7 @@ def __init__(self): pd_base_tests.ThriftInterfaceDataPlane.__init__(self, "dc") def runTest(self): - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -882,7 +881,7 @@ def __init__(self): pd_base_tests.ThriftInterfaceDataPlane.__init__(self, "dc") def runTest(self): - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() mc_sess_hdl = self.mc.mc_create_session() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 @@ -991,7 +990,7 @@ def __init__(self): def runTest(self): print - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) device = 0 diff --git a/tests/ptf-tests/sai-tests/switch.py b/tests/ptf-tests/sai-tests/switch.py index 6b40af6..f3c0790 100644 --- a/tests/ptf-tests/sai-tests/switch.py +++ b/tests/ptf-tests/sai-tests/switch.py @@ -38,12 +38,14 @@ this_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(os.path.join(this_dir, '..')) +from common.utils import * from common.sai_utils import * from erspan3 import * this_dir = os.path.dirname(os.path.abspath(__file__)) +cpu_port=64 switch_inited=0 port_list = [] table_attr_list = [] @@ -84,9 +86,8 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - 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) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -104,7 +105,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class L2TrunkToTrunkVlanTest(sai_base_test.ThriftInterfaceDataPlane): @@ -120,9 +122,8 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - vlan_port1 = sai_thrift_vlan_port_t(port_id=port1, tagging_mode=SAI_VLAN_PORT_TAGGED) - vlan_port2 = sai_thrift_vlan_port_t(port_id=port2, tagging_mode=SAI_VLAN_PORT_TAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_TAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_TAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -149,7 +150,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class L2AccessToTrunkVlanTest(sai_base_test.ThriftInterfaceDataPlane): @@ -165,9 +167,8 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - vlan_port1 = sai_thrift_vlan_port_t(port_id=port1, tagging_mode=SAI_VLAN_PORT_TAGGED) - vlan_port2 = sai_thrift_vlan_port_t(port_id=port2, tagging_mode=SAI_VLAN_PORT_UNTAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_TAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -192,7 +193,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class L2TrunkToAccessVlanTest(sai_base_test.ThriftInterfaceDataPlane): @@ -208,9 +210,8 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - 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_TAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_TAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -235,7 +236,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class L2StpTest(sai_base_test.ThriftInterfaceDataPlane): @@ -252,9 +254,8 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - 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) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) stp_id = sai_thrift_create_stp_entry(self.client, vlan_list) self.client.sai_thrift_set_stp_port_state(stp_id, port1, SAI_PORT_STP_STATE_FORWARDING) @@ -297,7 +298,8 @@ def runTest(self): self.client.sai_thrift_remove_stp_entry(stp_id) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class L3IPv4HostTest(sai_base_test.ThriftInterfaceDataPlane): @@ -929,7 +931,7 @@ def runTest(self): print "Count = %s" % str(count) for i in range(0, 4): - self.assertTrue((count[i] >= ((max_itrs / 4) * 0.75)), + self.assertTrue((count[i] >= ((max_itrs / 4) * 0.50)), "Not all paths are equally balanced") finally: sai_thrift_remove_neighbor(self.client, addr_family, rif_id1, nhop_ip1, dmac1) @@ -965,10 +967,9 @@ def runTest(self): mac2 = '00:22:22:22:22:22' self.client.sai_thrift_create_vlan(vlan_id) - 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) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2, vlan_port3]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) + vlan_member3 = sai_thrift_create_vlan_member(self.client, vlan_id, port3, SAI_VLAN_PORT_UNTAGGED) pkt = simple_tcp_packet(eth_dst='00:11:11:11:11:11', eth_src='00:22:22:22:22:22', @@ -989,7 +990,9 @@ def runTest(self): verify_packets(self, exp_pkt, [1, 2]) finally: sai_thrift_flush_fdb_by_vlan(self.client, vlan_id) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2, vlan_port3]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) + self.client.sai_thrift_remove_vlan_member(vlan_member3) self.client.sai_thrift_delete_vlan(vlan_id) class L2LagTest(sai_base_test.ThriftInterfaceDataPlane): @@ -1013,9 +1016,8 @@ def runTest(self): 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=lag_id1, tagging_mode=SAI_VLAN_PORT_UNTAGGED) - vlan_port2 = 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_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, lag_id1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port5, SAI_VLAN_PORT_UNTAGGED) 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) @@ -1077,7 +1079,8 @@ def runTest(self): 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]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_remove_lag_member(lag_member1) self.client.sai_thrift_remove_lag_member(lag_member2) @@ -1108,12 +1111,11 @@ def runTest(self): 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]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) + vlan_member3 = sai_thrift_create_vlan_member(self.client, vlan_id, port3, SAI_VLAN_PORT_UNTAGGED) + vlan_member4 = sai_thrift_create_vlan_member(self.client, vlan_id, port4, SAI_VLAN_PORT_UNTAGGED) + vlan_member5 = sai_thrift_create_vlan_member(self.client, vlan_id, port5, SAI_VLAN_PORT_UNTAGGED) 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) @@ -1175,8 +1177,11 @@ def runTest(self): 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_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) + self.client.sai_thrift_remove_vlan_member(vlan_member3) + self.client.sai_thrift_remove_vlan_member(vlan_member4) + self.client.sai_thrift_remove_vlan_member(vlan_member5) self.client.sai_thrift_remove_lag_member(lag_member1) self.client.sai_thrift_remove_lag_member(lag_member2) @@ -1542,8 +1547,7 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - vlan_port1 = sai_thrift_vlan_port_t(port_id=port1, tagging_mode=SAI_VLAN_PORT_UNTAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) mac1 = '' @@ -1612,7 +1616,7 @@ def runTest(self): self.client.sai_thrift_remove_next_hop(nhop2) self.client.sai_thrift_remove_router_interface(rif_id1) self.client.sai_thrift_remove_router_interface(rif_id2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) self.client.sai_thrift_delete_vlan(vlan_id) self.client.sai_thrift_remove_virtual_router(vr_id) @@ -1684,9 +1688,8 @@ def runTest(self): self.client.sai_thrift_create_vlan(vlan_id) - 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_TAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_TAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -1771,7 +1774,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class IngressERSpanMirrorTest(sai_base_test.ThriftInterfaceDataPlane): @@ -1790,9 +1794,8 @@ def runTest(self): self.client.sai_thrift_create_vlan(vlan_id) - 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_TAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_TAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -1882,7 +1885,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class EgressLocalMirrorTest(sai_base_test.ThriftInterfaceDataPlane): @@ -1901,9 +1905,8 @@ def runTest(self): self.client.sai_thrift_create_vlan(vlan_id) - 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_TAGGED) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_TAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -1963,7 +1966,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class EgressERSpanMirrorTest(sai_base_test.ThriftInterfaceDataPlane): @@ -1982,9 +1986,8 @@ def runTest(self): self.client.sai_thrift_create_vlan(vlan_id) - 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) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -2060,7 +2063,8 @@ def runTest(self): sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class L2VlanStatsTest(sai_base_test.ThriftInterfaceDataPlane): @@ -2076,9 +2080,8 @@ def runTest(self): mac_action = SAI_PACKET_ACTION_FORWARD self.client.sai_thrift_create_vlan(vlan_id) - 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) - self.client.sai_thrift_add_ports_to_vlan(vlan_id, [vlan_port1, vlan_port2]) + vlan_member1 = sai_thrift_create_vlan_member(self.client, vlan_id, port1, SAI_VLAN_PORT_UNTAGGED) + vlan_member2 = sai_thrift_create_vlan_member(self.client, vlan_id, port2, SAI_VLAN_PORT_UNTAGGED) sai_thrift_create_fdb(self.client, vlan_id, mac1, port1, mac_action) sai_thrift_create_fdb(self.client, vlan_id, mac2, port2, mac_action) @@ -2110,16 +2113,17 @@ def runTest(self): sai_thrift_print_vlan_stats(counter2_ids, counter2) - self.assertEqual(counter2[0], num_bytes) - self.assertEqual(counter2[1], num_packets) + self.assertEqual(counter2[SAI_VLAN_STAT_IN_OCTETS], num_bytes) + self.assertEqual(counter2[SAI_VLAN_STAT_IN_UCAST_PKTS], num_packets) #self.assertEqual(counter2[6], num_bytes) - self.assertEqual(counter2[7], num_packets) + self.assertEqual(counter2[SAI_VLAN_STAT_OUT_UCAST_PKTS], num_packets) finally: sai_thrift_delete_fdb(self.client, vlan_id, mac1, port1) sai_thrift_delete_fdb(self.client, vlan_id, mac2, port2) - self.client.sai_thrift_remove_ports_from_vlan(vlan_id, [vlan_port1, vlan_port2]) + self.client.sai_thrift_remove_vlan_member(vlan_member1) + self.client.sai_thrift_remove_vlan_member(vlan_member2) self.client.sai_thrift_delete_vlan(vlan_id) class IPAclStatsTest(sai_base_test.ThriftInterfaceDataPlane): @@ -2286,3 +2290,283 @@ def runTest(self): self.client.sai_thrift_remove_router_interface(rif_id2) self.client.sai_thrift_remove_virtual_router(vr_id) + +class NexthopGetSetTest(sai_base_test.ThriftInterfaceDataPlane): + def runTest(self): + return + switch_init(self.client) + port1 = port_list[1] + port2 = port_list[2] + v4_enabled = 1 + v6_enabled = 1 + v6_disabled = 0 + mac_valid = 0 + mac = '' + + vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) + rif_id = sai_thrift_create_router_interface(self.client, vr_id, 1, port1, 0, v4_enabled, v6_enabled, mac) + + addr_family = SAI_IP_ADDR_FAMILY_IPV4 + ip_addr = '10.10.10.1' + ip_mask = '255.255.255.255' + nhop = sai_thrift_create_nhop(self.client, addr_family, ip_addr, rif_id) + + # check get returns correct value + rif_attribute = sai_thrift_attribute_t(id=SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID) + resp = self.client.sai_thrift_get_next_hop_attribute(nhop, 1, [rif_attribute]) + assert(resp.status == 0) + assert(resp.attributes[0].value.oid == rif_id) + + # create a new vr_id, rif_id pair for set + rif_id2 = sai_thrift_create_router_interface(self.client, vr_id, 1, port2, 0, v4_enabled, v6_disabled, mac) + rif_attribute2 = sai_thrift_attribute_t(id=SAI_NEXT_HOP_ATTR_ROUTER_INTERFACE_ID, + value=sai_thrift_attribute_value_t(oid=rif_id2)) + status = self.client.sai_thrift_set_next_hop_attribute(nhop, [rif_attribute2]) + assert(status == 0) + + # get the new value to check if it's right + resp = self.client.sai_thrift_get_next_hop_attribute(nhop, 1, [rif_attribute]) + assert(resp.status == 0) + assert(resp.attributes[0].value.oid == rif_id2) + +# TODO: ip get/set + + self.client.sai_thrift_remove_next_hop(nhop) + self.client.sai_thrift_remove_router_interface(rif_id) + self.client.sai_thrift_remove_router_interface(rif_id2) + self.client.sai_thrift_remove_virtual_router(vr_id) + +class InterfaceGetSetTest(sai_base_test.ThriftInterfaceDataPlane): + def runTest(self): + switch_init(self.client) + port1 = port_list[1] + v4_enabled = 1 + v6_enabled = 1 + v6_disabled = 0 + mac_valid = 0 + mac = '00:11:22:33:44:55' + + vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) + port_rif_id = sai_thrift_create_router_interface(self.client, vr_id, 1, port1, 0, v4_enabled, v6_enabled, mac) + + # test gets -- these fields are read only + # vr_id + vr_id_attribute = sai_thrift_attribute_t(id=SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID) + resp = self.client.sai_thrift_get_router_interface_attribute(port_rif_id, 1, [vr_id_attribute]) + assert(resp.status == 0) + assert(resp.attributes[0].value.oid == vr_id) + + # port_id + port_id_attribute = sai_thrift_attribute_t(id=SAI_ROUTER_INTERFACE_ATTR_PORT_ID) + resp = self.client.sai_thrift_get_router_interface_attribute(port_rif_id, 1, [port_id_attribute]) + assert(resp.status == 0) + assert(resp.attributes[0].value.oid == port1) + + # need to create a new interface of type vlan to test vlan id get + # first delete the old interface + self.client.sai_thrift_remove_router_interface(port_rif_id) + + vlan_id = 10 + self.client.sai_thrift_create_vlan(vlan_id) + vlan_rif_id = sai_thrift_create_router_interface(self.client, vr_id, 0, 0, vlan_id, v4_enabled, v6_enabled, mac) + + vlan_id_attribute = sai_thrift_attribute_t(id=SAI_ROUTER_INTERFACE_ATTR_VLAN_ID) + resp = self.client.sai_thrift_get_router_interface_attribute(vlan_rif_id, 1, [vlan_id_attribute]) + assert(resp.status == 0) + assert(resp.attributes[0].value.u16 == vlan_id) + +# TODO: mac get/set + + self.client.sai_thrift_remove_router_interface(vlan_rif_id) + self.client.sai_thrift_remove_virtual_router(vr_id) + +class PortGetSetTest(sai_base_test.ThriftInterfaceDataPlane): + def runTest(self): + pass + +class HostIfTest(sai_base_test.ThriftInterfaceDataPlane): + def runTest(self): + print + switch_init(self.client) + port1 = port_list[1] + v4_enabled = 1 + v6_enabled = 1 + mac_valid = 0 + mac = '' + l2_qid = 1 + l2_policer = 2 + l3_qid = 3 + l3_policer = 4 + + vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) + + rif_id1 = sai_thrift_create_router_interface(self.client, vr_id, 1, port1, 0, v4_enabled, v6_enabled, mac) + + l2_trap_group = sai_thrift_create_hostif_trap_group(self.client, l2_qid, l2_policer) + l3_trap_group = sai_thrift_create_hostif_trap_group(self.client, l3_qid, l3_policer) + + try: + sai_thrift_create_hostif_trap( + self.client, + SAI_HOSTIF_TRAP_ID_ARP_REQUEST, + SAI_PACKET_ACTION_TRAP, + 1000, SAI_HOSTIF_TRAP_CHANNEL_CB, + l2_trap_group) + + sai_thrift_create_hostif_trap( + self.client, + SAI_HOSTIF_TRAP_ID_ARP_RESPONSE, + SAI_PACKET_ACTION_TRAP, + 1001, + SAI_HOSTIF_TRAP_CHANNEL_CB, + l2_trap_group) + + sai_thrift_create_hostif_trap( + self.client, + SAI_HOSTIF_TRAP_ID_STP, + SAI_PACKET_ACTION_TRAP, + 1002, + SAI_HOSTIF_TRAP_CHANNEL_CB, + l2_trap_group) + + sai_thrift_create_hostif_trap( + self.client, + SAI_HOSTIF_TRAP_ID_OSPF, + SAI_PACKET_ACTION_LOG, + 1003, + SAI_HOSTIF_TRAP_CHANNEL_CB, + l3_trap_group) + + sai_thrift_create_hostif_trap( + self.client, + SAI_HOSTIF_TRAP_ID_PIM, + SAI_PACKET_ACTION_LOG, + 1004, + SAI_HOSTIF_TRAP_CHANNEL_CB, + l3_trap_group) + + sai_thrift_create_hostif_trap( + self.client, + SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT, + SAI_PACKET_ACTION_LOG, + 1004, + SAI_HOSTIF_TRAP_CHANNEL_CB, + l3_trap_group) + + pkt = simple_arp_packet(arp_op=1, pktlen=100) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x201, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending ARP request broadcast' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_arp_packet(arp_op=2, eth_dst='00:77:66:55:44:33', pktlen=100) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x202, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending ARP response' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.5') + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x204, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending OSPF packet destined to 224.0.0.5' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.6') + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x204, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending OSPF packet destined to 224.0.0.6' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=2) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x108, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending IGMP v2 report' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_ip_packet(ip_proto=103) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x205, + ingress_bd=2, + inner_pkt = pkt) + + print 'Sending PIM packet' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + pkt = simple_eth_packet(eth_dst='01:80:C2:00:00:00', pktlen=100) + exp_pkt = simple_cpu_packet(ingress_port=1, + ingress_ifindex=2, + reason_code=0x100, + ingress_bd=2, + inner_pkt = pkt) + print 'Sending STP packet' + send_packet(self, 1, str(pkt)) + verify_packets(self, exp_pkt, [cpu_port]) + + print 'Deleting hostif reason codes Arp Request/Resp, OSPF, PIM, IGMP and STP' + self.client.sai_thrift_remove_hostif_trap(SAI_HOSTIF_TRAP_ID_ARP_REQUEST) + self.client.sai_thrift_remove_hostif_trap(SAI_HOSTIF_TRAP_ID_ARP_RESPONSE) + self.client.sai_thrift_remove_hostif_trap(SAI_HOSTIF_TRAP_ID_STP) + self.client.sai_thrift_remove_hostif_trap(SAI_HOSTIF_TRAP_ID_OSPF) + self.client.sai_thrift_remove_hostif_trap(SAI_HOSTIF_TRAP_ID_PIM) + self.client.sai_thrift_remove_hostif_trap(SAI_HOSTIF_TRAP_ID_IGMP_TYPE_V2_REPORT) + + print 'Sending ARP request broadcast' + pkt = simple_arp_packet(arp_op=1, pktlen=100) + send_packet(self, 1, str(pkt)) + + print 'Sending OSPF packet destined to 224.0.0.5' + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.5') + send_packet(self, 1, str(pkt)) + + print 'Sending OSPF packet destined to 224.0.0.6' + pkt = simple_ip_packet(ip_proto=89, ip_dst='224.0.0.6') + send_packet(self, 1, str(pkt)) + + print 'Sending IGMP v2 report' + pkt = simple_ip_packet(ip_proto=2) + send_packet(self, 1, str(pkt)) + + print 'Sending PIM packet' + pkt = simple_ip_packet(ip_proto=103) + send_packet(self, 1, str(pkt)) + + print 'Sending STP packet' + pkt = simple_eth_packet(eth_dst='01:80:C2:00:00:00', pktlen=100) + send_packet(self, 1, str(pkt)) + + verify_no_other_packets(self, timeout=1) + + finally: + self.client.sai_thrift_remove_hostif_trap_group(l2_trap_group) + self.client.sai_thrift_remove_hostif_trap_group(l3_trap_group) + + self.client.sai_thrift_remove_router_interface(rif_id1) + + self.client.sai_thrift_remove_virtual_router(vr_id) diff --git a/tests/ptf-tests/sai-tests/switch_qos.py b/tests/ptf-tests/sai-tests/switch_qos.py new file mode 100644 index 0000000..5871a34 --- /dev/null +++ b/tests/ptf-tests/sai-tests/switch_qos.py @@ -0,0 +1,145 @@ +# Copyright 2013-present Barefoot Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Thrift SAI interface basic tests +""" + +import switch_sai_thrift + +import time +import sys +import logging + +import unittest +import random + +import sai_base_test + +from ptf import config +from ptf.testutils import * +from ptf.thriftutils import * + +import os + +from switch_sai_thrift.ttypes import * +from switch_sai_thrift.sai_headers import * + +this_dir = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(os.path.join(this_dir, '..')) +from common.utils import * +from common.sai_utils import * + +from erspan3 import * + +this_dir = os.path.dirname(os.path.abspath(__file__)) + +switch_inited=0 +port_list = [] +table_attr_list = [] + +def switch_init(client): + global switch_inited + if switch_inited: + return + + switch_attr_list = client.sai_thrift_get_switch_attribute() + attr_list = switch_attr_list.attr_list + for attribute in attr_list: + if attribute.id == 0: + print "max ports: " + attribute.value.u32 + elif attribute.id == 1: + for x in attribute.value.objlist.object_id_list: + port_list.append(x) + else: + print "unknown switch attribute" + + attr_value = sai_thrift_attribute_value_t(mac='00:77:66:55:44:33') + attr = sai_thrift_attribute_t(id=SAI_SWITCH_ATTR_SRC_MAC_ADDRESS, value=attr_value) + client.sai_thrift_set_switch_attribute(attr) + switch_inited = 1 + +class L3IPv4QosDscpRewriteTest(sai_base_test.ThriftInterfaceDataPlane): + def runTest(self): + print + 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] + v4_enabled = 1 + v6_enabled = 1 + mac_valid = 0 + mac = '' + + vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) + + rif_id1 = sai_thrift_create_router_interface(self.client, vr_id, 1, port1, 0, v4_enabled, v6_enabled, mac) + 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_IPV4 + ip_addr1 = '10.10.10.1' + ip_mask1 = '255.255.255.255' + dmac1 = '00:11:22:33:44:55' + nhop1 = sai_thrift_create_nhop(self.client, addr_family, ip_addr1, rif_id1) + sai_thrift_create_route(self.client, vr_id, addr_family, ip_addr1, ip_mask1, nhop1) + sai_thrift_create_neighbor(self.client, addr_family, rif_id1, ip_addr1, dmac1) + + ingress_dscp_list = [1, 2, 3, 4] + ingress_tc_list = [11, 12, 13, 14] + ingress_qos_map_id = sai_thrift_create_qos_map(self.client, SAI_QOS_MAP_DSCP_TO_TC, ingress_dscp_list, ingress_tc_list) + + ingress_tc_list = [11, 12, 13, 14] + ingress_queue_list = [1, 2, 3, 4] + tc_qos_map_id = sai_thrift_create_qos_map(self.client, SAI_QOS_MAP_TC_TO_QUEUE, ingress_tc_list, ingress_queue_list) + + egress_tc_and_color_list = [[11, 0], [12, 0], [13, 0,], [14, 0]] + egress_dscp_list = [10, 20, 30, 40] + egress_qos_map_id = sai_thrift_create_qos_map(self.client, SAI_QOS_MAP_TC_AND_COLOR_TO_DSCP, egress_tc_and_color_list, egress_dscp_list) + + sai_thrift_set_port_attribute(self.client, port1, SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP, ingress_qos_map_id) + sai_thrift_set_port_attribute(self.client, port1, SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP, tc_qos_map_id) + sai_thrift_set_port_attribute(self.client, port1, SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP, egress_qos_map_id) + + sai_thrift_set_port_attribute(self.client, port2, SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP, ingress_qos_map_id) + sai_thrift_set_port_attribute(self.client, port2, SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP, tc_qos_map_id) + sai_thrift_set_port_attribute(self.client, port2, SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP, egress_qos_map_id) + + # send the test packet(s) + 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_tos=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_tos=10, + ip_id=105, + ip_ttl=63) + try: + send_packet(self, 2, str(pkt)) + verify_packets(self, exp_pkt, [1]) + finally: + sai_thrift_remove_neighbor(self.client, addr_family, rif_id1, ip_addr1, dmac1) + sai_thrift_remove_route(self.client, vr_id, addr_family, ip_addr1, ip_mask1, nhop1) + self.client.sai_thrift_remove_next_hop(nhop1) + + self.client.sai_thrift_remove_router_interface(rif_id1) + self.client.sai_thrift_remove_router_interface(rif_id2) + + self.client.sai_thrift_remove_virtual_router(vr_id) diff --git a/third-party/.clang-format b/third-party/.clang-format new file mode 100644 index 0000000..ac2aa81 --- /dev/null +++ b/third-party/.clang-format @@ -0,0 +1,3 @@ +--- +DisableFormat : true +... From 4fdf4457c7c4b5da2ea819b7121d1b40abc72fb9 Mon Sep 17 00:00:00 2001 From: krishna Date: Fri, 16 Sep 2016 14:00:14 -0700 Subject: [PATCH 6/7] typo in switchapi makefile --- switchapi/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/switchapi/Makefile.am b/switchapi/Makefile.am index 22a40cb..2a1347c 100644 --- a/switchapi/Makefile.am +++ b/switchapi/Makefile.am @@ -86,7 +86,7 @@ src/switch_pd_queue.c \ src/switch_pd_types.h \ src/switch_port.c \ src/switch_port_int.h \ -src/switch_qos.x \ +src/switch_qos.c \ src/switch_qos_int.h \ src/switch_queue.c \ src/switch_queue_int.h \ From ebbbd14a62f544bf110b6abaa5ce1d77f9057456 Mon Sep 17 00:00:00 2001 From: srikrishnagopu Date: Mon, 3 Oct 2016 12:45:13 -0700 Subject: [PATCH 7/7] Merge master to ops (#67) --- .travis.yml | 105 +++ CI/travis/install-bmv2.sh | 12 + CI/travis/install-p4c-bmv2.sh | 8 + CI/travis/install-p4ofagent.sh | 17 + CI/travis/install-ptf.sh | 6 + CI/travis/run_of_tests.sh | 5 + CI/travis/run_switch_tests.sh | 17 + CI/travis/veth_setup.sh | 38 + Makefile.am | 1 - bmv2/.gitignore | 8 + bmv2/Makefile.am | 39 + bmv2/bmv2_init.c | 105 +++ bmv2/dummy.p4 | 0 bmv2/main.c | 88 ++ bmv2/run_bm.sh.in | 16 + bmv2/run_drivers.sh.in | 11 + bmv2/run_of_tests.sh.in | 7 + bmv2/run_tests.sh.in | 10 + bmv2/split_pd_thrift.py | 53 ++ m4/adl_recursive_eval.m4 | 15 + m4/ax_prog_doxygen.m4 | 585 +++++++++++++ m4/ax_restore_flags.m4 | 31 + m4/ax_save_flags.m4 | 31 + openflow_mapping/l2.py | 12 + openflow_mapping/mapping_common.py | 10 + p4src/LICENSE | 177 ++++ p4src/acl.p4 | 278 ++++++- p4src/fabric.p4 | 1 + p4src/includes/drop_reasons.h | 55 -- p4src/includes/headers.p4 | 1 + p4src/includes/p4_table_sizes.h | 7 + p4src/includes/p4features.h | 10 + p4src/includes/parser.p4 | 15 - p4src/l2.p4 | 3 +- p4src/l3.p4 | 3 + p4src/meter.p4 | 16 +- p4src/openflow.p4 | 134 ++- p4src/p4_files.am | 29 + p4src/port.p4 | 3 +- p4src/switch.p4 | 14 +- p4src/tunnel.p4 | 7 + switchapi/Doxyfile | 2 +- switchapi/include/switchapi/switch_acl.h | 174 ++-- .../include/switchapi/switch_base_types.h | 2 +- switchapi/include/switchapi/switch_handle.h | 10 +- switchapi/src/switch_acl.c | 466 ++++++++--- switchapi/src/switch_acl_int.h | 7 + switchapi/src/switch_api.thrift | 26 +- switchapi/src/switch_api_rpc_server.cpp | 62 +- switchapi/src/switch_handle.c | 11 +- switchapi/src/switch_hostif.c | 92 ++- switchapi/src/switch_hostif_int.h | 6 +- switchapi/src/switch_init.c | 93 ++- switchapi/src/switch_nhop.c | 2 +- switchapi/src/switch_packet.c | 37 +- switchapi/src/switch_pd.c | 775 ++++++++++++++++-- switchapi/src/switch_pd.h | 87 +- switchapi/src/switch_port.c | 4 +- switchapi/src/switch_scheduler.c | 2 +- switchapi/src/switch_sflow.c | 4 +- switchlink/Makefile.am | 40 +- switchlink/configure.ac | 34 - switchsai/Makefile.am | 128 ++- switchsai/README.md | 2 + switchsai/src/sai.c | 3 + switchsai/src/saiacl.c | 629 ++++++++++---- switchsai/src/saiipmc.c | 3 +- switchsai/src/sail2mc.c | 3 +- switchsai/src/switch_sai.thrift | 10 + switchsai/src/switch_sai_rpc_server.cpp | 65 +- tests/of-tests/common/utils.py | 45 + tests/of-tests/openflow.py | 142 ++-- tests/ptf-tests/api-tests/switch.py | 226 ++--- tests/ptf-tests/api-tests/switch_acl.py | 330 +++++++- tests/ptf-tests/common/pd_utils.py | 41 +- tests/ptf-tests/common/sai_utils.py | 33 + tests/ptf-tests/common/utils.py | 24 +- tests/ptf-tests/sai-tests/switch.py | 200 ++++- tests/run_of_tests.py | 45 + tests/run_tests.py.in | 61 ++ testutils/erspan3.py | 38 + testutils/xnt.py | 75 ++ tools/veth_disable_ipv6.sh | 21 + tools/veth_setup.sh | 38 + tools/veth_teardown.sh | 21 + 85 files changed, 5149 insertions(+), 953 deletions(-) create mode 100644 .travis.yml create mode 100644 CI/travis/install-bmv2.sh create mode 100644 CI/travis/install-p4c-bmv2.sh create mode 100755 CI/travis/install-p4ofagent.sh create mode 100644 CI/travis/install-ptf.sh create mode 100755 CI/travis/run_of_tests.sh create mode 100755 CI/travis/run_switch_tests.sh create mode 100755 CI/travis/veth_setup.sh create mode 100644 bmv2/.gitignore create mode 100644 bmv2/Makefile.am create mode 100644 bmv2/bmv2_init.c create mode 100644 bmv2/dummy.p4 create mode 100644 bmv2/main.c create mode 100644 bmv2/run_bm.sh.in create mode 100644 bmv2/run_drivers.sh.in create mode 100644 bmv2/run_of_tests.sh.in create mode 100644 bmv2/run_tests.sh.in create mode 100644 bmv2/split_pd_thrift.py create mode 100644 m4/adl_recursive_eval.m4 create mode 100644 m4/ax_prog_doxygen.m4 create mode 100644 m4/ax_restore_flags.m4 create mode 100644 m4/ax_save_flags.m4 create mode 100644 openflow_mapping/l2.py create mode 100644 openflow_mapping/mapping_common.py create mode 100644 p4src/LICENSE delete mode 100644 p4src/includes/drop_reasons.h create mode 100644 p4src/p4_files.am delete mode 100644 switchlink/configure.ac create mode 100644 tests/of-tests/common/utils.py create mode 100755 tests/run_of_tests.py create mode 100755 tests/run_tests.py.in create mode 100644 testutils/erspan3.py create mode 100644 testutils/xnt.py create mode 100755 tools/veth_disable_ipv6.sh create mode 100755 tools/veth_setup.sh create mode 100755 tools/veth_teardown.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0c578ef --- /dev/null +++ b/.travis.yml @@ -0,0 +1,105 @@ +# Config file for automatic testing at travis-ci.org + +sudo: required + +dist: trusty + +language: c + +# My very smart trick to force inclusion of the veth kernel module +# (even though we do not use docker at all her) +services: + - docker + +env: + global: + - PYP_ADD="/usr/local/lib/python2.7/dist-packages:/usr/local/lib/python2.7/site-packages" + matrix: + - TEST_SCENARIO=switch + - TEST_SCENARIO=of + +# There is probably some redundant stuff in this list. If you find one, remove +# it +addons: + apt: + packages: + - libjudy-dev + - libgmp-dev + - libpcap-dev + - libboost-dev + - libboost-test-dev + - libboost-program-options-dev + - libboost-system-dev + - libboost-filesystem-dev + - libboost-thread-dev + - libboost-test-dev + - libevent-dev + - automake + - libtool + - flex + - bison + - pkg-config + - g++ + - libssl-dev + - doxygen + - git + - libedit-dev + - libevent-dev + - libfreetype6-dev + - libpng-dev + - libyaml-0-2 + - libbz2-dev + - libnl-route-3-dev + - openssl + - pkg-config + - python-dev + - python-matplotlib + - python-numpy + - python-pip + - python-scipy + - python-setuptools + - python-yaml + +# need to replace github ssh references with https +before_install: + - git submodule update --init --recursive + - sudo apt-get install ethtool + - sudo pip install --upgrade pip + - sudo pip install --upgrade thrift + - sudo pip install ctypesgen + - sudo pip install crc16 + +# install bmv2 before p4c-bmv2 to get nanomsg +install: + - wget https://s3-us-west-2.amazonaws.com/p4lang/thrift_bin.tar.gz + - tar -xzvf thrift_bin.tar.gz -C $HOME/ + - export PATH=$PATH:$HOME/thrift/bin/ + - export LDFLAGS="$LDFLAGS -L$HOME/thrift/lib" + - export CPPFLAGS="$CPPFLAGS -I$HOME/thrift/include" + - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/thrift/lib + - mkdir install_tmp && cd install_tmp/ + - sudo apt-get remove python-scapy + - git clone https://github.com/p4lang/scapy-vxlan.git && cd scapy-vxlan && sudo python setup.py install && cd .. + - cd .. && sudo rm -rf install_tmp/ + - bash CI/travis/install-ptf.sh + - bash CI/travis/install-bmv2.sh + - bash CI/travis/install-p4c-bmv2.sh + - bash CI/travis/install-p4ofagent.sh + - export CPPFLAGS="$CPPFLAGS -I$HOME/p4ofagent/include" + - export LDFLAGS="$LDFLAGS -L$HOME/p4ofagent/lib" + - git clone https://github.com/floodlight/oftest.git oftest_tmp + - export PYTHONPATH=$PYP_ADD:$PYTHONPATH + - sudo ldconfig + - ./autogen.sh + +before_script: + - cp CI/travis/veth_setup.sh tools/ + - cd tools; sudo ./veth_setup.sh; sudo ./veth_disable_ipv6.sh; cd .. + +script: + - if [ "$TEST_SCENARIO" = "switch" ] ; then ./configure --with-bmv2 --with-switchsai; fi + - if [ "$TEST_SCENARIO" = "of" ] ; then ./configure --with-bmv2 --with-of; fi + - make -j2 + - if [ "$TEST_SCENARIO" = "switch" ] ; then ./CI/travis/run_switch_tests.sh; fi + - if [ "$TEST_SCENARIO" = "of" ] ; then ./CI/travis/run_of_tests.sh; fi + diff --git a/CI/travis/install-bmv2.sh b/CI/travis/install-bmv2.sh new file mode 100644 index 0000000..051197d --- /dev/null +++ b/CI/travis/install-bmv2.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +git clone https://github.com/p4lang/behavioral-model.git bmv2_tmp +cd bmv2_tmp +bash travis/install-nanomsg.sh +sudo ldconfig +bash travis/install-nnpy.sh +./autogen.sh +./configure 'CXXFLAGS=-O0' --with-pdfixed +make -j2 && sudo make install +cd .. +rm -rf bmv2_tmp diff --git a/CI/travis/install-p4c-bmv2.sh b/CI/travis/install-p4c-bmv2.sh new file mode 100644 index 0000000..97de97c --- /dev/null +++ b/CI/travis/install-p4c-bmv2.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e +git clone https://github.com/p4lang/p4c-bm.git p4c-bmv2 +cd p4c-bmv2 +git submodule update --init --recursive +sudo pip install -r requirements.txt +sudo python setup.py install +cd .. diff --git a/CI/travis/install-p4ofagent.sh b/CI/travis/install-p4ofagent.sh new file mode 100755 index 0000000..1dbdcfa --- /dev/null +++ b/CI/travis/install-p4ofagent.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e +git clone https://github.com/p4lang/p4ofagent.git p4ofagent_tmp +cd p4ofagent_tmp +git submodule update --init +cd submodules/indigo/ +find -name ".gitmodules" -type f -exec sed -i 's/git@github.com:/https:\/\/github.com\//' {} \; +git submodule update --init +cd submodules/bigcode/ +find -name ".gitmodules" -type f -exec sed -i 's/git@github.com:/https:\/\/github.com\//' {} \; +cd ../../../../ +./autogen.sh +./configure --prefix=$HOME/p4ofagent +make p4ofagent CPPFLAGS="-D_BMV2_ -I$HOME/bmv2/include" +make install +cd .. +rm -rf p4ofagent_tmp diff --git a/CI/travis/install-ptf.sh b/CI/travis/install-ptf.sh new file mode 100644 index 0000000..77bf840 --- /dev/null +++ b/CI/travis/install-ptf.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +git clone https://github.com/p4lang/ptf.git +cd ptf +sudo python setup.py install +cd .. diff --git a/CI/travis/run_of_tests.sh b/CI/travis/run_of_tests.sh new file mode 100755 index 0000000..51da75f --- /dev/null +++ b/CI/travis/run_of_tests.sh @@ -0,0 +1,5 @@ +sudo ./bmv2/run_bm.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_drivers.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_of_tests.sh --oft-path oftest_tmp/oft diff --git a/CI/travis/run_switch_tests.sh b/CI/travis/run_switch_tests.sh new file mode 100755 index 0000000..03a549f --- /dev/null +++ b/CI/travis/run_switch_tests.sh @@ -0,0 +1,17 @@ +sudo ./bmv2/run_bm.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_drivers.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_tests.sh --test-dir tests/ptf-tests/api-tests +sudo killall bmswitchp4_drivers lt-bmswitchp4_drivers simple_switch lt-simple_switch; echo 0 +sudo ./bmv2/run_bm.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_drivers.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_tests.sh --test-dir tests/ptf-tests/sai-tests +sudo killall bmswitchp4_drivers lt-bmswitchp4_drivers simple_switch lt-simple_switch; echo 0 +sudo ./bmv2/run_bm.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_drivers.sh &>/dev/null & +sleep 10 +sudo ./bmv2/run_tests.sh diff --git a/CI/travis/veth_setup.sh b/CI/travis/veth_setup.sh new file mode 100755 index 0000000..5d53e1d --- /dev/null +++ b/CI/travis/veth_setup.sh @@ -0,0 +1,38 @@ +#!/bin/bash +noOfVeths=18 +if [ $# -eq 1 ]; then + noOfVeths=$1 +fi +echo "No of Veths is $noOfVeths" +idx=0 +let "vethpairs=$noOfVeths/2" +while [ $idx -lt $vethpairs ] +do +#1 2 3 4 5 6 7 125 + intf0="veth$(($idx*2))" + intf1="veth$(($idx*2+1))" + idx=$((idx + 1)) + if ! ip link show $intf0 &> /dev/null; then + ip link add name $intf0 type veth peer name $intf1 + ip link set dev $intf0 up + ip link set dev $intf1 up + TOE_OPTIONS="rx tx sg tso ufo gso gro rxvlan txvlan" + for TOE_OPTION in $TOE_OPTIONS; do + /sbin/ethtool --offload $intf0 "$TOE_OPTION" off + /sbin/ethtool --offload $intf1 "$TOE_OPTION" off + done + fi +done +idx=125 +intf0="veth$(($idx*2))" +intf1="veth$(($idx*2+1))" +if ! ip link show $intf0 &> /dev/null; then + ip link add name $intf0 type veth peer name $intf1 + ip link set dev $intf0 up + ip link set dev $intf1 up + TOE_OPTIONS="rx tx sg tso ufo gso gro rxvlan txvlan" + for TOE_OPTION in $TOE_OPTIONS; do + /sbin/ethtool --offload $intf0 "$TOE_OPTION" off + /sbin/ethtool --offload $intf1 "$TOE_OPTION" off + done +fi diff --git a/Makefile.am b/Makefile.am index 977a684..0fe7298 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,3 @@ ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -# P4FLAGS = -I . SUBDIRS = p4src switchapi switchsai switchlink diff --git a/bmv2/.gitignore b/bmv2/.gitignore new file mode 100644 index 0000000..51ad7f3 --- /dev/null +++ b/bmv2/.gitignore @@ -0,0 +1,8 @@ +# This scripts are generated by configure +run_bm.sh +run_drivers.sh +run_tests.sh + +gen-py.tar.lz +p4_pd +switch.json diff --git a/bmv2/Makefile.am b/bmv2/Makefile.am new file mode 100644 index 0000000..9eb67a3 --- /dev/null +++ b/bmv2/Makefile.am @@ -0,0 +1,39 @@ +ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 + +AM_CPPFLAGS += -DBMV2 +AM_CPPFLAGS += -I$(top_builddir)/p4-build +AM_CPPFLAGS += -isystem$(includedir) + +lib_LTLIBRARIES = libbmswitchp4.la +libbmswitchp4_la_CPPFLAGS = $(AM_CPPFLAGS) +libbmswitchp4_la_LIBADD = +if WITH_SWITCHLINK +libbmswitchp4_la_LIBADD += @top_builddir@/switchlink/libswitchlink.la +endif +if WITH_SWITCHSAI +libbmswitchp4_la_LIBADD += @top_builddir@/switchsai/libbmswitchsai.la +endif +if WITH_SWITCHAPI +libbmswitchp4_la_LIBADD += @top_builddir@/switchapi/libbmswitchapi.la +endif +if WITH_OF +libbmswitchp4_la_LIBADD += @top_builddir@/p4-build/bmv2/libof.la +endif +libbmswitchp4_la_LIBADD += \ +@top_builddir@/p4-build/bmv2/libpd.la \ +@top_builddir@/p4-build/bmv2/libpdthrift.la \ +-lbmpdfixed -lbmpdfixedthrift $(THRIFT_LIB) +libbmswitchp4_la_SOURCES = \ +bmv2_init.c + +bin_PROGRAMS = bmswitchp4_drivers +bmswitchp4_drivers_CPPFLAGS = $(AM_CPPFLAGS) +bmswitchp4_drivers_LDADD = \ +libbmswitchp4.la +if WITH_OF +bmswitchp4_drivers_LDADD += \ +-lp4ofagent @top_builddir@/p4-build/bmv2/libof.la \ +-lbmpdfixed -lpthread -lm +endif +bmswitchp4_drivers_SOURCES = \ +main.c diff --git a/bmv2/bmv2_init.c b/bmv2/bmv2_init.c new file mode 100644 index 0000000..eeba72c --- /dev/null +++ b/bmv2/bmv2_init.c @@ -0,0 +1,105 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +char *pd_server_str = NULL; +char *of_controller_str = NULL; +int of_ipv6 = 0; + +/** + * The maximum number of ports to support: + * @fixme should be runtime parameter + */ +#define PORT_COUNT 256 +#define PD_SERVER_DEFAULT_PORT 9090 + +/** + * Check an operation and return if there's an error. + */ +#define CHECK(op) \ + do { \ + int _rv; \ + if ((_rv = (op)) < 0) { \ + fprintf(stderr, "%s: ERROR %d at %s:%d", \ + #op, _rv, __FILE__, __LINE__); \ + return _rv; \ + } \ + } while (0) + +#ifdef SWITCHLINK_ENABLE +extern int switchlink_init(void); +#endif /* SWITCHLINK_ENABLE */ + +#ifdef SWITCHAPI_ENABLE +extern int switch_api_init(int device, unsigned int num_ports); +extern int start_switch_api_rpc_server(void); +extern int start_switch_api_packet_driver(void); +#endif /* SWITCHAPI_ENABLE */ + +#ifdef SWITCHSAI_ENABLE +#define SWITCH_SAI_THRIFT_RPC_SERVER_PORT "9092" +extern int start_p4_sai_thrift_rpc_server(char * port); +#endif /* SWITCHSAI_ENABLE */ + +#ifdef OPENFLOW_ENABLE +extern void p4ofagent_init(bool ipv6, char *ip_ctl); +#endif + +int +bmv2_model_init() { + int rv=0; + /* Start up the PD RPC server */ + void *pd_server_cookie; + start_bfn_pd_rpc_server(&pd_server_cookie); + add_to_rpc_server(pd_server_cookie); + + p4_pd_init(); + p4_pd_dc_init(); + p4_pd_dc_assign_device(0, "ipc:///tmp/bmv2-0-notifications.ipc", 10001); + + /* Start up the API RPC server */ +#ifdef SWITCHAPI_ENABLE + CHECK(switch_api_init(0, 256)); + CHECK(start_switch_api_rpc_server()); + CHECK(start_switch_api_packet_driver()); +#endif /* SWITCHAPI_DISABLE */ + +#ifdef SWITCHSAI_ENABLE + CHECK(start_p4_sai_thrift_rpc_server(SWITCH_SAI_THRIFT_RPC_SERVER_PORT)); +#endif /*SWITCHSAI_ENABLE */ + +#ifdef SWITCHLINK_ENABLE + CHECK(switchlink_init()); +#endif /* SWITCHLINK_ENABLE */ + +#ifdef OPENFLOW_ENABLE + p4ofagent_init(of_ipv6, of_controller_str); +#endif + + return rv; +} diff --git a/bmv2/dummy.p4 b/bmv2/dummy.p4 new file mode 100644 index 0000000..e69de29 diff --git a/bmv2/main.c b/bmv2/main.c new file mode 100644 index 0000000..66f3834 --- /dev/null +++ b/bmv2/main.c @@ -0,0 +1,88 @@ +/* +Copyright 2013-present Barefoot Networks, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern char *pd_server_str; +extern char *of_controller_str; +extern int of_ipv6; + +extern int bmv2_model_init(); + +static void +parse_options(int argc, char **argv) +{ + while (1) { + int option_index = 0; + /* Options without short equivalents */ + enum long_opts { + OPT_START = 256, + OPT_PDSERVER, + OPT_OFIP, + OPT_OFIPV6, + }; + static struct option long_options[] = { + {"help", no_argument, 0, 'h' }, + {"pd-server", required_argument, 0, OPT_PDSERVER }, + {"of-ip", required_argument, 0, OPT_OFIP }, + {"of-ipv6", no_argument, 0, OPT_OFIPV6 }, + {0, 0, 0, 0 } + }; + int c = getopt_long(argc, argv, "h", + long_options, &option_index); + if (c == -1) { + break; + } + switch (c) { + case OPT_PDSERVER: + pd_server_str = strdup(optarg); + break; + case 'h': + case '?': + printf("Drivers! \n"); + printf("Usage: drivers [OPTION]...\n"); + printf("\n"); + printf(" --pd-server=IP:PORT Listen for PD RPC calls\n"); + printf(" -h,--help Display this help message and exit\n"); + exit(c == 'h' ? 0 : 1); + break; + } + } +} + +int +main(int argc, char* argv[]) +{ + int rv = 0; + + parse_options(argc, argv); + + bmv2_model_init(); + + while (1) pause(); + + return rv; +} diff --git a/bmv2/run_bm.sh.in b/bmv2/run_bm.sh.in new file mode 100644 index 0000000..4acf586 --- /dev/null +++ b/bmv2/run_bm.sh.in @@ -0,0 +1,16 @@ +#!/bin/bash +if [[ $EUID -ne 0 ]]; then + echo "This script should be run using sudo or as the root user" + exit 1 +fi +if [ x@BM_SIMPLE_SWITCH@ = x ]; then + echo "simple_switch executable not found by latest configure run" + echo "have you installed bmv2 since? if yes, you need to run configure again" + exit 1 +fi +JSON_FILE=@abs_top_builddir@/p4-build/bmpd/switch.json +if [ ! -f $JSON_FILE ]; then + echo "switch.json not found; did you run 'make'?" + exit 1 +fi +@BM_SIMPLE_SWITCH@ --log-console -i 0@veth0 -i 1@veth2 -i 2@veth4 -i 3@veth6 -i 4@veth8 -i 5@veth10 -i 6@veth12 -i 7@veth14 -i 8@veth16 -i 64@veth250 --thrift-port 10001 --pcap $JSON_FILE diff --git a/bmv2/run_drivers.sh.in b/bmv2/run_drivers.sh.in new file mode 100644 index 0000000..83419b3 --- /dev/null +++ b/bmv2/run_drivers.sh.in @@ -0,0 +1,11 @@ +#!/bin/bash +if [[ $EUID -ne 0 ]]; then + echo "This script should be run using sudo or as the root user" + exit 1 +fi +DRIVERS_EXE=@abs_builddir@/bmswitchp4_drivers +if [ ! -f $DRIVERS_EXE ]; then + echo "bmswitchp4_drivers not found; did you run 'make'?" + exit 1 +fi +$DRIVERS_EXE diff --git a/bmv2/run_of_tests.sh.in b/bmv2/run_of_tests.sh.in new file mode 100644 index 0000000..4cebf22 --- /dev/null +++ b/bmv2/run_of_tests.sh.in @@ -0,0 +1,7 @@ +#!/bin/bash +if [[ $EUID -ne 0 ]]; then + echo "This script should be run using sudo or as the root user" + exit 1 +fi +export PYTHONPATH=@MY_PYTHONPATH@/bm/pdfixed:$PYTHONPATH +@PYTHON@ @abs_top_builddir@/tests/run_of_tests.py $* diff --git a/bmv2/run_tests.sh.in b/bmv2/run_tests.sh.in new file mode 100644 index 0000000..4553703 --- /dev/null +++ b/bmv2/run_tests.sh.in @@ -0,0 +1,10 @@ +#!/bin/bash +if [[ $EUID -ne 0 ]]; then + echo "This script should be run using sudo or as the root user" + exit 1 +fi +PD_THRIFT_PY=@abs_top_builddir@/p4-build/bmv2/pd_thrift_gen/gen-py +@PYTHON@ @abs_top_builddir@/tests/run_tests.py \ + --pd-thrift $PD_THRIFT_PY \ + --pd-thrift @MY_PYTHONPATH@/bm/pdfixed \ + $* diff --git a/bmv2/split_pd_thrift.py b/bmv2/split_pd_thrift.py new file mode 100644 index 0000000..5ed25ca --- /dev/null +++ b/bmv2/split_pd_thrift.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +import os +import subprocess +import sys + +def get_output_file_name(output_dir, output_file_num): + return os.path.join(output_dir, 'p4_prefix%d.cpp' % output_file_num) + +def split_pd_thrift(input_file_name, output_dir, num_output_files): + num_input_lines = int(subprocess.check_output( + 'wc -l %s | awk \'{print $1}\'' % input_file_name, + shell=True)) + for output_file_num in range(num_output_files): + output_file_name = get_output_file_name(output_dir, output_file_num) + os.system('grep "^#include" %s > %s' % (input_file_name, + output_file_name)) + os.system('grep namespace\ p4_pd_rpc %s >> %s' % (input_file_name, + output_file_name)) + + output_file_num = 0 + end_namespace = '} // namespace' + output_line_num = 0 + with open(input_file_name) as input_file: + for line in input_file: + if line == 'namespace p4_pd_rpc {\n': + break + for line in input_file: + if output_line_num == 0 and output_file_num < num_output_files: # { + output_file_name = get_output_file_name(output_dir, + output_file_num) + output_file = open(output_file_name, "a") + output_file_num += 1 + # } + output_file.write(line) + output_line_num += 1 + if line == end_namespace: + # Reached the end of the namespace (last line in file) + break + elif (output_line_num > (num_input_lines / num_output_files)) and \ + (line == '}\n'): # { + # Reached end of function. close the file + output_file.write('%s\n' % end_namespace) + output_file.close() + output_line_num = 0 + # } + + +if __name__ == '__main__': + assert len(sys.argv) == 4 + input_file_name = sys.argv[1] + output_dir = sys.argv[2] + num_output_files = sys.argv[3] + split_pd_thrift(input_file_name, output_dir, int(num_output_files)) diff --git a/m4/adl_recursive_eval.m4 b/m4/adl_recursive_eval.m4 new file mode 100644 index 0000000..56bf672 --- /dev/null +++ b/m4/adl_recursive_eval.m4 @@ -0,0 +1,15 @@ +dnl adl_RECURSIVE_EVAL(VALUE, RESULT) +dnl ================================= +dnl Interpolate the VALUE in loop until it doesn't change, +dnl and set the result to $RESULT. +dnl WARNING: It's easy to get an infinite loop with some unsane input. +AC_DEFUN([adl_RECURSIVE_EVAL], +[_lcl_receval="$1" +$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" + _lcl_receval_old='' + while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do + _lcl_receval_old="[$]_lcl_receval" + eval _lcl_receval="\"[$]_lcl_receval\"" + done + echo "[$]_lcl_receval")`]) diff --git a/m4/ax_prog_doxygen.m4 b/m4/ax_prog_doxygen.m4 new file mode 100644 index 0000000..b2a899f --- /dev/null +++ b/m4/ax_prog_doxygen.m4 @@ -0,0 +1,585 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html +# =========================================================================== +# +# SYNOPSIS +# +# DX_INIT_DOXYGEN(PROJECT-NAME, [DOXYFILE-PATH], [OUTPUT-DIR], ...) +# DX_DOXYGEN_FEATURE(ON|OFF) +# DX_DOT_FEATURE(ON|OFF) +# DX_HTML_FEATURE(ON|OFF) +# DX_CHM_FEATURE(ON|OFF) +# DX_CHI_FEATURE(ON|OFF) +# DX_MAN_FEATURE(ON|OFF) +# DX_RTF_FEATURE(ON|OFF) +# DX_XML_FEATURE(ON|OFF) +# DX_PDF_FEATURE(ON|OFF) +# DX_PS_FEATURE(ON|OFF) +# +# DESCRIPTION +# +# The DX_*_FEATURE macros control the default setting for the given +# Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for +# generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML +# help (for MS users), 'CHI' for generating a seperate .chi file by the +# .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate +# output formats. The environment variable DOXYGEN_PAPER_SIZE may be +# specified to override the default 'a4wide' paper size. +# +# By default, HTML, PDF and PS documentation is generated as this seems to +# be the most popular and portable combination. MAN pages created by +# Doxygen are usually problematic, though by picking an appropriate subset +# and doing some massaging they might be better than nothing. CHM and RTF +# are specific for MS (note that you can't generate both HTML and CHM at +# the same time). The XML is rather useless unless you apply specialized +# post-processing to it. +# +# The macros mainly control the default state of the feature. The use can +# override the default by specifying --enable or --disable. The macros +# ensure that contradictory flags are not given (e.g., +# --enable-doxygen-html and --enable-doxygen-chm, +# --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each +# feature will be automatically disabled (with a warning) if the required +# programs are missing. +# +# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN +# with the following parameters: a one-word name for the project for use +# as a filename base etc., an optional configuration file name (the +# default is '$(srcdir)/Doxyfile', the same as Doxygen's default), and an +# optional output directory name (the default is 'doxygen-doc'). To run +# doxygen multiple times for different configuration files and output +# directories provide more parameters: the second, forth, sixth, etc +# parameter are configuration file names and the third, fifth, seventh, +# etc parameter are output directories. No checking is done to catch +# duplicates. +# +# Automake Support +# +# The DX_RULES substitution can be used to add all needed rules to the +# Makefile. Note that this is a substitution without being a variable: +# only the @DX_RULES@ syntax will work. +# +# The provided targets are: +# +# doxygen-doc: Generate all doxygen documentation. +# +# doxygen-run: Run doxygen, which will generate some of the +# documentation (HTML, CHM, CHI, MAN, RTF, XML) +# but will not do the post processing required +# for the rest of it (PS, PDF). +# +# doxygen-ps: Generate doxygen PostScript documentation. +# +# doxygen-pdf: Generate doxygen PDF documentation. +# +# Note that by default these are not integrated into the automake targets. +# If doxygen is used to generate man pages, you can achieve this +# integration by setting man3_MANS to the list of man pages generated and +# then adding the dependency: +# +# $(man3_MANS): doxygen-doc +# +# This will cause make to run doxygen and generate all the documentation. +# +# The following variable is intended for use in Makefile.am: +# +# DX_CLEANFILES = everything to clean. +# +# Then add this variable to MOSTLYCLEANFILES. +# +# LICENSE +# +# Copyright (c) 2009 Oren Ben-Kiki +# Copyright (c) 2015 Olaf Mandel +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 19 + +## ----------## +## Defaults. ## +## ----------## + +DX_ENV="" +AC_DEFUN([DX_FEATURE_doc], ON) +AC_DEFUN([DX_FEATURE_dot], OFF) +AC_DEFUN([DX_FEATURE_man], OFF) +AC_DEFUN([DX_FEATURE_html], ON) +AC_DEFUN([DX_FEATURE_chm], OFF) +AC_DEFUN([DX_FEATURE_chi], OFF) +AC_DEFUN([DX_FEATURE_rtf], OFF) +AC_DEFUN([DX_FEATURE_xml], OFF) +AC_DEFUN([DX_FEATURE_pdf], ON) +AC_DEFUN([DX_FEATURE_ps], ON) + +## --------------- ## +## Private macros. ## +## --------------- ## + +# DX_ENV_APPEND(VARIABLE, VALUE) +# ------------------------------ +# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen and add it +# as a substitution (but not a Makefile variable). The substitution +# is skipped if the variable name is VERSION. +AC_DEFUN([DX_ENV_APPEND], +[AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])dnl +m4_if([$1], [VERSION], [], [AC_SUBST([$1], [$2])dnl +AM_SUBST_NOTMAKE([$1])])dnl +]) + +# DX_DIRNAME_EXPR +# --------------- +# Expand into a shell expression prints the directory part of a path. +AC_DEFUN([DX_DIRNAME_EXPR], + [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']]) + +# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF) +# ------------------------------------- +# Expands according to the M4 (static) status of the feature. +AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])]) + +# DX_REQUIRE_PROG(VARIABLE, PROGRAM) +# ---------------------------------- +# Require the specified program to be found for the DX_CURRENT_FEATURE to work. +AC_DEFUN([DX_REQUIRE_PROG], [ +AC_PATH_TOOL([$1], [$2]) +if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then + AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION]) + AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) +fi +]) + +# DX_TEST_FEATURE(FEATURE) +# ------------------------ +# Expand to a shell expression testing whether the feature is active. +AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1]) + +# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE) +# ------------------------------------------------- +# Verify that a required features has the right state before trying to turn on +# the DX_CURRENT_FEATURE. +AC_DEFUN([DX_CHECK_DEPEND], [ +test "$DX_FLAG_$1" = "$2" \ +|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1, + requires, contradicts) doxygen-DX_CURRENT_FEATURE]) +]) + +# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE) +# ---------------------------------------------------------- +# Turn off the DX_CURRENT_FEATURE if the required feature is off. +AC_DEFUN([DX_CLEAR_DEPEND], [ +test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) +]) + +# DX_FEATURE_ARG(FEATURE, DESCRIPTION, +# CHECK_DEPEND, CLEAR_DEPEND, +# REQUIRE, DO-IF-ON, DO-IF-OFF) +# -------------------------------------------- +# Parse the command-line option controlling a feature. CHECK_DEPEND is called +# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND), +# otherwise CLEAR_DEPEND is called to turn off the default state if a required +# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional +# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and +# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature. +AC_DEFUN([DX_ARG_ABLE], [ + AC_DEFUN([DX_CURRENT_FEATURE], [$1]) + AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2]) + AC_ARG_ENABLE(doxygen-$1, + [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1], + [--enable-doxygen-$1]), + DX_IF_FEATURE([$1], [don't $2], [$2]))], + [ +case "$enableval" in +#( +y|Y|yes|Yes|YES) + AC_SUBST([DX_FLAG_$1], 1) + $3 +;; #( +n|N|no|No|NO) + AC_SUBST([DX_FLAG_$1], 0) +;; #( +*) + AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1]) +;; +esac +], [ +AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)]) +$4 +]) +if DX_TEST_FEATURE([$1]); then + $5 + : +fi +if DX_TEST_FEATURE([$1]); then + $6 + : +else + $7 + : +fi +]) + +## -------------- ## +## Public macros. ## +## -------------- ## + +# DX_XXX_FEATURE(DEFAULT_STATE) +# ----------------------------- +AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])]) +AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])]) +AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])]) +AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])]) +AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])]) +AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])]) +AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])]) +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) +AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) +AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])]) +AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])]) + +# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR], ...) +# -------------------------------------------------------------- +# PROJECT also serves as the base name for the documentation files. +# The default CONFIG-FILE is "$(srcdir)/Doxyfile" and OUTPUT-DOC-DIR is +# "doxygen-doc". +# More arguments are interpreted as interleaved CONFIG-FILE and +# OUTPUT-DOC-DIR values. +AC_DEFUN([DX_INIT_DOXYGEN], [ + +# Files: +AC_SUBST([DX_PROJECT], [$1]) +AC_SUBST([DX_CONFIG], ['ifelse([$2], [], [$(srcdir)/Doxyfile], [$2])']) +AC_SUBST([DX_DOCDIR], ['ifelse([$3], [], [doxygen-doc], [$3])']) +m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 4, m4_count($@), 2, + [AC_SUBST([DX_CONFIG]m4_eval(DX_i[/2]), + 'm4_default_nblank_quoted(m4_argn(DX_i, $@), + [$(srcdir)/Doxyfile])')])])dnl +m4_if(m4_eval(3 < m4_count($@)), 1, [m4_for([DX_i], 5, m4_count($@,), 2, + [AC_SUBST([DX_DOCDIR]m4_eval([(]DX_i[-1)/2]), + 'm4_default_nblank_quoted(m4_argn(DX_i, $@), + [doxygen-doc])')])])dnl +m4_define([DX_loop], m4_dquote(m4_if(m4_eval(3 < m4_count($@)), 1, + [m4_for([DX_i], 4, m4_count($@), 2, [, m4_eval(DX_i[/2])])], + [])))dnl + +# Environment variables used inside doxygen.cfg: +DX_ENV_APPEND(SRCDIR, $srcdir) +DX_ENV_APPEND(PROJECT, $DX_PROJECT) +DX_ENV_APPEND(VERSION, $PACKAGE_VERSION) + +# Doxygen itself: +DX_ARG_ABLE(doc, [generate any doxygen documentation], + [], + [], + [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen) + DX_REQUIRE_PROG([DX_PERL], perl)], + [DX_ENV_APPEND(PERL_PATH, $DX_PERL)]) + +# Dot for graphics: +DX_ARG_ABLE(dot, [generate graphics for doxygen documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_DOT], dot)], + [DX_ENV_APPEND(HAVE_DOT, YES) + DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])], + [DX_ENV_APPEND(HAVE_DOT, NO)]) + +# Man pages generation: +DX_ARG_ABLE(man, [generate doxygen manual pages], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_MAN, YES)], + [DX_ENV_APPEND(GENERATE_MAN, NO)]) + +# RTF file generation: +DX_ARG_ABLE(rtf, [generate doxygen RTF documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_RTF, YES)], + [DX_ENV_APPEND(GENERATE_RTF, NO)]) + +# XML file generation: +DX_ARG_ABLE(xml, [generate doxygen XML documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [], + [DX_ENV_APPEND(GENERATE_XML, YES)], + [DX_ENV_APPEND(GENERATE_XML, NO)]) + +# (Compressed) HTML help generation: +DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_HHC], hhc)], + [DX_ENV_APPEND(HHC_PATH, $DX_HHC) + DX_ENV_APPEND(GENERATE_HTML, YES) + DX_ENV_APPEND(GENERATE_HTMLHELP, YES)], + [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)]) + +# Seperate CHI file generation. +DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file], + [DX_CHECK_DEPEND(chm, 1)], + [DX_CLEAR_DEPEND(chm, 1)], + [], + [DX_ENV_APPEND(GENERATE_CHI, YES)], + [DX_ENV_APPEND(GENERATE_CHI, NO)]) + +# Plain HTML pages generation: +DX_ARG_ABLE(html, [generate doxygen plain HTML documentation], + [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)], + [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)], + [], + [DX_ENV_APPEND(GENERATE_HTML, YES)], + [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)]) + +# PostScript file generation: +DX_ARG_ABLE(ps, [generate doxygen PostScript documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_LATEX], latex) + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) + DX_REQUIRE_PROG([DX_DVIPS], dvips) + DX_REQUIRE_PROG([DX_EGREP], egrep)]) + +# PDF file generation: +DX_ARG_ABLE(pdf, [generate doxygen PDF documentation], + [DX_CHECK_DEPEND(doc, 1)], + [DX_CLEAR_DEPEND(doc, 1)], + [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex) + DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) + DX_REQUIRE_PROG([DX_EGREP], egrep)]) + +# LaTeX generation for PS and/or PDF: +if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then + DX_ENV_APPEND(GENERATE_LATEX, YES) +else + DX_ENV_APPEND(GENERATE_LATEX, NO) +fi + +# Paper size for PS and/or PDF: +AC_ARG_VAR(DOXYGEN_PAPER_SIZE, + [a4wide (default), a4, letter, legal or executive]) +case "$DOXYGEN_PAPER_SIZE" in +#( +"") + AC_SUBST(DOXYGEN_PAPER_SIZE, "") +;; #( +a4wide|a4|letter|legal|executive) + DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE) +;; #( +*) + AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE']) +;; +esac + +# Rules: +AS_IF([[test $DX_FLAG_html -eq 1]], +[[DX_SNIPPET_html="## ------------------------------- ## +## Rules specific for HTML output. ## +## ------------------------------- ## + +DX_CLEAN_HTML = \$(DX_DOCDIR)/html]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/html]])[ + +"]], +[[DX_SNIPPET_html=""]]) +AS_IF([[test $DX_FLAG_chi -eq 1]], +[[DX_SNIPPET_chi=" +DX_CLEAN_CHI = \$(DX_DOCDIR)/\$(PACKAGE).chi]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).chi]])["]], +[[DX_SNIPPET_chi=""]]) +AS_IF([[test $DX_FLAG_chm -eq 1]], +[[DX_SNIPPET_chm="## ------------------------------ ## +## Rules specific for CHM output. ## +## ------------------------------ ## + +DX_CLEAN_CHM = \$(DX_DOCDIR)/chm]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/chm]])[\ +${DX_SNIPPET_chi} + +"]], +[[DX_SNIPPET_chm=""]]) +AS_IF([[test $DX_FLAG_man -eq 1]], +[[DX_SNIPPET_man="## ------------------------------ ## +## Rules specific for MAN output. ## +## ------------------------------ ## + +DX_CLEAN_MAN = \$(DX_DOCDIR)/man]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/man]])[ + +"]], +[[DX_SNIPPET_man=""]]) +AS_IF([[test $DX_FLAG_rtf -eq 1]], +[[DX_SNIPPET_rtf="## ------------------------------ ## +## Rules specific for RTF output. ## +## ------------------------------ ## + +DX_CLEAN_RTF = \$(DX_DOCDIR)/rtf]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/rtf]])[ + +"]], +[[DX_SNIPPET_rtf=""]]) +AS_IF([[test $DX_FLAG_xml -eq 1]], +[[DX_SNIPPET_xml="## ------------------------------ ## +## Rules specific for XML output. ## +## ------------------------------ ## + +DX_CLEAN_XML = \$(DX_DOCDIR)/xml]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/xml]])[ + +"]], +[[DX_SNIPPET_xml=""]]) +AS_IF([[test $DX_FLAG_ps -eq 1]], +[[DX_SNIPPET_ps="## ----------------------------- ## +## Rules specific for PS output. ## +## ----------------------------- ## + +DX_CLEAN_PS = \$(DX_DOCDIR)/\$(PACKAGE).ps]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps]])[ + +DX_PS_GOAL = doxygen-ps + +doxygen-ps: \$(DX_CLEAN_PS) + +]m4_foreach([DX_i], [DX_loop], +[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).ps: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag + \$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\ + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\ + \$(DX_LATEX) refman.tex; \\ + \$(DX_MAKEINDEX) refman.idx; \\ + \$(DX_LATEX) refman.tex; \\ + countdown=5; \\ + while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\ + refman.log > /dev/null 2>&1 \\ + && test \$\$countdown -gt 0; do \\ + \$(DX_LATEX) refman.tex; \\ + countdown=\`expr \$\$countdown - 1\`; \\ + done; \\ + \$(DX_DVIPS) -o ../\$(PACKAGE).ps refman.dvi + +]])["]], +[[DX_SNIPPET_ps=""]]) +AS_IF([[test $DX_FLAG_pdf -eq 1]], +[[DX_SNIPPET_pdf="## ------------------------------ ## +## Rules specific for PDF output. ## +## ------------------------------ ## + +DX_CLEAN_PDF = \$(DX_DOCDIR)/\$(PACKAGE).pdf]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf]])[ + +DX_PDF_GOAL = doxygen-pdf + +doxygen-pdf: \$(DX_CLEAN_PDF) + +]m4_foreach([DX_i], [DX_loop], +[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).pdf: \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag + \$(DX_V_LATEX)cd \$(DX_DOCDIR]DX_i[)/latex; \\ + rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\ + \$(DX_PDFLATEX) refman.tex; \\ + \$(DX_MAKEINDEX) refman.idx; \\ + \$(DX_PDFLATEX) refman.tex; \\ + countdown=5; \\ + while \$(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\ + refman.log > /dev/null 2>&1 \\ + && test \$\$countdown -gt 0; do \\ + \$(DX_PDFLATEX) refman.tex; \\ + countdown=\`expr \$\$countdown - 1\`; \\ + done; \\ + mv refman.pdf ../\$(PACKAGE).pdf + +]])["]], +[[DX_SNIPPET_pdf=""]]) +AS_IF([[test $DX_FLAG_ps -eq 1 -o $DX_FLAG_pdf -eq 1]], +[[DX_SNIPPET_latex="## ------------------------------------------------- ## +## Rules specific for LaTeX (shared for PS and PDF). ## +## ------------------------------------------------- ## + +DX_V_LATEX = \$(_DX_v_LATEX_\$(V)) +_DX_v_LATEX_ = \$(_DX_v_LATEX_\$(AM_DEFAULT_VERBOSITY)) +_DX_v_LATEX_0 = @echo \" LATEX \" \$][@; + +DX_CLEAN_LATEX = \$(DX_DOCDIR)/latex]dnl +m4_foreach([DX_i], [m4_shift(DX_loop)], [[\\ + \$(DX_DOCDIR]DX_i[)/latex]])[ + +"]], +[[DX_SNIPPET_latex=""]]) + +AS_IF([[test $DX_FLAG_doc -eq 1]], +[[DX_SNIPPET_doc="## --------------------------------- ## +## Format-independent Doxygen rules. ## +## --------------------------------- ## + +${DX_SNIPPET_html}\ +${DX_SNIPPET_chm}\ +${DX_SNIPPET_man}\ +${DX_SNIPPET_rtf}\ +${DX_SNIPPET_xml}\ +${DX_SNIPPET_ps}\ +${DX_SNIPPET_pdf}\ +${DX_SNIPPET_latex}\ +DX_V_DXGEN = \$(_DX_v_DXGEN_\$(V)) +_DX_v_DXGEN_ = \$(_DX_v_DXGEN_\$(AM_DEFAULT_VERBOSITY)) +_DX_v_DXGEN_0 = @echo \" DXGEN \" \$<; + +.PHONY: doxygen-run doxygen-doc \$(DX_PS_GOAL) \$(DX_PDF_GOAL) + +.INTERMEDIATE: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL) + +doxygen-run:]m4_foreach([DX_i], [DX_loop], + [[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag]])[ + +doxygen-doc: doxygen-run \$(DX_PS_GOAL) \$(DX_PDF_GOAL) + +]m4_foreach([DX_i], [DX_loop], +[[\$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag: \$(DX_CONFIG]DX_i[) \$(pkginclude_HEADERS) + \$(A""M_V_at)rm -rf \$(DX_DOCDIR]DX_i[) + \$(DX_V_DXGEN)\$(DX_ENV) DOCDIR=\$(DX_DOCDIR]DX_i[) \$(DX_DOXYGEN) \$(DX_CONFIG]DX_i[) + \$(A""M_V_at)echo Timestamp >\$][@ + +]])dnl +[DX_CLEANFILES = \\] +m4_foreach([DX_i], [DX_loop], +[[ \$(DX_DOCDIR]DX_i[)/\$(PACKAGE).tag \\ +]])dnl +[ -r \\ + \$(DX_CLEAN_HTML) \\ + \$(DX_CLEAN_CHM) \\ + \$(DX_CLEAN_CHI) \\ + \$(DX_CLEAN_MAN) \\ + \$(DX_CLEAN_RTF) \\ + \$(DX_CLEAN_XML) \\ + \$(DX_CLEAN_PS) \\ + \$(DX_CLEAN_PDF) \\ + \$(DX_CLEAN_LATEX)"]], +[[DX_SNIPPET_doc=""]]) +AC_SUBST([DX_RULES], +["${DX_SNIPPET_doc}"])dnl +AM_SUBST_NOTMAKE([DX_RULES]) + +#For debugging: +#echo DX_FLAG_doc=$DX_FLAG_doc +#echo DX_FLAG_dot=$DX_FLAG_dot +#echo DX_FLAG_man=$DX_FLAG_man +#echo DX_FLAG_html=$DX_FLAG_html +#echo DX_FLAG_chm=$DX_FLAG_chm +#echo DX_FLAG_chi=$DX_FLAG_chi +#echo DX_FLAG_rtf=$DX_FLAG_rtf +#echo DX_FLAG_xml=$DX_FLAG_xml +#echo DX_FLAG_pdf=$DX_FLAG_pdf +#echo DX_FLAG_ps=$DX_FLAG_ps +#echo DX_ENV=$DX_ENV +]) diff --git a/m4/ax_restore_flags.m4 b/m4/ax_restore_flags.m4 new file mode 100644 index 0000000..cf03cae --- /dev/null +++ b/m4/ax_restore_flags.m4 @@ -0,0 +1,31 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_restore_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_RESTORE_FLAGS() +# +# DESCRIPTION +# +# Restore common compilation flags from temporary variables +# +# LICENSE +# +# Copyright (c) 2009 Filippo Giunchedi +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_RESTORE_FLAGS], [ + CPPFLAGS="${CPPFLAGS_save}" + CFLAGS="${CFLAGS_save}" + CXXFLAGS="${CXXFLAGS_save}" + OBJCFLAGS="${OBJCFLAGS_save}" + LDFLAGS="${LDFLAGS_save}" + LIBS="${LIBS_save}" +]) diff --git a/m4/ax_save_flags.m4 b/m4/ax_save_flags.m4 new file mode 100644 index 0000000..d2a0542 --- /dev/null +++ b/m4/ax_save_flags.m4 @@ -0,0 +1,31 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_save_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_SAVE_FLAGS() +# +# DESCRIPTION +# +# Save common compilation flags into temporary variables +# +# LICENSE +# +# Copyright (c) 2009 Filippo Giunchedi +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_SAVE_FLAGS], [ + CPPFLAGS_save="${CPPFLAGS}" + CFLAGS_save="${CFLAGS}" + CXXFLAGS_save="${CXXFLAGS}" + OBJCFLAGS_save="${OBJCFLAGS}" + LDFLAGS_save="${LDFLAGS}" + LIBS_save="${LIBS}" +]) diff --git a/openflow_mapping/l2.py b/openflow_mapping/l2.py new file mode 100644 index 0000000..f2981f3 --- /dev/null +++ b/openflow_mapping/l2.py @@ -0,0 +1,12 @@ +from mapping_common import * + +openflow_tables = { + "dmac": OFTable( + match_fields = { + "ingress_metadata_bd": OFMatchField(field="OFPXMT_OFB_VLAN_VID"), + "l2_metadata_lkp_mac_da" : OFMatchField(field="OFPXMT_OFB_ETH_DST") + }, + + id = 0 + ) +} diff --git a/openflow_mapping/mapping_common.py b/openflow_mapping/mapping_common.py new file mode 100644 index 0000000..637b02f --- /dev/null +++ b/openflow_mapping/mapping_common.py @@ -0,0 +1,10 @@ +class OFTable(): + def __init__(self, match_fields, id): + self.match_fields = match_fields + self.id = id + +class OFMatchField(): + def __init__(self, field, match_type="exact", val=None): + self.field = field + self.match_type = match_type + self.testval = val diff --git a/p4src/LICENSE b/p4src/LICENSE new file mode 100644 index 0000000..ddcb230 --- /dev/null +++ b/p4src/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/p4src/acl.p4 b/p4src/acl.p4 index 5897d37..0327690 100644 --- a/p4src/acl.p4 +++ b/p4src/acl.p4 @@ -34,6 +34,12 @@ header_type acl_metadata_t { if_label : 16; /* if label for acls */ bd_label : 16; /* bd label for acls */ acl_stats_index : 14; /* acl stats index */ + egress_if_label : 16; /* if label for egress acls */ + egress_bd_label : 16; /* bd label for egress acls */ + ingress_src_port_range_id : 8; /* ingress src port range id */ + ingress_dst_port_range_id : 8; /* ingress dst port range id */ + egress_src_port_range_id : 8; /* egress src port range id */ + egress_dst_port_range_id : 8; /* egress dst port range id */ } } @@ -47,6 +53,125 @@ header_type i2e_metadata_t { metadata acl_metadata_t acl_metadata; metadata i2e_metadata_t i2e_metadata; +/*****************************************************************************/ +/* Egress ACL l4 port range */ +/*****************************************************************************/ +#ifdef EGRESS_ACL_ENABLE +action set_egress_tcp_port_fields() { + modify_field(l3_metadata.egress_l4_sport, tcp.srcPort); + modify_field(l3_metadata.egress_l4_dport, tcp.dstPort); +} + +action set_egress_udp_port_fields() { + modify_field(l3_metadata.egress_l4_sport, udp.srcPort); + modify_field(l3_metadata.egress_l4_dport, udp.dstPort); +} + +action set_egress_icmp_port_fields() { + modify_field(l3_metadata.egress_l4_sport, icmp.typeCode); +} + +table egress_l4port_fields { + reads { + tcp : valid; + udp : valid; + icmp : valid; + } + actions { + nop; + set_egress_tcp_port_fields; + set_egress_udp_port_fields; + set_egress_icmp_port_fields; + } + size: EGRESS_PORT_LKP_FIELD_SIZE; +} + +#ifndef ACL_RANGE_DISABLE +action set_egress_src_port_range_id(range_id) { + modify_field(acl_metadata.egress_src_port_range_id, range_id); +} + +table egress_l4_src_port { + reads { + l3_metadata.egress_l4_sport : range; + } + actions { + nop; + set_egress_src_port_range_id; + } + size: EGRESS_ACL_RANGE_TABLE_SIZE; +} + +action set_egress_dst_port_range_id(range_id) { + modify_field(acl_metadata.egress_dst_port_range_id, range_id); +} + +table egress_l4_dst_port { + reads { + l3_metadata.egress_l4_dport : range; + } + actions { + nop; + set_egress_dst_port_range_id; + } + size: EGRESS_ACL_RANGE_TABLE_SIZE; +} + +#endif /* ACL_RANGE_DISABLE */ +#endif /* EGRESS_ACL_ENABLE */ + +control process_egress_l4port { +#ifdef EGRESS_ACL_ENABLE + apply(egress_l4port_fields); +#ifndef ACL_RANGE_DISABLE + apply(egress_l4_src_port); + apply(egress_l4_dst_port); +#endif /* ACL_RANGE_DISABLE */ +#endif /* EGRESS_ACL_ENABLE */ +} + +/*****************************************************************************/ +/* Ingress ACL l4 port range */ +/*****************************************************************************/ +#ifndef ACL_RANGE_DISABLE +action set_ingress_src_port_range_id(range_id) { + modify_field(acl_metadata.ingress_src_port_range_id, range_id); +} + +table ingress_l4_src_port { + reads { + l3_metadata.lkp_l4_sport : range; + } + actions { + nop; + set_ingress_src_port_range_id; + } + size: INGRESS_ACL_RANGE_TABLE_SIZE; +} + +action set_ingress_dst_port_range_id(range_id) { + modify_field(acl_metadata.ingress_dst_port_range_id, range_id); +} + +table ingress_l4_dst_port { + reads { + l3_metadata.lkp_l4_dport : range; + } + actions { + nop; + set_ingress_dst_port_range_id; + } + size: INGRESS_ACL_RANGE_TABLE_SIZE; +} +#endif /* ACL_RANGE_DISABLE */ + +control process_ingress_l4port { +#ifndef ACL_RANGE_DISABLE + apply(ingress_l4_src_port); + apply(ingress_l4_dst_port); +#endif /* ACL_RANGE_DISABLE */ +} + /*****************************************************************************/ /* ACL Actions */ /*****************************************************************************/ @@ -185,8 +310,8 @@ table ip_acl { ipv4_metadata.lkp_ipv4_sa : ternary; ipv4_metadata.lkp_ipv4_da : ternary; l3_metadata.lkp_ip_proto : ternary; - l3_metadata.lkp_l4_sport : ternary; - l3_metadata.lkp_l4_dport : ternary; + acl_metadata.ingress_src_port_range_id : exact; + acl_metadata.ingress_dst_port_range_id : exact; tcp.flags : ternary; l3_metadata.lkp_ip_ttl : ternary; @@ -218,8 +343,8 @@ table ipv6_acl { ipv6_metadata.lkp_ipv6_sa : ternary; ipv6_metadata.lkp_ipv6_da : ternary; l3_metadata.lkp_ip_proto : ternary; - l3_metadata.lkp_l4_sport : ternary; - l3_metadata.lkp_l4_dport : ternary; + acl_metadata.ingress_src_port_range_id : exact; + acl_metadata.ingress_dst_port_range_id : exact; tcp.flags : ternary; l3_metadata.lkp_ip_ttl : ternary; @@ -326,8 +451,8 @@ table ipv4_racl { ipv4_metadata.lkp_ipv4_sa : ternary; ipv4_metadata.lkp_ipv4_da : ternary; l3_metadata.lkp_ip_proto : ternary; - l3_metadata.lkp_l4_sport : ternary; - l3_metadata.lkp_l4_dport : ternary; + acl_metadata.ingress_src_port_range_id : exact; + acl_metadata.ingress_dst_port_range_id : exact; } actions { nop; @@ -346,7 +471,6 @@ control process_ipv4_racl { #endif /* IPV4_DISABLE */ } - /*****************************************************************************/ /* IPv6 RACL */ /*****************************************************************************/ @@ -358,8 +482,8 @@ table ipv6_racl { ipv6_metadata.lkp_ipv6_sa : ternary; ipv6_metadata.lkp_ipv6_da : ternary; l3_metadata.lkp_ip_proto : ternary; - l3_metadata.lkp_l4_sport : ternary; - l3_metadata.lkp_l4_dport : ternary; + acl_metadata.ingress_src_port_range_id : exact; + acl_metadata.ingress_dst_port_range_id : exact; } actions { nop; @@ -567,6 +691,112 @@ control process_system_acl { /*****************************************************************************/ /* Egress ACL */ /*****************************************************************************/ + +#ifdef EGRESS_ACL_ENABLE + +/*****************************************************************************/ +/* Egress ACL Actions */ +/*****************************************************************************/ +action egress_acl_deny(acl_copy_reason) { + modify_field(acl_metadata.acl_deny, TRUE); + modify_field(fabric_metadata.reason_code, acl_copy_reason); +} + +action egress_acl_permit(acl_copy_reason) { + modify_field(fabric_metadata.reason_code, acl_copy_reason); +} + +/*****************************************************************************/ +/* Egress Mac ACL */ +/*****************************************************************************/ + +#ifndef L2_DISABLE +table egress_mac_acl { + reads { + acl_metadata.egress_if_label : ternary; + acl_metadata.egress_bd_label : ternary; + + ethernet.srcAddr : ternary; + ethernet.dstAddr : ternary; + ethernet.etherType: ternary; + } + actions { + nop; + egress_acl_deny; + egress_acl_permit; + } + size : EGRESS_MAC_ACL_TABLE_SIZE; +} +#endif /* L2_DISABLE */ + +/*****************************************************************************/ +/* Egress IPv4 ACL */ +/*****************************************************************************/ +#ifndef IPV4_DISABLE +table egress_ip_acl { + reads { + acl_metadata.egress_if_label : ternary; + acl_metadata.egress_bd_label : ternary; + + ipv4.srcAddr : ternary; + ipv4.dstAddr : ternary; + ipv4.protocol : ternary; + acl_metadata.egress_src_port_range_id : exact; + acl_metadata.egress_dst_port_range_id : exact; + } + actions { + nop; + egress_acl_deny; + egress_acl_permit; + } + size : EGRESS_IP_ACL_TABLE_SIZE; +} +#endif /* IPV4_DISABLE */ + +/*****************************************************************************/ +/* Egress IPv6 ACL */ +/*****************************************************************************/ +#ifndef IPV6_DISABLE +table egress_ipv6_acl { + reads { + acl_metadata.egress_if_label : ternary; + acl_metadata.egress_bd_label : ternary; + + ipv6.srcAddr : ternary; + ipv6.dstAddr : ternary; + ipv6.nextHdr : ternary; + acl_metadata.egress_src_port_range_id : exact; + acl_metadata.egress_dst_port_range_id : exact; + } + actions { + nop; + egress_acl_deny; + egress_acl_permit; + } + size : EGRESS_IPV6_ACL_TABLE_SIZE; +} + +#endif /* IPV6_DISABLE */ +#endif /* EGRESS_ACL_ENABLE */ + +control process_egress_acl { +#ifdef EGRESS_ACL_ENABLE + if (valid(ipv4)) { +#ifndef IPV4_DISABLE + apply(egress_ip_acl); +#endif /* IPV4_DISABLE */ + } else { + if (valid(ipv6)) { +#ifndef IPV6_DISABLE + apply(egress_ipv6_acl); +#endif /* IPV6_DISABLE */ + } else { + apply(egress_mac_acl); + } + } +#endif /* EGRESS_ACL_ENABLE */ +} + action egress_mirror(session_id) { modify_field(i2e_metadata.mirror_session_id, session_id); clone_egress_pkt_to_egress(session_id, e2e_mirror_info); @@ -577,33 +807,47 @@ action egress_mirror_drop(session_id) { drop(); } -action egress_redirect_to_cpu(reason_code) { - egress_copy_to_cpu(reason_code); +action egress_copy_to_cpu() { + clone_egress_pkt_to_egress(CPU_MIRROR_SESSION_ID, cpu_info); +} + +action egress_redirect_to_cpu() { + egress_copy_to_cpu(); drop(); } -action egress_copy_to_cpu(reason_code) { +action egress_copy_to_cpu_with_reason(reason_code) { modify_field(fabric_metadata.reason_code, reason_code); - clone_egress_pkt_to_egress(CPU_MIRROR_SESSION_ID, cpu_info); + egress_copy_to_cpu(); } -table egress_acl { +action egress_redirect_to_cpu_with_reason(reason_code) { + egress_copy_to_cpu_with_reason(reason_code); + drop(); +} +table egress_system_acl { reads { + fabric_metadata.reason_code : ternary; standard_metadata.egress_port : ternary; intrinsic_metadata.deflection_flag : ternary; l3_metadata.l3_mtu_check : ternary; + acl_metadata.acl_deny : ternary; } actions { nop; + drop_packet; + egress_copy_to_cpu; + egress_redirect_to_cpu; + egress_copy_to_cpu_with_reason; + egress_redirect_to_cpu_with_reason; egress_mirror; egress_mirror_drop; - egress_redirect_to_cpu; } size : EGRESS_ACL_TABLE_SIZE; } -control process_egress_acl { +control process_egress_system_acl { if (egress_metadata.bypass == FALSE) { - apply(egress_acl); + apply(egress_system_acl); } } diff --git a/p4src/fabric.p4 b/p4src/fabric.p4 index 478c5b6..c3880af 100644 --- a/p4src/fabric.p4 +++ b/p4src/fabric.p4 @@ -40,6 +40,7 @@ action terminate_cpu_packet() { modify_field(standard_metadata.egress_spec, fabric_header.dstPortOrGroup); modify_field(egress_metadata.bypass, fabric_header_cpu.txBypass); + modify_field(intrinsic_metadata.mcast_grp, fabric_header_cpu.mcast_grp); modify_field(ethernet.etherType, fabric_payload_header.etherType); remove_header(fabric_header); diff --git a/p4src/includes/drop_reasons.h b/p4src/includes/drop_reasons.h deleted file mode 100644 index 38ce55c..0000000 --- a/p4src/includes/drop_reasons.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#define DROP_UNKNOWN 0 - -#define DROP_OUTER_SRC_MAC_ZERO 10 -#define DROP_OUTER_SRC_MAC_MULTICAST 11 -#define DROP_OUTER_DST_MAC_ZERO 12 -#define DROP_OUTER_ETHERNET_MISS 13 -#define DROP_SRC_MAC_ZERO 14 -#define DROP_SRC_MAC_MULTICAST 15 -#define DROP_DST_MAC_ZERO 16 - -#define DROP_OUTER_IP_VERSION_INVALID 25 -#define DROP_OUTER_IP_TTL_ZERO 26 -#define DROP_OUTER_IP_SRC_MULTICAST 27 -#define DROP_OUTER_IP_SRC_LOOPBACK 28 -#define DROP_OUTER_IP_MISS 29 -#define DROP_IP_VERSION_INVALID 30 -#define DROP_IP_TTL_ZERO 31 -#define DROP_IP_SRC_MULTICAST 32 -#define DROP_IP_SRC_LOOPBACK 33 - -#define DROP_PORT_VLAN_MAPPING_MISS 40 -#define DROP_STP_STATE_LEARNING 41 -#define DROP_STP_STATE_BLOCKING 42 -#define DROP_SAME_IFINDEX 43 -#define DROP_MULTICAST_SNOOPING_ENABLED 44 - -#define DROP_ACL_DENY 60 -#define DROP_RACL_DENY 61 -#define DROP_URPF_CHECK_FAIL 62 -#define DROP_IPSG_MISS 63 -#define DROP_IFINDEX 64 - -/* - * other reason codes shared between P4 program and APIs - * Must match the definitions in switch_hostif.h file - */ - -#define CPU_REASON_CODE_SFLOW 0x4 -#define CPU_REASON_CODE_L3_REDIRECT 0x217 diff --git a/p4src/includes/headers.p4 b/p4src/includes/headers.p4 index a0947d6..55b330f 100644 --- a/p4src/includes/headers.p4 +++ b/p4src/includes/headers.p4 @@ -520,6 +520,7 @@ header_type fabric_header_cpu_t { ingressBd : 16; reasonCode : 16; + mcast_grp : 16; } } diff --git a/p4src/includes/p4_table_sizes.h b/p4src/includes/p4_table_sizes.h index 7879bf3..903968f 100644 --- a/p4src/includes/p4_table_sizes.h +++ b/p4src/includes/p4_table_sizes.h @@ -47,6 +47,9 @@ limitations under the License. #define INGRESS_MAC_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IP_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IPV6_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE +#define EGRESS_MAC_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE +#define EGRESS_IP_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE +#define EGRESS_IPV6_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IP_RACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define INGRESS_IPV6_RACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define IP_NAT_TABLE_SIZE MIN_SRAM_TABLE_SIZE @@ -83,6 +86,8 @@ limitations under the License. #define SPANNING_TREE_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define FABRIC_REWRITE_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define EGRESS_ACL_TABLE_SIZE MIN_TCAM_TABLE_SIZE +#define INGRESS_ACL_RANGE_TABLE_SIZE MIN_TCAM_TABLE_SIZE +#define EGRESS_ACL_RANGE_TABLE_SIZE MIN_TCAM_TABLE_SIZE #define VLAN_DECAP_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define TUNNEL_HEADER_TABLE_SIZE MIN_SRAM_TABLE_SIZE #define TUNNEL_REWRITE_TABLE_SIZE MIN_SRAM_TABLE_SIZE @@ -110,3 +115,5 @@ limitations under the License. #define PCP_TO_TC_AND_COLOR_TABLE_SIZE 64 #define COPP_TABLE_SIZE 128 + +#define EGRESS_PORT_LKP_FIELD_SIZE 4 diff --git a/p4src/includes/p4features.h b/p4src/includes/p4features.h index 978fcde..270a535 100644 --- a/p4src/includes/p4features.h +++ b/p4src/includes/p4features.h @@ -21,6 +21,8 @@ limitations under the License. #define OUTER_PIM_BIDIR_OPTIMIZATION #define PIM_BIDIR_OPTIMIZATION #define SFLOW_ENABLE +#define EGRESS_ACL_ENABLE +#define ACL_RANGE_DISABLE #ifdef MULTICAST_DISABLE #define L2_MULTICAST_DISABLE @@ -115,3 +117,11 @@ limitations under the License. #ifdef METER_DISABLE #define P4_METER_DISABLE #endif + +#ifdef EGRESS_ACL_ENABLE +#define P4_EGRESS_ACL_ENABLE +#endif + +#ifdef ACL_RANGE_DISABLE +#define P4_ACL_RANGE_DISABLE +#endif diff --git a/p4src/includes/parser.p4 b/p4src/includes/parser.p4 index 39f7c6f..50bf5a4 100644 --- a/p4src/includes/parser.p4 +++ b/p4src/includes/parser.p4 @@ -609,22 +609,7 @@ parser parse_erspan_t3 { return parse_inner_ethernet; } -#define ARP_PROTOTYPES_ARP_RARP_IPV4 0x0800 - -header arp_rarp_t arp_rarp; - parser parse_arp_rarp { - extract(arp_rarp); - return select(latest.protoType) { - ARP_PROTOTYPES_ARP_RARP_IPV4 : parse_arp_rarp_ipv4; - default: ingress; - } -} - -header arp_rarp_ipv4_t arp_rarp_ipv4; - -parser parse_arp_rarp_ipv4 { - extract(arp_rarp_ipv4); return parse_set_prio_med; } diff --git a/p4src/l2.p4 b/p4src/l2.p4 index 000c2bc..230ebbb 100644 --- a/p4src/l2.p4 +++ b/p4src/l2.p4 @@ -299,9 +299,10 @@ control process_egress_bd_stats { #endif /* STATS_DISABLE */ } -action set_egress_bd_properties(smac_idx, nat_mode) { +action set_egress_bd_properties(smac_idx, nat_mode, bd_label) { modify_field(egress_metadata.smac_idx, smac_idx); modify_field(nat_metadata.egress_nat_mode, nat_mode); + modify_field(acl_metadata.egress_bd_label, bd_label); } table egress_bd_map { diff --git a/p4src/l3.p4 b/p4src/l3.p4 index 807ca3d..c5b76b6 100644 --- a/p4src/l3.p4 +++ b/p4src/l3.p4 @@ -51,6 +51,9 @@ header_type l3_metadata_t { mtu_index : 8; /* index into mtu table */ l3_copy : 1; /* copy packet to CPU */ l3_mtu_check : 16 (saturating); /* result of mtu check */ + + egress_l4_sport : 16; + egress_l4_dport : 16; } } diff --git a/p4src/meter.p4 b/p4src/meter.p4 index ca8e400..e592cbd 100644 --- a/p4src/meter.p4 +++ b/p4src/meter.p4 @@ -1,18 +1,6 @@ /* -Copyright 2013-present Barefoot Networks, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ + * Meter processing + */ /* * Meter metadata diff --git a/p4src/openflow.p4 b/p4src/openflow.p4 index 66dd965..8b7cc57 100644 --- a/p4src/openflow.p4 +++ b/p4src/openflow.p4 @@ -23,9 +23,14 @@ limitations under the License. #define OPENFLOW_ENABLE_VLAN #define OPENFLOW_ENABLE_L3 -/* enables fabric header for non-switch.p4 targets */ +// adds some handy stuff from switch.p4 for packet in/out //#define OPENFLOW_PACKET_IN_OUT +#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 + header_type openflow_metadata_t { fields { index : 32; @@ -41,10 +46,13 @@ metadata openflow_metadata_t openflow_metadata; #define CPU_PORT_ID 64 #endif +#define TRUE 1 + #ifdef OPENFLOW_PACKET_IN_OUT #define ETHERTYPE_BF_FABRIC 0x9000 -#define TRUE 1 +#define FABRIC_HEADER_TYPE_MULTICAST 2 +#define FABRIC_HEADER_TYPE_CPU 5 header_type fabric_header_t { fields { @@ -61,6 +69,20 @@ header_type fabric_header_t { } } +header_type fabric_header_multicast_t { + fields { + routed : 1; + outerRouted : 1; + tunnelTerminate : 1; + ingressTunnelType : 5; + + ingressIfindex : 16; + ingressBd : 16; + + mcastGrp : 16; + } +} + header_type fabric_header_cpu_t { fields { egressQueue : 5; @@ -83,26 +105,86 @@ header_type fabric_payload_header_t { header fabric_header_t fabric_header; header fabric_header_cpu_t fabric_header_cpu; +header fabric_header_multicast_t fabric_header_multicast; header fabric_payload_header_t fabric_payload_header; -parser fabric_header { + +parser parse_fabric_header { extract(fabric_header); + return select(latest.packetType) { + FABRIC_HEADER_TYPE_MULTICAST : parse_fabric_header_multicast; + FABRIC_HEADER_TYPE_CPU : parse_fabric_header_cpu; + default : ingress; + } +} + +parser parse_fabric_header_multicast { + extract(fabric_header_multicast); + return parse_fabric_payload_header; +} + +parser parse_fabric_header_cpu { extract(fabric_header_cpu); + return parse_fabric_payload_header; +} + +parser parse_fabric_payload_header { extract(fabric_payload_header); - return ingress; + return select(latest.etherType) { + // add more ethertypes here if you want + default: ingress; + } } action nop () { } +// remove the comments in "terminate_cpu_packet" and "terminate_fabric_multicast_packet" +// as necessary. I'm just assuming these features aren't used (Except copying the +// ethertype from the fabric payload header, that's necessary but I don't want to +// assume you've named your ethernet header "ethernet" :) ) + action terminate_cpu_packet() { - modify_field(ingress_egress_port,fabric_header.dstPortOrGroup); - modify_field(ethernet.etherType, fabric_payload_header.etherType); + modify_field(ingress_egress_port, + fabric_header.dstPortOrGroup); +// modify_field(egress_metadata.bypass, fabric_header_cpu.txBypass); + modify_field(ethernet.etherType, fabric_payload_header.etherType); remove_header(fabric_header); remove_header(fabric_header_cpu); remove_header(fabric_payload_header); } + +action terminate_fabric_multicast_packet() { +// modify_field(tunnel_metadata.tunnel_terminate, +// fabric_header_multicast.tunnelTerminate); +// modify_field(tunnel_metadata.ingress_tunnel_type, +// fabric_header_multicast.ingressTunnelType); +// modify_field(l3_metadata.nexthop_index, 0); +// modify_field(l3_metadata.routed, fabric_header_multicast.routed); +// modify_field(l3_metadata.outer_routed, +// fabric_header_multicast.outerRouted); + + modify_field(intrinsic_mcast_grp, + fabric_header_multicast.mcastGrp); + + modify_field(ethernet.etherType, fabric_payload_header.etherType); + remove_header(fabric_header); + remove_header(fabric_header_multicast); + remove_header(fabric_payload_header); +} + +table packet_out { + reads { + fabric_header.packetType : exact; + } + actions { + nop; + terminate_cpu_packet; + terminate_fabric_multicast_packet; + } +} + #endif /* OPENFLOW_PACKET_IN_OUT */ /**************************************************************** @@ -119,6 +201,16 @@ action openflow_apply(bmap, index, group_id) { } action openflow_miss(reason, table_id) { +#ifdef OPENFLOW_PACKET_IN_OUT + add_header(fabric_header); + add_header(fabric_header_cpu); + add_header(fabric_payload_header); + + modify_field(fabric_metadata.etherType, ethernet.etherType); + + modify_field(fabric_metadata.ingressPort, ingress_input_port); +#endif + modify_field(fabric_metadata.reason_code, reason); shift_left(fabric_metadata.reason_code, fabric_metadata.reason_code, 8); @@ -127,35 +219,6 @@ action openflow_miss(reason, table_id) { modify_field(ingress_egress_port, CPU_PORT_ID); } -/*************************************************************** - * Packet Out - ***************************************************************/ - -action packet_out_eth_flood() { - modify_field(intrinsic_metadata.mcast_grp, fabric_header.dstPortOrGroup); - terminate_cpu_packet(); - modify_field(openflow_metadata.ofvalid, TRUE); -} - -action packet_out_unicast() { - modify_field(ingress_egress_port, fabric_header.dstPortOrGroup); - terminate_cpu_packet(); - modify_field(openflow_metadata.ofvalid, TRUE); -} - -table packet_out { - reads { - fabric_header.packetType : exact; - fabric_header_cpu.reasonCode : exact; - } - - actions { - packet_out_eth_flood; - packet_out_unicast; - nop; - } -} - /**************************************************************** * Egress openflow bitmap translation ****************************************************************/ @@ -206,6 +269,7 @@ table ofpat_group_ingress { action ofpat_output(egress_port) { modify_field(ingress_egress_port, egress_port); +// for switch.p4 modify_field(ingress_metadata.egress_ifindex, 0); } diff --git a/p4src/p4_files.am b/p4src/p4_files.am new file mode 100644 index 0000000..3fee0b9 --- /dev/null +++ b/p4src/p4_files.am @@ -0,0 +1,29 @@ +p4_files = \ +$(top_srcdir)/p4src/acl.p4 \ +$(top_srcdir)/p4src/archdeps.p4 \ +$(top_srcdir)/p4src/egress_filter.p4 \ +$(top_srcdir)/p4src/fabric.p4 \ +$(top_srcdir)/p4src/hashes.p4 \ +$(top_srcdir)/p4src/int_transit.p4 \ +$(top_srcdir)/p4src/ipv4.p4 \ +$(top_srcdir)/p4src/ipv6.p4 \ +$(top_srcdir)/p4src/l2.p4 \ +$(top_srcdir)/p4src/l3.p4 \ +$(top_srcdir)/p4src/meter.p4 \ +$(top_srcdir)/p4src/mirror.p4 \ +$(top_srcdir)/p4src/multicast.p4 \ +$(top_srcdir)/p4src/nexthop.p4 \ +$(top_srcdir)/p4src/openflow.p4 \ +$(top_srcdir)/p4src/port.p4 \ +$(top_srcdir)/p4src/rewrite.p4 \ +$(top_srcdir)/p4src/security.p4 \ +$(top_srcdir)/p4src/switch_config.p4 \ +$(top_srcdir)/p4src/switch.p4 \ +$(top_srcdir)/p4src/tunnel.p4 \ +$(top_srcdir)/p4src/includes/defines.p4 \ +$(top_srcdir)/p4src/includes/drop_reasons.h \ +$(top_srcdir)/p4src/includes/headers.p4 \ +$(top_srcdir)/p4src/includes/intrinsic.p4 \ +$(top_srcdir)/p4src/includes/p4features.h \ +$(top_srcdir)/p4src/includes/parser.p4 \ +$(top_srcdir)/p4src/includes/sizes.p4 diff --git a/p4src/port.p4 b/p4src/port.p4 index b083ddb..61d3767 100644 --- a/p4src/port.p4 +++ b/p4src/port.p4 @@ -354,10 +354,11 @@ control process_lag { /*****************************************************************************/ /* Egress port lookup */ /*****************************************************************************/ -action egress_port_type_normal(ifindex, qos_group) { +action egress_port_type_normal(ifindex, qos_group, if_label) { modify_field(egress_metadata.port_type, PORT_TYPE_NORMAL); modify_field(egress_metadata.ifindex, ifindex); modify_field(qos_metadata.egress_qos_group, qos_group); + modify_field(acl_metadata.egress_if_label, if_label); } action egress_port_type_fabric(ifindex) { diff --git a/p4src/switch.p4 b/p4src/switch.p4 index 4fcdd72..a2db625 100644 --- a/p4src/switch.p4 +++ b/p4src/switch.p4 @@ -139,10 +139,12 @@ control ingress { #ifndef MPLS_DISABLE if (not (valid(mpls[0]) and (l3_metadata.fib_hit == TRUE))) { #endif /* MPLS_DISABLE */ - /* validate packet */ process_validate_packet(); + /* perform ingress l4 port range */ + process_ingress_l4port(); + /* l2 lookups */ process_mac(); @@ -292,10 +294,16 @@ control egress { process_egress_bd_stats(); } } - + + /* perform egress l4 port range */ + process_egress_l4port(); + /* perform tunnel encap */ process_tunnel_encap(); + /* egress acl */ + process_egress_acl(); + /* update underlay header based on INT information inserted */ process_int_outer_encap(); @@ -309,7 +317,7 @@ control egress { } /* apply egress acl */ - process_egress_acl(); + process_egress_system_acl(); #ifdef OPENFLOW_ENABLE } #endif /* OPENFLOW_ENABLE */ diff --git a/p4src/tunnel.p4 b/p4src/tunnel.p4 index 58ef42b..ed042cf 100644 --- a/p4src/tunnel.p4 +++ b/p4src/tunnel.p4 @@ -599,6 +599,7 @@ action decap_vxlan_inner_non_ip() { remove_header(vxlan); remove_header(ipv4); remove_header(ipv6); + remove_header(inner_ethernet); } action decap_genv_inner_ipv4() { @@ -624,6 +625,7 @@ action decap_genv_inner_non_ip() { remove_header(genv); remove_header(ipv4); remove_header(ipv6); + remove_header(inner_ethernet); } #ifndef NVGRE_DISABLE @@ -653,6 +655,7 @@ action decap_nvgre_inner_non_ip() { remove_header(gre); remove_header(ipv4); remove_header(ipv6); + remove_header(inner_ethernet); } #endif @@ -1047,6 +1050,8 @@ action f_insert_vxlan_header() { modify_field(udp.srcPort, hash_metadata.entropy_hash); modify_field(udp.dstPort, UDP_PORT_VXLAN); + modify_field(l3_metadata.egress_l4_sport, hash_metadata.entropy_hash); + modify_field(l3_metadata.egress_l4_dport, UDP_PORT_VXLAN); modify_field(udp.checksum, 0); add(udp.length_, egress_metadata.payload_length, 30); @@ -1077,6 +1082,8 @@ action f_insert_genv_header() { modify_field(udp.srcPort, hash_metadata.entropy_hash); modify_field(udp.dstPort, UDP_PORT_GENV); + modify_field(l3_metadata.egress_l4_sport, hash_metadata.entropy_hash); + modify_field(l3_metadata.egress_l4_dport, UDP_PORT_GENV); modify_field(udp.checksum, 0); add(udp.length_, egress_metadata.payload_length, 30); diff --git a/switchapi/Doxyfile b/switchapi/Doxyfile index 550f2c5..5f82571 100644 --- a/switchapi/Doxyfile +++ b/switchapi/Doxyfile @@ -653,7 +653,7 @@ WARN_LOGFILE = # with spaces. INPUT = switchapi/main.dox \ - switchapi/inc/switchapi + switchapi/include/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/include/switchapi/switch_acl.h b/switchapi/include/switchapi/switch_acl.h index 8b2d682..e6bec99 100644 --- a/switchapi/include/switchapi/switch_acl.h +++ b/switchapi/include/switchapi/switch_acl.h @@ -46,66 +46,66 @@ typedef enum switch_acl_type_ { /** Acl IP field enum */ typedef enum switch_acl_ip_field_ { - SWITCH_ACL_IP_FIELD_IPV4_SRC, /**< IPv4 Source address */ - SWITCH_ACL_IP_FIELD_IPV4_DEST, /**< IPv4 Dest address */ - SWITCH_ACL_IP_FIELD_IP_PROTO, /**< IP Protocol */ - SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT, /**< L4 source port UDP/TCP */ - SWITCH_ACL_IP_FIELD_L4_DEST_PORT, /**< L4 dest port UDP/TCP */ - SWITCH_ACL_IP_FIELD_ICMP_TYPE, /**< ICMP type */ - SWITCH_ACL_IP_FIELD_ICMP_CODE, /**< ICMP code */ - SWITCH_ACL_IP_FIELD_TCP_FLAGS, /**< TCP flags */ - SWITCH_ACL_IP_FIELD_TTL, /**< TTL */ - SWITCH_ACL_IP_FIELD_IP_FLAGS, /**< IP flags */ - SWITCH_ACL_IP_FIELD_IP_FRAGMENT, /**< IP FRAG */ + SWITCH_ACL_IP_FIELD_IPV4_SRC, /**< IPv4 Source address */ + SWITCH_ACL_IP_FIELD_IPV4_DEST, /**< IPv4 Dest address */ + SWITCH_ACL_IP_FIELD_IP_PROTO, /**< IP Protocol */ + SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE, /**< L4 source port UDP/TCP */ + SWITCH_ACL_IP_FIELD_L4_DEST_PORT_RANGE, /**< L4 dest port UDP/TCP */ + SWITCH_ACL_IP_FIELD_ICMP_TYPE, /**< ICMP type */ + SWITCH_ACL_IP_FIELD_ICMP_CODE, /**< ICMP code */ + SWITCH_ACL_IP_FIELD_TCP_FLAGS, /**< TCP flags */ + SWITCH_ACL_IP_FIELD_TTL, /**< TTL */ + SWITCH_ACL_IP_FIELD_IP_FLAGS, /**< IP flags */ + SWITCH_ACL_IP_FIELD_IP_FRAGMENT, /**< IP FRAG */ SWITCH_ACL_IP_FIELD_MAX } switch_acl_ip_field_t; /** Acl IPv6 field enum */ typedef enum switch_acl_ipv6_field_ { - SWITCH_ACL_IPV6_FIELD_IPV6_SRC, /**< IPv6 Source address */ - SWITCH_ACL_IPV6_FIELD_IPV6_DEST, /**< IPv6 Destination address */ - SWITCH_ACL_IPV6_FIELD_IP_PROTO, /**< IP protocol */ - SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT, /**< L4 source port (UDP/TCP) */ - SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT, /**< L4 Dest port (UDP/TCP) */ - SWITCH_ACL_IPV6_FIELD_ICMP_TYPE, /**< ICMP type */ - SWITCH_ACL_IPV6_FIELD_ICMP_CODE, /**< ICMP code */ - SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, /**< TCP flags */ - SWITCH_ACL_IPV6_FIELD_TTL, /**< TTL */ - SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, /**< Flow Label */ + SWITCH_ACL_IPV6_FIELD_IPV6_SRC, /**< IPv6 Source address */ + SWITCH_ACL_IPV6_FIELD_IPV6_DEST, /**< IPv6 Destination address */ + SWITCH_ACL_IPV6_FIELD_IP_PROTO, /**< IP protocol */ + SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT_RANGE, /**< L4 source port (UDP/TCP) */ + SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT_RANGE, /**< L4 Dest port (UDP/TCP) */ + SWITCH_ACL_IPV6_FIELD_ICMP_TYPE, /**< ICMP type */ + SWITCH_ACL_IPV6_FIELD_ICMP_CODE, /**< ICMP code */ + SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, /**< TCP flags */ + SWITCH_ACL_IPV6_FIELD_TTL, /**< TTL */ + SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, /**< Flow Label */ SWITCH_ACL_IPV6_FIELD_MAX } switch_acl_ipv6_field_t; /** Acl IP field list */ typedef union switch_acl_ip_value_ { - unsigned int ipv4_source; /**< v4 source IP */ - unsigned int ipv4_dest; /**< v4 destination IP */ - unsigned char ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< souce port */ - unsigned short l4_dest_port; /**< destination port */ - unsigned char icmp_type; /**< icmp type */ - unsigned char icmp_code; /**< icmp code */ - unsigned char tcp_flags; /**< tcp flags */ - unsigned char ttl; /**< time to live */ - unsigned char dscp; /**< DSCP */ - unsigned char ip_flags; /**< IP flags */ - unsigned char tos; /**< TOS */ - unsigned char ip_frag; /**< IP FRAG */ + unsigned int ipv4_source; /**< v4 source IP */ + unsigned int ipv4_dest; /**< v4 destination IP */ + unsigned char ip_proto; /**< protocol */ + unsigned char icmp_type; /**< icmp type */ + unsigned char icmp_code; /**< icmp code */ + unsigned char tcp_flags; /**< tcp flags */ + unsigned char ttl; /**< time to live */ + unsigned char dscp; /**< DSCP */ + unsigned char ip_flags; /**< IP flags */ + unsigned char tos; /**< TOS */ + unsigned char ip_frag; /**< IP FRAG */ + switch_handle_t sport_range_handle; /**< sport range handle */ + switch_handle_t dport_range_handle; /**< dport range handle */ } switch_acl_ip_value; /** Acl IPv6 field list */ typedef union switch_acl_ipv6_value_ { - uint128_t ipv6_source; /**< v6 souce IP */ - uint128_t ipv6_dest; /**< v6 destination IP */ - unsigned char ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< source port */ - unsigned short l4_dest_port; /**< destination port */ - unsigned char icmp_type; /**< icmp type */ - unsigned char icmp_code; /**< icmp code */ - unsigned char tcp_flags; /**< tcp flags */ - unsigned char ttl; /**< time to live */ - uint32_t flow_label; /**< flow label */ + uint128_t ipv6_source; /**< v6 souce IP */ + uint128_t ipv6_dest; /**< v6 destination IP */ + unsigned char ip_proto; /**< protocol */ + unsigned char icmp_type; /**< icmp type */ + unsigned char icmp_code; /**< icmp code */ + unsigned char tcp_flags; /**< tcp flags */ + unsigned char ttl; /**< time to live */ + uint32_t flow_label; /**< flow label */ + switch_handle_t sport_range_handle; /**< sport range handle */ + switch_handle_t dport_range_handle; /**< dport range handle */ } switch_acl_ipv6_value; /** Acl IP mask */ @@ -196,42 +196,42 @@ typedef struct switch_acl_mac_key_value_pair_ { /** ACL ip racl field enum */ typedef enum switch_acl_ip_racl_field_ { - SWITCH_ACL_IP_RACL_FIELD_IPV4_SRC, /**< IPv4 Source address */ - SWITCH_ACL_IP_RACL_FIELD_IPV4_DEST, /**< IPv4 Dest address */ - SWITCH_ACL_IP_RACL_FIELD_IP_PROTO, /**< IP protocol (TCP/UDP) */ - SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT, /**< L4 source port */ - SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT, /**< L4 dest port */ + SWITCH_ACL_IP_RACL_FIELD_IPV4_SRC, /**< IPv4 Source address */ + SWITCH_ACL_IP_RACL_FIELD_IPV4_DEST, /**< IPv4 Dest address */ + SWITCH_ACL_IP_RACL_FIELD_IP_PROTO, /**< IP protocol (TCP/UDP) */ + SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT_RANGE, /**< L4 source port */ + SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT_RANGE, /**< L4 dest port */ SWITCH_ACL_IP_RACL_FIELD_MAX } switch_acl_ip_racl_field_t; /** ACL ipv6 racl field enum */ typedef enum switch_acl_ipv6_racl_field_ { - SWITCH_ACL_IPV6_RACL_FIELD_IPV6_SRC, /**< IPv6 source address */ - SWITCH_ACL_IPV6_RACL_FIELD_IPV6_DEST, /**< IPv6 dest address */ - SWITCH_ACL_IPV6_RACL_FIELD_IP_PROTO, /**< IPv6 protocol */ - SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT, /**< L4 source port */ - SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT, /**< L4 dest port */ + SWITCH_ACL_IPV6_RACL_FIELD_IPV6_SRC, /**< IPv6 source address */ + SWITCH_ACL_IPV6_RACL_FIELD_IPV6_DEST, /**< IPv6 dest address */ + SWITCH_ACL_IPV6_RACL_FIELD_IP_PROTO, /**< IPv6 protocol */ + SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT_RANGE, /**< L4 source port */ + SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT_RANGE, /**< L4 dest port */ SWITCH_ACL_IPV6_RACL_FIELD_MAX } switch_acl_ipv6_racl_field_t; /** Acl ip racl field list */ typedef union switch_acl_ip_racl_value_ { - unsigned int ipv4_source; /**< v4 source IP */ - unsigned int ipv4_dest; /**< v4 destination IP */ - unsigned short ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< source port */ - unsigned short l4_dest_port; /**< destination port */ + unsigned int ipv4_source; /**< v4 source IP */ + unsigned int ipv4_dest; /**< v4 destination IP */ + unsigned short ip_proto; /**< protocol */ + switch_handle_t sport_range_handle; /**< sport range handle */ + switch_handle_t dport_range_handle; /**< dport range handle */ } switch_acl_ip_racl_value; /** Acl ipv6 racl field list */ typedef union switch_acl_ipv6_racl_value_ { - uint128_t ipv6_source; /**< v6 source IP */ - uint128_t ipv6_dest; /**< v6 destination IP */ - unsigned short ip_proto; /**< protocol */ - unsigned short l4_source_port; /**< source port */ - unsigned short l4_dest_port; /**< destination port */ + uint128_t ipv6_source; /**< v6 source IP */ + uint128_t ipv6_dest; /**< v6 destination IP */ + unsigned short ip_proto; /**< protocol */ + switch_handle_t sport_range_handle; /**< sport range handle */ + switch_handle_t dport_range_handle; /**< dport range handle */ } switch_acl_ipv6_racl_value; /** Acl ip racl mask */ @@ -413,6 +413,7 @@ typedef enum switch_acl_egr_field_ { SWITCH_ACL_EGR_DEST_PORT, SWITCH_ACL_EGR_DEFLECT, SWITCH_ACL_EGR_L3_MTU_CHECK, + SWITCH_ACL_EGR_ACL_DENY, SWITCH_ACL_EGR_FIELD_MAX } switch_acl_egr_field_t; @@ -421,6 +422,7 @@ typedef union switch_acl_egr_value_ { switch_handle_t egr_port; /**< egress port */ bool deflection_flag; /**< deflection flag */ unsigned short l3_mtu_check; /**< L3 MTU check */ + bool acl_deny; /**< acl deny */ } switch_acl_egr_value_t; /** Egress ACL match mask */ @@ -445,6 +447,8 @@ typedef enum switch_acl_egr_action_ { SWITCH_ACL_EGR_ACTION_SET_MIRROR, /**< Set mirror session */ SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU, /**< redirect to cpu */ SWITCH_ACL_EGR_MIRROR_DROP, /**< negative mirror */ + SWITCH_ACL_EGR_ACTION_DROP, /**< drop packets */ + SWITCH_ACL_EGR_ACTION_PERMIT /**< permit packets */ } switch_acl_egr_action_t; typedef switch_acl_action_t switch_acl_ip_action_t; /**< acl action */ @@ -455,17 +459,32 @@ typedef switch_acl_action_t /** Acl info struct */ typedef struct switch_acl_info_ { - switch_acl_type_t type; /**< acl type */ - void *rules; /**< set of rules */ - tommy_list interface_list; /**< list of interface handles */ + switch_acl_type_t type; /**< acl type */ + switch_direction_t direction; /**< acl direction */ + void *rules; /**< set of rules */ + tommy_list interface_list; /**< list of interface handles */ } switch_acl_info_t; +typedef enum switch_range_type_ { + SWITCH_RANGE_TYPE_NONE = 0x0, + SWITCH_RANGE_TYPE_SRC_PORT = 0x1, + SWITCH_RANGE_TYPE_DST_PORT = 0x2, + SWITCH_RANGE_TYPE_VLAN = 0x3, + SWITCH_RANGE_TYPE_PACKET_LENGTH = 0x4 +} switch_range_type_t; + +typedef struct switch_range_ { + uint32_t start_value; + uint32_t end_value; +} switch_range_t; + /** ACL Key list create @param device device @param type - acl type */ switch_handle_t switch_api_acl_list_create(switch_device_t device, + switch_direction_t direction, switch_acl_type_t type); /** @@ -597,6 +616,27 @@ switch_status_t switch_api_acl_stats_get(switch_device_t device, switch_acl_type_t switch_acl_type_get(switch_device_t device, switch_handle_t acl_handle); +switch_status_t switch_api_acl_range_create(switch_device_t device, + switch_direction_t direction, + switch_range_type_t range_type, + switch_range_t *range, + switch_handle_t *range_handle); + +switch_status_t switch_api_acl_range_update(switch_device_t device, + switch_handle_t range_handle, + switch_range_t *range); + +switch_status_t switch_api_acl_range_type_get(switch_device_t device, + switch_handle_t range_handle, + switch_range_type_t *range_type); + +switch_status_t switch_api_acl_range_get(switch_device_t device, + switch_handle_t range_handle, + switch_range_t *range); + +switch_status_t switch_api_acl_range_delete(switch_device_t device, + switch_handle_t range_handle); + /** @} */ // end of ACL API #ifdef __cplusplus diff --git a/switchapi/include/switchapi/switch_base_types.h b/switchapi/include/switchapi/switch_base_types.h index bc4b45b..d3e67ea 100644 --- a/switchapi/include/switchapi/switch_base_types.h +++ b/switchapi/include/switchapi/switch_base_types.h @@ -44,7 +44,7 @@ extern "C" { #define switch_free(x) free(x) #define switch_realloc(x, sz) realloc(x, sz) -#define HANDLE_TYPE_SHIFT 27 +#define HANDLE_TYPE_SHIFT 26 #define handle_to_id(x) (x & 0x3FFFFFF) #define id_to_handle(t, x) (t << HANDLE_TYPE_SHIFT | (x)) diff --git a/switchapi/include/switchapi/switch_handle.h b/switchapi/include/switchapi/switch_handle.h index 4eeb3df..c8206d2 100644 --- a/switchapi/include/switchapi/switch_handle.h +++ b/switchapi/include/switchapi/switch_handle.h @@ -58,15 +58,16 @@ typedef enum { SWITCH_HANDLE_TYPE_BUFFER_PROFILE, SWITCH_HANDLE_TYPE_VLAN_MEMBER, SWITCH_HANDLE_TYPE_SCHEDULER, + SWITCH_HANDLE_TYPE_RANGE, - SWITCH_HANDLE_TYPE_MAX = 32 + SWITCH_HANDLE_TYPE_MAX = 64 } switch_handle_type_t; /** Generic handle to encode different types of objects handle impicitly encodes the device, type and type specific */ -typedef unsigned long switch_handle_t; +typedef uint64_t switch_handle_t; /** Handle related information */ typedef struct { @@ -140,8 +141,11 @@ switch_handle_type_t switch_handle_get_type(switch_handle_t handle); #define SWITCH_HOSTIF_HANDLE_VALID(handle) \ SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_HOSTIF) +#define SWITCH_RANGE_HANDLE_VALID(handle) \ + SWITCH_HANDLE_VALID(handle, SWITCH_HANDLE_TYPE_RANGE) + // Easy use macros -#define SWITCH_API_INVALID_HANDLE 0xFFFFFFFF +#define SWITCH_API_INVALID_HANDLE ((uint64_t) ~(0)) #define SWITCH_HW_INVALID_HANDLE 0xFFFFFFFF #define _switch_handle_create(_type, _info, _judy, _init, _handle) \ diff --git a/switchapi/src/switch_acl.c b/switchapi/src/switch_acl.c index 8bf5890..a7ef706 100644 --- a/switchapi/src/switch_acl.c +++ b/switchapi/src/switch_acl.c @@ -20,18 +20,21 @@ limitations under the License. #include "switch_acl_int.h" #include "switch_interface_int.h" #include "switch_pd.h" +#include "switch_log_int.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ static void *switch_acl_array; +static void *switch_range_array; switch_api_id_allocator *acl_counter_index = NULL; switch_status_t switch_acl_init(switch_device_t device) { switch_acl_array = NULL; switch_handle_type_init(SWITCH_HANDLE_TYPE_ACL, (4 * 1024)); switch_handle_type_init(SWITCH_HANDLE_TYPE_ACE, (4 * 1024)); + switch_handle_type_init(SWITCH_HANDLE_TYPE_RANGE, (1024)); acl_counter_index = switch_api_id_allocator_new(4 * 1024, FALSE); return SWITCH_STATUS_SUCCESS; } @@ -40,6 +43,7 @@ switch_status_t switch_acl_free(switch_device_t device) { switch_api_id_allocator_destroy(acl_counter_index); switch_handle_type_free(SWITCH_HANDLE_TYPE_ACE); switch_handle_type_free(SWITCH_HANDLE_TYPE_ACL); + switch_handle_type_free(SWITCH_HANDLE_TYPE_RANGE); return SWITCH_STATUS_SUCCESS; } @@ -73,6 +77,7 @@ void switch_acl_counter_index_free(unsigned int index) { } switch_handle_t switch_api_acl_list_create(switch_device_t device, + switch_direction_t direction, switch_acl_type_t type) { switch_acl_info_t *acl_info = NULL; switch_handle_t acl_handle; @@ -83,6 +88,7 @@ switch_handle_t switch_api_acl_list_create(switch_device_t device, return SWITCH_STATUS_NO_MEMORY; } acl_info->type = type; + acl_info->direction = direction; acl_info->rules = NULL; tommy_list_init(&(acl_info->interface_list)); return acl_handle; @@ -141,6 +147,7 @@ static switch_status_t switch_ace_delete(switch_handle_t handle) { static switch_status_t switch_acl_ip_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -153,7 +160,7 @@ static switch_status_t switch_acl_ip_set_fields_actions( if (interface_handle) { if (switch_handle_get_type(interface_handle) == SWITCH_HANDLE_TYPE_PORT) { - if_label = handle_to_id(interface_handle); + if_label = handle_to_id(interface_handle) + 1; } else { intf_info = switch_api_interface_get(interface_handle); if (!intf_info) { @@ -161,10 +168,10 @@ static switch_status_t switch_acl_ip_set_fields_actions( } switch (switch_handle_get_type(interface_handle)) { case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; + if_label = intf_info->api_intf_info.u.port_lag_handle + 1; break; case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); + bd_label = handle_to_id(interface_handle) + 1; ; break; default: @@ -178,21 +185,35 @@ static switch_status_t switch_acl_ip_set_fields_actions( } ip_acl = (switch_acl_ip_key_value_pair_t *)p->fields; - status = switch_pd_ipv4_acl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - ip_acl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_ipv4_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ip_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } else { + status = switch_pd_egress_ipv4_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ip_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } return status; } static switch_status_t switch_acl_ipv6_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -203,38 +224,57 @@ static switch_status_t switch_acl_ipv6_set_fields_actions( switch_status_t status = SWITCH_STATUS_SUCCESS; if (interface_handle) { - intf_info = switch_api_interface_get(interface_handle); - if (!intf_info) { - return SWITCH_STATUS_INVALID_INTERFACE; - } - switch (switch_handle_get_type(interface_handle)) { - case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; - break; - case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); - ; - break; - default: - return SWITCH_STATUS_INVALID_HANDLE; + if (switch_handle_get_type(interface_handle) == SWITCH_HANDLE_TYPE_PORT) { + if_label = handle_to_id(interface_handle) + 1; + } else { + intf_info = switch_api_interface_get(interface_handle); + if (!intf_info) { + return SWITCH_STATUS_INVALID_INTERFACE; + } + switch (switch_handle_get_type(interface_handle)) { + case SWITCH_HANDLE_TYPE_INTERFACE: + if_label = intf_info->api_intf_info.u.port_lag_handle + 1; + break; + case SWITCH_HANDLE_TYPE_BD: + bd_label = handle_to_id(interface_handle) + 1; + ; + break; + default: + return SWITCH_STATUS_INVALID_HANDLE; + } } } ipv6_acl = (switch_acl_ipv6_key_value_pair_t *)p->fields; - status = switch_pd_ipv6_acl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - ipv6_acl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_ipv6_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ipv6_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } else { + status = switch_pd_egress_ipv6_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ipv6_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } return status; } static switch_status_t switch_acl_mac_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -251,10 +291,10 @@ static switch_status_t switch_acl_mac_set_fields_actions( } switch (switch_handle_get_type(interface_handle)) { case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; + if_label = intf_info->api_intf_info.u.port_lag_handle + 1; break; case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); + bd_label = handle_to_id(interface_handle) + 1; ; break; default: @@ -263,21 +303,36 @@ static switch_status_t switch_acl_mac_set_fields_actions( } mac_acl = (switch_acl_mac_key_value_pair_t *)p->fields; - status = switch_pd_mac_acl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - mac_acl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_mac_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + mac_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } else { + status = switch_pd_egress_mac_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + mac_acl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } + return status; } static switch_status_t switch_acl_ip_racl_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -289,29 +344,36 @@ static switch_status_t switch_acl_ip_racl_set_fields_actions( if (interface_handle) { switch (switch_handle_get_type(interface_handle)) { case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); + bd_label = handle_to_id(interface_handle) + 1; ; break; default: return SWITCH_STATUS_INVALID_HANDLE; } } + ip_racl = (switch_acl_ip_racl_key_value_pair_t *)p->fields; - status = switch_pd_ipv4_racl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - ip_racl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_ipv4_racl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ip_racl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } else { + status = SWITCH_STATUS_NOT_SUPPORTED; + } return status; } static switch_status_t switch_acl_ipv6_racl_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -323,7 +385,7 @@ static switch_status_t switch_acl_ipv6_racl_set_fields_actions( if (interface_handle) { switch (switch_handle_get_type(interface_handle)) { case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); + bd_label = handle_to_id(interface_handle) + 1; ; break; default: @@ -332,21 +394,28 @@ static switch_status_t switch_acl_ipv6_racl_set_fields_actions( } } ipv6_racl = (switch_acl_ipv6_racl_key_value_pair_t *)p->fields; - status = switch_pd_ipv6_racl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - ipv6_racl, - p->action, - &(p->action_params), - &(p->opt_action_params), - entry); + + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_ipv6_racl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + ipv6_racl, + p->action, + &(p->action_params), + &(p->opt_action_params), + entry); + } else { + status = SWITCH_STATUS_NOT_SUPPORTED; + } + return status; } static switch_status_t switch_acl_system_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -363,10 +432,10 @@ static switch_status_t switch_acl_system_set_fields_actions( } switch (switch_handle_get_type(interface_handle)) { case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; + if_label = intf_info->api_intf_info.u.port_lag_handle + 1; break; case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); + bd_label = handle_to_id(interface_handle) + 1; ; break; default: @@ -374,21 +443,25 @@ static switch_status_t switch_acl_system_set_fields_actions( } } system_acl = (switch_acl_system_key_value_pair_t *)p->fields; - status = switch_pd_system_acl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - system_acl, - p->action, - &p->action_params, - &p->opt_action_params, - entry); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = switch_pd_system_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + system_acl, + p->action, + &p->action_params, + &p->opt_action_params, + entry); + } else { + } return status; } static switch_status_t switch_acl_egr_set_fields_actions( switch_device_t device, + switch_direction_t direction, switch_acl_rule_t *p, switch_handle_t interface_handle, p4_pd_entry_hdl_t *entry) { @@ -408,10 +481,10 @@ static switch_status_t switch_acl_egr_set_fields_actions( } switch (switch_handle_get_type(interface_handle)) { case SWITCH_HANDLE_TYPE_INTERFACE: - if_label = intf_info->api_intf_info.u.port_lag_handle; + if_label = intf_info->api_intf_info.u.port_lag_handle + 1; break; case SWITCH_HANDLE_TYPE_BD: - bd_label = handle_to_id(interface_handle); + bd_label = handle_to_id(interface_handle) + 1; ; break; default: @@ -421,16 +494,19 @@ static switch_status_t switch_acl_egr_set_fields_actions( } egr_acl = (switch_acl_egr_key_value_pair_t *)p->fields; - status = switch_pd_egr_acl_table_add_entry(device, - if_label, - bd_label, - p->priority, - p->field_count, - egr_acl, - p->action, - &p->action_params, - &p->opt_action_params, - entry); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + } else { + status = switch_pd_egr_acl_table_add_entry(device, + if_label, + bd_label, + p->priority, + p->field_count, + egr_acl, + p->action, + &p->action_params, + &p->opt_action_params, + entry); + } return status; } @@ -447,31 +523,31 @@ static switch_status_t acl_hw_set(switch_device_t device, switch (acl_info->type) { case SWITCH_ACL_TYPE_SYSTEM: status = switch_acl_system_set_fields_actions( - device, p, interface_handle, &entry); + device, acl_info->direction, p, interface_handle, &entry); break; case SWITCH_ACL_TYPE_IP: - status = - switch_acl_ip_set_fields_actions(device, p, interface_handle, &entry); + status = switch_acl_ip_set_fields_actions( + device, acl_info->direction, p, interface_handle, &entry); break; case SWITCH_ACL_TYPE_IPV6: status = switch_acl_ipv6_set_fields_actions( - device, p, interface_handle, &entry); + device, acl_info->direction, p, interface_handle, &entry); break; case SWITCH_ACL_TYPE_IP_RACL: status = switch_acl_ip_racl_set_fields_actions( - device, p, interface_handle, &entry); + device, acl_info->direction, p, interface_handle, &entry); break; case SWITCH_ACL_TYPE_IPV6_RACL: status = switch_acl_ipv6_racl_set_fields_actions( - device, p, interface_handle, &entry); + device, acl_info->direction, p, interface_handle, &entry); break; case SWITCH_ACL_TYPE_MAC: status = switch_acl_mac_set_fields_actions( - device, p, interface_handle, &entry); + device, acl_info->direction, p, interface_handle, &entry); break; case SWITCH_ACL_TYPE_EGRESS_SYSTEM: status = switch_acl_egr_set_fields_actions( - device, p, interface_handle, &entry); + device, acl_info->direction, p, interface_handle, &entry); break; default: break; @@ -504,7 +580,7 @@ static switch_status_t acl_hw_del(switch_device_t device, return SWITCH_STATUS_UNSUPPORTED_TYPE; return switch_pd_system_acl_table_delete_entry( - device, switch_ace_get(ace_handle)->hw_entry); + device, acl_info->direction, switch_ace_get(ace_handle)->hw_entry); } JLG(hw_entry, intf->entries, ace_handle); @@ -512,31 +588,31 @@ static switch_status_t acl_hw_del(switch_device_t device, switch (acl_info->type) { case SWITCH_ACL_TYPE_SYSTEM: status = switch_pd_system_acl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; case SWITCH_ACL_TYPE_IP: status = switch_pd_ipv4_acl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; case SWITCH_ACL_TYPE_IPV6: status = switch_pd_ipv6_acl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; case SWITCH_ACL_TYPE_IP_RACL: status = switch_pd_ipv4_racl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; case SWITCH_ACL_TYPE_IPV6_RACL: status = switch_pd_ipv6_racl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; case SWITCH_ACL_TYPE_MAC: status = switch_pd_mac_acl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; case SWITCH_ACL_TYPE_EGRESS_SYSTEM: status = switch_pd_egr_acl_table_delete_entry( - device, *(unsigned long *)hw_entry); + device, acl_info->direction, *(unsigned long *)hw_entry); break; default: break; @@ -894,6 +970,174 @@ switch_acl_type_t switch_acl_type_get(switch_device_t device, return acl_info->type; } +switch_handle_t switch_range_handle_create() { + switch_handle_t range_handle; + _switch_handle_create(SWITCH_HANDLE_TYPE_RANGE, + switch_range_info_t, + switch_range_array, + NULL, + range_handle); + return range_handle; +} + +switch_range_info_t *switch_range_get(switch_handle_t range_handle) { + switch_range_info_t *range_info = NULL; + _switch_handle_get( + switch_range_info_t, switch_range_array, range_handle, range_info); + return range_info; +} + +switch_status_t switch_range_handle_delete(switch_handle_t handle) { + _switch_handle_delete(switch_range_info_t, switch_range_array, handle); + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t switch_api_acl_range_create(switch_device_t device, + switch_direction_t direction, + switch_range_type_t range_type, + switch_range_t *range, + switch_handle_t *range_handle) { + switch_range_info_t *range_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + *range_handle = switch_range_handle_create(); + range_info = switch_range_get(*range_handle); + if (!range_info) { + SWITCH_API_ERROR("failed to create range handle"); + return SWITCH_STATUS_NO_MEMORY; + } + + if (range_type == SWITCH_RANGE_TYPE_VLAN || + range_type == SWITCH_RANGE_TYPE_PACKET_LENGTH) { + SWITCH_API_ERROR( + "failed to create range handle." + "invalid range type (vlan or packet length)"); + return SWITCH_STATUS_NOT_SUPPORTED; + } + + if (direction != SWITCH_API_DIRECTION_INGRESS && + direction != SWITCH_API_DIRECTION_EGRESS) { + SWITCH_API_ERROR("failed to create range"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + memcpy(&range_info->range, range, sizeof(switch_range_t)); + range_info->range_type = range_type; + range_info->direction = direction; + + status = switch_pd_range_entry_add(device, + direction, + handle_to_id(*range_handle), + range_type, + range, + &range_info->hw_entry); + + return status; +} + +switch_status_t switch_api_acl_range_update(switch_device_t device, + switch_handle_t range_handle, + switch_range_t *range) { + switch_range_info_t *range_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_RANGE_HANDLE_VALID(range_handle)) { + SWITCH_API_ERROR("failed to update range. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + range_info = switch_range_get(range_handle); + if (!range_info) { + SWITCH_API_ERROR("failed to update range. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + memcpy(&range_info->range, range, sizeof(switch_range_t)); + + status = switch_pd_range_entry_update(device, + range_info->direction, + handle_to_id(range_handle), + range_info->range_type, + range, + range_info->hw_entry); + return status; +} + +switch_status_t switch_api_acl_range_get(switch_device_t device, + switch_handle_t range_handle, + switch_range_t *range) { + switch_range_info_t *range_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_RANGE_HANDLE_VALID(range_handle)) { + SWITCH_API_ERROR("failed to get range. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + range_info = switch_range_get(range_handle); + if (!range_info) { + SWITCH_API_ERROR("failed to get range. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + memcpy(range, &range_info->range, sizeof(switch_range_t)); + + return status; +} + +switch_status_t switch_api_acl_range_delete(switch_device_t device, + switch_handle_t range_handle) { + switch_range_info_t *range_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_RANGE_HANDLE_VALID(range_handle)) { + SWITCH_API_ERROR("failed to delete range. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + range_info = switch_range_get(range_handle); + if (!range_info) { + SWITCH_API_ERROR("failed to delete range. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + status = switch_pd_range_entry_delete(device, + range_info->direction, + range_info->range_type, + range_info->hw_entry); + + if (status != SWITCH_STATUS_SUCCESS) { + SWITCH_API_ERROR("failed to delete range. pd delete failed"); + return status; + } + + switch_range_handle_delete(range_handle); + + return status; +} + +switch_status_t switch_api_acl_range_type_get(switch_device_t device, + switch_handle_t range_handle, + switch_range_type_t *range_type) { + switch_range_info_t *range_info = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (!SWITCH_RANGE_HANDLE_VALID(range_handle)) { + SWITCH_API_ERROR("failed to get range type. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + range_info = switch_range_get(range_handle); + if (!range_info) { + SWITCH_API_ERROR("failed to get range type. invalid range handle"); + return SWITCH_STATUS_INVALID_PARAMETER; + } + + *range_type = range_info->range_type; + + return status; +} + #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_acl_int.h b/switchapi/src/switch_acl_int.h index 34a5dd8..5725c66 100644 --- a/switchapi/src/switch_acl_int.h +++ b/switchapi/src/switch_acl_int.h @@ -33,6 +33,13 @@ typedef struct switch_acl_interface_ { void *entries; } switch_acl_interface_t; +typedef struct switch_range_info_ { + switch_range_t range; + switch_range_type_t range_type; + switch_direction_t direction; + p4_pd_entry_hdl_t hw_entry; +} switch_range_info_t; + typedef struct switch_acl_rule_ { switch_handle_t acl_handle; int priority; diff --git a/switchapi/src/switch_api.thrift b/switchapi/src/switch_api.thrift index 16c47c6..454e2b2 100644 --- a/switchapi/src/switch_api.thrift +++ b/switchapi/src/switch_api.thrift @@ -78,7 +78,7 @@ typedef i32 switcht_handle_type_t typedef byte switcht_device_t typedef i32 switcht_vrf_id_t -typedef i32 switcht_handle_t +typedef i64 switcht_handle_t typedef string switcht_mac_addr_t typedef i32 switcht_port_t typedef i16 switcht_vlan_t @@ -527,6 +527,11 @@ struct switcht_scheduler_info_t { 9: i32 max_rate; } +struct switcht_range_t { + 1: i32 start_value; + 2: i32 end_value; +} + service switch_api_rpc { /* init */ switcht_status_t switcht_api_init(1:switcht_device_t device); @@ -702,7 +707,10 @@ service switch_api_rpc { switcht_status_t switcht_api_nat_delete(1:switcht_device_t device, 2:switcht_nat_info_t nat_info); /* ACL API */ - switcht_handle_t switcht_api_acl_list_create(1:switcht_device_t device, 2:switcht_acl_type_t type); + switcht_handle_t switcht_api_acl_list_create( + 1:switcht_device_t device, + 2:switcht_direction_t direction, + 3:switcht_acl_type_t type); switcht_status_t switcht_api_acl_list_delete(1:switcht_device_t device, 2:switcht_handle_t handle); switcht_handle_t switcht_api_acl_mac_rule_create( 1:switcht_device_t device, @@ -796,6 +804,18 @@ service switch_api_rpc { switcht_counter_t switcht_api_acl_stats_get( 1: switcht_device_t device, 2: switcht_handle_t counter_handle); + switcht_handle_t switcht_api_acl_range_create( + 1: switcht_device_t device, + 2: switcht_direction_t direction, + 3: byte range_type, + 4: switcht_range_t range); + switcht_status_t switcht_api_acl_range_update( + 1: switcht_device_t device, + 2: switcht_handle_t range_handle, + 3: switcht_range_t range); + switcht_status_t switcht_api_acl_range_delete( + 1: switcht_device_t device, + 2: switcht_handle_t range_handle); /* HOSTIF API */ switcht_handle_t switcht_api_hostif_group_create(1:switcht_device_t device, 2:switcht_hostif_group_t hostif_group); @@ -883,7 +903,7 @@ service switch_api_rpc { switcht_status_t switcht_api_sflow_session_delete(1:switcht_device_t device, 2:switcht_handle_t sflow_hdl, 3:bool all_cleanup); - switcht_status_t switcht_api_sflow_session_attach( + switcht_handle_t switcht_api_sflow_session_attach( 1:switcht_device_t device, 2:switcht_handle_t sflow_handle, 3:switcht_direction_t direction, diff --git a/switchapi/src/switch_api_rpc_server.cpp b/switchapi/src/switch_api_rpc_server.cpp index e695887..b7d5e36 100644 --- a/switchapi/src/switch_api_rpc_server.cpp +++ b/switchapi/src/switch_api_rpc_server.cpp @@ -275,7 +275,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_port_qos_group_egress_set(device, port_handle, qos_handle); } - switcht_status_t switcht_api_vrf_create(const switcht_device_t device, const switcht_vrf_id_t vrf) { + switcht_handle_t switcht_api_vrf_create(const switcht_device_t device, const switcht_vrf_id_t vrf) { printf("switcht_api_l3_vrf_create\n"); return switch_api_vrf_create(device, vrf); } @@ -529,7 +529,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return; } - switcht_status_t switcht_api_mac_table_entry_create(const switcht_device_t device, const switcht_handle_t vlan_handle, const switcht_mac_addr_t& mac, const int8_t entry_type, const switcht_interface_handle_t interface_handle) { + switcht_status_t switcht_api_mac_table_entry_create(const switcht_device_t device, const switcht_handle_t vlan_handle, const switcht_mac_addr_t& mac, const int8_t entry_type, const switcht_handle_t interface_handle) { switch_api_mac_entry_t mac_entry; switch_string_to_mac(mac, mac_entry.mac.mac_addr); printf("switcht_api_l2_mac_add\n"); @@ -539,7 +539,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return switch_api_mac_table_entry_add(device, &mac_entry); } - switcht_status_t switcht_api_mac_table_entry_update(const switcht_device_t device, const switcht_handle_t vlan_handle, const switcht_mac_addr_t& mac, const int8_t entry_type, const switcht_interface_handle_t interface_handle) { + switcht_status_t switcht_api_mac_table_entry_update(const switcht_device_t device, const switcht_handle_t vlan_handle, const switcht_mac_addr_t& mac, const int8_t entry_type, const switcht_handle_t interface_handle) { switch_api_mac_entry_t mac_entry; switch_string_to_mac(mac, mac_entry.mac.mac_addr); printf("switcht_api_l2_mac_update\n"); @@ -974,9 +974,12 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { // ACL - switcht_handle_t switcht_api_acl_list_create(const switcht_device_t device, const switcht_acl_type_t type) { + switcht_handle_t switcht_api_acl_list_create( + const switcht_device_t device, + const switcht_direction_t direction, + const switcht_acl_type_t type) { printf("switcht_api_acl_list_create\n"); - return switch_api_acl_list_create(device, (switch_acl_type_t)type); + return switch_api_acl_list_create(device, (switch_direction_t) direction, (switch_acl_type_t)type); } switcht_status_t switcht_api_acl_list_delete(const switcht_device_t device, const switcht_handle_t handle) { @@ -1000,7 +1003,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { std::vector::const_iterator f=acl_kvp.begin(); - void *fields = calloc(sizeof(switch_acl_ip_key_value_pair_t)*acl_kvp.size(), 1); + void *fields = calloc(sizeof(switch_acl_mac_key_value_pair_t)*acl_kvp.size(), 1); for(uint32_t i=0;ifield = (switch_acl_mac_field_t)f->field; switch ((switch_acl_mac_field_t) f->field) { @@ -1009,7 +1012,7 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { { unsigned char *mac = (unsigned char *) (((switch_acl_mac_key_value_pair_t *) fields + i)->value.source_mac.mac_addr); switch_string_to_mac(f->value.value_str, mac); - unsigned char *mac_mask = (unsigned char *) (((switch_acl_mac_key_value_pair_t *) fields + i)->mask.u.mask); + unsigned char *mac_mask = (unsigned char *) (&(((switch_acl_mac_key_value_pair_t *) fields + i)->mask.u.mask)); switch_string_to_mac(f->mask.value_str, mac_mask); break; } @@ -1382,6 +1385,51 @@ class switch_api_rpcHandler : virtual public switch_api_rpcIf { return; } + switcht_handle_t + switcht_api_acl_range_create( + const switcht_device_t device, + const switcht_direction_t direction, + const int8_t range_type, + const switcht_range_t& range) { + switch_handle_t range_handle = 0; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_range_t api_range; + memset(&api_range, 0x0, sizeof(api_range)); + api_range.start_value = range.start_value; + api_range.end_value = range.end_value; + status = switch_api_acl_range_create( + device, + (switch_direction_t) direction, + (switch_range_type_t) range_type, + &api_range, + &range_handle); + return range_handle; + } + + switcht_status_t + switcht_api_acl_range_update( + const switcht_device_t device, + const switcht_handle_t range_handle, + const switcht_range_t& range) { + switch_range_t api_range; + switch_status_t status = SWITCH_STATUS_SUCCESS; + memset(&api_range, 0x0, sizeof(api_range)); + api_range.start_value = range.start_value; + api_range.end_value = range.end_value; + status = switch_api_acl_range_update( + device, + range_handle, + &api_range); + return status; + } + + switcht_status_t switcht_api_acl_range_delete( + const switcht_device_t device, + const switcht_handle_t range_handle) { + return switch_api_acl_range_delete(device, range_handle); + } + + switcht_handle_t switcht_api_multicast_tree_create(const switcht_device_t device) { printf("switcht_api_multicast_tree_create\n"); return switch_api_multicast_tree_create(device); diff --git a/switchapi/src/switch_handle.c b/switchapi/src/switch_handle.c index a677313..3e148af 100644 --- a/switchapi/src/switch_handle.c +++ b/switchapi/src/switch_handle.c @@ -112,17 +112,22 @@ void switch_handle_free(switch_handle_t handle) { switch_handle_info_t *handle_info = NULL; void *p = NULL; - type = (handle & 0xF8000000) >> HANDLE_TYPE_SHIFT; + uint32_t handle_id_mask = ((1 << HANDLE_TYPE_SHIFT) - 1); + uint32_t handle_type_mask = ~(handle_id_mask); + + type = (handle & handle_type_mask) >> HANDLE_TYPE_SHIFT; JLG(p, switch_handle_array, (unsigned int)type); if ((handle_info = (switch_handle_info_t *)(*(unsigned long *)p))) { switch_api_id_allocator_release(handle_info->allocator, - handle & 0x00FFFFFF); + handle & handle_id_mask); handle_info->num_in_use--; } } switch_handle_type_t switch_handle_get_type(switch_handle_t handle) { - switch_handle_type_t type = (handle & 0xF8000000) >> HANDLE_TYPE_SHIFT; + uint32_t handle_id_mask = ((1 << HANDLE_TYPE_SHIFT) - 1); + uint32_t handle_type_mask = ~(handle_id_mask); + switch_handle_type_t type = (handle & handle_type_mask) >> HANDLE_TYPE_SHIFT; return type; } diff --git a/switchapi/src/switch_hostif.c b/switchapi/src/switch_hostif.c index 31d4b28..48d08d6 100644 --- a/switchapi/src/switch_hostif.c +++ b/switchapi/src/switch_hostif.c @@ -170,7 +170,8 @@ switch_status_t switch_api_hostif_reason_code_create( switch (rcode_api_info->reason_code) { case SWITCH_HOSTIF_REASON_CODE_STP: { // stp bpdu, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_MAC); switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -196,8 +197,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -230,7 +231,8 @@ switch_status_t switch_api_hostif_reason_code_create( } case SWITCH_HOSTIF_REASON_CODE_LACP: { // lacp bpdu, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_MAC); switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -256,8 +258,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -290,7 +292,8 @@ switch_status_t switch_api_hostif_reason_code_create( } case SWITCH_HOSTIF_REASON_CODE_LLDP: { // lacp frame, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_MAC); switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -374,8 +377,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -406,7 +409,8 @@ switch_status_t switch_api_hostif_reason_code_create( break; } case SWITCH_HOSTIF_REASON_CODE_OSPF: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_IP); switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; // All OSPF routers 224.0.0.5, copy to cpu @@ -457,8 +461,8 @@ switch_status_t switch_api_hostif_reason_code_create( switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -494,7 +498,8 @@ switch_status_t switch_api_hostif_reason_code_create( } case SWITCH_HOSTIF_REASON_CODE_OSPFV6: { // All OSPFv3 routers ff02::5, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IPV6); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_IPV6); switch_acl_ipv6_key_value_pair_t acl_kvp[SWITCH_ACL_IPV6_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); @@ -546,8 +551,8 @@ switch_status_t switch_api_hostif_reason_code_create( switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -583,7 +588,8 @@ switch_status_t switch_api_hostif_reason_code_create( } case SWITCH_HOSTIF_REASON_CODE_IPV6_NEIGHBOR_DISCOVERY: { // IPV6 ND packet, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IPV6); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_IPV6); switch_acl_ipv6_key_value_pair_t acl_kvp[SWITCH_ACL_IPV6_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); @@ -648,8 +654,8 @@ switch_status_t switch_api_hostif_reason_code_create( switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -685,7 +691,8 @@ switch_status_t switch_api_hostif_reason_code_create( } case SWITCH_HOSTIF_REASON_CODE_PIM: { // PIM packet, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_IP); switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -706,8 +713,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -743,7 +750,8 @@ switch_status_t switch_api_hostif_reason_code_create( } case SWITCH_HOSTIF_REASON_CODE_IGMP_TYPE_V2_REPORT: { // IGMPv2 report packet, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_IP); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_IP); switch_acl_ip_key_value_pair_t acl_kvp[SWITCH_ACL_IP_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -764,8 +772,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -796,7 +804,8 @@ switch_status_t switch_api_hostif_reason_code_create( break; } case SWITCH_HOSTIF_REASON_CODE_ARP_REQUEST: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_MAC); switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -826,8 +835,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -862,7 +871,8 @@ switch_status_t switch_api_hostif_reason_code_create( break; } case SWITCH_HOSTIF_REASON_CODE_ARP_RESPONSE: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_MAC); switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -883,8 +893,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -923,7 +933,8 @@ switch_status_t switch_api_hostif_reason_code_create( break; } case SWITCH_HOSTIF_REASON_CODE_TTL_ERROR: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -971,7 +982,8 @@ switch_status_t switch_api_hostif_reason_code_create( break; } case SWITCH_HOSTIF_REASON_CODE_BROADCAST: { - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_MAC); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_MAC); switch_acl_mac_key_value_pair_t acl_kvp[SWITCH_ACL_MAC_FIELD_MAX]; memset(&acl_kvp, 0, sizeof(acl_kvp)); field_count = 0; @@ -997,8 +1009,8 @@ switch_status_t switch_api_hostif_reason_code_create( &ace_handle); switch_api_acl_reference(device, acl_handle, 0); - system_acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + system_acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); switch_acl_system_key_value_pair_t system_acl_kvp[SWITCH_ACL_SYSTEM_FIELD_MAX]; memset(&system_acl_kvp, 0, sizeof(system_acl_kvp)); @@ -1182,12 +1194,8 @@ const char *switch_api_hostif_code_string( } switch_status_t switch_api_hostif_rx_packet_from_hw( - switch_packet_header_t *packet_header, - switch_opt_header_t *opt_header, - char *packet, - int packet_size) { + switch_packet_header_t *packet_header, char *packet, int packet_size) { switch_cpu_header_t *cpu_header = NULL; - switch_sflow_header_t *sflow_header = NULL; switch_hostif_rcode_info_t *rcode_info = NULL; void *temp = NULL; switch_hostif_packet_t hostif_packet; @@ -1218,12 +1226,6 @@ switch_status_t switch_api_hostif_rx_packet_from_hw( hostif_packet.handle = id_to_handle(SWITCH_HANDLE_TYPE_PORT, cpu_header->ingress_port); - 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; - } - if (SWITCH_IS_LAG_IFINDEX(cpu_header->ingress_ifindex)) { hostif_packet.is_lag = TRUE; } diff --git a/switchapi/src/switch_hostif_int.h b/switchapi/src/switch_hostif_int.h index f44f574..16047a3 100644 --- a/switchapi/src/switch_hostif_int.h +++ b/switchapi/src/switch_hostif_int.h @@ -71,6 +71,7 @@ typedef struct __attribute__((__packed__)) switch_cpu_header_ { uint16_t ingress_ifindex; uint16_t ingress_bd; uint16_t reason_code; + uint16_t mcast_grp; } switch_cpu_header_t; typedef struct __attribute__((__packed__)) switch_sflow_header_ { @@ -110,10 +111,7 @@ switch_status_t switch_hostif_init(switch_device_t device); 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, - switch_opt_header_t *opt_header, - char *packet, - int packet_size); + switch_packet_header_t *packet_header, char *packet, int packet_size); 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, diff --git a/switchapi/src/switch_init.c b/switchapi/src/switch_init.c index cb41a08..bc16a7d 100644 --- a/switchapi/src/switch_init.c +++ b/switchapi/src/switch_init.c @@ -152,6 +152,7 @@ switch_status_t switch_api_init_default_entries(switch_device_t device) { switch_pd_l3_rewrite_table_add_default_entry(device); switch_pd_adjust_lkp_fields_table_add_default_entry(device); switch_pd_qos_default_entry_add(device); + switch_pd_l4port_default_entry_add(device); SWITCH_API_TRACE("Programming init entries!!"); switch_pd_learn_notify_table_add_init_entry(device); @@ -168,6 +169,7 @@ switch_status_t switch_api_init_default_entries(switch_device_t device) { switch_pd_replica_type_table_init_entry(device); switch_pd_rewrite_multicast_table_init_entry(device); switch_pd_l3_rewrite_table_init_entry(device); + switch_pd_egress_l4port_fields_init_entry(device); switch_pd_nat_init(device); #ifdef P4_INT_ENABLE @@ -181,8 +183,8 @@ switch_status_t switch_api_init_default_entries(switch_device_t device) { void switch_system_acl_entries_delete(switch_device_t device) { // go over the array, delete dynamic entries switch_default_acl_t *acl = &_switch_system_acl_data[device][0]; - - for (int i = 0; i < SWITCH_INGRESS_ACL_ENTRIES; i++) { + int i = 0; + for (i = 0; i < SWITCH_INGRESS_ACL_ENTRIES; i++) { switch_api_acl_rule_delete(device, acl->acl_handle, acl->ace_handle); acl++; } @@ -195,8 +197,8 @@ void switch_system_acl_entries_add(switch_device_t device) { memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); action = SWITCH_ACL_ACTION_DROP; - - for (int i = 0; i < SWITCH_INGRESS_ACL_ENTRIES; i++) { + int i = 0; + for (i = 0; i < SWITCH_INGRESS_ACL_ENTRIES; i++) { switch_api_acl_rule_create(device, acl->acl_handle, acl->priority, @@ -212,8 +214,8 @@ void switch_system_acl_entries_add(switch_device_t device) { void switch_egress_acl_entries_delete(switch_device_t device) { switch_default_acl_t *acl = &_switch_egress_acl_data[device][0]; - - for (int i = 0; i < SWITCH_EGRESS_ACL_ENTRIES; i++) { + int i = 0; + for (i = 0; i < SWITCH_EGRESS_ACL_ENTRIES; i++) { switch_api_acl_rule_delete(device, acl->acl_handle, acl->ace_handle); acl++; } @@ -242,6 +244,23 @@ void switch_egress_acl_entries_add(switch_device_t device) { &acl->action_params, &opt_action_params, &acl->ace_handle); + + acl++; + + memset(egr_acl_kvp, 0, sizeof(egr_acl_kvp)); + egr_acl_kvp[0].field = SWITCH_ACL_EGR_ACL_DENY; + egr_acl_kvp[0].value.acl_deny = 1; + egr_acl_kvp[0].mask.u.mask = 0xFF; + memset(&acl->action_params, 0, sizeof(switch_acl_action_params_t)); + switch_api_acl_rule_create(device, + acl->acl_handle, + acl->priority, + acl->key_value_count, + egr_acl_kvp, + SWITCH_ACL_EGR_ACTION_DROP, + &acl->action_params, + &opt_action_params, + &acl->ace_handle); } switch_status_t switch_negative_mirroring_set(switch_device_t device, @@ -272,7 +291,8 @@ static switch_status_t switch_api_init_default_acl_entries( memset(&opt_action_params, 0, sizeof(switch_acl_opt_action_params_t)); // system acl for dropped packets - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_DROP; dacl->acl_kvp[0].value.drop_flag = 1; @@ -283,7 +303,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // port vlan mapping miss, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_PORT_VLAN_MAPPING_MISS; dacl->acl_kvp[0].value.port_vlan_mapping_miss = 1; @@ -295,7 +316,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // STP state == blocked, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; dacl->acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_BLOCKING; @@ -307,7 +329,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // STP state == learning, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_STP_STATE; dacl->acl_kvp[0].value.stp_state = SWITCH_PORT_STP_STATE_LEARNING; @@ -319,7 +342,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // ACL deny, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ACL_DENY; dacl->acl_kvp[0].value.acl_deny = 1; @@ -331,7 +355,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // URPF check fail, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_URPF_CHECK; dacl->acl_kvp[0].value.urpf_check_fail = 1; @@ -343,7 +368,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // same if check fail, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_IF_CHECK; dacl->acl_kvp[0].value.if_check = 0; @@ -364,7 +390,8 @@ static switch_status_t switch_api_init_default_acl_entries( dacl++; // egress ifindex is drop ifindex, drop - dacl->acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + dacl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(dacl->acl_kvp, 0, sizeof(dacl->acl_kvp)); dacl->acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_EGRESS_IFINDEX; dacl->acl_kvp[0].value.out_ifindex = switch_api_drop_ifindex(); @@ -378,7 +405,8 @@ static switch_status_t switch_api_init_default_acl_entries( switch_system_acl_entries_add(device); // routed, ttl == 1, egress_ifindex == cpu, permit - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; @@ -401,7 +429,8 @@ static switch_status_t switch_api_init_default_acl_entries( &handle); // routed, ttl == 1, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; @@ -422,7 +451,8 @@ static switch_status_t switch_api_init_default_acl_entries( &handle); // routed, ipv6_src_is_link_local == 1, egress_ifindex == cpu, permit - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; @@ -447,7 +477,8 @@ static switch_status_t switch_api_init_default_acl_entries( &handle); // routed, ipv6_src_is_link_local == 1, redirect to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; @@ -469,7 +500,8 @@ static switch_status_t switch_api_init_default_acl_entries( &handle); // routed, ingress bd == egress bd, copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_ROUTED; acl_kvp[0].value.routed = true; @@ -491,7 +523,8 @@ static switch_status_t switch_api_init_default_acl_entries( &handle); // l3_copy to cpu - acl_handle = switch_api_acl_list_create(device, SWITCH_ACL_TYPE_SYSTEM); + acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_SYSTEM); memset(acl_kvp, 0, sizeof(acl_kvp)); acl_kvp[0].field = SWITCH_ACL_SYSTEM_FIELD_L3_COPY; acl_kvp[0].value.l3_copy = true; @@ -509,21 +542,29 @@ static switch_status_t switch_api_init_default_acl_entries( switch_default_acl_t *egr_acl = &_switch_egress_acl_data[device][0]; // set acl handler and priority for egress mtu check rule - egr_acl->acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_EGRESS_SYSTEM); + egr_acl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); egr_acl->priority = priority++; egr_acl->key_value_count = 1; switch_api_acl_reference(device, egr_acl->acl_handle, 0); egr_acl++; // set acl handler and priority for egress dod rule - egr_acl->acl_handle = - switch_api_acl_list_create(device, SWITCH_ACL_TYPE_EGRESS_SYSTEM); - egr_acl->priority = priority; + egr_acl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); + egr_acl->priority = priority++; + egr_acl->key_value_count = 1; + switch_api_acl_reference(device, egr_acl->acl_handle, 0); + egr_acl++; + + egr_acl->acl_handle = switch_api_acl_list_create( + device, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_EGRESS_SYSTEM); + egr_acl->priority = priority++; egr_acl->key_value_count = 1; - switch_egress_acl_entries_add(device); switch_api_acl_reference(device, egr_acl->acl_handle, 0); + switch_egress_acl_entries_add(device); + return SWITCH_STATUS_SUCCESS; } diff --git a/switchapi/src/switch_nhop.c b/switchapi/src/switch_nhop.c index 1d73f1f..293fd7a 100644 --- a/switchapi/src/switch_nhop.c +++ b/switchapi/src/switch_nhop.c @@ -421,7 +421,7 @@ switch_status_t switch_api_nhop_update(switch_device_t device, tunnel, &spath_info->hw_entry); if (status != SWITCH_STATUS_SUCCESS) { - return SWITCH_API_INVALID_HANDLE; + return status; } #endif diff --git a/switchapi/src/switch_packet.c b/switchapi/src/switch_packet.c index 3c5498d..a31a17a 100644 --- a/switchapi/src/switch_packet.c +++ b/switchapi/src/switch_packet.c @@ -139,31 +139,12 @@ void switch_packet_tx_to_hw(switch_packet_header_t *packet_header, // packet_header->fabric_header.dst_port_or_group); } -static void switch_packet_extract_optional_header( - switch_packet_header_t *packet_header, - switch_opt_header_t **opt_header, - uint16_t *opt_length) { - *opt_length = 0; - if (packet_header->cpu_header.reason_code == - SWITCH_HOSTIF_REASON_CODE_SFLOW_SAMPLE) { - *opt_header = - (switch_opt_header_t *)(packet_header + sizeof(switch_packet_header_t)); - (*opt_header)->sflow_header.sflow_session_id = - ntohs((*opt_header)->sflow_header.sflow_session_id); - (*opt_header)->sflow_header.sflow_egress_ifindex = - ntohs((*opt_header)->sflow_header.sflow_egress_ifindex); - *opt_length = sizeof(switch_sflow_header_t); - } -} - static void switch_packet_rx_from_hw() { int packet_size = 0; switch_packet_header_t *packet_header = NULL; - switch_opt_header_t *opt_header = NULL; static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; switch_status_t status = SWITCH_STATUS_SUCCESS; - uint16_t opt_length = 0; // read packet from cpu port while ((packet_size = read(cpu_sock_fd, in_packet, sizeof(in_packet))) > 0) { @@ -171,29 +152,25 @@ static void switch_packet_rx_from_hw() { if (ntohs(ethType) != 0x9000) continue; packet_header = (switch_packet_header_t *)(in_packet + SWITCH_PACKET_HEADER_OFFSET); + packet_size = packet_size - sizeof(switch_packet_header_t); memcpy(packet, in_packet, SWITCH_PACKET_HEADER_OFFSET); + memcpy(packet + SWITCH_PACKET_HEADER_OFFSET, + in_packet + SWITCH_PACKET_HEADER_OFFSET + + sizeof(switch_packet_header_t), + packet_size - SWITCH_PACKET_HEADER_OFFSET); packet_header->cpu_header.reason_code = ntohs(packet_header->cpu_header.reason_code); if (packet_header->cpu_header.reason_code == SWITCH_HOSTIF_REASON_CODE_NULL_DROP) continue; - - switch_packet_extract_optional_header( - packet_header, &opt_header, &opt_length); - packet_size = packet_size - sizeof(switch_packet_header_t) - opt_length; - memcpy(packet + SWITCH_PACKET_HEADER_OFFSET, - in_packet + SWITCH_PACKET_HEADER_OFFSET + - sizeof(switch_packet_header_t) + opt_length, - packet_size - SWITCH_PACKET_HEADER_OFFSET); - packet_header->cpu_header.ingress_port = ntohs(packet_header->cpu_header.ingress_port); packet_header->cpu_header.ingress_ifindex = ntohs(packet_header->cpu_header.ingress_ifindex); packet_header->cpu_header.ingress_bd = ntohs(packet_header->cpu_header.ingress_bd); - status = switch_api_hostif_rx_packet_from_hw( - packet_header, opt_header, packet, packet_size); + status = + switch_api_hostif_rx_packet_from_hw(packet_header, packet, packet_size); if (status != SWITCH_STATUS_SUCCESS) { return; } diff --git a/switchapi/src/switch_pd.c b/switchapi/src/switch_pd.c index 68a0fce..b8c1155 100644 --- a/switchapi/src/switch_pd.c +++ b/switchapi/src/switch_pd.c @@ -826,7 +826,7 @@ p4_pd_status_t switch_pd_src_vtep_table_add_entry( 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_srcAddr = SWITCH_IP_ENCAP_IPV4_SRC_IP(ip_encap); + v4_match_spec.ipv4_srcAddr = SWITCH_IP_ENCAP_IPV4_DST_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; @@ -844,7 +844,7 @@ p4_pd_status_t switch_pd_src_vtep_table_add_entry( v6_match_spec.l3_metadata_vrf = handle_to_id(ip_encap->vrf_handle); memcpy( - &v6_match_spec.ipv6_srcAddr, SWITCH_IP_ENCAP_IPV6_SRC_IP(ip_encap), 16); + &v6_match_spec.ipv6_srcAddr, 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); v6_action_spec.action_ifindex = ifindex; @@ -894,7 +894,7 @@ p4_pd_status_t switch_pd_dest_vtep_table_add_entry( 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_dstAddr = SWITCH_IP_ENCAP_IPV4_DST_IP(ip_encap); + v4_match_spec.ipv4_dstAddr = SWITCH_IP_ENCAP_IPV4_SRC_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( @@ -906,7 +906,7 @@ p4_pd_status_t switch_pd_dest_vtep_table_add_entry( 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_dstAddr, SWITCH_IP_ENCAP_IPV6_DST_IP(ip_encap), 16); + &v6_match_spec.ipv6_dstAddr, 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); status = p4_pd_dc_ipv6_dest_vtep_table_add_with_set_tunnel_termination_flag( @@ -2608,6 +2608,7 @@ p4_pd_status_t switch_pd_egress_bd_map_table_add_entry( match_spec.egress_metadata_bd = handle_to_id(bd_handle); action_spec.action_smac_idx = bd_info->smac_index; action_spec.action_nat_mode = SWITCH_LN_NAT_MODE(bd_info); + action_spec.action_bd_label = handle_to_id(bd_info->ln_info.bd_label); status = p4_pd_dc_egress_bd_map_table_add_with_set_egress_bd_properties( g_sess_hdl, @@ -2633,6 +2634,7 @@ p4_pd_status_t switch_pd_egress_bd_map_table_update_entry( match_spec.egress_metadata_bd = handle_to_id(bd_handle); action_spec.action_smac_idx = bd_info->smac_index; action_spec.action_nat_mode = SWITCH_LN_NAT_MODE(bd_info); + action_spec.action_bd_label = handle_to_id(bd_info->ln_info.bd_label); status = p4_pd_dc_egress_bd_map_table_modify_with_set_egress_bd_properties( g_sess_hdl, device, bd_info->egress_bd_entry, &action_spec); @@ -2816,7 +2818,7 @@ p4_pd_status_t switch_pd_ingress_port_mapping_table_add_entry( action1_spec.action_port_type = port_info->port_type; match2_spec.standard_metadata_ingress_port = SWITCH_PORT_ID(port_info); - action2_spec.action_if_label = SWITCH_PORT_ID(port_info); + action2_spec.action_if_label = SWITCH_PORT_ID(port_info) + 1; action2_spec.action_qos_group = port_info->ingress_qos_group; action2_spec.action_tc_qos_group = port_info->tc_qos_group; action2_spec.action_tc = port_info->tc; @@ -2888,6 +2890,7 @@ p4_pd_status_t switch_pd_egress_port_mapping_table_add_entry( memset(&action_spec, 0, sizeof(action_spec)); action_spec.action_ifindex = ifindex; action_spec.action_qos_group = qos_group; + action_spec.action_if_label = port_id + 1; status = p4_pd_dc_egress_port_mapping_table_add_with_egress_port_type_normal( g_sess_hdl, p4_pd_device, &match_spec, &action_spec, entry_hdl); @@ -2911,6 +2914,7 @@ p4_pd_status_t switch_pd_egress_port_mapping_table_add_entry( memset(&action_spec, 0, sizeof(action_spec)); action_spec.action_ifindex = ifindex; action_spec.action_qos_group = qos_group; + action_spec.action_if_label = port_id + 1; status = p4_pd_dc_egress_port_mapping_table_modify_with_egress_port_type_normal( g_sess_hdl, device, *entry_hdl, &action_spec); @@ -4074,7 +4078,9 @@ p4_pd_status_t switch_pd_system_acl_table_add_entry( } p4_pd_status_t switch_pd_system_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; p4_pd_dc_system_acl_table_delete(g_sess_hdl, device, entry_hdl); return status; @@ -4499,25 +4505,21 @@ p4_pd_status_t switch_pd_ipv4_acl_table_add_entry( match_spec.l3_metadata_lkp_ip_proto = ip_acl[i].value.ip_proto; match_spec.l3_metadata_lkp_ip_proto_mask = ip_acl[i].mask.u.mask & 0xFF; break; - case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ip_acl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = - ip_acl[i].mask.u.mask & 0xFFFF; + case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE: + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ip_acl[i].value.sport_range_handle); break; - case SWITCH_ACL_IP_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ip_acl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = - ip_acl[i].mask.u.mask & 0xFFFF; + case SWITCH_ACL_IP_FIELD_L4_DEST_PORT_RANGE: + match_spec.acl_metadata_ingress_dst_port_range_id = + handle_to_id(ip_acl[i].value.dport_range_handle); break; case SWITCH_ACL_IP_FIELD_ICMP_TYPE: - match_spec.l3_metadata_lkp_l4_sport |= ip_acl[i].value.icmp_type << 8; - match_spec.l3_metadata_lkp_l4_sport_mask |= - (ip_acl[i].mask.u.mask & 0xFF) << 8; + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ip_acl[i].value.sport_range_handle); break; case SWITCH_ACL_IP_FIELD_ICMP_CODE: - match_spec.l3_metadata_lkp_l4_sport |= ip_acl[i].value.icmp_code; - match_spec.l3_metadata_lkp_l4_sport_mask |= - ip_acl[i].mask.u.mask & 0xFF; + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ip_acl[i].value.sport_range_handle); break; case SWITCH_ACL_IP_FIELD_TCP_FLAGS: match_spec.tcp_flags = ip_acl[i].value.tcp_flags; @@ -4644,11 +4646,113 @@ p4_pd_status_t switch_pd_ipv4_acl_table_add_entry( return status; } +p4_pd_status_t switch_pd_egress_ipv4_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ip_key_value_pair_t *ip_acl, + switch_acl_ip_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#ifdef P4_EGRESS_ACL_ENABLE +#if !defined(P4_ACL_DISABLE) && !defined(P4_IPV4_DISABLE) + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_egress_ip_acl_match_spec_t match_spec; + unsigned int i = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(match_spec)); + + if (if_label) { + match_spec.acl_metadata_egress_if_label = if_label; + match_spec.acl_metadata_egress_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_egress_bd_label = bd_label; + match_spec.acl_metadata_egress_bd_label_mask = 0xFFFF; + } + + for (i = 0; i < count; i++) { + switch (ip_acl[i].field) { + case SWITCH_ACL_IP_FIELD_IPV4_SRC: + match_spec.ipv4_srcAddr = ip_acl[i].value.ipv4_source; + match_spec.ipv4_srcAddr_mask = ip_acl[i].mask.u.mask & 0xFFFFFFFF; + break; + case SWITCH_ACL_IP_FIELD_IPV4_DEST: + match_spec.ipv4_dstAddr = ip_acl[i].value.ipv4_dest; + match_spec.ipv4_dstAddr_mask = ip_acl[i].mask.u.mask & 0xFFFFFFFF; + break; + case SWITCH_ACL_IP_FIELD_IP_PROTO: + match_spec.ipv4_protocol = ip_acl[i].value.ip_proto; + match_spec.ipv4_protocol_mask = ip_acl[i].mask.u.mask & 0xFF; + break; + case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE: + match_spec.acl_metadata_egress_src_port_range_id = + handle_to_id(ip_acl[i].value.sport_range_handle); + break; + case SWITCH_ACL_IP_FIELD_L4_DEST_PORT_RANGE: + match_spec.acl_metadata_egress_dst_port_range_id = + handle_to_id(ip_acl[i].value.dport_range_handle); + break; + default: + break; + } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_egress_acl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + status = + p4_pd_dc_egress_ip_acl_table_add_with_egress_acl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_egress_acl_permit_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + status = + p4_pd_dc_egress_ip_acl_table_add_with_egress_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + default: + break; + } +#endif /* P4_ACL_DISABLE && P4_IPV4_DISABLE */ +#endif /* P4_EGRESS_ACL_ENABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + p4_pd_status_t switch_pd_ipv4_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; #if !defined(P4_IPV4_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_ip_acl_table_delete(g_sess_hdl, device, entry_hdl); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = p4_pd_dc_ip_acl_table_delete(g_sess_hdl, device, entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + status = p4_pd_dc_egress_ip_acl_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } #endif /* P4_IPV4_DISABLE & P4_ACL_DISABLE */ p4_pd_complete_operations(g_sess_hdl); return status; @@ -4714,25 +4818,21 @@ p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( match_spec.l3_metadata_lkp_ip_proto_mask = ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; break; - case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ipv6_acl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = - ipv6_acl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT_RANGE: + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ipv6_acl[i].value.sport_range_handle); break; - case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ipv6_acl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = - ipv6_acl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT_RANGE: + match_spec.acl_metadata_ingress_dst_port_range_id = + handle_to_id(ipv6_acl[i].value.dport_range_handle); break; case SWITCH_ACL_IPV6_FIELD_ICMP_TYPE: - match_spec.l3_metadata_lkp_l4_sport |= ipv6_acl[i].value.icmp_type << 8; - match_spec.l3_metadata_lkp_l4_sport_mask |= - (ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF) << 8; + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ipv6_acl[i].value.sport_range_handle); break; case SWITCH_ACL_IPV6_FIELD_ICMP_CODE: - match_spec.l3_metadata_lkp_l4_sport |= ipv6_acl[i].value.icmp_code; - match_spec.l3_metadata_lkp_l4_sport_mask |= - ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ipv6_acl[i].value.sport_range_handle); break; case SWITCH_ACL_IPV6_FIELD_TCP_FLAGS: match_spec.tcp_flags = ipv6_acl[i].value.tcp_flags; @@ -4826,11 +4926,120 @@ p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( return status; } +p4_pd_status_t switch_pd_egress_ipv6_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ipv6_key_value_pair_t *ipv6_acl, + switch_acl_ipv6_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_egress_ipv6_acl_match_spec_t match_spec; + unsigned int i = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(match_spec)); + + if (if_label) { + match_spec.acl_metadata_egress_if_label = if_label; + match_spec.acl_metadata_egress_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_egress_bd_label = bd_label; + match_spec.acl_metadata_egress_bd_label_mask = 0xFFFF; + } + + for (i = 0; i < count; i++) { + switch (ipv6_acl[i].field) { + case SWITCH_ACL_IPV6_FIELD_IPV6_SRC: + memcpy( + match_spec.ipv6_srcAddr, ipv6_acl[i].value.ipv6_source.u.addr8, 16); + memcpy( + match_spec.ipv6_srcAddr_mask, ipv6_acl[i].mask.u.mask.u.addr8, 16); + break; + case SWITCH_ACL_IPV6_FIELD_IPV6_DEST: + memcpy( + match_spec.ipv6_dstAddr, ipv6_acl[i].value.ipv6_dest.u.addr8, 16); + memcpy( + match_spec.ipv6_dstAddr_mask, ipv6_acl[i].mask.u.mask.u.addr8, 16); + break; + case SWITCH_ACL_IPV6_FIELD_IP_PROTO: + match_spec.ipv6_nextHdr = ipv6_acl[i].value.ip_proto; + match_spec.ipv6_nextHdr_mask = + ipv6_acl[i].mask.u.mask.u.addr8[0] & 0xFF; + break; + case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT_RANGE: + match_spec.acl_metadata_egress_src_port_range_id = + handle_to_id(ipv6_acl[i].value.sport_range_handle); + break; + case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT_RANGE: + match_spec.acl_metadata_egress_dst_port_range_id = + handle_to_id(ipv6_acl[i].value.dport_range_handle); + break; + default: + break; + } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_egress_acl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + status = + p4_pd_dc_egress_ipv6_acl_table_add_with_egress_acl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_egress_acl_permit_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + status = p4_pd_dc_egress_ipv6_acl_table_add_with_egress_acl_permit( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + default: + break; + } + +#endif /* P4_EGRESS_ACL_ENABLE */ +#endif /* P4_IPV6_DISABLE && P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + p4_pd_status_t switch_pd_ipv6_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; #if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_ipv6_acl_table_delete(g_sess_hdl, device, entry_hdl); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = p4_pd_dc_ipv6_acl_table_delete(g_sess_hdl, device, entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + status = + p4_pd_dc_egress_ipv6_acl_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } #endif /* P4_IPV6_DISABLE & P4_ACL_DISABLE */ p4_pd_complete_operations(g_sess_hdl); return status; @@ -4887,15 +5096,13 @@ p4_pd_status_t switch_pd_ipv4_racl_table_add_entry( match_spec.l3_metadata_lkp_ip_proto_mask = ip_racl[i].mask.u.mask & 0xFF; break; - case SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ip_racl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = - ip_racl[i].mask.u.mask & 0xFFFF; + case SWITCH_ACL_IP_RACL_FIELD_L4_SOURCE_PORT_RANGE: + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ip_racl[i].value.sport_range_handle); break; - case SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ip_racl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = - ip_racl[i].mask.u.mask & 0xFFFF; + case SWITCH_ACL_IP_RACL_FIELD_L4_DEST_PORT_RANGE: + match_spec.acl_metadata_ingress_dst_port_range_id = + handle_to_id(ip_racl[i].value.dport_range_handle); break; default: break; @@ -4980,7 +5187,9 @@ p4_pd_status_t switch_pd_ipv4_racl_table_add_entry( } p4_pd_status_t switch_pd_ipv4_racl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; #if !defined(P4_IPV4_DISABLE) && !defined(P4_ACL_DISABLE) p4_pd_dc_ipv4_racl_table_delete(g_sess_hdl, device, entry_hdl); @@ -5034,15 +5243,13 @@ p4_pd_status_t switch_pd_ipv6_racl_table_add_entry( match_spec.l3_metadata_lkp_ip_proto_mask = ipv6_racl[i].mask.u.mask.u.addr8[0] & 0xFF; break; - case SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT: - match_spec.l3_metadata_lkp_l4_sport = ipv6_racl[i].value.l4_source_port; - match_spec.l3_metadata_lkp_l4_sport_mask = - ipv6_racl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + case SWITCH_ACL_IPV6_RACL_FIELD_L4_SOURCE_PORT_RANGE: + match_spec.acl_metadata_ingress_src_port_range_id = + handle_to_id(ipv6_racl[i].value.sport_range_handle); break; - case SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT: - match_spec.l3_metadata_lkp_l4_dport = ipv6_racl[i].value.l4_dest_port; - match_spec.l3_metadata_lkp_l4_dport_mask = - ipv6_racl[i].mask.u.mask.u.addr16[0] & 0xFFFF; + case SWITCH_ACL_IPV6_RACL_FIELD_L4_DEST_PORT_RANGE: + match_spec.acl_metadata_ingress_dst_port_range_id = + handle_to_id(ipv6_racl[i].value.dport_range_handle); break; default: break; @@ -5126,7 +5333,9 @@ p4_pd_status_t switch_pd_ipv6_racl_table_add_entry( } p4_pd_status_t switch_pd_ipv6_racl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; #if !defined(P4_IPV6_DISABLE) && !defined(P4_ACL_DISABLE) p4_pd_dc_ipv6_racl_table_delete(g_sess_hdl, device, entry_hdl); @@ -5266,11 +5475,111 @@ p4_pd_status_t switch_pd_mac_acl_table_add_entry( return status; } +p4_pd_status_t switch_pd_egress_mac_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_mac_key_value_pair_t *mac_acl, + switch_acl_mac_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; +#if !defined(P4_L2_DISABLE) && !defined(P4_ACL_DISABLE) +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dev_target_t p4_pd_device; + p4_pd_dc_egress_mac_acl_match_spec_t match_spec; + unsigned int i = 0; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + memset(&match_spec, 0, sizeof(p4_pd_dc_mac_acl_match_spec_t)); + + if (if_label) { + match_spec.acl_metadata_egress_if_label = if_label; + match_spec.acl_metadata_egress_if_label_mask = 0xFFFF; + } + if (bd_label) { + match_spec.acl_metadata_egress_bd_label = bd_label; + match_spec.acl_metadata_egress_bd_label_mask = 0xFFFF; + } + for (i = 0; i < count; i++) { + switch (mac_acl[i].field) { + case SWITCH_ACL_MAC_FIELD_ETH_TYPE: + match_spec.ethernet_etherType = mac_acl[i].value.eth_type; + match_spec.ethernet_etherType_mask = mac_acl[i].mask.u.mask16 & 0xFFFF; + break; + case SWITCH_ACL_MAC_FIELD_SOURCE_MAC: + memcpy(match_spec.ethernet_srcAddr, + mac_acl[i].value.source_mac.mac_addr, + ETH_LEN); + memcpy( + match_spec.ethernet_srcAddr_mask, &mac_acl[i].mask.u.mask, ETH_LEN); + break; + case SWITCH_ACL_MAC_FIELD_DEST_MAC: + memcpy(match_spec.ethernet_dstAddr, + mac_acl[i].value.dest_mac.mac_addr, + ETH_LEN); + memcpy( + match_spec.ethernet_dstAddr_mask, &mac_acl[i].mask.u.mask, ETH_LEN); + break; + default: + break; + } + } + switch (action) { + case SWITCH_ACL_ACTION_DROP: { + p4_pd_dc_egress_acl_deny_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + status = + p4_pd_dc_egress_mac_acl_table_add_with_egress_acl_deny(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + case SWITCH_ACL_ACTION_PERMIT: { + p4_pd_dc_egress_acl_permit_action_spec_t action_spec; + memset(&action_spec, 0, sizeof(action_spec)); + action_spec.action_acl_copy_reason = + action_params->cpu_redirect.reason_code; + status = + p4_pd_dc_egress_mac_acl_table_add_with_egress_acl_permit(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); + } break; + default: + break; + } +#endif /* P4_EGRESS_ACL_ENABLE */ +#endif /* P4_L2_DISABLE && P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); + return status; +} + p4_pd_status_t switch_pd_mac_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; #if !defined(P4_L2_DISABLE) && !defined(P4_ACL_DISABLE) - p4_pd_dc_mac_acl_table_delete(g_sess_hdl, device, entry_hdl); + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = p4_pd_dc_mac_acl_table_delete(g_sess_hdl, device, entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + status = + p4_pd_dc_egress_mac_acl_table_delete(g_sess_hdl, device, entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } #endif /* P4_L2_DISABLE & P4_ACL_DISABLE */ p4_pd_complete_operations(g_sess_hdl); return status; @@ -5294,12 +5603,12 @@ p4_pd_status_t switch_pd_egr_acl_table_add_entry( #ifndef P4_ACL_DISABLE unsigned int i; p4_pd_dev_target_t p4_pd_device; - p4_pd_dc_egress_acl_match_spec_t match_spec; + p4_pd_dc_egress_system_acl_match_spec_t match_spec; p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - memset(&match_spec, 0, sizeof(p4_pd_dc_egress_acl_match_spec_t)); + memset(&match_spec, 0, sizeof(p4_pd_dc_egress_system_acl_match_spec_t)); for (i = 0; i < count; i++) { switch (egr_acl[i].field) { case SWITCH_ACL_EGR_DEST_PORT: { @@ -5316,42 +5625,53 @@ p4_pd_status_t switch_pd_egr_acl_table_add_entry( match_spec.l3_metadata_l3_mtu_check = egr_acl[i].value.l3_mtu_check; match_spec.l3_metadata_l3_mtu_check_mask = 0xFFFF; } break; + case SWITCH_ACL_EGR_ACL_DENY: { + match_spec.acl_metadata_acl_deny = egr_acl[i].value.acl_deny; + match_spec.acl_metadata_acl_deny_mask = 0xFF; + } break; default: break; } } switch (action) { - case SWITCH_ACL_EGR_ACTION_NOP: - status = p4_pd_dc_egress_acl_table_add_with_nop( + case SWITCH_ACL_EGR_ACTION_PERMIT: { + status = p4_pd_dc_egress_system_acl_table_add_with_nop( g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); - break; + } break; + case SWITCH_ACL_EGR_ACTION_DROP: { + status = p4_pd_dc_egress_system_acl_table_add_with_drop_packet( + g_sess_hdl, p4_pd_device, &match_spec, priority, entry_hdl); + } break; case SWITCH_ACL_EGR_ACTION_SET_MIRROR: { #if !defined(P4_MIRROR_DISABLE) p4_pd_dc_egress_mirror_action_spec_t action_spec; action_spec.action_session_id = handle_to_id(opt_action_params->mirror_handle); - status = p4_pd_dc_egress_acl_table_add_with_egress_mirror(g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &action_spec, - entry_hdl); + status = + p4_pd_dc_egress_system_acl_table_add_with_egress_mirror(g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); break; #endif /* P4_MIRROR_DISABLE */ } case SWITCH_ACL_EGR_ACTION_REDIRECT_TO_CPU: { - p4_pd_dc_egress_redirect_to_cpu_action_spec_t action_spec; + p4_pd_dc_egress_redirect_to_cpu_with_reason_action_spec_t action_spec; action_spec.action_reason_code = action_params->cpu_redirect.reason_code; - status = p4_pd_dc_egress_acl_table_add_with_egress_redirect_to_cpu( - g_sess_hdl, - p4_pd_device, - &match_spec, - priority, - &action_spec, - entry_hdl); + status = + p4_pd_dc_egress_system_acl_table_add_with_egress_redirect_to_cpu_with_reason( + g_sess_hdl, + p4_pd_device, + &match_spec, + priority, + &action_spec, + entry_hdl); break; } + default: break; } @@ -5362,10 +5682,13 @@ p4_pd_status_t switch_pd_egr_acl_table_add_entry( } p4_pd_status_t switch_pd_egr_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl) { + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl) { p4_pd_status_t status = 0; #ifndef P4_ACL_DISABLE - status = p4_pd_dc_egress_acl_table_delete(g_sess_hdl, device, entry_hdl); + status = + p4_pd_dc_egress_system_acl_table_delete(g_sess_hdl, device, entry_hdl); p4_pd_complete_operations(g_sess_hdl); #endif /* P4_ACL_DISABLE */ return status; @@ -6073,6 +6396,25 @@ p4_pd_status_t switch_pd_acl_table_add_default_entry(switch_device_t device) { #endif /* P4_ACL_DISABLE */ #endif /* P4_STATS_DISABLE */ +#ifndef P4_ACL_DISABLE +#ifdef P4_EGRESS_ACL_ENABLE + + status = p4_pd_dc_egress_mac_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#ifndef P4_IPV4_DISABLE + status = p4_pd_dc_egress_ip_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_IPV4_DISABLE */ + +#ifndef P4_IPV6_DISABLE + status = p4_pd_dc_egress_ipv6_acl_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); +#endif /* P4_IPV6_DISABLE */ + +#endif /* P4_EGRESS_ACL_ENABLE */ +#endif /* P4_ACL_DISABLE */ + p4_pd_complete_operations(g_sess_hdl); return status; } @@ -6362,7 +6704,7 @@ p4_pd_status_t switch_pd_egress_acl_add_default_entry(switch_device_t device) { p4_pd_device.device_id = device; p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; - status = p4_pd_dc_egress_acl_set_default_action_nop( + status = p4_pd_dc_egress_system_acl_set_default_action_nop( g_sess_hdl, p4_pd_device, &entry_hdl); #endif /* P4_ACL_DISABLE */ p4_pd_complete_operations(g_sess_hdl); @@ -8796,13 +9138,13 @@ switch_status_t switch_pd_sflow_session_delete( if (sflow_info->mirror_table_ent_hdl != SWITCH_API_INVALID_HANDLE) { p4_pd_dc_mirror_table_delete( g_sess_hdl, device, sflow_info->mirror_table_ent_hdl); - sflow_info->mirror_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + sflow_info->mirror_table_ent_hdl = SWITCH_HW_INVALID_HANDLE; op_started = true; } if (sflow_info->ing_take_sample_table_ent_hdl != SWITCH_API_INVALID_HANDLE) { p4_pd_dc_sflow_ing_take_sample_table_delete( g_sess_hdl, device, sflow_info->ing_take_sample_table_ent_hdl); - sflow_info->ing_take_sample_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + sflow_info->ing_take_sample_table_ent_hdl = SWITCH_HW_INVALID_HANDLE; op_started = true; } if (op_started) { @@ -8929,3 +9271,272 @@ p4_pd_status_t switch_pd_hostif_meter_set(switch_device_t device, return status; } + +p4_pd_status_t switch_pd_range_entry_add(switch_device_t device, + switch_direction_t direction, + uint16_t range_id, + switch_range_type_t range_type, + switch_range_t *range, + p4_pd_entry_hdl_t *entry_hdl) { + p4_pd_status_t status = 0; + +#ifndef P4_ACL_RANGE_DISABLE + + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + switch (range_type) { + case SWITCH_RANGE_TYPE_SRC_PORT: { + if (direction == SWITCH_API_DIRECTION_INGRESS) { + p4_pd_dc_ingress_l4_src_port_match_spec_t match_spec; + p4_pd_dc_set_ingress_src_port_range_id_action_spec_t action_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.l3_metadata_lkp_l4_sport_start = range->start_value; + match_spec.l3_metadata_lkp_l4_sport_end = range->end_value; + action_spec.action_range_id = range_id; + status = + p4_pd_dc_ingress_l4_src_port_table_add_with_set_ingress_src_port_range_id( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dc_egress_l4_src_port_match_spec_t match_spec; + p4_pd_dc_set_egress_src_port_range_id_action_spec_t action_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.l3_metadata_egress_l4_sport_start = range->start_value; + match_spec.l3_metadata_egress_l4_sport_end = range->end_value; + action_spec.action_range_id = range_id; + status = + p4_pd_dc_egress_l4_src_port_table_add_with_set_egress_src_port_range_id( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } + } break; + + case SWITCH_RANGE_TYPE_DST_PORT: { + if (direction == SWITCH_API_DIRECTION_INGRESS) { + p4_pd_dc_ingress_l4_dst_port_match_spec_t match_spec; + p4_pd_dc_set_ingress_dst_port_range_id_action_spec_t action_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.l3_metadata_lkp_l4_dport_start = range->start_value; + match_spec.l3_metadata_lkp_l4_dport_end = range->end_value; + action_spec.action_range_id = range_id; + status = + p4_pd_dc_ingress_l4_dst_port_table_add_with_set_ingress_dst_port_range_id( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dc_egress_l4_dst_port_match_spec_t match_spec; + p4_pd_dc_set_egress_dst_port_range_id_action_spec_t action_spec; + memset(&match_spec, 0x0, sizeof(match_spec)); + memset(&action_spec, 0x0, sizeof(action_spec)); + match_spec.l3_metadata_egress_l4_dport_start = range->start_value; + match_spec.l3_metadata_egress_l4_dport_end = range->end_value; + action_spec.action_range_id = range_id; + status = + p4_pd_dc_egress_l4_dst_port_table_add_with_set_egress_dst_port_range_id( + g_sess_hdl, + p4_pd_device, + &match_spec, + 1000, + &action_spec, + entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } + } break; + default: + return SWITCH_STATUS_NOT_SUPPORTED; + } + +#endif /* P4_ACL_RANGE_DISABLE */ + + return status; +} + +p4_pd_status_t switch_pd_range_entry_update(switch_device_t device, + switch_direction_t direction, + uint16_t range_id, + switch_range_type_t range_type, + switch_range_t *range, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + +#ifndef P4_ACL_RANGE_DISABLE + + switch (range_type) { + case SWITCH_RANGE_TYPE_SRC_PORT: { + if (direction == SWITCH_API_DIRECTION_INGRESS) { + p4_pd_dc_set_ingress_src_port_range_id_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + action_spec.action_range_id = range_id; + status = + p4_pd_dc_ingress_l4_src_port_table_modify_with_set_ingress_src_port_range_id( + g_sess_hdl, device, entry_hdl, &action_spec); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dc_set_egress_src_port_range_id_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + action_spec.action_range_id = range_id; + status = + p4_pd_dc_egress_l4_src_port_table_modify_with_set_egress_src_port_range_id( + g_sess_hdl, device, entry_hdl, &action_spec); +#endif /* P4_EGRESS_ACL_ENABLE */ + } + } break; + + case SWITCH_RANGE_TYPE_DST_PORT: { + if (direction == SWITCH_API_DIRECTION_INGRESS) { + p4_pd_dc_set_ingress_dst_port_range_id_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + action_spec.action_range_id = range_id; + status = + p4_pd_dc_ingress_l4_dst_port_table_modify_with_set_ingress_dst_port_range_id( + g_sess_hdl, device, entry_hdl, &action_spec); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dc_set_egress_dst_port_range_id_action_spec_t action_spec; + memset(&action_spec, 0x0, sizeof(action_spec)); + action_spec.action_range_id = range_id; + status = + p4_pd_dc_egress_l4_dst_port_table_modify_with_set_egress_dst_port_range_id( + g_sess_hdl, device, entry_hdl, &action_spec); +#endif /* P4_EGRESS_ACL_ENABLE */ + } + } break; + default: + return SWITCH_STATUS_NOT_SUPPORTED; + } + +#endif /* P4_ACL_RANGE_DISABLE */ + + return status; +} + +p4_pd_status_t switch_pd_range_entry_delete(switch_device_t device, + switch_direction_t direction, + switch_range_type_t range_type, + p4_pd_entry_hdl_t entry_hdl) { + p4_pd_status_t status = 0; + +#ifndef P4_ACL_RANGE_DISABLE + + switch (range_type) { + case SWITCH_RANGE_TYPE_SRC_PORT: { + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = p4_pd_dc_ingress_l4_src_port_table_delete( + g_sess_hdl, device, entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + status = p4_pd_dc_egress_l4_src_port_table_delete( + g_sess_hdl, device, entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } + break; + + case SWITCH_RANGE_TYPE_DST_PORT: { + if (direction == SWITCH_API_DIRECTION_INGRESS) { + status = p4_pd_dc_ingress_l4_dst_port_table_delete( + g_sess_hdl, device, entry_hdl); + } else { +#ifdef P4_EGRESS_ACL_ENABLE + status = p4_pd_dc_egress_l4_dst_port_table_delete( + g_sess_hdl, device, entry_hdl); +#endif /* P4_EGRESS_ACL_ENABLE */ + } + } break; + default: + return SWITCH_STATUS_NOT_SUPPORTED; + } + } + +#endif /* P4_ACL_RANGE_DISABLE */ + + return status; +} + +p4_pd_status_t switch_pd_egress_l4port_fields_init_entry( + switch_device_t device) { + p4_pd_status_t status = 0; + +#ifdef P4_EGRESS_ACL_ENABLE + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dc_egress_l4port_fields_match_spec_t match_spec; + + status = p4_pd_dc_egress_l4port_fields_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + memset(&match_spec, 0x0, sizeof(match_spec)); + match_spec.tcp_valid = 1; + status = + p4_pd_dc_egress_l4port_fields_table_add_with_set_egress_tcp_port_fields( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl); + + memset(&match_spec, 0x0, sizeof(match_spec)); + match_spec.udp_valid = 1; + status = + p4_pd_dc_egress_l4port_fields_table_add_with_set_egress_udp_port_fields( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl); + + memset(&match_spec, 0x0, sizeof(match_spec)); + match_spec.icmp_valid = 1; + status = + p4_pd_dc_egress_l4port_fields_table_add_with_set_egress_icmp_port_fields( + g_sess_hdl, p4_pd_device, &match_spec, &entry_hdl); + +#endif /* P4_EGRESS_ACL_ENABLE */ + + return status; +} + +p4_pd_status_t switch_pd_l4port_default_entry_add(switch_device_t device) { + p4_pd_status_t status = 0; + +#ifndef P4_ACL_RANGE_DISABLE + p4_pd_entry_hdl_t entry_hdl; + p4_pd_dev_target_t p4_pd_device; + + p4_pd_device.device_id = device; + p4_pd_device.dev_pipe_id = SWITCH_DEV_PIPE_ID; + + status = p4_pd_dc_ingress_l4_src_port_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + status = p4_pd_dc_ingress_l4_dst_port_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#ifdef P4_EGRESS_ACL_ENABLE + status = p4_pd_dc_egress_l4_src_port_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + + status = p4_pd_dc_egress_l4_dst_port_set_default_action_nop( + g_sess_hdl, p4_pd_device, &entry_hdl); + +#endif /* P4_EGRESS_ACL_ENABLE */ +#endif /* P4_ACL_RANGE_DISABLE */ + + return status; +} diff --git a/switchapi/src/switch_pd.h b/switchapi/src/switch_pd.h index 482b671..b8ea187 100644 --- a/switchapi/src/switch_pd.h +++ b/switchapi/src/switch_pd.h @@ -563,8 +563,22 @@ p4_pd_status_t switch_pd_ipv4_acl_table_add_entry( switch_acl_opt_action_params_t *opt_action_params, p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_egress_ipv4_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ip_key_value_pair_t *ip_acl, + switch_acl_ip_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + p4_pd_status_t switch_pd_ipv4_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( switch_device_t device, @@ -578,8 +592,22 @@ p4_pd_status_t switch_pd_ipv6_acl_table_add_entry( switch_acl_opt_action_params_t *opt_action_params, p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_egress_ipv6_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_ipv6_key_value_pair_t *ipv6_acl, + switch_acl_ipv6_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + p4_pd_status_t switch_pd_ipv6_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_ipv4_racl_table_add_entry( switch_device_t device, @@ -594,7 +622,9 @@ p4_pd_status_t switch_pd_ipv4_racl_table_add_entry( p4_pd_entry_hdl_t *entry_hdl); p4_pd_status_t switch_pd_ipv4_racl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_ipv6_racl_table_add_entry( switch_device_t device, @@ -609,7 +639,9 @@ p4_pd_status_t switch_pd_ipv6_racl_table_add_entry( p4_pd_entry_hdl_t *entry_hdl); p4_pd_status_t switch_pd_ipv6_racl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_mac_acl_table_add_entry( switch_device_t device, @@ -623,8 +655,22 @@ p4_pd_status_t switch_pd_mac_acl_table_add_entry( switch_acl_opt_action_params_t *opt_action_params, p4_pd_entry_hdl_t *entry_hdl); +p4_pd_status_t switch_pd_egress_mac_acl_table_add_entry( + switch_device_t device, + uint16_t if_label, + uint16_t bd_label, + uint16_t priority, + unsigned int count, + switch_acl_mac_key_value_pair_t *mac_acl, + switch_acl_mac_action_t action, + switch_acl_action_params_t *action_params, + switch_acl_opt_action_params_t *opt_action_params, + p4_pd_entry_hdl_t *entry_hdl); + p4_pd_status_t switch_pd_mac_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_system_acl_table_add_entry( switch_device_t device, @@ -639,7 +685,9 @@ p4_pd_status_t switch_pd_system_acl_table_add_entry( p4_pd_entry_hdl_t *entry_hdl); p4_pd_status_t switch_pd_system_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_egr_acl_table_add_entry( switch_device_t device, @@ -654,7 +702,9 @@ p4_pd_status_t switch_pd_egr_acl_table_add_entry( p4_pd_entry_hdl_t *entry_hdl); p4_pd_status_t switch_pd_egr_acl_table_delete_entry( - switch_device_t device, p4_pd_entry_hdl_t entry_hdl); + switch_device_t device, + switch_direction_t direction, + p4_pd_entry_hdl_t entry_hdl); p4_pd_status_t switch_pd_bd_ingress_stats_get(switch_device_t device, switch_bd_stats_t *bd_stats); @@ -1174,6 +1224,29 @@ p4_pd_status_t switch_pd_hostif_meter_set(switch_device_t device, switch_meter_info_t *meter_info, bool enable); +p4_pd_status_t switch_pd_range_entry_add(switch_device_t device, + switch_direction_t direction, + uint16_t range_id, + switch_range_type_t range_type, + switch_range_t *range, + p4_pd_entry_hdl_t *entry_hdl); + +p4_pd_status_t switch_pd_range_entry_update(switch_device_t device, + switch_direction_t direction, + uint16_t range_id, + switch_range_type_t range_type, + switch_range_t *range, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_range_entry_delete(switch_device_t device, + switch_direction_t direction, + switch_range_type_t range_type, + p4_pd_entry_hdl_t entry_hdl); + +p4_pd_status_t switch_pd_egress_l4port_fields_init_entry( + switch_device_t device); + +p4_pd_status_t switch_pd_l4port_default_entry_add(switch_device_t device); #ifdef __cplusplus } #endif diff --git a/switchapi/src/switch_port.c b/switchapi/src/switch_port.c index b25cdd2..b0c661d 100644 --- a/switchapi/src/switch_port.c +++ b/switchapi/src/switch_port.c @@ -331,7 +331,7 @@ switch_status_t switch_api_ppg_delete(switch_device_t device, ppg_info = switch_ppg_get(ppg_handle); if (!ppg_info) { SWITCH_API_ERROR("failed to allocate port_priority group"); - return SWITCH_API_INVALID_HANDLE; + return SWITCH_STATUS_INVALID_HANDLE; } status = switch_pd_ppg_delete(device, ppg_handle); @@ -419,7 +419,7 @@ switch_status_t switch_api_port_qos_group_ingress_set( qos_map_list = switch_qos_map_get(qos_handle); if (!qos_map_list) { SWITCH_API_ERROR("qos map get failed\n"); - return SWITCH_API_INVALID_HANDLE; + return SWITCH_STATUS_INVALID_HANDLE; } port_info->ingress_qos_group = qos_map_list->qos_group; } diff --git a/switchapi/src/switch_scheduler.c b/switchapi/src/switch_scheduler.c index 945ec16..4add559 100644 --- a/switchapi/src/switch_scheduler.c +++ b/switchapi/src/switch_scheduler.c @@ -143,7 +143,7 @@ switch_status_t switch_api_scheduler_delete(switch_device_t device, scheduler_info = switch_scheduler_info_get(scheduler_handle); if (!scheduler_info) { SWITCH_API_ERROR("scheduler create failed"); - return SWITCH_API_INVALID_HANDLE; + return SWITCH_STATUS_INVALID_HANDLE; } status = switch_scheduler_handle_delete(scheduler_handle); diff --git a/switchapi/src/switch_sflow.c b/switchapi/src/switch_sflow.c index c111f8f..382052c 100644 --- a/switchapi/src/switch_sflow.c +++ b/switchapi/src/switch_sflow.c @@ -131,8 +131,8 @@ switch_handle_t switch_api_sflow_session_create( tommy_list_init(&sflow_info->match_list); sflow_info->mirror_hdl = SWITCH_API_INVALID_HANDLE; - sflow_info->mirror_table_ent_hdl = SWITCH_API_INVALID_HANDLE; - sflow_info->ing_take_sample_table_ent_hdl = SWITCH_API_INVALID_HANDLE; + sflow_info->mirror_table_ent_hdl = SWITCH_HW_INVALID_HANDLE; + sflow_info->ing_take_sample_table_ent_hdl = SWITCH_HW_INVALID_HANDLE; // Create a mirror session to send sampled pkts to CPU. // SWITCH_CPU_MIRROR_SESSION_ID mirror-session can be used, except diff --git a/switchlink/Makefile.am b/switchlink/Makefile.am index a6c95b9..096178a 100644 --- a/switchlink/Makefile.am +++ b/switchlink/Makefile.am @@ -2,16 +2,13 @@ ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 SUBDIRS = third-party/xxhash -libswitchlink_la_CFLAGS = -I$(srcdir)/third-party/xxhash/include -libswitchlink_la_CFLAGS += -I$(SUBMODULE_SWITCHSAI)/submodules/SAI/inc -libswitchlink_la_CFLAGS += -I$(SUBMODULE_SWITCHAPI)/third-party/tommyds/include -libswitchlink_la_CFLAGS += $(shell pkg-config --cflags libnl-3.0) -libswitchlink_a_CFLAGS = $(libswitchlink_la_CFLAGS) +AM_CPPFLAGS += -I$(srcdir)/third-party/xxhash/include +AM_CPPFLAGS += -I$(top_srcdir)/switchsai/submodules/SAI/inc +AM_CPPFLAGS += -I$(top_srcdir)/switchapi/third-party/tommyds/include +# TODO: could this be done in configure? +AM_CPPFLAGS += $(shell pkg-config --cflags libnl-3.0) -lib_LIBRARIES = libswitchlink.a -lib_LTLIBRARIES = libswitchlink.la - -libswitchlink_la_SOURCES = \ +switchlink_sources = \ src/switchlink_address.c \ src/switchlink_db.c \ src/switchlink_db.h \ @@ -32,9 +29,32 @@ src/switchlink_route.h \ src/switchlink_sai.c \ src/switchlink_sai.h -libswitchlink_a_SOURCES = $(libswitchlink_la_SOURCES) +noinst_LTLIBRARIES = +lib_LIBRARIES = +lib_LTLIBRARIES = +if WITH_BMV2 +# has the advantage of avoiding "created both with libtool and without" error +libswitchlink_la_CPPFLAGS = $(AM_CPPFLAGS) +libswitchlink_la_CPPFLAGS += -DBMV2 +noinst_LTLIBRARIES += libswitchlink.la +libswitchlink_la_SOURCES = $(switchlink_sources) libswitchlink_la_LIBADD = third-party/xxhash/libxxhash.la +libswitchlink_la_LIBADD += $(NETLINK_LIBS) +endif + +# FIXME: legacy support, relies on p4factory +if WITH_P4FACTORY +lib_LIBRARIES += libswitchlink.a +libswitchlink_a_SOURCES = $(switchlink_sources) +# FIXME: this also creates shared libraries for p4factory, needs to be +# deprecated +lib_LTLIBRARIES += libswitchlink.la +# has the advantage of avoiding "created both with libtool and without" error +libswitchlink_la_CPPFLAGS = $(AM_CPPFLAGS) +libswitchlink_la_SOURCES = $(switchlink_sources) +endif +# FIXME: dos this really serve a purpose? switch-local: all switch-install-local: install diff --git a/switchlink/configure.ac b/switchlink/configure.ac deleted file mode 100644 index 5542194..0000000 --- a/switchlink/configure.ac +++ /dev/null @@ -1,34 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.69]) -AC_INIT([switchlink], [0.1], []) -AM_INIT_AUTOMAKE([foreign subdir-objects]) -AM_SILENT_RULES([yes]) -AC_CONFIG_HEADERS([config.h]) - -# Checks for programs. -CFLAGS="-g -Wall -Wextra -Wno-unused-parameter" -AC_PROG_CC_STDC -AC_PROG_CXX -LT_INIT - -AC_CONFIG_MACRO_DIR([m4]) - -# Checks for header files. -AC_LANG_PUSH(C) - -AC_CHECK_LIB([pcap], [pcap_create], [], [AC_MSG_ERROR([Missing libpcap])]) -if test -n "$COVERAGE_FLAGS"; then - AC_CHECK_LIB([gcov], [__gcov_init], [], [AC_MSG_ERROR([Missing gcov library])]) -fi - -# Checks for typedefs, structures, and compiler characteristics. -AC_CHECK_HEADER_STDBOOL -AC_TYPE_SIZE_T -AC_TYPE_UINT64_T - -# Generate makefiles -AC_CONFIG_FILES([Makefile third-party/xxhash/Makefile]) - -AC_OUTPUT diff --git a/switchsai/Makefile.am b/switchsai/Makefile.am index 7424732..f894994 100644 --- a/switchsai/Makefile.am +++ b/switchsai/Makefile.am @@ -1,13 +1,14 @@ ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -libswitchsai_la_CFLAGS = -I$(srcdir)/submodules/SAI/inc -libswitchsai_la_CFLAGS += -I$(srcdir)/../../modules/BMI/module/inc -libswitchsai_la_CFLAGS += -I$(builddir)/src/gen-cpp -libswitchsai_la_CFLAGS += -I$(top_srcdir)/switchapi/third-party/tommyds/include -libswitchsai_la_CFLAGS += -I$(top_srcdir)/p4src/includes -libswitchsai_la_CXXFLAGS = $(libswitchsai_la_CFLAGS) -libswitchsai_a_CFLAGS = $(libswitchsai_la_CFLAGS) -libswitchsai_a_CXXFLAGS = $(libswitchsai_a_CFLAGS) +AM_CPPFLAGS += -I$(srcdir)/submodules/SAI/inc +AM_CPPFLAGS += -I$(top_srcdir)/switchapi/include +AM_CPPFLAGS += -I$(builddir)/src/gen-cpp +AM_CPPFLAGS += -I$(top_srcdir)/switchapi/third-party/tommyds/include +AM_CPPFLAGS += -I$(top_srcdir)/p4src/includes + +if P4THRIFT + AM_CPPFLAGS += -DP4THRIFT +endif thrift_cpp_sources = \ @builddir@/src/gen-cpp/switch_sai_constants.cpp \ @@ -68,7 +69,12 @@ libswitchsai_a_SOURCES = $(libswitchsai_la_SOURCES) BUILT_SOURCES = \ $(thrift_cpp_sources) \ -$(thrift_py_sources) +$(thrift_py_sources) \ +$(sai_ctypesgen) + +$(sai_ctypesgen) : $(thrift_py_sources) + @$(CTYPESGEN) -I/usr/include -I$(srcdir)/submodules/SAI/inc \ + $(srcdir)/submodules/SAI/inc/*.h -o $@ > /dev/null 2>&1 # The recipe to invoke the thrift compiler is copied from: # http://www.gnu.org/software/automake/manual/html_node/Multiple-Outputs.html @@ -77,9 +83,11 @@ switchsai.ts : @srcdir@/src/switch_sai.thrift @touch switchsai.tmp $(THRIFT) -o @builddir@/src/ --gen cpp -r @srcdir@/src/switch_sai.thrift $(THRIFT) -o @builddir@/src/ --gen py -r @srcdir@/src/switch_sai.thrift +## FIXME: p4factory legacy + cp -r @builddir@/src/gen-py/switch_sai/ @builddir@/switch_sai_thrift @mv -f switchsai.tmp $@ -$(BUILT_SOURCES) : switchsai.ts +$(thrift_cpp_sources) $(thrift_py_sources) : switchsai.ts ## Recover from the removal of $@ @if test -f $@; then :; else \ trap 'rm -rf switchsai.lock switchsai.ts' 1 2 13 15; \ @@ -98,4 +106,102 @@ $(BUILT_SOURCES) : switchsai.ts fi; \ fi -CLEANFILES = $(BUILT_SOURCES) +switchsai_sources = \ +$(thrift_cpp_sources) \ +src/saiacl.c \ +src/sai.c \ +src/sai_bmlib.c \ +src/saibuffer.c \ +src/saifdb.c \ +src/saihash.c \ +src/saihostintf.c \ +src/saiinternal.h \ +src/saiipmc.c \ +src/sail2mc.c \ +src/sailag.c \ +src/saimirror.c \ +src/saineighbor.c \ +src/sainexthop.c \ +src/sainexthopgroup.c \ +src/saiobject.c \ +src/saipolicer.c \ +src/saiport.c \ +src/saiqosmaps.c \ +src/saiqueue.c \ +src/sairoute.c \ +src/sairouter.c \ +src/sairouterintf.c \ +src/saischeduler.c \ +src/saischedulergroup.c \ +src/saistp.c \ +src/saiswitch.c \ +src/saiudf.c \ +src/saiutils.c \ +src/saivlan.c \ +src/switch_sai_rpc_server.cpp + +sai_headers = \ +submodules/SAI/inc/sai.h \ +submodules/SAI/inc/saihash.h \ +submodules/SAI/inc/sailag.h \ +submodules/SAI/inc/sainexthopgroup.h \ +submodules/SAI/inc/saiqosmaps.h \ +submodules/SAI/inc/sairouterintf.h \ +submodules/SAI/inc/saistatus.h \ +submodules/SAI/inc/saitypes.h \ +submodules/SAI/inc/saiacl.h \ +submodules/SAI/inc/saihostintf.h \ +submodules/SAI/inc/saimirror.h \ +submodules/SAI/inc/saiobject.h \ +submodules/SAI/inc/saiqueue.h \ +submodules/SAI/inc/saisamplepacket.h \ +submodules/SAI/inc/saistp.h \ +submodules/SAI/inc/saiudf.h \ +submodules/SAI/inc/saibuffer.h \ +submodules/SAI/inc/saiipmc.h \ +submodules/SAI/inc/saineighbor.h \ +submodules/SAI/inc/saipolicer.h \ +submodules/SAI/inc/sairoute.h \ +submodules/SAI/inc/saischeduler.h \ +submodules/SAI/inc/saiswitch.h \ +submodules/SAI/inc/saivlan.h \ +submodules/SAI/inc/saifdb.h \ +submodules/SAI/inc/sail2mc.h \ +submodules/SAI/inc/sainexthop.h \ +submodules/SAI/inc/saiport.h \ +submodules/SAI/inc/sairouter.h \ +submodules/SAI/inc/saischedulergroup.h \ +submodules/SAI/inc/saitunnel.h \ +submodules/SAI/inc/saiwred.h + +saiincludedir = $(includedir)/sai +saiinclude_HEADERS = $(sai_headers) +noinst_LTLIBRARIES = +lib_LIBRARIES = +lib_LTLIBRARIES = + +if WITH_BMV2 +libbmswitchsai_la_CPPFLAGS = $(AM_CPPFLAGS) +libbmswitchsai_la_CPPFLAGS += -DBMV2 +libbmswitchsai_la_CPPFLAGS += -I$(top_builddir)/p4-build/ +libbmswitchsai_la_CPPFLAGS += -isystem$(includedir) +noinst_LTLIBRARIES += libbmswitchsai.la +libbmswitchsai_la_SOURCES = $(switchsai_sources) +endif + +# FIXME: legacy support, relies on p4factory +if WITH_P4FACTORY +lib_LIBRARIES += libswitchsai.a +libswitchsai_a_SOURCES = $(switchsai_sources) +# FIXME: this also creates shared libraries for p4factory, needs to be +# deprecated +lib_LTLIBRARIES += libswitchsai.la +# has the advantage of avoiding "created both with libtool and without" error +libswitchsai_la_CPPFLAGS = $(AM_CPPFLAGS) +libswitchsai_la_SOURCES = $(switchsai_sources) +endif + +# FIXME: not sure if this serves a real purpose +$(lib_LTLIBRARIES) : $(thrift_py_sources) + +CLEANFILES = $(BUILT_SOURCES) switchsai.ts diff --git a/switchsai/README.md b/switchsai/README.md index be70ff0..d50c33c 100644 --- a/switchsai/README.md +++ b/switchsai/README.md @@ -37,5 +37,7 @@ Supported Features 8. Host interface 9. Ingress Policers 10. Statistics: VLAN, ACL +11. Qos (Quality of Service) - Buffers, Queues +12. CoPP (Control Plane Policing) For the list of supported APIs and attributes, please refer to sai_support.pdf file in the doc directory. diff --git a/switchsai/src/sai.c b/switchsai/src/sai.c index c35c073..0ea0428 100644 --- a/switchsai/src/sai.c +++ b/switchsai/src/sai.c @@ -242,6 +242,9 @@ sai_object_type_t sai_object_type_query(_In_ sai_object_id_t sai_object_id) { case SWITCH_HANDLE_TYPE_ACE: object_type = SAI_OBJECT_TYPE_ACL_ENTRY; break; + case SWITCH_HANDLE_TYPE_RANGE: + object_type = SAI_OBJECT_TYPE_ACL_RANGE; + break; case SWITCH_HANDLE_TYPE_HOSTIF: object_type = SAI_OBJECT_TYPE_HOST_INTERFACE; break; diff --git a/switchsai/src/saiacl.c b/switchsai/src/saiacl.c index 41967ef..92b4b41 100644 --- a/switchsai/src/saiacl.c +++ b/switchsai/src/saiacl.c @@ -29,159 +29,199 @@ scheme will allow for having multiple actions be speicifed in any combination in response to a match */ -typedef int sai_acl_table_match_qualifiers[SAI_ACL_TABLE_ATTR_FIELD_END - - SAI_ACL_TABLE_ATTR_FIELD_START + 1]; - typedef struct sai_handle_node_ { tommy_node node; switch_handle_t handle; } sai_handle_node_t; -static sai_acl_table_match_qualifiers ip_acl = { - -1, - -1, // v6 - -1, - -1, // MAC - SWITCH_ACL_IP_FIELD_IPV4_SRC, - SWITCH_ACL_IP_FIELD_IPV4_DEST, // v4 - -2, - -2, - -2, - -1, - -1, // ports - -1, - -1, - -1, - -1, - -1, - -1, // VLAN outer and inner - SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT, - SWITCH_ACL_IP_FIELD_L4_DEST_PORT, // l4 ports - -1, - SWITCH_ACL_IP_FIELD_IP_PROTO, - -1, // dscp - -1, // ecn - SWITCH_ACL_IP_FIELD_TTL, // ttl - -1, // tos - SWITCH_ACL_IP_FIELD_IP_FLAGS, - SWITCH_ACL_IP_FIELD_TCP_FLAGS, // tcp flags - -1, // ip type - -1, // ip frag - -1, // ipv6 flow - -1 // tc -}; - -static sai_acl_table_match_qualifiers ipv6_acl = { - SWITCH_ACL_IPV6_FIELD_IPV6_SRC, - SWITCH_ACL_IPV6_FIELD_IPV6_DEST, - -1, - -1, // MAC - -1, - -1, // v4 - -2, - -2, - -1, - -1, - -1, // ports - -1, - -1, - -1, - -1, - -1, - -1, // VLAN outer and inner - SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT, - SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT, // l4 ports - -1, - SWITCH_ACL_IPV6_FIELD_IP_PROTO, - -1, // dscp - -1, // ecn - SWITCH_ACL_IPV6_FIELD_TTL, // ttl - -1, // tos - -1, // ip flags - SWITCH_ACL_IPV6_FIELD_TCP_FLAGS, // tcp flags - -1, // ip type - -1, // ip frag - SWITCH_ACL_IPV6_FIELD_FLOW_LABEL, - -1 // tc -}; - -static sai_acl_table_match_qualifiers mac_acl = { - -1, - -1, // v6 - SWITCH_ACL_MAC_FIELD_SOURCE_MAC, - SWITCH_ACL_MAC_FIELD_DEST_MAC, // MAC - -1, - -1, // v4 - -2, - -2, - -1, - -1, - -1, // ports - -1, - SWITCH_ACL_MAC_FIELD_VLAN_PRI, - SWITCH_ACL_MAC_FIELD_VLAN_CFI, - -1, - -1, - -1, // VLAN outer and inner - -1, - -1, // l4 ports - SWITCH_ACL_MAC_FIELD_ETH_TYPE, - -1, - -1, - -1, // ecn - -1, // ttl - -1, - -1, - -1, // tcp flags - -1, // ip type - -1, // ip frag - -1, // ipv6 flow - -1 // tc -}; +#define SAI_ACL_FIELD_NOT_SUPPORTED -1 +int switch_acl[SWITCH_ACL_TYPE_MAX][SAI_ACL_TABLE_ATTR_FIELD_END - + SAI_ACL_TABLE_ATTR_FIELD_START + 1]; + +void sai_acl_qualifiers_load() { + switch_acl_type_t acl_type = SWITCH_ACL_TYPE_IP; + sai_acl_table_attr_t acl_table_field = SAI_ACL_TABLE_ATTR_FIELD_START; + int acl_attr_index = 0; + + for (acl_type = SWITCH_ACL_TYPE_IP; acl_type < SWITCH_ACL_TYPE_MAX; + acl_type++) { + acl_attr_index = 0; + for (acl_table_field = SAI_ACL_TABLE_ATTR_FIELD_START; + acl_table_field < SAI_ACL_TABLE_ATTR_FIELD_END; + acl_table_field++, acl_attr_index++) { + switch (acl_type) { + case SWITCH_ACL_TYPE_IP: { + switch (acl_table_field) { + case SAI_ACL_TABLE_ATTR_FIELD_SRC_IP: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IP_FIELD_IPV4_SRC; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_DST_IP: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IP_FIELD_IPV4_DEST; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IP_FIELD_IP_PROTO; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_TTL: + switch_acl[acl_type][acl_attr_index] = SWITCH_ACL_IP_FIELD_TTL; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IP_FLAGS: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IP_FIELD_IP_FLAGS; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IP_FIELD_TCP_FLAGS; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_RANGE: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_OUT_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORT: + switch_acl[acl_type][acl_attr_index] = -2; + break; + + default: + switch_acl[acl_type][acl_attr_index] = + SAI_ACL_FIELD_NOT_SUPPORTED; + break; + } + } break; + + case SWITCH_ACL_TYPE_IPV6: { + switch (acl_table_field) { + case SAI_ACL_TABLE_ATTR_FIELD_SRC_IPv6: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IPV6_FIELD_IPV6_SRC; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_DST_IPv6: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IPV6_FIELD_IPV6_DEST; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IPV6_FIELD_IP_PROTO; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_TTL: + switch_acl[acl_type][acl_attr_index] = SWITCH_ACL_IPV6_FIELD_TTL; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IPV6_FIELD_TCP_FLAGS; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_RANGE: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT_RANGE; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IPv6_FLOW_LABEL: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_IPV6_FIELD_FLOW_LABEL; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_OUT_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORT: + switch_acl[acl_type][acl_attr_index] = -2; + break; + + default: + switch_acl[acl_type][acl_attr_index] = + SAI_ACL_FIELD_NOT_SUPPORTED; + break; + } + } break; + + case SWITCH_ACL_TYPE_MAC: { + switch (acl_table_field) { + case SAI_ACL_TABLE_ATTR_FIELD_SRC_MAC: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_MAC_FIELD_SOURCE_MAC; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_DST_MAC: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_MAC_FIELD_DEST_MAC; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_PRI: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_MAC_FIELD_VLAN_PRI; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_CFI: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_MAC_FIELD_VLAN_CFI; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE: + switch_acl[acl_type][acl_attr_index] = + SWITCH_ACL_MAC_FIELD_ETH_TYPE; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_OUT_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORT: + switch_acl[acl_type][acl_attr_index] = -2; + break; + + default: + switch_acl[acl_type][acl_attr_index] = + SAI_ACL_FIELD_NOT_SUPPORTED; + break; + } + } break; + + case SWITCH_ACL_TYPE_EGRESS_SYSTEM: { + switch (acl_table_field) { + case SAI_ACL_TABLE_ATTR_FIELD_OUT_PORT: + switch_acl[acl_type][acl_attr_index] = SWITCH_ACL_EGR_DEST_PORT; + break; + + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_OUT_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORT: + switch_acl[acl_type][acl_attr_index] = -2; + break; + + default: + switch_acl[acl_type][acl_attr_index] = + SAI_ACL_FIELD_NOT_SUPPORTED; + break; + } + } break; -static sai_acl_table_match_qualifiers egress_acl = { - -1, - -1, // v6 - -1, - -1, // MAC - -1, - -1, // v4 - -2, - -2, - -1, - SWITCH_ACL_EGR_DEST_PORT, // ports - -1, - -1, - -1, - -1, - -1, - -1, // VLAN outer and inner - -1, - -1, // l4 ports - -1, - -1, - -1, - -1, // ecn - -1, // ttl - -1, - -1, - -1, // tcp flags - -1, // ip type - -1, // ip frag - -1, // ipv6 flow - -1 // tc -}; + default: + switch_acl[acl_type][acl_attr_index] = SAI_ACL_FIELD_NOT_SUPPORTED; + break; + } + } + } +} static int *sai_acl_p4_match_table_get(switch_acl_type_t table_type) { switch (table_type) { case SWITCH_ACL_TYPE_IP: - return ip_acl; case SWITCH_ACL_TYPE_IPV6: - return ipv6_acl; case SWITCH_ACL_TYPE_MAC: - return mac_acl; case SWITCH_ACL_TYPE_EGRESS_SYSTEM: - return egress_acl; + return switch_acl[table_type]; default: return NULL; } @@ -211,11 +251,9 @@ static sai_status_t sai_acl_match_table_type_get( 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: + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_OUT_PORTS: + case SAI_ACL_TABLE_ATTR_FIELD_IN_PORT: break; // ignore above for matching fields default: @@ -272,6 +310,8 @@ static sai_status_t sai_acl_xform_field_value( _In_ int field, _In_ void *dest, _In_ const sai_acl_field_data_t *source) { + sai_object_id_t *objlist = NULL; + uint32_t index = 0; switch (acl_type) { case SWITCH_ACL_TYPE_IP: { switch_acl_ip_key_value_pair_t *kvp = @@ -289,14 +329,6 @@ static sai_status_t sai_acl_xform_field_value( kvp->value.ip_proto = source->data.u16; kvp->mask.u.mask = source->mask.u16; break; - case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT: - kvp->value.l4_source_port = source->data.u16; - kvp->mask.u.mask = source->mask.u16; - break; - case SWITCH_ACL_IP_FIELD_L4_DEST_PORT: - kvp->value.l4_dest_port = source->data.u16; - kvp->mask.u.mask = source->mask.u16; - break; case SWITCH_ACL_IP_FIELD_ICMP_TYPE: case SWITCH_ACL_IP_FIELD_ICMP_CODE: case SWITCH_ACL_IP_FIELD_TCP_FLAGS: @@ -315,23 +347,71 @@ static sai_status_t sai_acl_xform_field_value( kvp->value.ip_frag = source->data.u8; kvp->mask.u.mask = source->mask.u8; break; + + case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE: + case SWITCH_ACL_IP_FIELD_L4_DEST_PORT_RANGE: + objlist = source->data.objlist.list; + for (index = 0; index < source->data.objlist.count; index++) { + switch_handle_t range_handle = 0; + range_handle = (switch_handle_t)objlist[index]; + switch_range_type_t range_type = SWITCH_RANGE_TYPE_NONE; + switch_api_acl_range_type_get(device, range_handle, &range_type); + if (range_type == SWITCH_RANGE_TYPE_SRC_PORT) { + kvp->value.sport_range_handle = range_handle; + } + if (range_type == SWITCH_RANGE_TYPE_DST_PORT) { + kvp->value.dport_range_handle = range_handle; + } + } + break; default: break; } } break; case SWITCH_ACL_TYPE_IPV6: { + switch_acl_ipv6_key_value_pair_t *kvp = + (switch_acl_ipv6_key_value_pair_t *)dest; switch (field) { case SWITCH_ACL_IPV6_FIELD_IPV6_SRC: + memcpy(kvp->value.ipv6_source.u.addr8, source->data.ip6, 16); + memcpy(kvp->mask.u.mask.u.addr8, source->mask.ip6, 16); + break; case SWITCH_ACL_IPV6_FIELD_IPV6_DEST: + memcpy(kvp->value.ipv6_dest.u.addr8, source->data.ip6, 16); + memcpy(kvp->mask.u.mask.u.addr8, source->mask.ip6, 16); + break; case SWITCH_ACL_IPV6_FIELD_IP_PROTO: - case SWITCH_ACL_IPV6_FIELD_L4_SOURCE_PORT: - case SWITCH_ACL_IPV6_FIELD_L4_DEST_PORT: + kvp->value.ip_proto = source->data.u16; + kvp->mask.u.mask.u.addr8[0] = source->mask.u16; + break; case SWITCH_ACL_IPV6_FIELD_ICMP_TYPE: case SWITCH_ACL_IPV6_FIELD_ICMP_CODE: case SWITCH_ACL_IPV6_FIELD_TCP_FLAGS: + kvp->value.tcp_flags = source->data.u8; + kvp->mask.u.mask.u.addr8[0] = source->mask.u8; + break; case SWITCH_ACL_IPV6_FIELD_TTL: + kvp->value.ttl = source->data.u8; + kvp->mask.u.mask.u.addr8[0] = source->mask.u8; + break; case SWITCH_ACL_IPV6_FIELD_FLOW_LABEL: break; + case SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE: + case SWITCH_ACL_IP_FIELD_L4_DEST_PORT_RANGE: + objlist = source->data.objlist.list; + for (index = 0; index < source->data.objlist.count; index++) { + switch_handle_t range_handle = 0; + range_handle = (switch_handle_t)objlist[index]; + switch_range_type_t range_type = SWITCH_RANGE_TYPE_NONE; + switch_api_acl_range_type_get(device, range_handle, &range_type); + if (range_type == SWITCH_RANGE_TYPE_SRC_PORT) { + kvp->value.sport_range_handle = range_handle; + } + if (range_type == SWITCH_RANGE_TYPE_DST_PORT) { + kvp->value.dport_range_handle = range_handle; + } + } + break; default: break; } @@ -382,6 +462,34 @@ static sai_status_t sai_acl_xform_field_value( return SAI_STATUS_SUCCESS; } +sai_status_t sai_acl_direction_get(uint32_t attr_count, + const sai_attribute_t *attr_list, + switch_direction_t *direction) { + sai_status_t status = SAI_STATUS_SUCCESS; + uint32_t index = 0; + *direction = SWITCH_API_DIRECTION_INGRESS; + + for (index = 0; index < attr_count; index++) { + // skip ports and VLAN attributes on check + switch (attr_list[index].id) { + case SAI_ACL_TABLE_ATTR_STAGE: { + sai_acl_stage_t acl_stage = attr_list[index].value.s32; + switch (acl_stage) { + case SAI_ACL_STAGE_EGRESS: + *direction = SWITCH_API_DIRECTION_EGRESS; + break; + case SAI_ACL_STAGE_INGRESS: + default: + *direction = SWITCH_API_DIRECTION_INGRESS; + break; + } + } + } + } + + return status; +} + /* * Routine Description: * Create an ACL table @@ -402,6 +510,7 @@ sai_status_t sai_create_acl_table(_Out_ sai_object_id_t *acl_table_id, sai_status_t status = SAI_STATUS_SUCCESS; switch_acl_type_t acl_type = 0; + switch_direction_t direction = SWITCH_API_DIRECTION_INGRESS; if (!attr_list) { status = SAI_STATUS_INVALID_PARAMETER; @@ -417,7 +526,16 @@ sai_status_t sai_create_acl_table(_Out_ sai_object_id_t *acl_table_id, return status; } - *acl_table_id = (sai_object_id_t)switch_api_acl_list_create(device, acl_type); + status = sai_acl_direction_get(attr_count, attr_list, &direction); + if (status != SAI_STATUS_SUCCESS) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("failed to get acl direction: %s", + sai_status_to_string(status)); + return status; + } + + *acl_table_id = + (sai_object_id_t)switch_api_acl_list_create(device, direction, acl_type); status = (*acl_table_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE : SAI_STATUS_SUCCESS; @@ -927,6 +1045,198 @@ sai_status_t sai_get_acl_counter_attribute(_In_ sai_object_id_t acl_counter_id, return (sai_status_t)status; } +sai_status_t sai_acl_range_attribute_to_switch_acl_range_attrbute( + sai_acl_range_type_t range_type, switch_range_type_t *switch_range_type) { + sai_status_t status = SAI_STATUS_SUCCESS; + switch (range_type) { + case SAI_ACL_RANGE_L4_SRC_PORT_RANGE: + *switch_range_type = SWITCH_RANGE_TYPE_SRC_PORT; + break; + + case SAI_ACL_RANGE_L4_DST_PORT_RANGE: + *switch_range_type = SWITCH_RANGE_TYPE_DST_PORT; + break; + + case SAI_ACL_RANGE_OUTER_VLAN: + case SAI_ACL_RANGE_INNER_VLAN: + *switch_range_type = SWITCH_RANGE_TYPE_VLAN; + break; + + case SAI_ACL_RANGE_PACKET_LENGTH: + *switch_range_type = SWITCH_RANGE_TYPE_PACKET_LENGTH; + break; + + default: + *switch_range_type = SWITCH_RANGE_TYPE_NONE; + } + + return status; +} + +/** + * Routine Description: + * @brief Create an ACL Range + * + * Arguments: + * @param[out] acl_range_id - the acl range id + * @param[in] attr_count - number of attributes + * @param[in] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_create_acl_range(_Out_ sai_object_id_t *acl_range_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { + const sai_attribute_t *attribute = NULL; + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + switch_range_type_t range_type = SWITCH_RANGE_TYPE_NONE; + switch_range_t switch_range; + switch_direction_t direction = SWITCH_API_DIRECTION_INGRESS; + switch_handle_t range_handle = 0; + uint32_t i = 0; + + SAI_LOG_ENTER(); + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + + for (i = 0; i < attr_count; i++) { + attribute = &attr_list[i]; + switch (attribute->id) { + case SAI_ACL_RANGE_ATTR_TYPE: + sai_acl_range_attribute_to_switch_acl_range_attrbute( + attribute->value.s32, &range_type); + break; + + case SAI_ACL_RANGE_ATTR_LIMIT: + switch_range.start_value = attribute->value.s32range.min; + switch_range.end_value = attribute->value.s32range.max; + break; + } + } + + *acl_range_id = 0; + + switch_status = switch_api_acl_range_create( + device, direction, range_type, &switch_range, &range_handle); + status = sai_switch_status_to_sai_status(switch_status); + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to create acl range : %s", + sai_status_to_string(status)); + } + + *acl_range_id = (sai_object_id_t)range_handle; + + SAI_LOG_EXIT(); + + return status; +} + +/** + * Routine Description: + * @brief Remove an ACL Range + * + * Arguments: + * @param[in] acl_range_id - the acl range id + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_remove_acl_range(_In_ sai_object_id_t acl_range_id) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + switch_status_t switch_status = SWITCH_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(acl_range_id) == SAI_OBJECT_TYPE_ACL_RANGE); + + switch_status = + switch_api_acl_range_delete(device, (switch_handle_t)acl_range_id); + status = sai_switch_status_to_sai_status(switch_status); + + if (status != SAI_STATUS_SUCCESS) { + SAI_LOG_ERROR("failed to delete acl range%lx : %s", + acl_range_id, + sai_status_to_string(status)); + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * Routine Description: + * @brief Set ACL range attribute + * + * Arguments: + * @param[in] acl_range_id - the acl range id + * @param[in] attr - attribute + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_set_acl_range_attribute(_In_ sai_object_id_t acl_range_id, + _In_ const sai_attribute_t *attr) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(acl_range_id) == SAI_OBJECT_TYPE_ACL_RANGE); + + if (!attr) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); + return status; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + +/** + * Routine Description: + * @brief Get ACL range attribute + * + * Arguments: + * @param[in] acl_range_id - acl range id + * @param[in] attr_count - number of attributes + * @param[out] attr_list - array of attributes + * + * Return Values: + * @return SAI_STATUS_SUCCESS on success + * Failure status code on error + */ +sai_status_t sai_get_acl_range_attribute(_In_ sai_object_id_t acl_range_id, + _In_ uint32_t attr_count, + _Out_ sai_attribute_t *attr_list) { + SAI_LOG_ENTER(); + + sai_status_t status = SAI_STATUS_SUCCESS; + + SAI_ASSERT(sai_object_type_query(acl_range_id) == SAI_OBJECT_TYPE_ACL_RANGE); + + if (!attr_list) { + status = SAI_STATUS_INVALID_PARAMETER; + SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); + return status; + } + + SAI_LOG_EXIT(); + + return (sai_status_t)status; +} + /* * ACL methods table retrieved with sai_api_query() */ @@ -938,12 +1248,17 @@ sai_acl_api_t acl_api = { .create_acl_counter = sai_create_acl_counter, .delete_acl_counter = sai_delete_acl_counter, .set_acl_counter_attribute = sai_set_acl_counter_attribute, - .get_acl_counter_attribute = sai_get_acl_counter_attribute + .get_acl_counter_attribute = sai_get_acl_counter_attribute, + .create_acl_range = sai_create_acl_range, + .remove_acl_range = sai_remove_acl_range, + .set_acl_range_attribute = sai_set_acl_range_attribute, + .get_acl_range_attribute = sai_get_acl_range_attribute }; sai_status_t sai_acl_initialize(sai_api_service_t *sai_api_service) { SAI_LOG_DEBUG("Initializing acl"); sai_api_service->acl_api = acl_api; + sai_acl_qualifiers_load(); return SAI_STATUS_SUCCESS; } diff --git a/switchsai/src/saiipmc.c b/switchsai/src/saiipmc.c index b21282b..695a774 100644 --- a/switchsai/src/saiipmc.c +++ b/switchsai/src/saiipmc.c @@ -126,7 +126,8 @@ static switch_handle_t sai_ipmc_tree_create( mbrs = switch_malloc(sizeof(switch_vlan_interface_t), oif_list_count); mcast_handle = switch_api_multicast_tree_create(device); - for (int i = 0; i < oif_list_count; i++) { + int i = 0; + for (i = 0; i < oif_list_count; i++) { switch_handle_t intf_handle = oif_list_handle[i]; switch_interface_type_t type; status = switch_api_interface_get_type(intf_handle, &type); diff --git a/switchsai/src/sail2mc.c b/switchsai/src/sail2mc.c index 33d598a..1704716 100644 --- a/switchsai/src/sail2mc.c +++ b/switchsai/src/sail2mc.c @@ -155,7 +155,8 @@ sai_status_t sai_create_l2mc_entry(_In_ const sai_l2mc_entry_t *l2mc_entry, switch_vlan_interface_t *mbrs; mbrs = switch_malloc(sizeof(switch_vlan_interface_t), port_list_count); - for (int i = 0; i < port_list_count; i++) { + int i = 0; + for (i = 0; i < port_list_count; i++) { mbrs[i].vlan_handle = vlan_handle; mbrs[i].intf_handle = port_list_handle[i]; } diff --git a/switchsai/src/switch_sai.thrift b/switchsai/src/switch_sai.thrift index 6c0ee5c..78878c4 100644 --- a/switchsai/src/switch_sai.thrift +++ b/switchsai/src/switch_sai.thrift @@ -133,6 +133,11 @@ struct sai_thrift_qos_map_list_t { 2: list data; } +struct sai_thrift_range_t { + 1: i32 min; + 2: i32 max; +} + union sai_thrift_attribute_value_t { 1: bool booldata; 2: string chardata; @@ -154,6 +159,8 @@ union sai_thrift_attribute_value_t { 18: sai_thrift_acl_field_data_t aclfield; 19: sai_thrift_acl_action_data_t aclaction; 20: sai_thrift_qos_map_list_t qosmap; + 21: sai_thrift_range_t s32range; + 22: sai_thrift_range_t u32range; } struct sai_thrift_attribute_t { @@ -268,6 +275,9 @@ service switch_sai_rpc { 1: sai_thrift_object_id_t acl_counter_id, 2: list thrift_attr_ids); + sai_thrift_object_id_t sai_thrift_create_acl_range(1: list thrift_attr_list); + sai_thrift_status_t sai_thrift_delete_acl_range(1: sai_thrift_object_id_t acl_range_id); + // Mirror API sai_thrift_object_id_t sai_thrift_create_mirror_session(1: list thrift_attr_list); sai_thrift_status_t sai_thrift_remove_mirror_session(1: sai_thrift_object_id_t session_id); diff --git a/switchsai/src/switch_sai_rpc_server.cpp b/switchsai/src/switch_sai_rpc_server.cpp index acbffc7..ce2c44f 100644 --- a/switchsai/src/switch_sai_rpc_server.cpp +++ b/switchsai/src/switch_sai_rpc_server.cpp @@ -1276,6 +1276,10 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { attribute = (sai_thrift_attribute_t)*it; attr_list[i].id = attribute.id; switch (attribute.id) { + case SAI_ACL_TABLE_ATTR_STAGE: + attr_list[i].value.s32 = attribute.value.s32; + break; + case SAI_ACL_TABLE_ATTR_FIELD_SRC_IPv6: case SAI_ACL_TABLE_ATTR_FIELD_DST_IPv6: case SAI_ACL_TABLE_ATTR_FIELD_SRC_MAC: @@ -1410,12 +1414,44 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { case SAI_ACL_ENTRY_ATTR_PACKET_ACTION: attr_list[i].value.aclfield.data.s32 = attribute.value.aclfield.data.s32; break; + case SAI_ACL_ENTRY_ATTR_FIELD_RANGE: + { + int count = attribute.value.aclfield.data.objlist.object_id_list.size(); + sai_object_id_t *oid_list = NULL; + std::vector::const_iterator it = attribute.value.aclfield.data.objlist.object_id_list.begin(); + oid_list = (sai_object_id_t *) malloc(sizeof(sai_object_id_t) * count); + for(int j = 0; j < count; j++, it++) + *(oid_list + j) = (sai_object_id_t) *it; + attr_list[i].value.aclfield.data.objlist.list = oid_list; + attr_list[i].value.aclfield.data.objlist.count = count; + } + break; default: break; } } } + void sai_thrift_convert_to_acl_range_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_ACL_RANGE_ATTR_TYPE: + attr_list[i].value.s32 = attribute.value.s32; + break; + case SAI_ACL_RANGE_ATTR_LIMIT: + attr_list[i].value.u32range.min = attribute.value.u32range.min; + attr_list[i].value.u32range.max = attribute.value.u32range.max; + break; + } + } + } + void sai_thrift_convert_to_acl_counter_attributes( const std::vector &thrift_attr_list, sai_attribute_t *attr_list) { @@ -1443,7 +1479,6 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { } } } - void sai_thrift_convert_to_acl_thrift_counter_attributes( sai_attribute_t *attr_list, uint32_t attr_count, @@ -1588,6 +1623,34 @@ class switch_sai_rpcHandler : virtual public switch_sai_rpcIf { return; } + sai_thrift_object_id_t sai_thrift_create_acl_range(const std::vector & thrift_attr_list) { + sai_object_id_t acl_range_id = 0ULL; + sai_acl_api_t *acl_api; + sai_status_t status = SAI_STATUS_SUCCESS; + status = sai_api_query(SAI_API_ACL, (void **) &acl_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + sai_attribute_t *attr_list = (sai_attribute_t *) malloc(sizeof(sai_attribute_t) * thrift_attr_list.size()); + sai_thrift_convert_to_acl_range_attributes(thrift_attr_list, attr_list); + uint32_t attr_count = thrift_attr_list.size(); + status = acl_api->create_acl_range(&acl_range_id, attr_count, attr_list); + free(attr_list); + return acl_range_id; + } + + sai_thrift_status_t sai_thrift_delete_acl_range(const sai_thrift_object_id_t acl_range_id) { + sai_object_id_t acl_entry = 0ULL; + sai_acl_api_t *acl_api; + sai_status_t status = SAI_STATUS_SUCCESS; + status = sai_api_query(SAI_API_ACL, (void **) &acl_api); + if (status != SAI_STATUS_SUCCESS) { + return status; + } + status = acl_api->remove_acl_range(acl_range_id); + return status; + } + void sai_thrift_parse_mirror_session_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; diff --git a/tests/of-tests/common/utils.py b/tests/of-tests/common/utils.py new file mode 100644 index 0000000..7067c62 --- /dev/null +++ b/tests/of-tests/common/utils.py @@ -0,0 +1,45 @@ +import struct + +# thrift does not support unsigned integers +def hex_to_i16(h): + x = int(h) + if (x > 0x7FFF): x-= 0x10000 + return x +def hex_to_i32(h): + x = int(h) + if (x > 0x7FFFFFFF): x-= 0x100000000 + return x +def hex_to_byte(h): + x = int(h) + if (x > 0x7F): x-= 0x100 + return x +def uint_to_i32(u): + if (u > 0x7FFFFFFF): u-= 0x100000000 + return u + +def bytes_to_string(byte_array): + form = 'B' * len(byte_array) + return struct.pack(form, *byte_array) + +def string_to_bytes(string): + form = 'B' * len(string) + return list(struct.unpack(form, string)) + +def macAddr_to_string(addr): + byte_array = [int(b, 16) for b in addr.split(':')] + return bytes_to_string(byte_array) + +def ipv4Addr_to_i32(addr): + byte_array = [int(b) for b in addr.split('.')] + res = 0 + for b in byte_array: res = res * 256 + b + return uint_to_i32(res) + +def stringify_macAddr(addr): + return ':'.join('%02x' % byte_to_u(x) for x in addr) + +def i32_to_ipv4Addr(addr): + return socket.inet_ntoa(struct.pack("!I", addr)) + +def ipv6Addr_to_string(addr): + return (str(socket.inet_pton(socket.AF_INET6, addr))) diff --git a/tests/of-tests/openflow.py b/tests/of-tests/openflow.py index 0b89814..a91239c 100644 --- a/tests/of-tests/openflow.py +++ b/tests/of-tests/openflow.py @@ -5,7 +5,6 @@ import os import time - import logging from oftest import config import oftest.base_tests as base_tests @@ -16,19 +15,19 @@ import openflow_base_tests -sys.path.append(os.path.join(sys.path[0], '..', '..', '..', '..', - 'testutils')) +root_dir = os.path.dirname(os.path.realpath(__file__)) + +sys.path.append(os.path.join(root_dir, 'common')) from utils import * -sys.path.append(os.path.join(sys.path[0], '..', '..', '..', '..', - 'targets', 'switch', 'tests', 'pd_thrift')) +sys.path.append(os.path.join(root_dir, '..', '..', 'p4-build', 'bmv2', + 'pd_thrift_gen', 'gen-py')) from p4_pd_rpc.ttypes import * from res_pd_rpc.ttypes import * -sys.path.append(os.path.join(sys.path[0], '..', '..', '..', '..', - 'targets', 'switch', 'openflow_mapping')) +sys.path.append(os.path.join(root_dir, '..', '..', 'openflow_mapping')) from l2 import * ### TODO: generate expected packets @@ -168,6 +167,42 @@ def setup_default_table_configurations(client, sess_hdl, dev_tgt): sess_hdl, dev_tgt, match_spec, mbr_hdl) + ifindex = 0x41 + action_spec = dc_set_bd_properties_action_spec_t( + action_bd=0, + action_vrf=0, + action_rmac_group=0, + action_bd_label=0, + action_ipv4_unicast_enabled=True, + action_ipv6_unicast_enabled=False, + action_ipv4_multicast_enabled=False, + action_ipv6_multicast_enabled=False, + action_igmp_snooping_enabled=0, + action_mld_snooping_enabled=0, + action_ipv4_urpf_mode=0, + action_ipv6_urpf_mode=0, + action_stp_group=0, + action_mrpf_group=0, + action_ipv4_mcast_key_type=0, + action_ipv4_mcast_key=0, + action_ipv6_mcast_key_type=0, + action_ipv6_mcast_key=0, + action_stats_idx=0, + action_learning_enabled=0) + + mbr_hdl = client.bd_action_profile_add_member_with_set_bd_properties( + sess_hdl, dev_tgt, + action_spec) + match_spec = dc_port_vlan_mapping_match_spec_t( + ingress_metadata_ifindex=ifindex, + vlan_tag__0__valid=0, + vlan_tag__0__vid=0, + vlan_tag__1__valid=0, + vlan_tag__1__vid=0) + client.port_vlan_mapping_add_entry( + sess_hdl, dev_tgt, + match_spec, mbr_hdl) + def setup_pre(mc, sess_hdl, dev_tgt): mgrp_hdl = mc.mc_mgrp_create(sess_hdl, dev_tgt.dev_id, 1) port_map = [0] * 32 @@ -180,7 +215,7 @@ def setup_pre(mc, sess_hdl, dev_tgt): mc.mc_associate_node(sess_hdl, dev_tgt.dev_id, mgrp_hdl, node_hdl) def setup(self): - sess_hdl = self.conn_mgr.client_init(16) + sess_hdl = self.conn_mgr.client_init() dev_tgt = DevTarget_t(0, hex_to_i16(0xFFFF)) setup_default_table_configurations(self.client, sess_hdl, dev_tgt) setup_pre(self.mc, sess_hdl, dev_tgt) @@ -420,61 +455,6 @@ def runTest(self): self.controller.message_send(req) do_barrier(self.controller) -class TableStatsGet(openflow_base_tests.OFTestInterface): - """ - """ - def __init__(self): - openflow_base_tests.OFTestInterface.__init__(self, "dc") - - def runTest(self): - setup(self) - - req = table_stats_req() - (reply, pkt) = self.controller.transact(req) - initial_matched_count = reply.entries[0].matched_count - initial_lookup_count = reply.entries[0].lookup_count - - ports = sorted(config["port_map"].keys()) - out_port = ports[0] - - table = openflow_tables["dmac"] - table.match_fields[eth_dst_addr].testval = TEST_ETH_DST - table.match_fields[ingress_vlan].testval = TEST_VLAN - hit_pkt, match = get_match(table.match_fields) - - output = { - "OUTPUT": out_port - } - - instr = get_apply_actions(output) - req = flow_add(table_id=table.id, match=match, instructions=instr, - buffer_id=buf, priority=1, cookie=45) - self.controller.message_send(req) - do_barrier(self.controller) - - num_hit_packets = 10 - for _ in xrange(num_hit_packets): - self.dataplane.send(ports[0], hit_pkt) - - miss_pkt = str(simple_tcp_packet(eth_dst="00:77:22:55:99:11", - dl_vlan_enable=True, vlan_vid=3)) - - num_miss_packets = 7 - for _ in xrange(num_miss_packets): - self.dataplane.send(ports[0], miss_pkt) - - time.sleep(3) - - req = table_stats_req() - (reply, pkt) = self.controller.transact(req) - - req = flow_delete(cookie=45, table_id=0) - self.controller.message_send(req) - do_barrier(self.controller) - - assert reply.entries[0].lookup_count == num_miss_packets + num_hit_packets + initial_lookup_count - assert reply.entries[0].matched_count == num_hit_packets + initial_matched_count - class PacketIn(openflow_base_tests.OFTestInterface): """ """ @@ -510,3 +490,39 @@ def runTest(self): self.controller.message_send(req) do_barrier(self.controller) +class PacketOut(openflow_base_tests.OFTestInterface): + """ + """ + def __init__(self): + openflow_base_tests.OFTestInterface.__init__(self, "dc") + + def runTest(self): + setup(self) + + ports = sorted(config["port_map"].keys()) + port1 = ports[1] + + outpkt = simple_tcp_packet() + + # flood packet out + flood = ofp.message.packet_out() + flood.data = str(outpkt) + flood_act = ofp.action.output() + flood_act.port = 0xfffffffb + flood.actions.append(flood_act) + flood.buffer_id = 0xffffffff + self.controller.message_send(flood) + verify_packets(self, outpkt, ports) + + time.sleep(2) + + # unicast packet out + unicast = ofp.message.packet_out() + unicast.data = str(outpkt) + unicast_act = ofp.action.output() + unicast_act.port = port1 + unicast.actions.append(unicast_act) + unicast.buffer_id = 0xffffffff + self.controller.message_send(unicast) + verify_packet(self, outpkt, port1) + diff --git a/tests/ptf-tests/api-tests/switch.py b/tests/ptf-tests/api-tests/switch.py index 4c705af..badf9c6 100644 --- a/tests/ptf-tests/api-tests/switch.py +++ b/tests/ptf-tests/api-tests/switch.py @@ -2803,8 +2803,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -3025,8 +3025,8 @@ def runTest(self): vxlan_pkt = simple_vxlanv6_packet( eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', - ipv6_dst=ipv6_dst_addr, - ipv6_src=ipv6_src_addr, + ipv6_dst=ipv6_src_addr, + ipv6_src=ipv6_dst_addr, ipv6_hlim=64, udp_sport=0, with_udp_chksum=False, @@ -3143,8 +3143,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, nvgre_tni=0x1234, inner_frame=pkt) @@ -3239,8 +3239,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, nvgre_tni=0x1234, inner_frame=pkt) @@ -3364,8 +3364,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -3529,8 +3529,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -3636,8 +3636,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -3782,8 +3782,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, nvgre_tni=0x1234, inner_frame=pkt) @@ -4021,8 +4021,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -4056,8 +4056,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -4205,8 +4205,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -4242,8 +4242,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -4374,8 +4374,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -4503,8 +4503,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -4672,8 +4672,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -4706,8 +4706,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -4856,8 +4856,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -4896,8 +4896,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -5034,8 +5034,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -5198,8 +5198,8 @@ def runTest(self): eth_src='00:44:44:44:44:44', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -5905,8 +5905,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -5939,8 +5939,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -5973,8 +5973,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -6002,8 +6002,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:33:33:33:33:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -6376,8 +6376,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -6410,8 +6410,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -6444,8 +6444,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -6473,8 +6473,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:33:33:33:33:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -6530,8 +6530,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -6563,8 +6563,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:44:44:44:44:44', ip_id=0, - ip_dst='2.2.2.3', - ip_src='2.2.2.1', + ip_dst='2.2.2.1', + ip_src='2.2.2.3', ip_ttl=64, udp_sport=574, with_udp_chksum=False, @@ -6596,8 +6596,8 @@ def runTest(self): eth_src='00:66:66:66:66:66', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='3.3.3.3', - ip_src='3.3.3.1', + ip_dst='3.3.3.1', + ip_src='3.3.3.3', ip_ttl=64, nvgre_tni=0x4545, inner_frame=pkt) @@ -6628,8 +6628,8 @@ def runTest(self): eth_src='00:66:66:66:66:66', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='3.3.3.3', - ip_src='3.3.3.1', + ip_dst='3.3.3.1', + ip_src='3.3.3.3', ip_ttl=64, nvgre_tni=0x4545, inner_frame=pkt) @@ -6661,8 +6661,8 @@ def runTest(self): eth_dst='00:77:66:55:44:33', eth_src='00:66:66:66:66:66', ip_id=0, - ip_dst='3.3.3.3', - ip_src='3.3.3.1', + ip_dst='3.3.3.1', + ip_src='3.3.3.3', ip_ttl=64, nvgre_tni=0x4545, inner_frame=pkt) @@ -6914,8 +6914,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8463,8 +8463,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8483,8 +8483,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8502,8 +8502,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8521,8 +8521,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8540,8 +8540,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8559,8 +8559,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8592,8 +8592,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8609,8 +8609,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8644,8 +8644,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8662,8 +8662,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8681,7 +8681,7 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', + ip_dst='1.1.1.1', ip_src='127.1.1.1', ip_ttl=64, udp_sport=11638, @@ -8700,7 +8700,7 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', + ip_dst='1.1.1.1', ip_src='225.1.1.1', ip_ttl=64, udp_sport=11638, @@ -8720,8 +8720,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8740,8 +8740,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -8763,8 +8763,8 @@ def runTest(self): eth_src='00:33:33:33:33:33', eth_dst='00:77:66:55:44:33', ip_id=0, - ip_dst='1.1.1.3', - ip_src='1.1.1.1', + ip_dst='1.1.1.1', + ip_src='1.1.1.3', ip_ttl=64, udp_sport=11638, with_udp_chksum=False, @@ -9773,8 +9773,8 @@ def runTest(self): 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_dst='10.100.1.1', + ip_src='10.200.1.3', ip_ttl=64, inner_frame=pkt1['IP']) pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', @@ -9795,8 +9795,8 @@ def runTest(self): 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_dst='10.100.1.1', + ip_src='10.200.1.3', ip_ttl=64, inner_frame=pkt1['IPv6']) pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', @@ -9816,8 +9816,8 @@ def runTest(self): 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_dst='3ffe::1', + ipv6_src='3ffe::2', ipv6_hlim=64, inner_frame=pkt1['IP']) pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', @@ -9837,8 +9837,8 @@ def runTest(self): 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_dst='3ffe::1', + ipv6_src='3ffe::2', ipv6_hlim=64, inner_frame=pkt1['IPv6']) pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', @@ -9859,8 +9859,8 @@ def runTest(self): 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_dst='10.100.1.1', + ip_src='10.200.1.3', ip_ttl=64, inner_frame=pkt1['IP']) pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', @@ -9881,8 +9881,8 @@ def runTest(self): 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_dst='10.100.1.1', + ip_src='10.200.1.3', ip_ttl=64, inner_frame=pkt1['IPv6']) pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', @@ -9902,8 +9902,8 @@ def runTest(self): 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_dst='3ffe::1', + ipv6_src='3ffe::2', ipv6_hlim=64, inner_frame=pkt1['IP']) pkt2 = simple_tcp_packet(eth_src='00:77:66:55:44:33', @@ -9923,8 +9923,8 @@ def runTest(self): 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_dst='3ffe::1', + ipv6_src='3ffe::2', ipv6_hlim=64, inner_frame=pkt1['IPv6']) pkt2 = simple_tcpv6_packet(eth_src='00:77:66:55:44:33', @@ -10274,7 +10274,7 @@ def setUp(self): neighbor_entry) # create NAT ACL (permit all) - self.acl = self.client.switcht_api_acl_list_create(device, 0) + self.acl = self.client.switcht_api_acl_list_create(device, SWITCH_API_DIRECTION_INGRESS, 0) kvp = [] acl_priority = 10 action = 2 diff --git a/tests/ptf-tests/api-tests/switch_acl.py b/tests/ptf-tests/api-tests/switch_acl.py index 2323543..f35a117 100644 --- a/tests/ptf-tests/api-tests/switch_acl.py +++ b/tests/ptf-tests/api-tests/switch_acl.py @@ -100,7 +100,7 @@ def runTest(self): # setup a deny ACL to verify that the same packet does not make it # ip acl - acl = self.client.switcht_api_acl_list_create(0, 0) + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_INGRESS, 0) # create kvp to match destination IP kvp = [] kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) @@ -142,6 +142,107 @@ def runTest(self): self.client.switcht_api_router_mac_group_delete(0, rmac) self.client.switcht_api_vrf_delete(0, vrf) +############################################################################### +@group('acl') +@group('maxsizes') +class IPEgressAclTest(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])" + self.client.switcht_api_init(0) + vrf = self.client.switcht_api_vrf_create(0, 1) + + rmac = self.client.switcht_api_router_mac_group_create(0) + self.client.switcht_api_router_mac_add(0, rmac, '00:77:66:55:44:33') + + iu1 = interface_union(port_lag_handle = swports[1]) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if1 = self.client.switcht_api_interface_create(0, i_info1) + i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if2 = self.client.switcht_api_interface_create(0, i_info2) + i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) + + # Add a static route + i_ip3 = switcht_ip_addr_t(ipaddr='10.10.10.1', prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + nhop = self.client.switcht_api_nhop_create(0, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, + interface_handle=if2, + mac_addr='00:11:22:33:44:55', + ip_addr=i_ip3, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) + self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) + + # send the test packet(s) + 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) + send_packet(self, swports[1], str(pkt)) + + 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, + #ip_tos=3, + ip_ttl=63) + verify_packets(self, exp_pkt, [swports[2]]) + + + # setup a deny ACL to verify that the same packet does not make it + # ip acl + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_EGRESS, 0) + # create kvp to match destination IP + kvp = [] + kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) + kvp_mask = switcht_acl_value_t(value_num=int("ffffffff", 16)) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_IPV4_DEST, kvp_val, kvp_mask)) + action = 1 + action_params = switcht_acl_action_params_t(redirect = switcht_acl_action_redirect(handle = 0)) + opt_action_params = switcht_acl_opt_action_params_t() + ace = self.client.switcht_api_acl_ip_rule_create(0, acl, 10, 1, kvp, action, + action_params, + opt_action_params) + self.client.switcht_api_acl_reference(0, acl, if2) + send_packet(self, swports[1], str(pkt)) + + # check for absence of packet here! + try: + verify_packets(self, exp_pkt, [swports[2]]) + print 'FAILED - did not expect packet' + except: + print 'Success' + + # ip_acl + self.client.switcht_api_acl_remove(0, acl, if2) + self.client.switcht_api_acl_rule_delete(0, acl, ace) + self.client.switcht_api_acl_list_delete(0, acl) + + #cleanup + self.client.switcht_api_neighbor_entry_remove(0, neighbor) + self.client.switcht_api_nhop_delete(0, nhop) + self.client.switcht_api_l3_route_delete(0, vrf, i_ip3, if2) + + self.client.switcht_api_l3_interface_address_delete(0, if1, vrf, i_ip1) + self.client.switcht_api_l3_interface_address_delete(0, if2, vrf, i_ip2) + + self.client.switcht_api_interface_delete(0, if1) + self.client.switcht_api_interface_delete(0, if2) + + self.client.switcht_api_router_mac_delete(0, rmac, '00:77:66:55:44:33') + self.client.switcht_api_router_mac_group_delete(0, rmac) + self.client.switcht_api_vrf_delete(0, vrf) ############################################################################### @group('acl') @@ -210,7 +311,7 @@ def runTest(self): # setup a Mirror acl # ip acl print "Create Mirror ACL to mirror i2e from 1->4" - acl = self.client.switcht_api_acl_list_create(0, 0) + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_INGRESS, 0) # create kvp to match destination IP kvp = [] kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) @@ -353,7 +454,7 @@ def runTest(self): # setup a egress Mirror acl 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) + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_EGRESS, 6) # create kvp to match egress port and deflect bit kvp = [] kvp_val = switcht_acl_value_t(value_num=swports[2]) @@ -518,7 +619,7 @@ def runTest(self): mirror1 = self.client.switcht_api_mirror_session_create(0, minfo1) print "Create Mirror ACL to mirror i2e from 1->4" - acl = self.client.switcht_api_acl_list_create(0, 0) + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_INGRESS, 0) # create kvp to match destination IP kvp = [] kvp_val = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) @@ -624,7 +725,7 @@ def runTest(self): counter = self.client.switcht_api_acl_counter_create(0) - acl = self.client.switcht_api_acl_list_create(0, 0) + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_INGRESS, 0) kvp = [] kvp_val1 = switcht_acl_value_t(value_num=int("0a0a0a01", 16)) kvp_mask1 = switcht_acl_value_t(value_num=int("ffffffff", 16)) @@ -727,3 +828,222 @@ def runTest(self): self.client.switcht_api_router_mac_delete(0, rmac, '00:77:66:55:44:33') self.client.switcht_api_router_mac_group_delete(0, rmac) self.client.switcht_api_vrf_delete(0, vrf) + +############################################################################### +@group('acl') +@group('maxsizes') +class IPIngressAclRangeTcamTest(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])" + self.client.switcht_api_init(0) + vrf = self.client.switcht_api_vrf_create(0, 1) + + rmac = self.client.switcht_api_router_mac_group_create(0) + self.client.switcht_api_router_mac_add(0, rmac, '00:77:66:55:44:33') + + iu1 = interface_union(port_lag_handle = swports[1]) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if1 = self.client.switcht_api_interface_create(0, i_info1) + i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if2 = self.client.switcht_api_interface_create(0, i_info2) + i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) + + # Add a static route + i_ip3 = switcht_ip_addr_t(ipaddr='10.10.10.1', prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + nhop = self.client.switcht_api_nhop_create(0, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, + interface_handle=if2, + mac_addr='00:11:22:33:44:55', + ip_addr=i_ip3, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) + self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) + + # send the test packet(s) + 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) + send_packet(self, swports[1], str(pkt)) + + 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, + #ip_tos=3, + ip_ttl=63) + verify_packets(self, exp_pkt, [swports[2]]) + + switch_range = switcht_range_t(start_value = 1000, end_value=2000) + acl_range_handle = self.client.switcht_api_acl_range_create( + 0, + SWITCH_API_DIRECTION_INGRESS, + SWITCH_RANGE_TYPE_SRC_PORT, + switch_range) + + # setup a deny ACL to verify that the same packet does not make it + # ip acl + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_INGRESS, SWITCH_ACL_TYPE_IP) + # create kvp to match destination IP + kvp = [] + kvp_val = switcht_acl_value_t(value_num=acl_range_handle) + kvp_mask = switcht_acl_value_t(value_num=0xffffffff) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_L4_SOURCE_PORT_RANGE, kvp_val, kvp_mask)) + action = SWITCH_ACL_ACTION_DROP + action_params = switcht_acl_action_params_t(redirect = switcht_acl_action_redirect(handle = 0)) + opt_action_params = switcht_acl_opt_action_params_t() + ace = self.client.switcht_api_acl_ip_rule_create(0, acl, 10, 1, kvp, action, + action_params, + opt_action_params) + self.client.switcht_api_acl_reference(0, acl, if1) + send_packet(self, swports[1], str(pkt)) + + # check for absence of packet here! + try: + verify_packets(self, exp_pkt, [swports[2]]) + print 'FAILED - did not expect packet' + except: + print 'Success' + + # ip_acl + self.client.switcht_api_acl_remove(0, acl, if1) + self.client.switcht_api_acl_rule_delete(0, acl, ace) + self.client.switcht_api_acl_list_delete(0, acl) + self.client.switcht_api_acl_range_delete(0, acl_range_handle) + + #cleanup + self.client.switcht_api_neighbor_entry_remove(0, neighbor) + self.client.switcht_api_nhop_delete(0, nhop) + self.client.switcht_api_l3_route_delete(0, vrf, i_ip3, if2) + + self.client.switcht_api_l3_interface_address_delete(0, if1, vrf, i_ip1) + self.client.switcht_api_l3_interface_address_delete(0, if2, vrf, i_ip2) + + self.client.switcht_api_interface_delete(0, if1) + self.client.switcht_api_interface_delete(0, if2) + + self.client.switcht_api_router_mac_delete(0, rmac, '00:77:66:55:44:33') + self.client.switcht_api_router_mac_group_delete(0, rmac) + self.client.switcht_api_vrf_delete(0, vrf) + +############################################################################### +@group('acl') +@group('maxsizes') +class IPEgressAclRangeTcamTest(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])" + self.client.switcht_api_init(0) + vrf = self.client.switcht_api_vrf_create(0, 1) + + rmac = self.client.switcht_api_router_mac_group_create(0) + self.client.switcht_api_router_mac_add(0, rmac, '00:77:66:55:44:33') + + iu1 = interface_union(port_lag_handle = swports[1]) + i_info1 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu1, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if1 = self.client.switcht_api_interface_create(0, i_info1) + i_ip1 = switcht_ip_addr_t(ipaddr='192.168.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if1, vrf, i_ip1) + + iu2 = interface_union(port_lag_handle = swports[2]) + i_info2 = switcht_interface_info_t(device=0, type=SWITCH_API_INTERFACE_L3, u=iu2, mac='00:77:66:55:44:33', label=0, vrf_handle=vrf, rmac_handle=rmac) + if2 = self.client.switcht_api_interface_create(0, i_info2) + i_ip2 = switcht_ip_addr_t(ipaddr='10.0.0.2', prefix_length=16) + self.client.switcht_api_l3_interface_address_add(0, if2, vrf, i_ip2) + + # Add a static route + i_ip3 = switcht_ip_addr_t(ipaddr='10.10.10.1', prefix_length=32) + nhop_key = switcht_nhop_key_t(intf_handle=if2, ip_addr_valid=0) + nhop = self.client.switcht_api_nhop_create(0, nhop_key) + neighbor_entry = switcht_neighbor_info_t(nhop_handle=nhop, + interface_handle=if2, + mac_addr='00:11:22:33:44:55', + ip_addr=i_ip3, + rw_type=SWITCH_API_NEIGHBOR_RW_TYPE_L3) + neighbor = self.client.switcht_api_neighbor_entry_add(0, neighbor_entry) + self.client.switcht_api_l3_route_add(0, vrf, i_ip3, nhop) + + # send the test packet(s) + 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', + tcp_dport=1500, + ip_id=105, + ip_ttl=64) + send_packet(self, swports[1], str(pkt)) + + 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, + tcp_dport=1500, + #ip_tos=3, + ip_ttl=63) + verify_packets(self, exp_pkt, [swports[2]]) + + switch_range = switcht_range_t(start_value = 1000, end_value=2000) + acl_range_handle = self.client.switcht_api_acl_range_create( + 0, + SWITCH_API_DIRECTION_EGRESS, + SWITCH_RANGE_TYPE_DST_PORT, + switch_range) + + # setup a deny ACL to verify that the same packet does not make it + # ip acl + acl = self.client.switcht_api_acl_list_create(0, SWITCH_API_DIRECTION_EGRESS, SWITCH_ACL_TYPE_IP) + # create kvp to match destination IP + kvp = [] + kvp_val = switcht_acl_value_t(value_num=acl_range_handle) + kvp_mask = switcht_acl_value_t(value_num=0xffffffff) + kvp.append(switcht_acl_key_value_pair_t(SWITCH_ACL_IP_FIELD_L4_DEST_PORT_RANGE, kvp_val, kvp_mask)) + action = SWITCH_ACL_ACTION_DROP + action_params = switcht_acl_action_params_t(redirect = switcht_acl_action_redirect(handle = 0)) + opt_action_params = switcht_acl_opt_action_params_t() + ace = self.client.switcht_api_acl_ip_rule_create(0, acl, 10, 1, kvp, action, + action_params, + opt_action_params) + self.client.switcht_api_acl_reference(0, acl, if2) + send_packet(self, swports[1], str(pkt)) + + # check for absence of packet here! + try: + verify_packets(self, exp_pkt, [swports[2]]) + print 'FAILED - did not expect packet' + except: + print 'Success' + + # ip_acl + self.client.switcht_api_acl_remove(0, acl, if2) + self.client.switcht_api_acl_rule_delete(0, acl, ace) + self.client.switcht_api_acl_list_delete(0, acl) + self.client.switcht_api_acl_range_delete(0, acl_range_handle) + + #cleanup + self.client.switcht_api_neighbor_entry_remove(0, neighbor) + self.client.switcht_api_nhop_delete(0, nhop) + self.client.switcht_api_l3_route_delete(0, vrf, i_ip3, if2) + + self.client.switcht_api_l3_interface_address_delete(0, if1, vrf, i_ip1) + self.client.switcht_api_l3_interface_address_delete(0, if2, vrf, i_ip2) + + self.client.switcht_api_interface_delete(0, if1) + self.client.switcht_api_interface_delete(0, if2) + + self.client.switcht_api_router_mac_delete(0, rmac, '00:77:66:55:44:33') + self.client.switcht_api_router_mac_group_delete(0, rmac) + self.client.switcht_api_vrf_delete(0, vrf) diff --git a/tests/ptf-tests/common/pd_utils.py b/tests/ptf-tests/common/pd_utils.py index aa77333..a4ee913 100644 --- a/tests/ptf-tests/common/pd_utils.py +++ b/tests/ptf-tests/common/pd_utils.py @@ -10,6 +10,7 @@ default_entries = {} stats_enabled = 1 nat_enabled = 1 +egress_acl_enabled = 1 def port_to_pipe(port): return port >> 7 @@ -86,7 +87,7 @@ def populate_default_fabric_entries(client, sess_hdl, dev_tgt, ipv6_enabled=0, if acl_enabled: client.ip_acl_set_default_action_nop(sess_hdl, dev_tgt) client.ipv4_racl_set_default_action_nop(sess_hdl, dev_tgt) - client.egress_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_system_acl_set_default_action_nop(sess_hdl, dev_tgt) client.validate_packet_set_default_action_nop(sess_hdl, dev_tgt) if tunnel_enabled: client.outer_rmac_set_default_action_on_miss(sess_hdl, dev_tgt) @@ -136,6 +137,16 @@ def populate_default_fabric_entries(client, sess_hdl, dev_tgt, ipv6_enabled=0, client.nat_src_set_default_action_on_miss(sess_hdl, dev_tgt) client.nat_flow_set_default_action_nop(sess_hdl, dev_tgt) + if egress_acl_enabled: + client.egress_mac_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_ip_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_ipv6_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.ingress_l4_src_port_set_default_action_nop(sess_hdl, dev_tgt) + client.ingress_l4_dst_port_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_l4_src_port_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_l4_dst_port_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_l4port_fields_set_default_action_nop(sess_hdl, dev_tgt) + def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, acl_enabled, tunnel_enabled, multicast_enabled, int_enabled): index = 0 @@ -197,7 +208,10 @@ 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, action_qos_group=0) + action_spec = dc_egress_port_type_normal_action_spec_t( + action_ifindex=0, + action_qos_group=0, + action_if_label=0) client.egress_port_mapping_set_default_action_egress_port_type_normal( sess_hdl, dev_tgt, action_spec) client.mtu_set_default_action_mtu_miss( @@ -235,7 +249,7 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, sess_hdl, dev_tgt) client.ipv4_racl_set_default_action_nop( sess_hdl, dev_tgt) - client.egress_acl_set_default_action_nop( + client.egress_system_acl_set_default_action_nop( sess_hdl, dev_tgt) client.acl_stats_set_default_action_acl_stats_update( sess_hdl, dev_tgt) @@ -322,6 +336,16 @@ def populate_default_entries(client, sess_hdl, dev_tgt, ipv6_enabled, client.nat_src_set_default_action_on_miss(sess_hdl, dev_tgt) client.nat_flow_set_default_action_nop(sess_hdl, dev_tgt) + if egress_acl_enabled: + client.egress_mac_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_ip_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_ipv6_acl_set_default_action_nop(sess_hdl, dev_tgt) + client.ingress_l4_src_port_set_default_action_nop(sess_hdl, dev_tgt) + client.ingress_l4_dst_port_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_l4_src_port_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_l4_dst_port_set_default_action_nop(sess_hdl, dev_tgt) + client.egress_l4port_fields_set_default_action_nop(sess_hdl, dev_tgt) + def delete_default_entries(client, sess_hdl, dev_id): return @@ -654,7 +678,8 @@ def program_ports(client, sess_hdl, dev_tgt, port_count): standard_metadata_egress_port=count) action_spec = dc_egress_port_type_normal_action_spec_t( action_ifindex=count, - action_qos_group=0) + action_qos_group=0, + action_if_label=0) egress_hdl = client.egress_port_mapping_table_add_with_egress_port_type_normal( sess_hdl, dev_tgt, @@ -705,7 +730,8 @@ def program_emulation_ports(client, sess_hdl, dev_tgt, port_count): eg_intr_md_egress_port=count) action_spec = dc_egress_port_type_normal_action_spec_t( action_ifindex=count, - action_qos_group=0) + action_qos_group=0, + action_if_label=0) egress_hdl = client.egress_port_mapping_table_add_with_egress_port_type_normal( sess_hdl, dev_tgt, @@ -834,7 +860,7 @@ def program_vlan(client, sess_hdl, dev_tgt, vrf, inner_rmac_group, def program_egress_bd_map(client, sess_hdl, dev_tgt, smac_index, vlan): match_spec = dc_egress_bd_map_match_spec_t(egress_metadata_bd=vlan) action_spec = dc_set_egress_bd_properties_action_spec_t( - action_smac_idx=smac_index, action_nat_mode=0) + action_smac_idx=smac_index, action_nat_mode=0, action_bd_label=0) client.egress_bd_map_table_add_with_set_egress_bd_properties( sess_hdl, dev_tgt, match_spec, action_spec) @@ -1415,7 +1441,8 @@ def program_egress_bd_properties(client, sess_hdl, dev_tgt, bd, rewrite_index): egress_metadata_bd=bd) action_spec = dc_set_egress_bd_properties_action_spec_t( action_smac_idx=rewrite_index, - action_nat_mode=0) + action_nat_mode=0, + action_bd_label=0) hdl = client.egress_bd_map_table_add_with_set_egress_bd_properties( sess_hdl, dev_tgt, match_spec, action_spec) return hdl diff --git a/tests/ptf-tests/common/sai_utils.py b/tests/ptf-tests/common/sai_utils.py index de1953f..9fbcbcc 100644 --- a/tests/ptf-tests/common/sai_utils.py +++ b/tests/ptf-tests/common/sai_utils.py @@ -304,6 +304,7 @@ def sai_thrift_create_hostif(client, rif_or_port_id, intf_name): return hif_id def sai_thrift_create_acl_table(client, + acl_stage = SAI_ACL_STAGE_INGRESS, addr_family = False, ip_src = False, ip_dst = False, @@ -313,6 +314,12 @@ def sai_thrift_create_acl_table(client, in_port = False, out_port = False): acl_attr_list = [] + + attribute_value = sai_thrift_attribute_value_t(s32=acl_stage) + attribute = sai_thrift_attribute_t(id=SAI_ACL_TABLE_ATTR_STAGE, + value=attribute_value) + acl_attr_list.append(attribute) + if ip_src: attribute_value = sai_thrift_attribute_value_t(booldata=1) attribute = sai_thrift_attribute_t(id=SAI_ACL_TABLE_ATTR_FIELD_SRC_IP, @@ -364,6 +371,7 @@ def sai_thrift_create_acl_entry(client, acl_table_id, out_ports = None, in_port = None, out_port = None, + range_list = None, packet_action = None, ingress_mirror_id = None, egress_mirror_id = None, @@ -426,6 +434,13 @@ def sai_thrift_create_acl_entry(client, acl_table_id, value=attribute_value) acl_attr_list.append(attribute) + if range_list != None: + acl_range_list = sai_thrift_object_list_t(count=len(range_list), object_id_list=range_list) + attribute_value = sai_thrift_attribute_value_t(aclfield=sai_thrift_acl_field_data_t(data = sai_thrift_acl_data_t(objlist=acl_range_list))) + attribute = sai_thrift_attribute_t(id=SAI_ACL_ENTRY_ATTR_FIELD_RANGE, + value=attribute_value) + acl_attr_list.append(attribute) + #Packet action for action in action_list: if action == SAI_ACL_ENTRY_ATTR_PACKET_ACTION: @@ -501,6 +516,24 @@ def sai_thrift_create_acl_counter(client, acl_table_id, packet_enable = True, by acl_counter_id = client.sai_thrift_create_acl_counter(attr_list) return acl_counter_id +def sai_thrift_create_acl_range(client, range_type, range_value): + attr_list = [] + + attribute1_value = sai_thrift_attribute_value_t(s32=range_type) + attribute1 = sai_thrift_attribute_t( + id=SAI_ACL_RANGE_ATTR_TYPE, + value=attribute1_value) + attr_list.append(attribute1) + + attribute2_value = sai_thrift_attribute_value_t(u32range=range_value) + attribute2 = sai_thrift_attribute_t( + id=SAI_ACL_RANGE_ATTR_LIMIT, + value=attribute2_value) + attr_list.append(attribute2) + + acl_range_id = client.sai_thrift_create_acl_range(attr_list) + return acl_range_id + def sai_thrift_create_mirror_session(client, mirror_type, port, vlan, vlan_priority, vlan_tpid, src_mac, dst_mac, diff --git a/tests/ptf-tests/common/utils.py b/tests/ptf-tests/common/utils.py index cd6e912..233ee29 100644 --- a/tests/ptf-tests/common/utils.py +++ b/tests/ptf-tests/common/utils.py @@ -81,7 +81,15 @@ class FabricCpuHeader(Packet): XShortField("ingress_ifindex", 0), XShortField("ingress_bd", 0), - XShortField("reason_code", 0) + XShortField("reason_code", 0), + XShortField("mcast_grp", 0) + ] + +class FabricCpuSflowHeader(Packet): + name = "Fabric Cpu Sflow Header" + fields_desc = [ + XShortField("sflow_sid", 0), + XShortField("sflow_egress_port", 0), ] class FabricCpuSflowHeader(Packet): @@ -133,6 +141,7 @@ def simple_cpu_packet(header_version = 0, dst_port_or_group = 0, ingress_ifindex = 1, ingress_bd = 0, + mcast_grp = 0, egress_queue = 0, tx_bypass = False, ingress_port = 1, @@ -160,7 +169,8 @@ def simple_cpu_packet(header_version = 0, ingress_port = ingress_port, ingress_ifindex = ingress_ifindex, ingress_bd = ingress_bd, - reason_code = reason_code) + reason_code = reason_code, + mcast_grp = mcast_grp) fabric_payload_header = FabricPayloadHeader(ether_type = eth_type) @@ -295,12 +305,14 @@ def crc16_regular(buff, crc = 0, poly = 0xa001): i += 1 return crc -def entropy_hash(pkt, layer='ipv4'): - buff = pkt[Ether].src.translate(None, ':') +def entropy_hash(pkt, layer='ipv4', ifindex=0): + buff='' + if layer == 'ether': + buff += str(ifindex).zfill(4) + buff += pkt[Ether].src.translate(None, ':') buff += pkt[Ether].dst.translate(None, ':') if layer == 'ether': - #buff += str(hex(pkt[Ether].type)[2:]).zfill(4) - buff += ''.zfill(26) + buff += str(hex(pkt[Ether].type)[2:]).zfill(4) elif layer == 'ipv4': buff += socket.inet_aton(pkt[IP].src).encode('hex') buff += socket.inet_aton(pkt[IP].dst).encode('hex') diff --git a/tests/ptf-tests/sai-tests/switch.py b/tests/ptf-tests/sai-tests/switch.py index f3c0790..f7aeffc 100644 --- a/tests/ptf-tests/sai-tests/switch.py +++ b/tests/ptf-tests/sai-tests/switch.py @@ -1475,11 +1475,6 @@ def runTest(self): ip_src='192.168.0.1', ip_id=105, ip_ttl=63) -# try: -# send_packet(self, 2, str(pkt)) -# verify_packets(self, exp_pkt, [1]) -# -# finally: if True: # setup ACL to block based on Source IP @@ -1534,6 +1529,198 @@ def runTest(self): self.client.sai_thrift_remove_virtual_router(vr_id) +class IPIngressAclRangeTcamTest(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])" + switch_init(self.client) + port1 = port_list[1] + port2 = port_list[2] + v4_enabled = 1 + v6_enabled = 1 + mac = '' + + vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) + + rif_id1 = sai_thrift_create_router_interface(self.client, vr_id, 1, port1, 0, v4_enabled, v6_enabled, mac) + 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_IPV4 + ip_addr1 = '10.10.10.1' + ip_mask1 = '255.255.255.255' + dmac1 = '00:11:22:33:44:55' + nhop1 = sai_thrift_create_nhop(self.client, addr_family, ip_addr1, rif_id1) + sai_thrift_create_route(self.client, vr_id, addr_family, ip_addr1, ip_mask1, nhop1) + sai_thrift_create_neighbor(self.client, addr_family, rif_id1, ip_addr1, dmac1) + + # send the test packet(s) + 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, + ip_ttl=63) + if True: + + u32range = sai_thrift_range_t(min=1000, max=2000) + acl_range_id = sai_thrift_create_acl_range(self.client, SAI_ACL_RANGE_L4_SRC_PORT_RANGE, u32range) + range_list = [acl_range_id] + + # setup ACL to block based on Source IP + action_list = [SAI_ACL_ENTRY_ATTR_PACKET_ACTION] + packet_action = SAI_PACKET_ACTION_DROP + in_ports = [port1, port2] + ip_src = "192.168.0.1" + ip_src_mask = "255.255.255.0" + + acl_table_id = sai_thrift_create_acl_table( + client = self.client, + ip_src = True, + in_ports = True) + + acl_entry_id = sai_thrift_create_acl_entry( + client = self.client, + acl_table_id = acl_table_id, + action_list = action_list, + range_list = range_list, + ip_src = ip_src, + ip_src_mask = ip_src_mask, + in_ports = in_ports) + + # send the same packet + failed = 0 + send_packet(self, 2, str(pkt)) + + # ensure packet is dropped + # check for absence of packet here! + try: + verify_packets(self, exp_pkt, [1]) + print 'FAILED - did not expect packet' + failed = 1 + except: + print 'Success' + + finally: + if failed == 1: + self.assertFalse() + + + # delete ACL + self.client.sai_thrift_delete_acl_entry(acl_entry_id) + self.client.sai_thrift_delete_acl_table(acl_table_id) + self.client.sai_thrift_delete_acl_range(acl_range_id) + + # cleanup + sai_thrift_remove_neighbor(self.client, addr_family, rif_id1, ip_addr1, dmac1) + sai_thrift_remove_route(self.client, vr_id, addr_family, ip_addr1, ip_mask1, nhop1) + self.client.sai_thrift_remove_next_hop(nhop1) + + self.client.sai_thrift_remove_router_interface(rif_id1) + self.client.sai_thrift_remove_router_interface(rif_id2) + + self.client.sai_thrift_remove_virtual_router(vr_id) + +class IPEgressAclTest(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])" + switch_init(self.client) + port1 = port_list[1] + port2 = port_list[2] + v4_enabled = 1 + v6_enabled = 1 + mac = '' + + vr_id = sai_thrift_create_virtual_router(self.client, v4_enabled, v6_enabled) + + rif_id1 = sai_thrift_create_router_interface(self.client, vr_id, 1, port1, 0, v4_enabled, v6_enabled, mac) + 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_IPV4 + ip_addr1 = '10.10.10.1' + ip_mask1 = '255.255.255.255' + dmac1 = '00:11:22:33:44:55' + nhop1 = sai_thrift_create_nhop(self.client, addr_family, ip_addr1, rif_id1) + sai_thrift_create_route(self.client, vr_id, addr_family, ip_addr1, ip_mask1, nhop1) + sai_thrift_create_neighbor(self.client, addr_family, rif_id1, ip_addr1, dmac1) + + # send the test packet(s) + 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, + ip_ttl=63) + if True: + + # setup ACL to block based on Source IP + action_list = [SAI_ACL_ENTRY_ATTR_PACKET_ACTION] + packet_action = SAI_PACKET_ACTION_DROP + in_ports = [port1, port2] + ip_src = "192.168.0.1" + ip_src_mask = "255.255.255.0" + + acl_table_id = sai_thrift_create_acl_table( + client = self.client, + acl_stage = SAI_ACL_STAGE_EGRESS, + ip_src = True, + in_ports = True) + + acl_entry_id = sai_thrift_create_acl_entry( + client = self.client, + acl_table_id = acl_table_id, + action_list = action_list, + ip_src = ip_src, + ip_src_mask = ip_src_mask, + in_ports = in_ports) + + # send the same packet + failed = 0 + send_packet(self, 2, str(pkt)) + + # ensure packet is dropped + # check for absence of packet here! + try: + verify_packets(self, exp_pkt, [1]) + print 'FAILED - did not expect packet' + failed = 1 + except: + print 'Success' + + finally: + if failed == 1: + self.assertFalse() + + + # delete ACL + self.client.sai_thrift_delete_acl_entry(acl_entry_id) + self.client.sai_thrift_delete_acl_table(acl_table_id) + + # cleanup + sai_thrift_remove_neighbor(self.client, addr_family, rif_id1, ip_addr1, dmac1) + sai_thrift_remove_route(self.client, vr_id, addr_family, ip_addr1, ip_mask1, nhop1) + self.client.sai_thrift_remove_next_hop(nhop1) + + self.client.sai_thrift_remove_router_interface(rif_id1) + self.client.sai_thrift_remove_router_interface(rif_id2) + + self.client.sai_thrift_remove_virtual_router(vr_id) + class L3VIIPv4HostTest(sai_base_test.ThriftInterfaceDataPlane): def runTest(self): print @@ -1925,6 +2112,7 @@ def runTest(self): acl_table_id = sai_thrift_create_acl_table( client = self.client, + acl_stage = SAI_ACL_STAGE_EGRESS, out_port = True) acl_entry_id = sai_thrift_create_acl_entry( @@ -2013,6 +2201,7 @@ def runTest(self): acl_table_id = sai_thrift_create_acl_table( client = self.client, + acl_stage=SAI_ACL_STAGE_EGRESS, out_port = True) acl_entry_id = sai_thrift_create_acl_entry( @@ -2293,7 +2482,6 @@ def runTest(self): class NexthopGetSetTest(sai_base_test.ThriftInterfaceDataPlane): def runTest(self): - return switch_init(self.client) port1 = port_list[1] port2 = port_list[2] diff --git a/tests/run_of_tests.py b/tests/run_of_tests.py new file mode 100755 index 0000000..f1968a8 --- /dev/null +++ b/tests/run_of_tests.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +# Copyright 2013-present Barefoot Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os +from subprocess import Popen +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("--oft-path", required=True, + help="Location of oftest framework oft") +args, unknown_args = parser.parse_known_args() + +root_dir = os.path.dirname(os.path.realpath(__file__)) +oft_path = args.oft_path +test_dir = os.path.join(root_dir, "of-tests") + +if __name__ == "__main__": + new_args = unknown_args + new_args += ["-S 127.0.0.1", "-V1.3"] + new_args += ["--test-dir", test_dir] + new_args += ["--interface", "0@veth1"] + new_args += ["--interface", "2@veth5"] + new_args += ["--interface", "3@veth7"] + new_args += ["--interface", "4@veth9"] + new_args += ["--interface", "5@veth11"] + new_args += ["--interface", "6@veth13"] + new_args += ["--interface", "7@veth15"] + + child = Popen([oft_path] + new_args) + child.wait() + sys.exit(child.returncode) diff --git a/tests/run_tests.py.in b/tests/run_tests.py.in new file mode 100755 index 0000000..b871088 --- /dev/null +++ b/tests/run_tests.py.in @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +# Copyright 2013-present Barefoot Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os +from subprocess import Popen +import argparse + +root_dir = "@abs_srcdir@" +default_test_dir = os.path.join(root_dir, "ptf-tests", "pd-tests") + +parser = argparse.ArgumentParser() +parser.add_argument("--test-dir", required=False, + default=default_test_dir, + help="directory containing the tests (default %s)" % default_test_dir) +parser.add_argument("--pd-thrift", action="append", + help="a directory containing PD Thrift Python bindings, can be used multiple times") +args, unknown_args = parser.parse_known_args() + +testutils_dir = os.path.join(root_dir, '..', 'testutils') + +max_ports = 9 +cpu_port = 64 +cpu_veth = 251 + +if __name__ == "__main__": + if "@PTF@" == "": + print "configure could not find an installed version of ptf" + sys.exit(1) + new_args = [] + if args.pd_thrift: + for p in args.pd_thrift: + new_args += ["--pypath", p] + switchapi_py = os.path.join("@abs_top_builddir@", "switchapi") + if os.path.exists(switchapi_py): + new_args += ["--pypath", switchapi_py] + switchsai_py = os.path.join("@abs_top_builddir@", "switchsai") + if os.path.exists(switchsai_py): + new_args += ["--pypath", switchsai_py] + new_args += ["--pypath", testutils_dir] + new_args += ["--test-dir", args.test_dir] + for port in xrange(max_ports): + new_args += ["--interface", "%d@veth%d" % (port, 2 * port + 1)] + new_args += ["--interface", "%s@veth%s" % (cpu_port, cpu_veth)] + new_args += unknown_args + child = Popen(["@PTF@"] + new_args) + child.wait() + sys.exit(child.returncode) diff --git a/testutils/erspan3.py b/testutils/erspan3.py new file mode 100644 index 0000000..120b1c0 --- /dev/null +++ b/testutils/erspan3.py @@ -0,0 +1,38 @@ +import ptf.dataplane as dataplane + +def match_erspan3_pkt(exp_pkt, pkt, ignore_tstamp=True): + """ + Compare ERSPAN_III packets, ignore the timestamp value. Just make sure + it is non-zero + """ + if ignore_tstamp: + erspan3 = pkt.getlayer(ERSPAN_III) + if erspan3 == None: + #self.logger.error("No ERSPAN pkt received") + return False + + #if erspan3.timestamp == 0: + # #self.logger.error("Invalid ERSPAN timestamp") + # return False + + #fix the exp_pkt timestamp and compare + exp_erspan3 = exp_pkt.getlayer(ERSPAN_III) + if erspan3 == None: + #self.logger.error("Test user error - exp_pkt is not ERSPAN_III packet") + return False + + exp_erspan3.timestamp = 0 + erspan3.timestamp = 0 + + return dataplane.match_exp_pkt(exp_pkt, pkt) + +def verify_erspan3_packet(test, pkt, ofport): + """ + Check that an expected packet is received + """ + logging.debug("Checking for pkt on port %r", ofport) + (_, rcv_port, rcv_pkt, pkt_time) = test.dataplane.poll(port_number=ofport, timeout=2, exp_pkt=None) + test.assertTrue(rcv_pkt != None, "Did not receive pkt on %r" % ofport) + # convert rcv_pkt string back to layered pkt + nrcv = pkt.__class__(rcv_pkt) + test.assertTrue(match_erspan3_pkt(pkt, nrcv), "Received packet did not match expected packet") diff --git a/testutils/xnt.py b/testutils/xnt.py new file mode 100644 index 0000000..d5d5247 --- /dev/null +++ b/testutils/xnt.py @@ -0,0 +1,75 @@ +import sys + +from ptf.testutils import * + +try: + import scapy.config + import scapy.route + import scapy.layers.l2 + import scapy.layers.inet + import scapy.main +except ImportError: + sys.exit("Need to install scapy for packet parsing") + +try: + scapy.main.load_contrib("vxlan") + scapy.main.load_contrib("xnt") + VXLAN_GPE = scapy.contrib.vxlan.VXLAN_GPE + VXLAN_GPE_INT = scapy.contrib.xnt.VXLAN_GPE_INT + INT_META_HDR = scapy.contrib.xnt.INT_META_HDR + INT_hop_info = scapy.contrib.xnt.INT_hop_info +except: + pass + +def vxlan_gpe_int_src_packet(eth_dst='00:77:66:55:44:33', + eth_src='00:22:22:22:22:22', + ip_id=0x0, + ip_dst='10.10.10.1', + ip_src='192.168.0.1', + ip_ttl=64, + udp_sport=101, + with_udp_chksum=False, + vxlan_vni=0x1234, + int_inst_mask=0xAC00, + int_inst_cnt=4, + max_hop_cnt=32, + inner_frame=None): + + udp_pkt = simple_udp_packet( + pktlen=0, + eth_dst=eth_dst, + eth_src=eth_src, + ip_dst=ip_dst, + ip_src=ip_src, + ip_ttl=ip_ttl, + udp_sport=udp_sport, + udp_dport=4790, + with_udp_chksum=with_udp_chksum, + ) + + vxlan_pkt = udp_pkt / VXLAN_GPE(vni = vxlan_vni) + + vxlan_pkt['VXLAN_GPE'].next_proto = 0x5 + int_header = VXLAN_GPE_INT() + int_header.length = 3 # this header(4) + INT meta header (8) + int_meta_header = INT_META_HDR(ins_cnt=int_inst_cnt, + max_hop_cnt=max_hop_cnt, inst_mask=int_inst_mask) + return vxlan_pkt / int_header / int_meta_header / inner_frame + +def vxlan_gpe_int_packet_add_hop_info(Packet, + bos=False, + val=0x7FFFFFFF, incr_cnt=0): + # Find the start of INT data (following INT_META_HDR) + meta_hdr = Packet[INT_META_HDR] + if meta_hdr == None: + return Packet + + # copy the packet and truncate everything after META_HDR + new_pkt = Packet.copy() + new_pkt[INT_META_HDR].remove_payload() + new_pkt = new_pkt/INT_hop_info(bos=bos, val=val)/Packet[INT_META_HDR].payload + # update all the headers - IP UDP header lens are updated automatically + new_pkt[INT_META_HDR].total_hop_cnt += incr_cnt + new_pkt[VXLAN_GPE_INT].length += 1 + + return new_pkt diff --git a/tools/veth_disable_ipv6.sh b/tools/veth_disable_ipv6.sh new file mode 100755 index 0000000..88c2d41 --- /dev/null +++ b/tools/veth_disable_ipv6.sh @@ -0,0 +1,21 @@ +#!/bin/bash +noOfVeths=18 +if [ $# -eq 1 ]; then + noOfVeths=$1 +fi +echo "No of Veths is $noOfVeths" +idx=0 +let "vethpairs=$noOfVeths/2" +while [ $idx -lt $vethpairs ] +do + intf0="veth$(($idx*2))" + intf1="veth$(($idx*2+1))" + sysctl net.ipv6.conf.$intf0.disable_ipv6=1 + sysctl net.ipv6.conf.$intf1.disable_ipv6=1 + idx=$((idx + 1)) +done +idx=125 +intf0="veth$(($idx*2))" +intf1="veth$(($idx*2+1))" +sysctl net.ipv6.conf.$intf0.disable_ipv6=1 +sysctl net.ipv6.conf.$intf1.disable_ipv6=1 diff --git a/tools/veth_setup.sh b/tools/veth_setup.sh new file mode 100755 index 0000000..ded6d9f --- /dev/null +++ b/tools/veth_setup.sh @@ -0,0 +1,38 @@ +#!/bin/bash +noOfVeths=18 +if [ $# -eq 1 ]; then + noOfVeths=$1 +fi +echo "No of Veths is $noOfVeths" +idx=0 +let "vethpairs=$noOfVeths/2" +while [ $idx -lt $vethpairs ] +do +#1 2 3 4 5 6 7 125 + intf0="veth$(($idx*2))" + intf1="veth$(($idx*2+1))" + idx=$((idx + 1)) + if ! ip link show $intf0 &> /dev/null; then + ip link add name $intf0 type veth peer name $intf1 + ip link set dev $intf0 up + ip link set dev $intf1 up + TOE_OPTIONS="rx tx sg tso ufo gso gro lro rxvlan txvlan rxhash" + for TOE_OPTION in $TOE_OPTIONS; do + /sbin/ethtool --offload $intf0 "$TOE_OPTION" off + /sbin/ethtool --offload $intf1 "$TOE_OPTION" off + done + fi +done +idx=125 +intf0="veth$(($idx*2))" +intf1="veth$(($idx*2+1))" +if ! ip link show $intf0 &> /dev/null; then + ip link add name $intf0 type veth peer name $intf1 + ip link set dev $intf0 up + ip link set dev $intf1 up + TOE_OPTIONS="rx tx sg tso ufo gso gro lro rxvlan txvlan rxhash" + for TOE_OPTION in $TOE_OPTIONS; do + /sbin/ethtool --offload $intf0 "$TOE_OPTION" off + /sbin/ethtool --offload $intf1 "$TOE_OPTION" off + done +fi diff --git a/tools/veth_teardown.sh b/tools/veth_teardown.sh new file mode 100755 index 0000000..b96591e --- /dev/null +++ b/tools/veth_teardown.sh @@ -0,0 +1,21 @@ +#!/bin/bash +noOfVeths=18 +if [ $# -eq 1 ]; then + noOfVeths=$1 +fi +echo "No of Veths is $noOfVeths" +idx=0 +while [ $idx -lt $noOfVeths ] +do +#for idx in 0 1 2 3 4 5 6 7 125; do + intf="veth$(($idx*2))" + if ip link show $intf &> /dev/null; then + ip link delete $intf type veth + fi + idx=$((idx + 1)) +done +idx=125 +intf="veth$(($idx*2))" +if ip link show $intf &> /dev/null; then + ip link delete $intf type veth +fi