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

tom.barbette at uliege.be tom.barbette at uliege.be
Thu Jul 19 11:14:33 CEST 2018


Hi,

https://git.dpdk.org/dpdk/tree/drivers/net/ixgbe/ixgbe_flow.c#n1525 gives you some guidelines about the issue here.

I guess one issue is that you overwrite pattern[2] instead of adding your UDP spec to pattern[3]. That paragraph states that you must have an IPv4 or IPv6 filter before a UDP filter.

Then, if you already have other rules for the same protocol (UDPv4) you will not be able to add a different flexible byte position. 82599 (and XL710 even more) are very limited in term of filtering capabilities and only support one global mask  (X(L)710 only one flex mask, not even headers mask).


Tom

----- Mail original -----
> De: "waqas ahmed" <waqasahmed1471 at gmail.com>
> À: users at dpdk.org
> Envoyé: Jeudi 19 Juillet 2018 08:18:45
> Objet: [dpdk-users] Flow Director RAW filter: Not supported action!!!

> 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