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

Commit bec810d9 authored by Jozsef Kadlecsik's avatar Jozsef Kadlecsik
Browse files

netfilter: ipset: Improve skbinfo get/init helpers



Use struct ip_set_skbinfo in struct ip_set_ext instead of open
coded fields and assign structure members in get/init helpers
instead of copying members one by one. Explicitly note that
struct ip_set_skbinfo must be padded to prevent non-aligned
access in the extension blob.

Ported from a patch proposed by Sergey Popovich <popovich_sergei@mail.ua>.

Suggested-by: default avatarSergey Popovich <popovich_sergei@mail.ua>
Signed-off-by: default avatarJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
parent 7ffea379
Loading
Loading
Loading
Loading
+11 −19
Original line number Diff line number Diff line
@@ -92,17 +92,6 @@ struct ip_set_ext_type {

extern const struct ip_set_ext_type ip_set_extensions[];

struct ip_set_ext {
	u64 packets;
	u64 bytes;
	u32 timeout;
	u32 skbmark;
	u32 skbmarkmask;
	u32 skbprio;
	u16 skbqueue;
	char *comment;
};

struct ip_set_counter {
	atomic64_t bytes;
	atomic64_t packets;
@@ -122,6 +111,15 @@ struct ip_set_skbinfo {
	u32 skbmarkmask;
	u32 skbprio;
	u16 skbqueue;
	u16 __pad;
};

struct ip_set_ext {
	struct ip_set_skbinfo skbinfo;
	u64 packets;
	u64 bytes;
	char *comment;
	u32 timeout;
};

struct ip_set;
@@ -360,10 +358,7 @@ ip_set_get_skbinfo(struct ip_set_skbinfo *skbinfo,
		   const struct ip_set_ext *ext,
		   struct ip_set_ext *mext, u32 flags)
{
	mext->skbmark = skbinfo->skbmark;
	mext->skbmarkmask = skbinfo->skbmarkmask;
	mext->skbprio = skbinfo->skbprio;
	mext->skbqueue = skbinfo->skbqueue;
	mext->skbinfo = *skbinfo;
}

static inline bool
@@ -387,10 +382,7 @@ static inline void
ip_set_init_skbinfo(struct ip_set_skbinfo *skbinfo,
		    const struct ip_set_ext *ext)
{
	skbinfo->skbmark = ext->skbmark;
	skbinfo->skbmarkmask = ext->skbmarkmask;
	skbinfo->skbprio = ext->skbprio;
	skbinfo->skbqueue = ext->skbqueue;
	*skbinfo = ext->skbinfo;
}

/* Netlink CB args */
+6 −6
Original line number Diff line number Diff line
@@ -426,20 +426,20 @@ ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
		if (!SET_WITH_SKBINFO(set))
			return -IPSET_ERR_SKBINFO;
		fullmark = be64_to_cpu(nla_get_be64(tb[IPSET_ATTR_SKBMARK]));
		ext->skbmark = fullmark >> 32;
		ext->skbmarkmask = fullmark & 0xffffffff;
		ext->skbinfo.skbmark = fullmark >> 32;
		ext->skbinfo.skbmarkmask = fullmark & 0xffffffff;
	}
	if (tb[IPSET_ATTR_SKBPRIO]) {
		if (!SET_WITH_SKBINFO(set))
			return -IPSET_ERR_SKBINFO;
		ext->skbprio = be32_to_cpu(nla_get_be32(
					    tb[IPSET_ATTR_SKBPRIO]));
		ext->skbinfo.skbprio =
			be32_to_cpu(nla_get_be32(tb[IPSET_ATTR_SKBPRIO]));
	}
	if (tb[IPSET_ATTR_SKBQUEUE]) {
		if (!SET_WITH_SKBINFO(set))
			return -IPSET_ERR_SKBINFO;
		ext->skbqueue = be16_to_cpu(nla_get_be16(
					    tb[IPSET_ATTR_SKBQUEUE]));
		ext->skbinfo.skbqueue =
			be16_to_cpu(nla_get_be16(tb[IPSET_ATTR_SKBQUEUE]));
	}
	return 0;
}
+7 −5
Original line number Diff line number Diff line
@@ -423,6 +423,8 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)

/* Revision 3 target */

#define MOPT(opt, member)	((opt).ext.skbinfo.member)

static unsigned int
set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
{
@@ -453,14 +455,14 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
		if (!ret)
			return XT_CONTINUE;
		if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBMARK)
			skb->mark = (skb->mark & ~(map_opt.ext.skbmarkmask))
				    ^ (map_opt.ext.skbmark);
			skb->mark = (skb->mark & ~MOPT(map_opt,skbmarkmask))
				    ^ MOPT(map_opt, skbmark);
		if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBPRIO)
			skb->priority = map_opt.ext.skbprio;
			skb->priority = MOPT(map_opt, skbprio);
		if ((map_opt.cmdflags & IPSET_FLAG_MAP_SKBQUEUE) &&
		    skb->dev &&
		    skb->dev->real_num_tx_queues > map_opt.ext.skbqueue)
			skb_set_queue_mapping(skb, map_opt.ext.skbqueue);
		    skb->dev->real_num_tx_queues > MOPT(map_opt, skbqueue))
			skb_set_queue_mapping(skb, MOPT(map_opt, skbqueue));
	}
	return XT_CONTINUE;
}