@@ -37,20 +37,22 @@ MODULE_ALIAS("ip6t_connmark");
static unsigned int
connmark_tg_shift(struct sk_buff *skb,
- const struct xt_connmark_tginfo1 *info,
+ u8 mode, u32 ctmark,
+ u32 ctmask, u32 nfmask,
u8 shift_bits, u8 shift_dir)
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
u_int32_t newmark;
+ u_int32_t new_targetmark;
ct = nf_ct_get(skb, &ctinfo);
if (ct == NULL)
return XT_CONTINUE;
- switch (info->mode) {
+ switch (mode) {
case XT_CONNMARK_SET:
- newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
+ newmark = (ct->mark & ~ctmask) ^ ctmark;
if (shift_dir == D_SHIFT_RIGHT)
newmark >>= shift_bits;
else
@@ -61,24 +63,26 @@ connmark_tg_shift(struct sk_buff *skb,
}
break;
case XT_CONNMARK_SAVE:
- newmark = (ct->mark & ~info->ctmask) ^
- (skb->mark & info->nfmask);
+ new_targetmark = (skb->mark & nfmask);
if (shift_dir == D_SHIFT_RIGHT)
- newmark >>= shift_bits;
+ new_targetmark >>= shift_bits;
else
- newmark <<= shift_bits;
+ new_targetmark <<= shift_bits;
+ newmark = (ct->mark & ~ctmask) ^
+ new_targetmark;
if (ct->mark != newmark) {
ct->mark = newmark;
nf_conntrack_event_cache(IPCT_MARK, ct);
}
break;
case XT_CONNMARK_RESTORE:
- newmark = (skb->mark & ~info->nfmask) ^
- (ct->mark & info->ctmask);
+ new_targetmark = (ct->mark & ctmask);
if (shift_dir == D_SHIFT_RIGHT)
- newmark >>= shift_bits;
+ new_targetmark >>= shift_bits;
else
- newmark <<= shift_bits;
+ new_targetmark <<= shift_bits;
+ newmark = (skb->mark & ~nfmask) ^
+ new_targetmark;
skb->mark = newmark;
break;
}
@@ -90,7 +94,8 @@ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_connmark_tginfo1 *info = par->targinfo;
- return connmark_tg_shift(skb, info, 0, 0);
+ return connmark_tg_shift(skb, info->mode, info->ctmark,
+ info->ctmask, info->nfmask, 0, 0);
}
static unsigned int
@@ -98,7 +103,8 @@ connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_connmark_tginfo2 *info = par->targinfo;
- return connmark_tg_shift(skb, (const struct xt_connmark_tginfo1 *)info,
+ return connmark_tg_shift(skb, info->mode, info->ctmark,
+ info->ctmask, info->nfmask,
info->shift_bits, info->shift_dir);
}