Commit c099a408 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'nf-hw-offload'



Pablo Neira Ayuso says:

====================
netfilter: add hardware offload infrastructure

This patchset adds support for Netfilter hardware offloads.

This patchset reuses the existing block infrastructure, the
netdev_ops->ndo_setup_tc() interface, TC_SETUP_CLSFLOWER classifier and
the flow rule API.

Patch #1 adds flow_block_cb_setup_simple(), most drivers do the same thing
         to set up flow blocks, to reduce the number of changes, consolidate
         codebase. Use _simple() postfix as requested by Jakub Kicinski.
         This new function resides in net/core/flow_offload.c

Patch #2 renames TC_BLOCK_{UN}BIND to FLOW_BLOCK_{UN}BIND.

Patch #3 renames TCF_BLOCK_BINDER_TYPE_* to FLOW_BLOCK_BINDER_TYPE_*.

Patch #4 adds flow_block_cb_alloc() and flow_block_cb_free() helper
         functions, this is the first patch of the flow block API.

Patch #5 adds the helper to deal with list operations in the flow block API.
         This includes flow_block_cb_lookup(), flow_block_cb_add() and
	 flow_block_cb_remove().

Patch #6 adds flow_block_cb_priv(), flow_block_cb_incref() and
         flow_block_cb_decref() which completes the flow block API.

Patch #7 updates the cls_api to use the flow block API from the new
         tcf_block_setup(). This infrastructure transports these objects
         via list (through the tc_block_offload object) back to the core
	 for registration.

            CLS_API                           DRIVER
        TC_SETUP_BLOCK    ---------->  setup flow_block_cb object &
                                 it adds object to flow_block_offload->cb_list
                                                |
            CLS_API     <-----------------------'
           registers                     list with flow blocks
         flow_block_cb &                   travels back to
       calls ->reoffload               the core for registration

         drivers allocate and sets up (configure the blocks), then
	 registration happens from the core (cls_api and netfilter).

Patch #8 updates drivers to use the flow block API.

Patch #9 removes the tcf block callback API, which is replaced by the
         flow block API.

Patch #10 adds the flow_block_cb_is_busy() helper to check if the block
	  is already used by a subsystem. This helper is invoked from
	  drivers. Once drivers are updated to support for multiple
	  subsystems, they can remove this check.

Patch #11 rename tc structure and definitions for the block bind/unbind
	  path.

Patch #12 introduces basic netfilter hardware offload infrastructure
          for the ingress chain. This includes 5-tuple exact matching
          and accept / drop rule actions. Only basechains are supported
          at this stage, no .reoffload callback is implemented either.
          Default policy to "accept" is only supported for now.

        table netdev filter {
                chain ingress {
                        type filter hook ingress device eth0 priority 0; flags offload;

                        ip daddr 192.168.0.10 tcp dport 22 drop
                }
        }

This patchset reuses the existing tcf block callback API and it places it
in the flow block callback API in net/core/flow_offload.c.

This series aims to address Jakub and Jiri's feedback, please see specific
patches in this batch for changelog in this v4.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2bb295f3 c9626a2c
Loading
Loading
Loading
Loading
+7 −20
Original line number Diff line number Diff line
@@ -9907,32 +9907,19 @@ static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
	}
}

static int bnxt_setup_tc_block(struct net_device *dev,
			       struct tc_block_offload *f)
{
	struct bnxt *bp = netdev_priv(dev);

	if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
		return -EOPNOTSUPP;

	switch (f->command) {
	case TC_BLOCK_BIND:
		return tcf_block_cb_register(f->block, bnxt_setup_tc_block_cb,
					     bp, bp, f->extack);
	case TC_BLOCK_UNBIND:
		tcf_block_cb_unregister(f->block, bnxt_setup_tc_block_cb, bp);
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}
static LIST_HEAD(bnxt_block_cb_list);

static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
			 void *type_data)
{
	struct bnxt *bp = netdev_priv(dev);

	switch (type) {
	case TC_SETUP_BLOCK:
		return bnxt_setup_tc_block(dev, type_data);
		return flow_block_cb_setup_simple(type_data,
						  &bnxt_block_cb_list,
						  bnxt_setup_tc_block_cb,
						  bp, bp, true);
	case TC_SETUP_QDISC_MQPRIO: {
		struct tc_mqprio_qopt *mqprio = type_data;

+9 −9
Original line number Diff line number Diff line
@@ -170,10 +170,10 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
}

static int bnxt_tc_parse_flow(struct bnxt *bp,
			      struct tc_cls_flower_offload *tc_flow_cmd,
			      struct flow_cls_offload *tc_flow_cmd,
			      struct bnxt_tc_flow *flow)
{
	struct flow_rule *rule = tc_cls_flower_offload_flow_rule(tc_flow_cmd);
	struct flow_rule *rule = flow_cls_offload_flow_rule(tc_flow_cmd);
	struct flow_dissector *dissector = rule->match.dissector;

	/* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */
@@ -1262,7 +1262,7 @@ static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow,
 * The hash-tables are already protected by the rhashtable API.
 */
static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
			    struct tc_cls_flower_offload *tc_flow_cmd)
			    struct flow_cls_offload *tc_flow_cmd)
{
	struct bnxt_tc_flow_node *new_node, *old_node;
	struct bnxt_tc_info *tc_info = bp->tc_info;
@@ -1348,7 +1348,7 @@ done:
}

static int bnxt_tc_del_flow(struct bnxt *bp,
			    struct tc_cls_flower_offload *tc_flow_cmd)
			    struct flow_cls_offload *tc_flow_cmd)
{
	struct bnxt_tc_info *tc_info = bp->tc_info;
	struct bnxt_tc_flow_node *flow_node;
@@ -1363,7 +1363,7 @@ static int bnxt_tc_del_flow(struct bnxt *bp,
}

static int bnxt_tc_get_flow_stats(struct bnxt *bp,
				  struct tc_cls_flower_offload *tc_flow_cmd)
				  struct flow_cls_offload *tc_flow_cmd)
{
	struct bnxt_tc_flow_stats stats, *curr_stats, *prev_stats;
	struct bnxt_tc_info *tc_info = bp->tc_info;
@@ -1585,14 +1585,14 @@ void bnxt_tc_flow_stats_work(struct bnxt *bp)
}

int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
			 struct tc_cls_flower_offload *cls_flower)
			 struct flow_cls_offload *cls_flower)
{
	switch (cls_flower->command) {
	case TC_CLSFLOWER_REPLACE:
	case FLOW_CLS_REPLACE:
		return bnxt_tc_add_flow(bp, src_fid, cls_flower);
	case TC_CLSFLOWER_DESTROY:
	case FLOW_CLS_DESTROY:
		return bnxt_tc_del_flow(bp, cls_flower);
	case TC_CLSFLOWER_STATS:
	case FLOW_CLS_STATS:
		return bnxt_tc_get_flow_stats(bp, cls_flower);
	default:
		return -EOPNOTSUPP;
+2 −2
Original line number Diff line number Diff line
@@ -196,7 +196,7 @@ struct bnxt_tc_flow_node {
};

int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
			 struct tc_cls_flower_offload *cls_flower);
			 struct flow_cls_offload *cls_flower);
int bnxt_init_tc(struct bnxt *bp);
void bnxt_shutdown_tc(struct bnxt *bp);
void bnxt_tc_flow_stats_work(struct bnxt *bp);
@@ -209,7 +209,7 @@ static inline bool bnxt_tc_flower_enabled(struct bnxt *bp)
#else /* CONFIG_BNXT_FLOWER_OFFLOAD */

static inline int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid,
				       struct tc_cls_flower_offload *cls_flower)
				       struct flow_cls_offload *cls_flower)
{
	return -EOPNOTSUPP;
}
+7 −22
Original line number Diff line number Diff line
@@ -161,34 +161,19 @@ static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type,
	}
}

static int bnxt_vf_rep_setup_tc_block(struct net_device *dev,
				      struct tc_block_offload *f)
{
	struct bnxt_vf_rep *vf_rep = netdev_priv(dev);

	if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
		return -EOPNOTSUPP;

	switch (f->command) {
	case TC_BLOCK_BIND:
		return tcf_block_cb_register(f->block,
					     bnxt_vf_rep_setup_tc_block_cb,
					     vf_rep, vf_rep, f->extack);
	case TC_BLOCK_UNBIND:
		tcf_block_cb_unregister(f->block,
					bnxt_vf_rep_setup_tc_block_cb, vf_rep);
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}
static LIST_HEAD(bnxt_vf_block_cb_list);

static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
				void *type_data)
{
	struct bnxt_vf_rep *vf_rep = netdev_priv(dev);

	switch (type) {
	case TC_SETUP_BLOCK:
		return bnxt_vf_rep_setup_tc_block(dev, type_data);
		return flow_block_cb_setup_simple(type_data,
						  &bnxt_vf_block_cb_list,
						  bnxt_vf_rep_setup_tc_block_cb,
						  vf_rep, vf_rep, true);
	default:
		return -EOPNOTSUPP;
	}
+11 −24
Original line number Diff line number Diff line
@@ -3135,14 +3135,14 @@ static int cxgb_set_tx_maxrate(struct net_device *dev, int index, u32 rate)
}

static int cxgb_setup_tc_flower(struct net_device *dev,
				struct tc_cls_flower_offload *cls_flower)
				struct flow_cls_offload *cls_flower)
{
	switch (cls_flower->command) {
	case TC_CLSFLOWER_REPLACE:
	case FLOW_CLS_REPLACE:
		return cxgb4_tc_flower_replace(dev, cls_flower);
	case TC_CLSFLOWER_DESTROY:
	case FLOW_CLS_DESTROY:
		return cxgb4_tc_flower_destroy(dev, cls_flower);
	case TC_CLSFLOWER_STATS:
	case FLOW_CLS_STATS:
		return cxgb4_tc_flower_stats(dev, cls_flower);
	default:
		return -EOPNOTSUPP;
@@ -3190,32 +3190,19 @@ static int cxgb_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
	}
}

static int cxgb_setup_tc_block(struct net_device *dev,
			       struct tc_block_offload *f)
{
	struct port_info *pi = netdev2pinfo(dev);

	if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
		return -EOPNOTSUPP;

	switch (f->command) {
	case TC_BLOCK_BIND:
		return tcf_block_cb_register(f->block, cxgb_setup_tc_block_cb,
					     pi, dev, f->extack);
	case TC_BLOCK_UNBIND:
		tcf_block_cb_unregister(f->block, cxgb_setup_tc_block_cb, pi);
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}
static LIST_HEAD(cxgb_block_cb_list);

static int cxgb_setup_tc(struct net_device *dev, enum tc_setup_type type,
			 void *type_data)
{
	struct port_info *pi = netdev2pinfo(dev);

	switch (type) {
	case TC_SETUP_BLOCK:
		return cxgb_setup_tc_block(dev, type_data);
		return flow_block_cb_setup_simple(type_data,
						  &cxgb_block_cb_list,
						  cxgb_setup_tc_block_cb,
						  pi, dev, true);
	default:
		return -EOPNOTSUPP;
	}
Loading