DPDK usage discussions
 help / color / mirror / Atom feed
* [dpdk-users] Flow Director RAW filter: Not supported action!!!
@ 2018-07-19  6:18 waqas ahmed
  2018-07-19  9:14 ` tom.barbette
  0 siblings, 1 reply; 3+ messages in thread
From: waqas ahmed @ 2018-07-19  6:18 UTC (permalink / raw)
  To: users

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-users] Flow Director RAW filter: Not supported action!!!
  2018-07-19  6:18 [dpdk-users] Flow Director RAW filter: Not supported action!!! waqas ahmed
@ 2018-07-19  9:14 ` tom.barbette
  2018-07-19 13:31   ` waqas ahmed
  0 siblings, 1 reply; 3+ messages in thread
From: tom.barbette @ 2018-07-19  9:14 UTC (permalink / raw)
  To: waqas ahmed; +Cc: users

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@gmail.com>
> À: users@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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dpdk-users] Flow Director RAW filter: Not supported action!!!
  2018-07-19  9:14 ` tom.barbette
@ 2018-07-19 13:31   ` waqas ahmed
  0 siblings, 0 replies; 3+ messages in thread
From: waqas ahmed @ 2018-07-19 13:31 UTC (permalink / raw)
  To: tom.barbette, users

Thanks tom, glad to see your response.
after correcting pattern[] issue,  rule can't be added again with same
error. we have 8 or more rtp streams coming with different sorts of
management traffic to rxq0, we may separate other traffic but how we direct
these streams to one specific rxq.
one solution might be to add 8-different filters set on udp ports, one for
each stream with action rxq-3. i was looking for 1 rule to fit on all the
streams!.
Thanks again.
ahmed

On Thu, Jul 19, 2018 at 2:14 PM, <tom.barbette@uliege.be> wrote:

> 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@gmail.com>
> > À: users@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
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-07-19 13:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-19  6:18 [dpdk-users] Flow Director RAW filter: Not supported action!!! waqas ahmed
2018-07-19  9:14 ` tom.barbette
2018-07-19 13:31   ` waqas ahmed

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).