[dpdk-users] Flow Director RAW filter: Not supported action!!!

waqas ahmed waqasahmed1471 at gmail.com
Thu Jul 19 08:18:45 CEST 2018


Greetings,
we are modifying dpdk sample *flow_filtering* app to extend its
functionality to add Flow Director RAW filter. this filter is used to
direct rtp traffic to specifc rx-queue.
RAW filter is based on searching first 2-bytes of RTP header values in UDP
payload.
before this we have added two filters successfully to separate igmp and udp
traffic on basis of their ip-protocol numbers 0x2 and 0x11 respectively.
NIC in use: 82599ES 10g
==================================================
OUTPUT of app:
----------------------------------------------------------------------------------------------------
EAL: Detected 8 lcore(s)
EAL: Multi-process socket /var/run/.rte_unix
EAL: Probing VFIO support...
EAL: PCI device 0000:01:00.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:10c9 net_e1000_igb
EAL: PCI device 0000:01:00.1 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:10c9 net_e1000_igb
EAL: PCI device 0000:05:00.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:10fb net_ixgbe
EAL: PCI device 0000:05:00.1 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:10fb net_ixgbe
:: initializing port: 0
:: initializing port: 0 done


*Flow can't be created 11 message: Not supported action.EAL: Error -
exiting with code: 1  Cause: error in creating flow*

==================================================
RAW filter function is given below
----------------------------------------------------------------------------------------------------
..... // start of function
        struct rte_flow_attr attr;
        struct rte_flow_item pattern[5];
        struct rte_flow_action action[5];
        struct rte_flow *flow = NULL;
        struct rte_flow_action_queue queue = { .index = rx_q };
        struct rte_flow_item_eth eth_spec;
        struct rte_flow_item_eth eth_mask;
        struct rte_flow_item_vlan vlan_spec;
        struct rte_flow_item_vlan vlan_mask;
        struct rte_flow_item_ipv4 ip_spec;
        struct rte_flow_item_ipv4 ip_mask;

        struct rte_flow_item_udp udp_spec;
        struct rte_flow_item_udp udp_mask;
        struct rte_flow_item_raw raw_spec;
        struct rte_flow_item_raw raw_mask;
        int res;

        memset(pattern, 0, sizeof(pattern));
        memset(action, 0, sizeof(action));

        /*
         * set the rule attribute.
         * in this case only ingress packets will be checked.
         */
        memset(&attr, 0, sizeof(struct rte_flow_attr));
        attr.ingress = 1;

        /*
         * create the action sequence.
         * one action only,  move packet to queue
         */
        action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
        action[0].conf = &queue;
        action[1].type = RTE_FLOW_ACTION_TYPE_END;

        /*
         * set the first level of the pattern (eth).
         * since in this example we just want to get the
         * ipv4 we set this level to allow all.
         */
        memset(&eth_spec, 0, sizeof(struct rte_flow_item_eth));
        memset(&eth_mask, 0, sizeof(struct rte_flow_item_eth));
        eth_spec.type = 0;
        eth_mask.type = 0;
        pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
        pattern[0].spec = &eth_spec;
        pattern[0].mask = &eth_mask;


        /*
         * setting the second level of the pattern (vlan).
         * since in this example we just want to get the
         * ipv4 we also set this level to allow all.
         */
        memset(&vlan_spec, 0, sizeof(struct rte_flow_item_vlan));
        memset(&vlan_mask, 0, sizeof(struct rte_flow_item_vlan));
        pattern[1].type = RTE_FLOW_ITEM_TYPE_VLAN;
        pattern[1].spec = &vlan_spec;
        pattern[1].mask = &vlan_mask;

        /*
         * setting the third level of the pattern (ip).
         * in this example this is the level we care about
         * so we set it according to the parameters.
         */
        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 = 0x0; //dest_mask;
        ip_spec.hdr.src_addr = htonl(src_ip);
        ip_mask.hdr.src_addr = 0x0; //src_mask;
        ip_spec.hdr.next_proto_id = 0x11;
        ip_mask.hdr.next_proto_id = 0xff;
        pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
        pattern[2].spec = &ip_spec;
        pattern[2].mask = &ip_mask;

        memset(&udp_spec, 0, sizeof(struct rte_flow_item_udp));
        memset(&udp_mask, 0, sizeof(struct rte_flow_item_udp));
        pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP;
        pattern[2].spec = &udp_spec;
        pattern[2].mask = &udp_mask;

        memset(&raw_spec, 0, sizeof(struct rte_flow_item_raw));
        memset(&raw_mask, 0, sizeof(struct rte_flow_item_raw));

        pattern[3].type = RTE_FLOW_ITEM_TYPE_RAW;
        pattern[3].spec = &raw_spec;
        pattern[3].mask = &raw_mask;
        raw_spec.relative = 1;
        raw_spec.search   = 1;
        raw_spec.reserved = 0;
        raw_spec.offset   = 10;
        raw_spec.length   = 2;
        raw_spec.pattern[0]  ='8';
        raw_spec.pattern[1]  ='0';
        /* the final level must be always type end */
        pattern[4].type = RTE_FLOW_ITEM_TYPE_END;

        res = rte_flow_validate(port_id, &attr, pattern, action, error);
        if (!res)
                flow = rte_flow_create(port_id, &attr, pattern, action,
error);

        return flow;

=======================================================
Thanks for reading & help is much appreciated
Ahmed


More information about the users mailing list