mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-19 07:27:50 +00:00
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: Sergey Popovich <popovich_sergei@mail.ua> Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
This commit is contained in:
parent
7ffea37957
commit
bec810d973
@ -92,17 +92,6 @@ struct ip_set_ext_type {
|
|||||||
|
|
||||||
extern const struct ip_set_ext_type ip_set_extensions[];
|
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 {
|
struct ip_set_counter {
|
||||||
atomic64_t bytes;
|
atomic64_t bytes;
|
||||||
atomic64_t packets;
|
atomic64_t packets;
|
||||||
@ -122,6 +111,15 @@ struct ip_set_skbinfo {
|
|||||||
u32 skbmarkmask;
|
u32 skbmarkmask;
|
||||||
u32 skbprio;
|
u32 skbprio;
|
||||||
u16 skbqueue;
|
u16 skbqueue;
|
||||||
|
u16 __pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip_set_ext {
|
||||||
|
struct ip_set_skbinfo skbinfo;
|
||||||
|
u64 packets;
|
||||||
|
u64 bytes;
|
||||||
|
char *comment;
|
||||||
|
u32 timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ip_set;
|
struct ip_set;
|
||||||
@ -360,10 +358,7 @@ ip_set_get_skbinfo(struct ip_set_skbinfo *skbinfo,
|
|||||||
const struct ip_set_ext *ext,
|
const struct ip_set_ext *ext,
|
||||||
struct ip_set_ext *mext, u32 flags)
|
struct ip_set_ext *mext, u32 flags)
|
||||||
{
|
{
|
||||||
mext->skbmark = skbinfo->skbmark;
|
mext->skbinfo = *skbinfo;
|
||||||
mext->skbmarkmask = skbinfo->skbmarkmask;
|
|
||||||
mext->skbprio = skbinfo->skbprio;
|
|
||||||
mext->skbqueue = skbinfo->skbqueue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
@ -387,10 +382,7 @@ static inline void
|
|||||||
ip_set_init_skbinfo(struct ip_set_skbinfo *skbinfo,
|
ip_set_init_skbinfo(struct ip_set_skbinfo *skbinfo,
|
||||||
const struct ip_set_ext *ext)
|
const struct ip_set_ext *ext)
|
||||||
{
|
{
|
||||||
skbinfo->skbmark = ext->skbmark;
|
*skbinfo = ext->skbinfo;
|
||||||
skbinfo->skbmarkmask = ext->skbmarkmask;
|
|
||||||
skbinfo->skbprio = ext->skbprio;
|
|
||||||
skbinfo->skbqueue = ext->skbqueue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Netlink CB args */
|
/* Netlink CB args */
|
||||||
|
@ -426,20 +426,20 @@ ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
|
|||||||
if (!SET_WITH_SKBINFO(set))
|
if (!SET_WITH_SKBINFO(set))
|
||||||
return -IPSET_ERR_SKBINFO;
|
return -IPSET_ERR_SKBINFO;
|
||||||
fullmark = be64_to_cpu(nla_get_be64(tb[IPSET_ATTR_SKBMARK]));
|
fullmark = be64_to_cpu(nla_get_be64(tb[IPSET_ATTR_SKBMARK]));
|
||||||
ext->skbmark = fullmark >> 32;
|
ext->skbinfo.skbmark = fullmark >> 32;
|
||||||
ext->skbmarkmask = fullmark & 0xffffffff;
|
ext->skbinfo.skbmarkmask = fullmark & 0xffffffff;
|
||||||
}
|
}
|
||||||
if (tb[IPSET_ATTR_SKBPRIO]) {
|
if (tb[IPSET_ATTR_SKBPRIO]) {
|
||||||
if (!SET_WITH_SKBINFO(set))
|
if (!SET_WITH_SKBINFO(set))
|
||||||
return -IPSET_ERR_SKBINFO;
|
return -IPSET_ERR_SKBINFO;
|
||||||
ext->skbprio = be32_to_cpu(nla_get_be32(
|
ext->skbinfo.skbprio =
|
||||||
tb[IPSET_ATTR_SKBPRIO]));
|
be32_to_cpu(nla_get_be32(tb[IPSET_ATTR_SKBPRIO]));
|
||||||
}
|
}
|
||||||
if (tb[IPSET_ATTR_SKBQUEUE]) {
|
if (tb[IPSET_ATTR_SKBQUEUE]) {
|
||||||
if (!SET_WITH_SKBINFO(set))
|
if (!SET_WITH_SKBINFO(set))
|
||||||
return -IPSET_ERR_SKBINFO;
|
return -IPSET_ERR_SKBINFO;
|
||||||
ext->skbqueue = be16_to_cpu(nla_get_be16(
|
ext->skbinfo.skbqueue =
|
||||||
tb[IPSET_ATTR_SKBQUEUE]));
|
be16_to_cpu(nla_get_be16(tb[IPSET_ATTR_SKBQUEUE]));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -423,6 +423,8 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
|
|
||||||
/* Revision 3 target */
|
/* Revision 3 target */
|
||||||
|
|
||||||
|
#define MOPT(opt, member) ((opt).ext.skbinfo.member)
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
|
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)
|
if (!ret)
|
||||||
return XT_CONTINUE;
|
return XT_CONTINUE;
|
||||||
if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBMARK)
|
if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBMARK)
|
||||||
skb->mark = (skb->mark & ~(map_opt.ext.skbmarkmask))
|
skb->mark = (skb->mark & ~MOPT(map_opt,skbmarkmask))
|
||||||
^ (map_opt.ext.skbmark);
|
^ MOPT(map_opt, skbmark);
|
||||||
if (map_opt.cmdflags & IPSET_FLAG_MAP_SKBPRIO)
|
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) &&
|
if ((map_opt.cmdflags & IPSET_FLAG_MAP_SKBQUEUE) &&
|
||||||
skb->dev &&
|
skb->dev &&
|
||||||
skb->dev->real_num_tx_queues > map_opt.ext.skbqueue)
|
skb->dev->real_num_tx_queues > MOPT(map_opt, skbqueue))
|
||||||
skb_set_queue_mapping(skb, map_opt.ext.skbqueue);
|
skb_set_queue_mapping(skb, MOPT(map_opt, skbqueue));
|
||||||
}
|
}
|
||||||
return XT_CONTINUE;
|
return XT_CONTINUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user