[Intel-wired-lan] [PATCH net-next 2/2] ixgbe: Add support for redirect action to cls_u32 offloads.

Samudrala, Sridhar sridhar.samudrala at intel.com
Tue Apr 5 18:15:49 UTC 2016



On 4/5/2016 10:39 AM, Sridhar Samudrala wrote:
> From: Sridhar Samudrala <sridhar.samudrala at intel.com>
>
> This patch enables 'redirect' to a SRIOV VF or a offloaded macvlan
> device queue via tc 'mirred' action.
Jeff,
This patch has a dependency on this patch
https://git.kernel.org/cgit/linux/kernel/git/jkirsher/next-queue.git/commit/?h=dev-queue&id=aff19cd6dd891364ba440ee0e02fe8a83a110f7c
which is in your dev_queue branch.

Thanks
Sridhar
>
> Verified with the following script that creates SRIOV VFs,  offloaded
> macvlan and adds tc u32 filters with redirect action to the associated
> netdevs.
>
>   # add ingress qdisc.
>   tc qdisc add dev p4p1 ingress
>
>   # enable hw tc offload.
>   ethtool -K p4p1 hw-tc-offload on
>
>   # create 4 sriov VFs and bring up the first one.
>   echo 4 > /sys/class/net/p4p1/device/sriov_numvfs
>   sleep 1
>   ip link set p4p1 up
>   ip link set p4p1_0 up
>
>   # create a offloaded macvlan device and bring it up.
>   ethtool -K p4p1 l2-fwd-offload on
>   ip link add link p4p1 name mvlan_1 type macvlan
>   ip link set mvlan_1 up
>
>   # add u32 filter with action to redirect to VF netdev
>   tc filter add dev p4p1 parent ffff: protocol ip prio 99 \
>      handle 800:0:1 u32 ht 800: \
>      match ip src 192.168.1.3/32 \
>      action mirred egress redirect dev p4p1_0
>
>   # add u32 filter with action to redirect to macvlan netdev
>   tc filter add dev p4p1 parent ffff: protocol ip prio 99 \
>      handle 800:0:2 u32 ht 800: \
>      match ip src 192.168.2.3/32 \
>      action mirred egress redirect dev mvlan_1
>
> Signed-off-by: Sridhar Samudrala <sridhar.samudrala at intel.com>
> ---
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 96 +++++++++++++++++++++++----
>   1 file changed, 83 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 19bf386..df7b10a 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -53,6 +53,7 @@
>   #include <net/vxlan.h>
>   #include <net/pkt_cls.h>
>   #include <net/tc_act/tc_gact.h>
> +#include <net/tc_act/tc_mirred.h>
>   
>   #include "ixgbe.h"
>   #include "ixgbe_common.h"
> @@ -8222,6 +8223,85 @@ static int ixgbe_configure_clsu32_del_hnode(struct ixgbe_adapter *adapter,
>   	return 0;
>   }
>   
> +#ifdef CONFIG_NET_CLS_ACT
> +static int handle_redirect_action(struct ixgbe_adapter *adapter, int ifindex,
> +				  u8 *queue, u64 *action)
> +{
> +	unsigned int num_vfs = adapter->num_vfs, vf;
> +	struct net_device *upper;
> +	struct list_head *iter;
> +
> +	/* redirect to a SRIOV VF */
> +	for (vf = 0; vf < num_vfs; ++vf) {
> +		upper = pci_get_drvdata(adapter->vfinfo[vf].vfdev);
> +		if (upper->ifindex == ifindex) {
> +			if (adapter->num_rx_pools > 1)
> +				*queue = vf * 2;
> +			else
> +				*queue = vf * adapter->num_rx_queues_per_pool;
> +
> +			*action = vf+1;
> +			*action <<= ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;
> +			return 0;
> +		}
> +	}
> +
> +	/* redirect to a offloaded macvlan netdev */
> +	netdev_for_each_all_upper_dev_rcu(adapter->netdev, upper, iter) {
> +		if (netif_is_macvlan(upper)) {
> +			struct macvlan_dev *dfwd = netdev_priv(upper);
> +			struct ixgbe_fwd_adapter *vadapter = dfwd->fwd_priv;
> +
> +			if (vadapter && vadapter->netdev->ifindex == ifindex) {
> +				*queue = adapter->rx_ring[vadapter->rx_base_queue]->reg_idx;
> +				*action = *queue;
> +				return 0;
> +			}
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int parse_tc_actions(struct ixgbe_adapter *adapter,
> +			    struct tcf_exts *exts, u64 *action, u8 *queue)
> +{
> +	const struct tc_action *a;
> +	int err;
> +
> +	if (tc_no_actions(exts))
> +		return -EINVAL;
> +
> +	tc_for_each_action(a, exts) {
> +
> +		/* Drop action */
> +		if (is_tcf_gact_shot(a)) {
> +			*action = IXGBE_FDIR_DROP_QUEUE;
> +			*queue = IXGBE_FDIR_DROP_QUEUE;
> +			return 0;
> +		}
> +
> +		/* Redirect to a VF or a offloaded macvlan */
> +		if (is_tcf_mirred_redirect(a)) {
> +			int ifindex = tcf_mirred_ifindex(a);
> +
> +			err = handle_redirect_action(adapter, ifindex, queue,
> +						     action);
> +			if (err == 0)
> +				return err;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +#else
> +static int parse_tc_actions(struct ixgbe_adapter *adapter,
> +			    struct tcf_exts *exts, u64 *action, u8 *queue)
> +{
> +	return -EINVAL;
> +}
> +#endif /* CONFIG_NET_CLS_ACT */
> +
>   static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
>   				  __be16 protocol,
>   				  struct tc_cls_u32_offload *cls)
> @@ -8231,9 +8311,6 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
>   	struct ixgbe_mat_field *field_ptr;
>   	struct ixgbe_fdir_filter *input;
>   	union ixgbe_atr_input mask;
> -#ifdef CONFIG_NET_CLS_ACT
> -	const struct tc_action *a;
> -#endif
>   	int i, err = 0;
>   	u8 queue;
>   	u32 uhtid, link_uhtid;
> @@ -8335,18 +8412,11 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
>   	if (input->filter.formatted.flow_type == IXGBE_ATR_FLOW_TYPE_IPV4)
>   		mask.formatted.flow_type &= IXGBE_ATR_L4TYPE_IPV6_MASK;
>   
> -#ifdef CONFIG_NET_CLS_ACT
> -	if (list_empty(&cls->knode.exts->actions))
> +	err = parse_tc_actions(adapter, cls->knode.exts, &input->action,
> +			       &queue);
> +	if (err < 0)
>   		goto err_out;
>   
> -	list_for_each_entry(a, &cls->knode.exts->actions, list) {
> -		if (!is_tcf_gact_shot(a))
> -			goto err_out;
> -	}
> -#endif
> -
> -	input->action = IXGBE_FDIR_DROP_QUEUE;
> -	queue = IXGBE_FDIR_DROP_QUEUE;
>   	input->sw_idx = loc;
>   
>   	spin_lock(&adapter->fdir_perfect_lock);



More information about the Intel-wired-lan mailing list