From 19b30c1448d52d2a64a6cb1a5d702a23d50d9ed9 Mon Sep 17 00:00:00 2001 From: chikkaiah-work <155310572+chikkaiah-work@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:05:30 -0400 Subject: [PATCH] SAI proposal for icmp echo offload (#2020) --- doc/SAI-Proposal-FRR.md | 4 +- doc/SAI-Proposal-ICMP-ECHO.md | 480 ++++++++++++++++++++++++++++ doc/figures/sai_icmp_echo_state.png | Bin 0 -> 38462 bytes inc/sai.h | 2 + inc/saiicmpecho.h | 388 ++++++++++++++++++++++ inc/saiswitch.h | 27 ++ inc/saitypes.h | 1 + meta/saisanitycheck.c | 3 +- 8 files changed, 902 insertions(+), 3 deletions(-) create mode 100644 doc/SAI-Proposal-ICMP-ECHO.md create mode 100644 doc/figures/sai_icmp_echo_state.png create mode 100644 inc/saiicmpecho.h diff --git a/doc/SAI-Proposal-FRR.md b/doc/SAI-Proposal-FRR.md index 5b9563c41..411889aa6 100644 --- a/doc/SAI-Proposal-FRR.md +++ b/doc/SAI-Proposal-FRR.md @@ -89,7 +89,7 @@ Entity. The switchover from the primary next hop to backup is triggered once a failure of a particular object is spotted. This object can be a physical port, a tunnel -interface, BFD session etc. +interface, BFD session, ICMP ECHO session etc. It is preferred that the switchover is triggered by the switching entity without involving control plane in the process. This way the amount of time it takes to @@ -173,7 +173,7 @@ be of one of the types that the hardware is able to monitor. - SAI\_NEXT\_HOP\_GROUP\_MEMBER\_ATTR\_MONITORED\_OBJECT This attribute allows the switching entity to monitor a specified object -(BFD session, physical port, tunnel interface etc) and in case of its failure, +(BFD session, ICMP ECHO session, physical port, tunnel interface etc) and in case of its failure, trigger a switchover. If the referred object fails, then the switch marks the next hop as FAILED and does not use it for forwarding. diff --git a/doc/SAI-Proposal-ICMP-ECHO.md b/doc/SAI-Proposal-ICMP-ECHO.md new file mode 100644 index 000000000..311267542 --- /dev/null +++ b/doc/SAI-Proposal-ICMP-ECHO.md @@ -0,0 +1,480 @@ +# ICMP ECHO offload +------------------------------------------------------------------------------- + Title | ICMP ECHO offload +-------------|----------------------------------------------------------------- + Authors | Chikkegowda Chikkaiah, Cisco + Status | In review + Type | Standards track + Created | 2024-01-1 - Initial Draft + SAI-Version | 1.12 +------------------------------------------------------------------------------- + + +## 1.0 Introduction + +The traditional use of ICMP-based link prober is to identify link failures. This prober sends ICMP echo packets, receives any ICMP echo replies, and reports the detection results. + +When control plane application carries out the link probe (software link failure detection), the system operates at a slow, periodic exchange of probe requests and replies since it uses the kernel network stack to send and receive control packets. This may prolong link failure detection. To decrease this detection interval, the application could utilize the HW/ASIC to send and receive link probe packets at a quicker rate. + +The objective of this document is to propose a SAI specification to simplify the ICMP-based probe as a basic service. The service primitives offered by ICMP echo include creating, destroying, and modifying a session, considering the destination address and other parameters. In response, ICMP Echo sends a signal to its clients when the ICMP Echo session starts or stops. + +This specification suggests: +- The idea of an ICMP echo object or session that can be transferred to HW/ASIC or other modules for faster link detection. +- The introduction of SAI APIs to outline ICMP echo session properties. +- The introduction of a switch-level notification API to monitor changes in ICMP echo session states. + + +## 1.1.0 Functional requirements of ICMP echo session +- Transmit ICMP echo requests (probes) at regular, configurable intervals. +- Identify and report changes in probe state to the control plane application. +- Enable applications to set customized transmit and receive intervals. +- Allow configuration of IP encapsulation parameters. +- Establish a unique identification for each probing session. +- Determine whether an offloaded session should process ICMP probing packets. +- Offer statistics on ICMP echo probe and reply activities. + +## 2.0 Protocol overview and ICMP echo session +ICMP echo is simple network link connectivity test protocol, similar to that most of the L3 routing protocols. ICMP Echo session runs between pair of devices exchanging ICMP echo request and reply packets. This protocol is used in SONiC sofware link prober and described in [linkmgrd](https://github.com/sonic-net/SONiC/blob/master/doc/dualtor/active_active_hld.md#33-linkmgrd) + +### 2.1.0 ICMP echo request and reply packet ### + +```C + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type | Code | Checksum | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Identifier | Sequence Number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Data ... + +-+-+-+-+- + +- Type + 8 echo request message (outgoing) + 0 echo response message (incoming) + +``` + +### 2.2.0 ICMP echo payload packet ### + +Besides the ICMP echo request and reply packets, additional information about the ICMP echo session is essential and is transmitted within the payload. The payload format used by the SONiC link prober is outlined below: + +```C + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Cookie | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | GUID(MSB) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | GUID(LSB) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+ Sequence Number +-+-+-+-+-+-+-+-+-+-+-+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |TLV Type | TLV Length (0) | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+: + +- Cookie + 4B, processing of this filed is imepplemtation specific. +- Version + 4B, set to 0 +- GUID MSB + 4B, The probing session unique identifier +- GUID LSB + 4B, The probing session unique identifier +- Sequence Number + 8B, processing of this filed is implementation specific. +- TLV Type + 1B, SENTINAL: 0xFF +- TLV Length + 2B, set to 0 + +``` +***GUID:*** Global unique identifier for the ICMP echo session to correlate probe and reply packets with a session, especially when the session is offloaded to hardware, a unique identifier is required. + +***Session Cookie:*** The offloading engine interprets this value to decide whether the packet should undergo processing by the ICMP echo session or not. Packets not matching the cookie are punted to NOS. This can also be used to differentiate regular icmp response and icmp link monitoring response. + +### 2.3.0 ICMP Echo Session State ### + +If a targeted device does not respond to an ICMP echo request within the detection time period, the link is marked "DOWN", If an ICMP echo response is subsequently received, the link is marked "UP". + + +![ICMP probe state machine](figures/sai_icmp_echo_state.png "Figure 1: icmp probe state machine ")__Figure 1: ICMP echo state machine.__ + + +## 3.0 Specification ## + +### sai.h ### +New type SAI_API_ICMP_ECHO is added into sai_api_t + +### saiswitch.h ### + +New attribute SAI_SWITCH_ATTR_ICMP_ECHO_SESSION_STATE_CHANGE_NOTIFY is added into sai_switch_attr_t + + +### New Header saiicmpecho.h ### + +#### sai_icmp_echo_session_state_t #### +This enumeration is used to represent the possible states of an ICMP echo session + +SAI_ICMP_ECHO_SESSION_DOWN: Signifies that the ICMP echo session has not received an ICMP echo reply packet within the designated receive interval period. + +SAI_ICMP_ECHO_SESSION_UP: Denotes that the ICMP echo session consistently receives ICMP echo reply packets within the specified receive interval period. + +#### sai_icmp_echo_session_state_notification_t ### +This defines state change notification fields + +icmp_echo_session_id: Identifies the ICMP echo session related to the state change notification. + +session_state: Reflects the operational state of the ICMP echo session, which can be either SAI_ICMP_ECHO_SESSION_UP or SAI_ICMP_ECHO_SESSION_DOWN. + +#### sai_icmp_echo_session_attr_t #### +This defines icmp echo session attributes. These attributes collectively define the configuration and behavior of ICMP echo sessions in the SAI framework. + +- SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID: A boolean value where true indicates that the device routes the generated packet to outgoing port and false indicates that the packet is injected as is to the specified Port. + +- SAI_ICMP_ECHO_SESSION_ATTR_VIRTUAL_ROUTER: The virtual router identifier. Only revelant when SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID is true. + +- SAI_ICMP_ECHO_SESSION_ATTR_PORT: Represents the destination port for ICMP echo sessions, with conditions based on hardware lookup validity. The generated packets are sent out on this port. + +- SAI_ICMP_ECHO_SESSION_ATTR_RX_PORT: Represents the source port for ICMP echo sessions where the imcoming packets are expected to be received. + +- SAI_ICMP_ECHO_SESSION_ATTR_GUID: Global unique identifier for the ICMP echo session, mandatory during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_COOKIE: Cookie value associated with the ICMP echo session, mandatory and settable during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_TOS: Sets the IP header Type of Service (TOS) value, with a default of 0. + +- SAI_ICMP_ECHO_SESSION_ATTR_TTL: Configures the IP header Time to Live (TTL), with a default value of 255. + +- SAI_ICMP_ECHO_SESSION_ATTR_IPHDR_VERSION: Specifies the IP header version, mandatory during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_SRC_IP_ADDRESS: Defines the source IP address, mandatory and settable during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_DST_IP_ADDRESS: Specifies the destination IP address, mandatory and settable during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_SRC_MAC_ADDRESS: Sets the L2 source MAC address, mandatory and settable during creation, with conditions on hardware lookup validity. + +- SAI_ICMP_ECHO_SESSION_ATTR_DST_MAC_ADDRESS: Configures the L2 destination MAC address, mandatory and settable during creation, with conditions on hardware lookup validity. + +- SAI_ICMP_ECHO_SESSION_ATTR_TX_INTERVAL: Defines the transmit interval in microseconds for echo request packets, mandatory and settable during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_RX_INTERVAL: Specifies the receive interval in microseconds for echo reply, mandatory and settable during creation. + +- SAI_ICMP_ECHO_SESSION_ATTR_SET_NEXT_HOP_GROUP_SWITCHOVER: If enabled, automatically switch from the primary to the backup next hop on a session state change. This requires next hop group of type SAI_NEXT_HOP_GROUP_TYPE_PROTECTION to be configured with the primary-backup pair and icmp echo session object as the monitored object. + +- SAI_ICMP_ECHO_SESSION_ATTR_STATE: Indicates the operational state of the ICMP echo session, read-only. + + +#### sai_icmp_echo_session_stat_t #### + +This enum type represents the counter IDs used in the sai_get_icmp_echo_session_stats() call for ICMP ECHO sessions. it has two members: + +- SAI_ICMP_ECHO_SESSION_STAT_IN_PACKETS: Represents the counter for the number of ingress (incoming) packets in the ICMP ECHO session. + +- SAI_ICMP_ECHO_SESSION_STAT_OUT_PACKETS: Represents the counter for the number of egress (outgoing) packets in the ICMP ECHO session. + + +#### sai_create_icmp_echo_session_fn #### +This defines the interfaces to create icmp echo seesion + +- icmp_echo_session_id (Out): A pointer to the variable where the created ICMP ECHO session ID will be stored. +- switch_id (In): The ID of the switch on which the ICMP ECHO session is to be created. +- attr_count (In): The number of attributes provided in the attr_list. +- attr_list (In): An array of sai_attribute_t structures containing the attribute key-value pairs to configure the ICMP ECHO session. + +The function returns SAI_STATUS_SUCCESS if the operation is successful; otherwise, it returns a different error code indicating the nature of the failure. + +#### sai_remove_icmp_echo_session_fn #### +This defines the interfaces to delete icmp echo seesion. +The function takes an ICMP ECHO session ID as a parameter. The function returns SAI_STATUS_SUCCESS if the operation is successful; otherwise, it returns a different error code indicating the nature of the failure. + +#### sai_set_icmp_echo_session_attribute_fn #### +This defines the interfaces to update icmp echo seesion attributes. It requires the unique identifier to specify the ICMP ECHO session, and the attr parameter represents the attribute to be set along with its value. The function returns SAI_STATUS_SUCCESS if the operation is successful; otherwise, it returns an error code, indicating the nature of the failure. + +#### sai_get_icmp_echo_session_attribute_fn #### +It takes the unique identifier icmp_echo_session_id to specify the ICMP ECHO session for which attributes are to be retrieved. The attr_count parameter indicates the number of attributes in the attr_list, and the attr_list itself holds the values of the requested attributes. + +If the operation is successful, the function returns SAI_STATUS_SUCCESS. Otherwise, it returns a different error code, indicating the nature of the failure. + + +#### sai_get_icmp_echo_session_stats_fn #### +This defines the interface to query session stats. + It takes the unique identifier icmp_echo_session_id to specify the ICMP ECHO session for which statistics are to be retrieved. The number_of_counters parameter indicates the count of counters specified in the counter_ids array. The counter_ids array specifies the particular statistics counters to retrieve, and the resulting counter values are stored in the counters array. + +If the operation is successful, the function returns SAI_STATUS_SUCCESS. Otherwise, it returns a failure status code, indicating the nature of the error. + +#### sai_clear_icmp_echo_session_stats_fn #### +This defines the interface to clear session stats. +It takes the unique identifier icmp_echo_session_id to specify the ICMP ECHO session for which statistics counters are to be cleared. The number_of_counters parameter indicates the count of counters specified in the counter_ids array. The counter_ids array specifies the particular statistics counters to clear. + +If the operation is successful, the function returns SAI_STATUS_SUCCESS. Otherwise, it returns a failure status code, indicating the nature of the error. + + +#### sai_icmp_echo_session_state_change_notification_fn #### +This is a callback function that is invoked to notify about changes in the state of ICMP ECHO sessions. This callback function is passed as a parameter during the initialization of the switch through the sai_initialize_switch() function. + +The callback function takes two parameters: + +- count: An integer representing the number of ICMP ECHO session state change notifications in the array. +- data: An array of sai_icmp_echo_session_state_notification_t structures, each containing information about the state change of an ICMP ECHO session. + +#### sai_icmp_echo_api_t #### +This defines the ICMP_ECHO API table +```C +/**  + * @brief ICMP ECHO method table retrieved with sai_api_query()  + */  +typedef struct _sai_icmp_echo_api_t  +{  +    sai_create_icmp_echo_session_fn            create_icmp_echo_session;  +    sai_remove_icmp_echo_session_fn            remove_icmp_echo_session;  +    sai_set_icmp_echo_session_attribute_fn     set_icmp_echo_session_attribute;  +    sai_get_icmp_echo_session_attribute_fn     get_icmp_echo_session_attribute;  +    sai_get_icmp_echo_session_stats_fn         get_icmp_echo_session_stats;  +    sai_clear_icmp_echo_session_stats_fn       clear_icmp_echo_session_stats;  + +} sai_icmp_echo_api_t;  +``` + +### 4.0 Examples ### + +#### 4.0.1 Create session using egress interface: #### +In this case SAI expects the application to tell the attributes related to encapsulation and egress physical interface. +```C +sai_api_query(SAI_API_ICMP_ECHO, &icmp_api); // Get ICMP echo object API pointer + +sai_object_id_t icmp_session = 0; +sai_attribute_t icmp_attr[10] = {0}; + +icmp_attr[0].id = SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID; +icmp_attr[0].value.booldata = false; + +icmp_attr[1].id = SAI_ICMP_ECHO_SESSION_ATTR_PORT; +icmp_attr[1].value.oid = 0x01; + +icmp_attr[2].id = SAI_ICMP_ECHO_SESSION_ATTR_GUID; +icmp_attr[2].value.s64 = 0x01; + +icmp_attr[3].id = SAI_ICMP_ECHO_SESSION_ATTR_IPHDR_VERSION; +icmp_attr[3].value.u8 = ipv4; + +icmp_attr[4].id = SAI_ICMP_ECHO_SESSION_ATTR_MULTIPLIER; +icmp_attr[4].value.s32 = 5; + +icmp_attr[5].id = SAI_ICMP_ECHO_SESSION_ATTR_SRC_IP_ADDRESS; +icmp_attr[5].value.ipaddr.addr.ip4 = 0xa0101002; +icmp_attr[5].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + +icmp_attr[6].id = SAI_ICMP_ECHO_SESSION_ATTR_DST_IP_ADDRESS; +icmp_attr[6].value.ipaddr.addr.ip4 = 0xa0101011; +icmp_attr[6].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + +icmp_attr[7].id = SAI_ICMP_ECHO_SESSION_ATTR_SRC_MAC_ADDRESS; +sai_mac_t s_mac = {0x00, 0x02, 0x03, 0x04, 0x05}; +memcpy(icmp_attr[7].value.mac, s_mac, sizeof(sai_mac_t)); + +icmp_attr[8].id = SAI_ICMP_ECHO_SESSION_ATTR_DST_MAC_ADDRESS; +sai_mac_t d_mac = {0x00, 0x11, 0x12, 0x13, 0x14, 0x15}; +memcpy(icmp_attr[8].value.mac, d_mac, sizeof(sai_mac_t)); + +icmp_attr[9].id = SAI_ICMP_ECHO_SESSION_ATTR_TX_INTERVAL; +icmp_attr[9].value.s32 = 500; // in microseconds + +icmp_attr[10].id = SAI_ICMP_ECHO_SESSION_ATTR_RX_INTERVAL; +icmp_attr[10].value.s32 = 500; // in Microseconds + +icmp_attr[11].id = SAI_ICMP_ECHO_SESSION_ATTR_COOKIE; +icmp_attr[11].value.s32 = 0xAAEEFFBB; + +uint32_t attr_count = 11; // Corrected attribute count +sai_status_t status = icmp_api->create_icmp_echo_session(&icmp_session, switch_id, attr_count, icmp_attr); // Invoke create session API +if (status == SAI_STATUS_SUCCESS) { + // ICMP ECHO session creation was successful +} else { + // Handle the error condition +} +``` +The other case being running ICMP probe sessions on each lag member link instead of running probe session on the lag interface itself. + +#### 4.0.2 Create session using Endpoint ip address: #### + +A ICMP echo session between two endpoints can be created by simply specifying the icmp ip packet attributes. In this case, either SAI or NPU can resolve the encap and egress interface. + +In this case SAI expects virtual router id and SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID set to true +```C +sai_api_query(SAI_API_ICMP_ECHO, &icmp_api); // get ICMP echo object API pointer + +sai_object_id_t icmp_session = 0; +sai_attribute_t icmp_attr[10] = {0}; + +icmp_attr[0].id = SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID; +icmp_attr[0].value.booldata = true; + +icmp_attr[1].id = SAI_ICMP_ECHO_SESSION_ATTR_VIRTUAL_ROUTER; +icmp_attr[1].value.oid = 0x01; + +icmp_attr[2].id = SAI_ICMP_ECHO_SESSION_ATTR_GUID; +icmp_attr[2].value.s32 = 0x01; + +icmp_attr[3].id = SAI_ICMP_ECHO_SESSION_ATTR_IPHDR_VERSION; +icmp_attr[3].value.u8 = ipv4; + +icmp_attr[4].id = SAI_ICMP_ECHO_SESSION_ATTR_MULTIPLIER; +icmp_attr[4].value.s32 = 5; + +icmp_attr[5].id = SAI_ICMP_ECHO_SESSION_ATTR_SRC_IP_ADDRESS; +icmp_attr[5].value.ipaddr.addr.ip4 = 0xa0101002; +icmp_attr[5].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + +icmp_attr[6].id = SAI_ICMP_ECHO_SESSION_ATTR_DST_IP_ADDRESS; +icmp_attr[6].value.ipaddr.addr.ip4 = 0xa0101011; +icmp_attr[6].value.ipaddr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + +icmp_attr[7].id = SAI_ICMP_ECHO_SESSION_ATTR_TX_INTERVAL; +icmp_attr[7].value.s32 = 500; // in microseconds + +icmp_attr[8].id = SAI_ICMP_ECHO_SESSION_ATTR_RX_INTERVAL; +icmp_attr[8].value.s32 = 500; // in microseconds + +icmp_attr[9].id = SAI_ICMP_ECHO_SESSION_ATTR_COOKIE; +icmp_attr[9].value.u32 = 0xAAEEFFBB; +uint32_t attr_count = 10; // Corrected attribute count +sai_status_t status = icmp_api->create_icmp_echo_session(&icmp_session, switch_id, attr_count, icmp_attr); // Invoke create session API +if (status == SAI_STATUS_SUCCESS) { + // ICMP ECHO session creation was successful +} else { + // Handle the error condition +} +``` + +#### 4.0.3 ICMP echo session with protection group #### +```C +icmp_echo_session_id = 1; //create a session as explained section 4.0.1 or 4.0.2. + +// set SAI_ICMP_ECHO_SESSION_ATTR_SET_NEXT_HOP_GROUP_SWITCHOVER to true if not already. +sai_attribute_t icmp_attr; +icmp_attr.id = SAI_ICMP_ECHO_SESSION_ATTR_SET_NEXT_HOP_GROUP_SWITCHOVER; +icmp_attr.value.booldata = true; +sai_api_query(SAI_API_ICMP_ECHO, &icmp_api); // get ICMP echo object API pointer +icmp_api->set_icmp_echo_session_attribute(icmp_echo_session_id, icmp_attr); + +// Create protection group by programming icmp echo session id as monitored object +nh_1_id = 1; +nh_2_id = 2; +switch_id = 0; + +// Create nexthop group +nhg_attrs[0].id = SAI_NEXT_HOP_GROUP_ATTR_TYPE; +nhg_attrs[0].value.u32 = SAI_NEXT_HOP_GROUP_TYPE_PROTECTION; +saistatus = sai_frr_api->create_next_hop_group(&nhg_id, switch_id, 1, nhg_attrs); +if (saistatus != SAI_STATUS_SUCCESS) { + return saistatus; +} + +// Program the primary NH Group member +nhgm_attrs[0].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID; +nhgm_attrs[0].value.oid = nhg_id; +nhgm_attrs[1].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID; +nhgm_attrs[1].value.oid = nh_1_id; +nhgm_attrs[2].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_CONFIGURED_ROLE; +nhgm_attrs[2].value.u32 = SAI_NEXT_HOP_GROUP_MEMBER_CONFIGURED_ROLE_PRIMARY; +nhgm_attrs[3].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_MONITORED_OBJECT; +nhgm_attrs[3].value.oid = icmp_echo_session_id; +saistatus = sai_frr_api->create_next_hop_group_member(&nhgm_1_id, switch_id, 2, nhgm_attrs); +if (saistatus != SAI_STATUS_SUCCESS) { + return saistatus; +} + +// Program the standby NH Group member +nhgm_attrs[0].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID; +nhgm_attrs[0].value.oid = nhg_id; +nhgm_attrs[1].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID; +nhgm_attrs[1].value.oid = nh_2_id; +nhgm_attrs[2].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_CONFIGURED_ROLE; +nhgm_attrs[2].value.u32 = SAI_NEXT_HOP_GROUP_MEMBER_CONFIGURED_ROLE_STANDBY; +nhgm_attrs[3].id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_MONITORED_OBJECT; +nhgm_attrs[3].value.oid = icmp_echo_session_id; +saistatus = sai_frr_api->create_next_hop_group_member(&nhgm_2_id, switch_id, 2, nhgm_attrs); +if (saistatus != SAI_STATUS_SUCCESS) { + return saistatus; +} +``` +Refer [FRR](https://github.com/opencomputeproject/SAI/blob/master/doc/SAI-Proposal-FRR.md) for further information regarding the attributes associated with the protection group. + +#### 4.0.3 Remove session #### +```C +// Example usage of the sai_remove_icmp_echo_session_fn function +sai_object_id_t icmp_echo_session_id = 0x01; +sai_status_t status = sai_remove_icmp_echo_session(icmp_echo_session_id); +if (status == SAI_STATUS_SUCCESS) { + // ICMP ECHO session removal was successful +} else { + // Handle the error condition +} +``` +#### 4.0.4 Session statistics #### +#### Query received and transmitted packet counts of a session #### +- Obtain the ICMP Echo session ID associated with the session of interest. +- Prepare an array of statistic IDs (counter_ids) indicating the specific statistics to retrieve. +- Call sai_get_icmp_echo_session_stats_fn with the session ID, number of statistics, counter_ids, and an array (counters) to hold the results. +- Check the returned status to verify the success of the operation. +- Access the counters array to retrieve the values of the requested statistics. + +```C +sai_object_id_t icmp_session_id = 0x01; +uint32_t number_of_counters = 2; // Example: Retrieving 2 statistics +sai_icmp_echo_session_stat_t counter_ids[2] = {SAI_ICMP_ECHO_SESSION_STAT_IN_PACKETS, SAI_ICMP_ECHO_SESSION_STAT_OUT_PACKETS}; +uint64_t counters[2]; + +sai_status_t status = sai_get_icmp_echo_session_stats_fn(icmp_session_id, number_of_counters, counter_ids, counters); + +if (status == SAI_STATUS_SUCCESS) { + // Access counters[0] for incoming packets and counters[1] for outgoing packets + printf("Incoming Packets: %lu, Outgoing Packets: %lu\n", counters[0], counters[1]); +} else { + printf("Failed to retrieve ICMP Echo session statistics.\n"); +} +``` +#### Clear received and transmitted packet counts of a session #### +- Obtain the ICMP Echo session ID associated with the session of interest. +- Prepare an array of statistic IDs (counter_ids) indicating the specific statistics to clear. +- Call sai_clear_icmp_echo_session_stats_fn with the session ID, number of statistics, and counter_ids. +- Check the returned status to verify the success of the operation. +```C +sai_object_id_t icmp_session_id = 0x01; +uint32_t number_of_counters = 2; // Example: Clearing 2 statistics +sai_icmp_echo_session_stat_t counter_ids[2] = {SAI_ICMP_ECHO_SESSION_STAT_IN_PACKETS, SAI_ICMP_ECHO_SESSION_STAT_OUT_PACKETS}; + +sai_status_t status = sai_clear_icmp_echo_session_stats_fn(icmp_session_id, number_of_counters, counter_ids); + +if (status == SAI_STATUS_SUCCESS) { + // ICMP Echo session statistics cleared successfully. +} else { + // Failed to clear ICMP Echo session statistics. +} +``` +### State Change Notification ### +The offloaded session is responsible for keeping the device’s session state up to date and notifying the clients on state changes. Whenever the state changes, the device notify’s all clients registered in SAI for the callback with the   _sai_icmp_echo_session_state_notification_t struct where icmp_session_id is session unique id and the session_state with either SAI_ICMP_ECHO_SESSION_STATE_DOWN when state changes to Down or SAI_ICMP_ECHO_SESSION_STATE_UP when state changes to Up.  +```C +// Example usage +void myCallbackFunction(uint32_t count, sai_icmp_echo_session_state_notification_t* data) { + printf("Received %d" count ICMP ECHO session state change notifications\n", cout); + for (uint32_t i = 0; i < count; ++i) { + printf("Session ID: %d State %d", data[i].icmp_echo_session_id, data[i].session_state); + } +} +``` +### ICMP echo session with LAG ### + +- Sessions across a LAG bundle: Individual sessions are created on each of the member links. The device creates ICMP echo requests for each configured probing session, which are sent through the port specified by the Session attribute SAI_ICMP_ECHO_SESSION_ATTR_PORT. + - For example, to create a session over a LAG, refer to the section [Create session using egress interface](#4.0.1). + +- Session on a logical bundle (LAG interface): A single session is set up on the LAG interface. Given that a LAG interface may have multiple next hops or that a next hop can vary dynamically, the destination for the outbound ICMP echo packets is determined by the router's lookup procedure. The session should be configured with the attributes SAI_ICMP_ECHO_SESSION_ATTR_VIRTUAL_ROUTER and SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID both set to true. + - For example, to create a session over a LAG, refer to the section [Create session using Endpoint IP address](#4.0.2). + +- Incoming ICMP echo response packets can arrive on any of the member links. If necessary, the Session attribute SAI_ICMP_ECHO_SESSION_ATTR_RX_PORT is provided to verify the incoming packets on a specific member link. diff --git a/doc/figures/sai_icmp_echo_state.png b/doc/figures/sai_icmp_echo_state.png new file mode 100644 index 0000000000000000000000000000000000000000..d035c9a1acf00643686e1af5f54733f0ceba83bf GIT binary patch literal 38462 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%0A+k7 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
&GifOIJc9?|X1C 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 Jjg+B<{|hux$=Cn@ literal 0 HcmV?d00001 diff --git a/inc/sai.h b/inc/sai.h index f33293364..c612c6173 100644 --- a/inc/sai.h +++ b/inc/sai.h @@ -80,6 +80,7 @@ #include "saitwamp.h" #include "saiversion.h" #include "saipoe.h" +#include "saiicmpecho.h" /** * @defgroup SAI SAI - Entry point specific API definitions. @@ -148,6 +149,7 @@ typedef enum _sai_api_t SAI_API_ARS_PROFILE = 49, /** + +/** + * @defgroup SAIICMPECHO SAI - ICMP_ECHO specific public APIs and data structures + * + * @{ + */ + +/** + * @brief SAI ICMP_ECHO session state + */ +typedef enum _sai_icmp_echo_session_state_t +{ + /** ICMP_ECHO Session is in Down */ + SAI_ICMP_ECHO_SESSION_STATE_DOWN = 0, + + /** ICMP_ECHO Session is Up */ + SAI_ICMP_ECHO_SESSION_STATE_UP, + +} sai_icmp_echo_session_state_t; + +/** + * @brief Defines the operational status of the ICMP_ECHO session + */ +typedef struct _sai_icmp_echo_session_state_notification_t +{ + /** + * @brief ICMP_ECHO Session id + * + * @objects SAI_OBJECT_TYPE_ICMP_ECHO_SESSION + */ + sai_object_id_t icmp_echo_session_id; + + /** ICMP_ECHO session state */ + sai_icmp_echo_session_state_t session_state; + +} sai_icmp_echo_session_state_notification_t; + +/** + * @brief SAI attributes for ICMP_ECHO session + */ +typedef enum _sai_icmp_echo_session_attr_t +{ + /** + * @brief Start of attributes + */ + SAI_ICMP_ECHO_SESSION_ATTR_START, + + /** + * @brief Hardware lookup valid. TRUE routes packets via L3 forward lookup; + * FALSE injects packets directly to specified port. + * + * @type bool + * @flags CREATE_ONLY + * @default true + */ + SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID = SAI_ICMP_ECHO_SESSION_ATTR_START, + + /** + * @brief Virtual Router + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + * @objects SAI_OBJECT_TYPE_VIRTUAL_ROUTER + * @condition SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID == true + */ + SAI_ICMP_ECHO_SESSION_ATTR_VIRTUAL_ROUTER, + + /** + * @brief Destination Port + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + * @objects SAI_OBJECT_TYPE_PORT + * @condition SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID == false + */ + SAI_ICMP_ECHO_SESSION_ATTR_PORT, + + /** + * @brief Source Port + * + * @type sai_object_id_t + * @flags CREATE_AND_SET + * @objects SAI_OBJECT_TYPE_PORT + * @allownull true + * @default SAI_NULL_OBJECT_ID + */ + SAI_ICMP_ECHO_SESSION_ATTR_RX_PORT, + + /** + * @brief Session Global Unique Identifier + * + * @type sai_uint64_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_ICMP_ECHO_SESSION_ATTR_GUID, + + /** + * @brief Session Cookie + * + * @type sai_uint32_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_ICMP_ECHO_SESSION_ATTR_COOKIE, + + /** + * @brief IP header version + * + * @type sai_uint8_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + */ + SAI_ICMP_ECHO_SESSION_ATTR_IPHDR_VERSION, + + /** + * @brief IP header TOS + * + * @type sai_uint8_t + * @flags CREATE_AND_SET + * @default 0 + */ + SAI_ICMP_ECHO_SESSION_ATTR_TOS, + + /** + * @brief IP header TTL + * + * @type sai_uint8_t + * @flags CREATE_AND_SET + * @default 255 + */ + SAI_ICMP_ECHO_SESSION_ATTR_TTL, + + /** + * @brief Source IP + * + * @type sai_ip_address_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_ICMP_ECHO_SESSION_ATTR_SRC_IP_ADDRESS, + + /** + * @brief Destination IP + * + * @type sai_ip_address_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_ICMP_ECHO_SESSION_ATTR_DST_IP_ADDRESS, + + /** + * @brief L2 source MAC address + * + * @type sai_mac_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + * @condition SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID == false + */ + SAI_ICMP_ECHO_SESSION_ATTR_SRC_MAC_ADDRESS, + + /** + * @brief L2 destination MAC address + * + * @type sai_mac_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + * @condition SAI_ICMP_ECHO_SESSION_ATTR_HW_LOOKUP_VALID == false + */ + SAI_ICMP_ECHO_SESSION_ATTR_DST_MAC_ADDRESS, + + /** + * @brief Transmit interval in microseconds + * + * @type sai_uint32_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + */ + SAI_ICMP_ECHO_SESSION_ATTR_TX_INTERVAL, + + /** + * @brief Receive interval in microseconds + * + * @type sai_uint32_t + * @flags MANDATORY_ON_CREATE | CREATE_AND_SET + */ + SAI_ICMP_ECHO_SESSION_ATTR_RX_INTERVAL, + + /** + * @brief To enable protection group switch over on session state change + * + * @type bool + * @flags CREATE_AND_SET + * @default false + */ + SAI_ICMP_ECHO_SESSION_ATTR_SET_NEXT_HOP_GROUP_SWITCHOVER, + + /** + * @brief ICMP_ECHO Session state + * + * @type sai_icmp_echo_session_state_t + * @flags READ_ONLY + */ + SAI_ICMP_ECHO_SESSION_ATTR_STATE, + + /** + * @brief End of attributes + */ + SAI_ICMP_ECHO_SESSION_ATTR_END, + + /** Custom range base value */ + SAI_ICMP_ECHO_SESSION_ATTR_CUSTOM_RANGE_START = 0x10000000, + + /** End of custom range base */ + SAI_ICMP_ECHO_SESSION_ATTR_CUSTOM_RANGE_END + +} sai_icmp_echo_session_attr_t; + +/** + * @brief ICMP_ECHO Session counter IDs in sai_get_icmp_echo_session_stats() call + */ +typedef enum _sai_icmp_echo_session_stat_t +{ + /** Ingress packet stat count */ + SAI_ICMP_ECHO_SESSION_STAT_IN_PACKETS, + + /** Egress packet stat count */ + SAI_ICMP_ECHO_SESSION_STAT_OUT_PACKETS, + +} sai_icmp_echo_session_stat_t; + +/** + * @brief Create ICMP_ECHO session. + * + * @param[out] icmp_echo_session_id ICMP_ECHO session id + * @param[in] switch_id Switch id + * @param[in] attr_count Number of attributes + * @param[in] attr_list Value of attributes + * + * @return #SAI_STATUS_SUCCESS if operation is successful otherwise a different + * error code is returned. + */ +typedef sai_status_t (*sai_create_icmp_echo_session_fn)( + _Out_ sai_object_id_t *icmp_echo_session_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + +/** + * @brief Remove ICMP_ECHO session. + * + * @param[in] icmp_echo_session_id ICMP_ECHO session id + * + * @return #SAI_STATUS_SUCCESS if operation is successful otherwise a different + * error code is returned. + */ +typedef sai_status_t (*sai_remove_icmp_echo_session_fn)( + _In_ sai_object_id_t icmp_echo_session_id); + +/** + * @brief Set ICMP_ECHO session attributes. + * + * @param[in] icmp_echo_session_id ICMP_ECHO session id + * @param[in] attr Value of attribute + * + * @return #SAI_STATUS_SUCCESS if operation is successful otherwise a different + * error code is returned. + */ +typedef sai_status_t (*sai_set_icmp_echo_session_attribute_fn)( + _In_ sai_object_id_t icmp_echo_session_id, + _In_ const sai_attribute_t *attr); + +/** + * @brief Get ICMP_ECHO session attributes. + * + * @param[in] icmp_echo_session_id ICMP_ECHO session id + * @param[in] attr_count Number of attributes + * @param[inout] attr_list Value of attribute + * + * @return #SAI_STATUS_SUCCESS if operation is successful otherwise a different + * error code is returned. + */ +typedef sai_status_t (*sai_get_icmp_echo_session_attribute_fn)( + _In_ sai_object_id_t icmp_echo_session_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list); + +/** + * @brief Get ICMP_ECHO session statistics counters. Deprecated for backward compatibility. + * + * @param[in] icmp_echo_session_id ICMP_ECHO session id + * @param[in] number_of_counters Number of counters in the array + * @param[in] counter_ids Specifies the array of counter ids + * @param[out] counters Array of resulting counter values. + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_get_icmp_echo_session_stats_fn)( + _In_ sai_object_id_t icmp_echo_session_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _Out_ uint64_t *counters); + +/** + * @brief Get ICMP_ECHO session statistics counters extended. + * + * @param[in] icmp_echo_session_id ICMP_ECHO session id + * @param[in] number_of_counters Number of counters in the array + * @param[in] counter_ids Specifies the array of counter ids + * @param[in] mode Statistics mode + * @param[out] counters Array of resulting counter values. + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_get_icmp_echo_session_stats_ext_fn)( + _In_ sai_object_id_t icmp_echo_session_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Out_ uint64_t *counters); + +/** + * @brief Clear ICMP_ECHO session statistics counters. + * + * @param[in] icmp_echo_session_id ICMP_ECHO session id + * @param[in] number_of_counters Number of counters in the array + * @param[in] counter_ids Specifies the array of counter ids + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_clear_icmp_echo_session_stats_fn)( + _In_ sai_object_id_t icmp_echo_session_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids); + +/** + * @brief ICMP_ECHO session state change notification + * + * Passed as a parameter into sai_initialize_switch() + * + * @count data[count] + * + * @param[in] count Number of notifications + * @param[in] data Array of ICMP_ECHO session state + */ +typedef void (*sai_icmp_echo_session_state_change_notification_fn)( + _In_ uint32_t count, + _In_ const sai_icmp_echo_session_state_notification_t *data); + +/** + * @brief ICMP_ECHO method table retrieved with sai_api_query() + */ +typedef struct _sai_icmp_echo_api_t +{ + sai_create_icmp_echo_session_fn create_icmp_echo_session; + sai_remove_icmp_echo_session_fn remove_icmp_echo_session; + sai_set_icmp_echo_session_attribute_fn set_icmp_echo_session_attribute; + sai_get_icmp_echo_session_attribute_fn get_icmp_echo_session_attribute; + sai_get_icmp_echo_session_stats_fn get_icmp_echo_session_stats; + sai_get_icmp_echo_session_stats_ext_fn get_icmp_echo_session_stats_ext; + sai_clear_icmp_echo_session_stats_fn clear_icmp_echo_session_stats; + +} sai_icmp_echo_api_t; + +/** + * @} + */ +#endif /** __SAIICMPECHO_H_ */ diff --git a/inc/saiswitch.h b/inc/saiswitch.h index 61401b693..4883b116e 100644 --- a/inc/saiswitch.h +++ b/inc/saiswitch.h @@ -3021,6 +3021,33 @@ typedef enum _sai_switch_attr_t */ SAI_SWITCH_ATTR_POE_DEVICE_LIST, + /** + * @brief Set Switch ICMP_ECHO session state change event notification callback function passed to the adapter. + * + * Use sai_icmp_echo_session_state_change_notification_fn as notification function. + * + * @type sai_pointer_t sai_icmp_echo_session_state_change_notification_fn + * @flags CREATE_AND_SET + * @default NULL + */ + SAI_SWITCH_ATTR_ICMP_ECHO_SESSION_STATE_CHANGE_NOTIFY, + + /** + * @brief Available ICMP ECHO sessions + * + * @type sai_uint32_t + * @flags READ_ONLY + */ + SAI_SWITCH_ATTR_AVAILABLE_ICMP_ECHO_SESSION, + + /** + * @brief Max number of ICMP ECHO sessions supported + * + * @type sai_uint32_t + * @flags READ_ONLY + */ + SAI_SWITCH_ATTR_MAX_ICMP_ECHO_SESSION, + /** * @brief End of attributes */ diff --git a/inc/saitypes.h b/inc/saitypes.h index 3ec3c9984..7da5c09cb 100644 --- a/inc/saitypes.h +++ b/inc/saitypes.h @@ -298,6 +298,7 @@ typedef enum _sai_object_type_t SAI_OBJECT_TYPE_POE_DEVICE = 108, SAI_OBJECT_TYPE_POE_PSE = 109, SAI_OBJECT_TYPE_POE_PORT = 110, + SAI_OBJECT_TYPE_ICMP_ECHO_SESSION = 111, /** Must remain in last position */ SAI_OBJECT_TYPE_MAX, diff --git a/meta/saisanitycheck.c b/meta/saisanitycheck.c index 3bc45bd7d..9b6c59586 100644 --- a/meta/saisanitycheck.c +++ b/meta/saisanitycheck.c @@ -4887,7 +4887,8 @@ void check_object_ro_list( oi->objecttype == SAI_OBJECT_TYPE_DTEL_QUEUE_REPORT || oi->objecttype == SAI_OBJECT_TYPE_DTEL_EVENT || oi->objecttype == SAI_OBJECT_TYPE_GENERIC_PROGRAMMABLE || - oi->objecttype == SAI_OBJECT_TYPE_TWAMP_SESSION) + oi->objecttype == SAI_OBJECT_TYPE_TWAMP_SESSION || + oi->objecttype == SAI_OBJECT_TYPE_ICMP_ECHO_SESSION) { /* * We skip hostif table entry since there is no 1 object which can