cpacketdpdkmpls

Strip MPLS header using DPDK


I am trying to strip MPLS header using DPDK, I have use the flow_filtering sample application as starting and tried to add another item in the pattern: Ethernet MPLS IPv4 END and I added the following action: RTE_FLOW_ACTION_TYPE_OF_POP_MPLS RTE_FLOW_ACTION_TYPE_END But while executing the code following error is thrown: Flow can't be created 16 message: Not supported action.

Following is the snippet of the code:

    action[0].type = RTE_FLOW_ACTION_TYPE_OF_POP_MPLS;
    action[1].type = RTE_FLOW_ACTION_TYPE_END;

    
    pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;

    pattern[1].type = RTE_FLOW_ITEM_TYPE_MPLS;
    
    memset(&ip_spec, 0, sizeof(struct rte_flow_item_ipv4));
    memset(&ip_mask, 0, sizeof(struct rte_flow_item_ipv4));
    ip_spec.hdr.dst_addr = htonl(dest_ip);
    ip_mask.hdr.dst_addr = dest_mask;
    ip_spec.hdr.src_addr = htonl(src_ip);
    ip_mask.hdr.src_addr = src_mask;
    pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
    pattern[2].spec = &ip_spec;
    pattern[2].mask = &ip_mask;

    pattern[3].type = RTE_FLOW_ITEM_TYPE_END;

    res = rte_flow_validate(port_id, &attr, pattern, action, error);

By removing the pattern[1].type = RTE_FLOW_ITEM_TYPE_MPLS; and action[0].type = RTE_FLOW_ACTION_TYPE_OF_POP_MPLS;. The code works fine.

I tried to change the order of MPLS in pattern even though MPLS header reside between L2 and L3 layer but no use.

Version:

Linux: CentOS 7

DPDK: 19.08.2

NIC: X520

Firmware version: 18.5.17


Solution

  • For Intel NIC X520 the error message Flow can't be created 16 messages: Not supported action is the right and expected behaviour. Hence there is no issue in DPDK IXGBE PMD driver.

    Explanation:

    1. RTE_FLOW is NIC based on Hardware Offload to filter and modify packets in both ingress and egress directions, more details here.
    2. There are multiple filter tags (like vlan, IP, TCP, UDP, MPLS) along with various action items (push pop vlan, push pop mpsl, dec inc mpls ttl, ...etc). But not all filter and actions are supported by all NIC (as these are optional).
    3. Refer Table 1.3 rte_flow actions availability in networking drivers (link here) which maps each NIC PMD with the action. IXGBE is not shown to support MPLS actions.
    4. Checking the PMD code here, even shows supported filter fields.
        const struct rte_flow_item_ipv4 *ipv4_spec;
        const struct rte_flow_item_ipv4 *ipv4_mask;
        const struct rte_flow_item_tcp *tcp_spec;
        const struct rte_flow_item_tcp *tcp_mask;
        const struct rte_flow_item_udp *udp_spec;
        const struct rte_flow_item_udp *udp_mask;
        const struct rte_flow_item_sctp *sctp_spec;
        const struct rte_flow_item_sctp *sctp_mask;
        const struct rte_flow_item_eth *eth_spec;
        const struct rte_flow_item_eth *eth_mask;
        const struct rte_flow_item_vlan *vlan_spec;
        const struct rte_flow_item_vlan *vlan_mask;
    

    Hence the code and IXGBE PMD behaviour are consistent and there is no error. It is the expectation from X550 to support an unsupported feature that is incorrect.

    [EDIT-1] according to the sheet, none of the drivers support the "of_pop_mpls" action which implies that we can't strip off the MPLS header using RTE_FLOWS

    That is the correct understanding, so far the current available foundational NIC shows none support MPLS pop/push. But I am familiar with Intel NIC FM10K which allowed MPLS POP/PUSH, but I do not see that NIC is supported under DPDK. SO you have 2 options,

    Note: PTYPE is supported in most NIC, and parsing of MPLS and saving tin rte_mbuf will be available too. This will also help while using SW approach.