What can I help you with?
NVIDIA DPDK Documentation MLNX_DPDK_22.11_2310.5.1 LTS

SRv6 Push/Remove Actions

Added support for pushing/removing IPv6 extension header into/from the original IPv6 packets directly. This method is more efficient than using tunnel encap/decap (e.g. VxLAN) with SRv6 in the outer header.

Note:

  • The maximal pushing length should be <= 128B.

  • The application should make sure that the SRv6 is the only present extension header after pushing (no fragmentation either).

  • Currently, only TCP and UDP protocols are supported in L4.

  • To generate the correct checksum after pushing, the application should set IPv6 dst_addr in the origin packet with the final address in SRv6 segment[0].

Hardware requirements:

  • REMOVE action: ConnectX-6 Dx and above

  • PUSH action: ConnectX-7 and above

Service Routing Header (SRH) can be used for SRv6 offload of an endpoint device (match + header add/remove)​. The user can create a rule to match on SRH and to validate it, or create an SRH with segment_list as source node​.

The match can be on the 1st 32 Bits of SRH: Routing Type, Next Header, Segment-Left.

SRv6-version-1-modificationdate-1736074530997-api-v2.png

Supported device type = endpoint node​

  • SR-SourceNode = Start SRv6 source route through Push/Encap (SRH)​

  • SR-EndNode = Hold the latest IP; End SRv6 source route through Pop/Decap (SRH); Also use match to validate that segment-left=0 & validate routing type=SRv6​

Supported Operations

  • Match: Required for SR-EndNode​

  • Push/Encap: Required for SR-SourceNode​

  • Pop/Decap: Required for SR-EndNode

IPv6 Extension Header Manipulation

IPv6 extension header manipulation ( add/remove header) is performed through on of the following methods:

  • Use encap/decap for adding IPv6 tunnel with Segment routing Header (SRH)​

    • Use the original/legacy encap/decap API (no API change)​

    • Enable adding any tunnel type, e.g. GRE/VxLAN, NVGRE

      SRv61-version-1-modificationdate-1736074530603-api-v2.png

  • Use the push/pop [newly added API] of IPv6 extension headers into/from IPv6 packets​

    • Before push, there should be no IPv6 extension header - IPv6.dst_addr = seg_list[0]

    • After push - IPv6.dst_addr = seg_list[n]

    • After pop - IPv6.dst_addr = seg_list[0]​

    • After push IPv6 routing should be the only present extension (not supporting multiple extensions)​

    • Push/Pop are complex actions, hence impacting on PPS and #rules should be limited​

      image2023-11-16_16-16-28-version-1-modificationdate-1736074530143-api-v2.png

Assumptions / Limitations​

  • Match is available on 1st 32 bits (partial/relevant fields)

    • Cannot match on further last Entry/flags/tag/…/ TLV options)

    • Only TCP, UDP, and IPv6 are supported by the Next Header field​

  • Push/Encap - size (encap buffer or push buffer) <= 128B (may limit the total # of segment list entries)​

  • Push

    • SRH next layer exclusively accommodates TCP and UDP​

    • Push is supported on BlueField-3 / ConnectX-7​

Remove Action

The remove action is unified in the template table and the action must be fully masked in the action template.

Copy
Copied!
            

> set ipv6_ext_remove 1 ipv6_ext type is 43 / end_set > flow pattern_template 0 create transfer relaxed no pattern_template_id 1 template represented_port ethdev_port_id is 0 / eth / ipv6 / ipv6_routing_ext / udp src is 100 / end > flow actions_template 0 create transfer actions_template_id 1 template ipv6_ext_remove index 1 / represented_port ethdev_port_id 1 / end mask ipv6_ext_remove index 1 / represented_port ethdev_port_id 1 / end > flow template_table 0 create group 0 priority 0 transfer table_id 1 rules_number 128 pattern_template 1 actions_template 1


Push Action

Copy
Copied!
            

> set ipv6_ext_push 1 ipv6_ext type is 43 / ipv6_routing_ext ext_type is 4 ext_next_hdr is 17 ext_seg_left is 2 / end_set > flow pattern_template 0 create transfer relaxed no pattern_template_id 1 template represented_port ethdev_port_id is 0 / eth / ipv6 / udp src is 1 / end > flow actions_template 0 create transfer actions_template_id 1 template ipv6_ext_push index 1 / represented_port ethdev_port_id 1 / end mask ipv6_ext_push index 1 / represented_port ethdev_port_id 1 / end > flow template_table 0 create group 0 priority 0 transfer table_id 1 rules_number 128 pattern_template 1 actions_template 1


Remove Action

Copy
Copied!
            

const struct rte_flow_action_ipv6_ext_remove remove_v = { .type = IPPROTO_ROUTING }; const struct rte_flow_action_ipv6_ext_remove remove_m = { .type = UINT8_MAX }; const struct rte_flow_action_queue queue_v = { .index = 0 }; const struct rte_flow_action_queue queue_m = { .index = UINT16_MAX }; const struct rte_flow_action actions[3] = {    [0] = {            .type = RTE_FLOW_ACTION_TYPE_IPV6_EXT_REMOVE,            .conf = &remove_v, }, [1] = {            .type = RTE_FLOW_ACTION_TYPE_QUEUE,            .conf = &queue_v,    }, [2] = { .type = RTE_FLOW_ACTION_TYPE_END } };   const struct rte_flow_action masks[3] = {    [0] = {            .type = RTE_FLOW_ACTION_TYPE_IPV6_EXT_REMOVE,            .conf = &remove_m, }, [1] = {            .type = RTE_FLOW_ACTION_TYPE_QUEUE,            .conf = &queue_m,    }, [2] = { .type = RTE_FLOW_ACTION_TYPE_END } };   const struct rte_flow_actions_template_attr at_attr = { .ingress = 1 }; rte_flow_actions_template_create(port_id, &at_attr, actions, masks, error);


Push Action

Copy
Copied!
            

const struct rte_flow_action_ipv6_ext_push push_v = { .type = IPPROTO_ROUTING, .size = 40, .data = {0x11, 4, 4, 2, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4} }; const struct rte_flow_action_queue queue_v = { .index = 0 }; const struct rte_flow_action_queue queue_m = { .index = UINT16_MAX }; const struct rte_flow_action actions[3] = {    [0] = {            .type = RTE_FLOW_ACTION_TYPE_IPV6_EXT_PUSH,            .conf = &push_v, }, [1] = {             .type = RTE_FLOW_ACTION_TYPE_QUEUE,            .conf = &queue_v,    }, [2] = { .type = RTE_FLOW_ACTION_TYPE_END } };   const struct rte_flow_action masks[3] = {    [0] = {            .type = RTE_FLOW_ACTION_TYPE_IPV6_EXT_PUSH,            .conf = NULL, }, [1] = {            .type = RTE_FLOW_ACTION_TYPE_QUEUE,            .conf = &queue_m,    }, [2] = { .type = RTE_FLOW_ACTION_TYPE_END } }; const struct rte_flow_actions_template_attr at_attr = { .ingress = 1 }; rte_flow_actions_template_create(port_id, &at_attr, actions, masks, error);


© Copyright 2024, NVIDIA. Last updated on Jan 9, 2025.