Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'net-sched-fixes'



Jamal Hadi Salim says:

====================
Some actions were broken in allowing for late binding of actions.
Late binding workflow is as follows:
a) create an action and provide all necessary parameters for it
Optionally provide an index or let the kernel give you one.
Example:
sudo tc actions add action police rate 1kbit burst 90k drop index 1

b) later on bind to the pre-created action from a filter definition
by merely specifying the index.
Example:
sudo tc filter add dev lo parent ffff: protocol ip prio 8 \
u32 match ip src 127.0.0.8/32 flowid 1:8 action police index 1
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 84a527a4 4e8c8615
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -423,7 +423,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
	u16 ife_type = 0;
	u8 *daddr = NULL;
	u8 *saddr = NULL;
	int ret = 0;
	int ret = 0, exists = 0;
	int err;

	err = nla_parse_nested(tb, TCA_IFE_MAX, nla, ife_policy);
@@ -435,25 +435,29 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,

	parm = nla_data(tb[TCA_IFE_PARMS]);

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

	if (parm->flags & IFE_ENCODE) {
		/* Until we get issued the ethertype, we cant have
		 * a default..
		**/
		if (!tb[TCA_IFE_TYPE]) {
			if (exists)
				tcf_hash_release(a, bind);
			pr_info("You MUST pass etherype for encoding\n");
			return -EINVAL;
		}
	}

	if (!tcf_hash_check(tn, parm->index, a, bind)) {
	if (!exists) {
		ret = tcf_hash_create(tn, parm->index, est, a, sizeof(*ife),
				      bind, false);
		if (ret)
			return ret;
		ret = ACT_P_CREATED;
	} else {
		if (bind)	/* dont override defaults */
			return 0;
		tcf_hash_release(a, bind);
		if (!ovr)
			return -EEXIST;
@@ -495,6 +499,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
				       NULL);
		if (err) {
metadata_parse_err:
			if (exists)
				tcf_hash_release(a, bind);
			if (ret == ACT_P_CREATED)
				_tcf_ife_cleanup(a, bind);

+12 −7
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
	struct tcf_ipt *ipt;
	struct xt_entry_target *td, *t;
	char *tname;
	int ret = 0, err;
	int ret = 0, err, exists = 0;
	u32 hook = 0;
	u32 index = 0;

@@ -107,18 +107,23 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
	if (err < 0)
		return err;

	if (tb[TCA_IPT_HOOK] == NULL)
		return -EINVAL;
	if (tb[TCA_IPT_TARG] == NULL)
	if (tb[TCA_IPT_INDEX] != NULL)
		index = nla_get_u32(tb[TCA_IPT_INDEX]);

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

	if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) {
		if (exists)
			tcf_hash_release(a, bind);
		return -EINVAL;
	}

	td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
	if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size)
		return -EINVAL;

	if (tb[TCA_IPT_INDEX] != NULL)
		index = nla_get_u32(tb[TCA_IPT_INDEX]);

	if (!tcf_hash_check(tn, index, a, bind)) {
		ret = tcf_hash_create(tn, index, est, a, sizeof(*ipt), bind,
				      false);
+13 −6
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
	struct tc_mirred *parm;
	struct tcf_mirred *m;
	struct net_device *dev;
	int ret, ok_push = 0;
	int ret, ok_push = 0, exists = 0;

	if (nla == NULL)
		return -EINVAL;
@@ -71,17 +71,27 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
	if (tb[TCA_MIRRED_PARMS] == NULL)
		return -EINVAL;
	parm = nla_data(tb[TCA_MIRRED_PARMS]);

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

	switch (parm->eaction) {
	case TCA_EGRESS_MIRROR:
	case TCA_EGRESS_REDIR:
		break;
	default:
		if (exists)
			tcf_hash_release(a, bind);
		return -EINVAL;
	}
	if (parm->ifindex) {
		dev = __dev_get_by_index(net, parm->ifindex);
		if (dev == NULL)
		if (dev == NULL) {
			if (exists)
				tcf_hash_release(a, bind);
			return -ENODEV;
		}
		switch (dev->type) {
		case ARPHRD_TUNNEL:
		case ARPHRD_TUNNEL6:
@@ -99,7 +109,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
		dev = NULL;
	}

	if (!tcf_hash_check(tn, parm->index, a, bind)) {
	if (!exists) {
		if (dev == NULL)
			return -EINVAL;
		ret = tcf_hash_create(tn, parm->index, est, a,
@@ -108,9 +118,6 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
			return ret;
		ret = ACT_P_CREATED;
	} else {
		if (bind)
			return 0;

		tcf_hash_release(a, bind);
		if (!ovr)
			return -EEXIST;
+12 −6
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
	struct tc_defact *parm;
	struct tcf_defact *d;
	char *defdata;
	int ret = 0, err;
	int ret = 0, err, exists = 0;

	if (nla == NULL)
		return -EINVAL;
@@ -99,13 +99,21 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
	if (tb[TCA_DEF_PARMS] == NULL)
		return -EINVAL;

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

	parm = nla_data(tb[TCA_DEF_PARMS]);
	exists = tcf_hash_check(tn, parm->index, a, bind);
	if (exists && bind)
		return 0;

	if (tb[TCA_DEF_DATA] == NULL) {
		if (exists)
			tcf_hash_release(a, bind);
		return -EINVAL;
	}

	defdata = nla_data(tb[TCA_DEF_DATA]);

	if (!tcf_hash_check(tn, parm->index, a, bind)) {
	if (!exists) {
		ret = tcf_hash_create(tn, parm->index, est, a,
				      sizeof(*d), bind, false);
		if (ret)
@@ -122,8 +130,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
	} else {
		d = to_defact(a);

		if (bind)
			return 0;
		tcf_hash_release(a, bind);
		if (!ovr)
			return -EEXIST;
+11 −7
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
	struct tcf_skbedit *d;
	u32 flags = 0, *priority = NULL, *mark = NULL;
	u16 *queue_mapping = NULL;
	int ret = 0, err;
	int ret = 0, err, exists = 0;

	if (nla == NULL)
		return -EINVAL;
@@ -96,12 +96,18 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
		mark = nla_data(tb[TCA_SKBEDIT_MARK]);
	}

	if (!flags)
		return -EINVAL;

	parm = nla_data(tb[TCA_SKBEDIT_PARMS]);

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

	if (!flags) {
		tcf_hash_release(a, bind);
		return -EINVAL;
	}

	if (!exists) {
		ret = tcf_hash_create(tn, parm->index, est, a,
				      sizeof(*d), bind, false);
		if (ret)
@@ -111,8 +117,6 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
		ret = ACT_P_CREATED;
	} else {
		d = to_skbedit(a);
		if (bind)
			return 0;
		tcf_hash_release(a, bind);
		if (!ovr)
			return -EEXIST;
Loading