All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jamal Hadi Salim <jhs@mojatatu.com>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: davem@davemloft.net, netdev@vger.kernel.org,
	daniel@iogearbox.net, xiyou.wangcong@gmail.com
Subject: Re: [PATCH v3 net-next 1/1] net_sched: Introduce skbmod action
Date: Mon, 29 Aug 2016 07:35:46 -0400	[thread overview]
Message-ID: <b117fac2-c73f-2d42-3843-52f9717224d9@mojatatu.com> (raw)
In-Reply-To: <b075631d-92cc-d016-3786-aaacb3d5c13a@mojatatu.com>

[-- Attachment #1: Type: text/plain, Size: 617 bytes --]

On 16-08-29 06:38 AM, Jamal Hadi Salim wrote:
> Let me see if i can
> try something. Trickery with RCU is not one of my virtues -
> so i may get it wrong but hope you can comment.

Something like attached? Compile tested.
I tried to emulate gact - but greping around I havent
seen sample code which uses  rcu_read_un/lock + synchronize_rcu
this way
[so be gentle if i got it wrong ;->]

I am not sure where Cong is going but probably introducing
a rcu head in each policy will allow to swap and free old one
with call_rcu may be a better approach. The cost may come in
slowing down replace operations.

cheers,
jamal

[-- Attachment #2: skbmod-rcu-maybe --]
[-- Type: text/plain, Size: 2894 bytes --]


static int tcf_skbmod_run(struct sk_buff *skb, const struct tc_action *a,
			  struct tcf_result *res)
{
	struct tcf_skbmod *d = to_skbmod(a);
	int action = READ_ONCE(d->tcf_action);
	u64 flags = READ_ONCE(d->flags);

	tcf_lastuse_update(&d->tcf_tm);
	bstats_cpu_update(this_cpu_ptr(d->common.cpu_bstats), skb);
	if (unlikely(action == TC_ACT_SHOT)) {
		qstats_drop_inc(this_cpu_ptr(d->common.cpu_qstats));
		return action;
	}

	flags = READ_ONCE(d->flags);
	rcu_read_lock();
	if (flags & SKBMOD_F_DMAC)
		ether_addr_copy(eth_hdr(skb)->h_dest, d->eth_dst);
	if (flags & SKBMOD_F_SMAC)
		ether_addr_copy(eth_hdr(skb)->h_source, d->eth_src);
	if (flags & SKBMOD_F_ETYPE)
		eth_hdr(skb)->h_proto = d->eth_type;
	if (flags & SKBMOD_F_SWAPMAC) {
		u8 tmpaddr[ETH_ALEN];
		/*XXX: I am sure we can come up with something more efficient */
		ether_addr_copy(tmpaddr, eth_hdr(skb)->h_dest);
		ether_addr_copy(eth_hdr(skb)->h_dest, eth_hdr(skb)->h_source);
		ether_addr_copy(eth_hdr(skb)->h_source, tmpaddr);
	}
	rcu_read_unlock();

	return action;
}

static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
			   struct nlattr *est, struct tc_action **a,
			   int ovr, int bind)
{
	struct tc_action_net *tn = net_generic(net, skbmod_net_id);
	struct nlattr *tb[TCA_SKBMOD_MAX + 1];
	struct tc_skbmod *parm;
	struct tcf_skbmod *d;
	u32 lflags = 0;
	u8 *daddr = NULL;
	u8 *saddr = NULL;
	u16 eth_type = 0;

	bool exists = false;
	int ret = 0, err;

	if (nla == NULL)
		return -EINVAL;

	err = nla_parse_nested(tb, TCA_SKBMOD_MAX, nla, skbmod_policy);
	if (err < 0)
		return err;

	if (tb[TCA_SKBMOD_PARMS] == NULL)
		return -EINVAL;

	if (tb[TCA_SKBMOD_DMAC]) {
		daddr = nla_data(tb[TCA_SKBMOD_DMAC]);
		lflags |= SKBMOD_F_DMAC;
	}

	if (tb[TCA_SKBMOD_SMAC]) {
		saddr = nla_data(tb[TCA_SKBMOD_SMAC]);
		lflags |= SKBMOD_F_SMAC;
	}

	if (tb[TCA_SKBMOD_ETYPE]) {
		eth_type = nla_get_u16(tb[TCA_SKBMOD_ETYPE]);
		lflags |= SKBMOD_F_ETYPE;
	}

	parm = nla_data(tb[TCA_SKBMOD_PARMS]);

	if (parm->flags & SKBMOD_F_SWAPMAC)
		lflags = SKBMOD_F_SWAPMAC;

	exists = tcf_hash_check(tn, parm->index, a, bind);
	if (exists && bind)
		return 0;

	if (!lflags) {
		return -EINVAL;
	}

	if (!exists) {
		ret = tcf_hash_create(tn, parm->index, est, a,
				      &act_skbmod_ops, bind, false);
		if (ret)
			return ret;

		d = to_skbmod(*a);
		ret = ACT_P_CREATED;
	} else {
		d = to_skbmod(*a);
		tcf_hash_release(*a, bind);
		if (!ovr)
			return -EEXIST;
	}

	ASSERT_RTNL();
	d->flags = lflags;
	d->tcf_action = parm->action;

	if (ovr)
		spin_lock_bh(&d->tcf_lock);

	if (lflags & SKBMOD_F_DMAC)
		ether_addr_copy(d->eth_dst, daddr);
	if (lflags & SKBMOD_F_SMAC)
		ether_addr_copy(d->eth_src, saddr);
	if (lflags & SKBMOD_F_ETYPE)
		d->eth_type = htons(eth_type);


	if (ovr) {
		spin_unlock_bh(&d->tcf_lock);
		synchronize_rcu();
	}

	if (ret == ACT_P_CREATED)
		tcf_hash_insert(tn, *a);
	return ret;
}


  parent reply	other threads:[~2016-08-29 11:42 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-28 12:19 [PATCH v3 net-next 1/1] net_sched: Introduce skbmod action Jamal Hadi Salim
2016-08-28 14:48 ` Alexei Starovoitov
2016-08-29 10:35   ` Jamal Hadi Salim
2016-08-28 16:07 ` Eric Dumazet
2016-08-29  5:10   ` Cong Wang
2016-08-29 13:27     ` Eric Dumazet
2016-08-29 10:38   ` Jamal Hadi Salim
2016-08-29 11:00     ` Daniel Borkmann
2016-08-29 11:40       ` Jamal Hadi Salim
2016-08-29 11:55         ` Jamal Hadi Salim
2016-08-29 11:35     ` Jamal Hadi Salim [this message]
2016-08-29 18:20       ` Eric Dumazet
2016-08-30 11:12         ` Jamal Hadi Salim
2016-08-30 11:57           ` Jamal Hadi Salim
2016-08-30 12:35             ` Eric Dumazet
2016-09-06 12:03               ` Jamal Hadi Salim
2016-08-30 12:44             ` Eric Dumazet
2016-09-06 12:08               ` Jamal Hadi Salim
2016-09-06 14:25                 ` Eric Dumazet
2016-09-08 10:38                   ` Jamal Hadi Salim
2016-09-08 16:02                     ` Eric Dumazet
2016-09-08 16:11                       ` Eric Dumazet
2016-09-09 12:33                         ` Jamal Hadi Salim
2016-08-30 12:20           ` Eric Dumazet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b117fac2-c73f-2d42-3843-52f9717224d9@mojatatu.com \
    --to=jhs@mojatatu.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.