Skip to content
Snippets Groups Projects
Commit 51541436 authored by Oskar Viljasaar's avatar Oskar Viljasaar
Browse files

Import openwrt hack patch 645-netfilter-connmark-introduce-set-dscpmark.patch

parent d0a3a714
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,11 @@ enum {
XT_CONNMARK_RESTORE
};
enum {
XT_CONNMARK_VALUE = (1 << 0),
XT_CONNMARK_DSCP = (1 << 1)
};
enum {
D_SHIFT_LEFT = 0,
D_SHIFT_RIGHT,
......@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 {
__u8 shift_dir, shift_bits, mode;
};
struct xt_connmark_tginfo3 {
__u32 ctmark, ctmask, nfmask;
__u8 shift_dir, shift_bits, mode, func;
};
struct xt_connmark_mtinfo1 {
__u32 mark, mask;
__u8 invert;
......
......@@ -36,12 +36,13 @@ MODULE_ALIAS("ipt_connmark");
MODULE_ALIAS("ip6t_connmark");
static unsigned int
connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
{
enum ip_conntrack_info ctinfo;
u_int32_t new_targetmark;
struct nf_conn *ct;
u_int32_t newmark;
u_int8_t dscp;
ct = nf_ct_get(skb, &ctinfo);
if (ct == NULL)
......@@ -49,12 +50,24 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
switch (info->mode) {
case XT_CONNMARK_SET:
newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
if (info->shift_dir == D_SHIFT_RIGHT)
newmark >>= info->shift_bits;
else
newmark <<= info->shift_bits;
newmark = ct->mark;
if (info->func & XT_CONNMARK_VALUE) {
newmark = (newmark & ~info->ctmask) ^ info->ctmark;
if (info->shift_dir == D_SHIFT_RIGHT)
newmark >>= info->shift_bits;
else
newmark <<= info->shift_bits;
} else if (info->func & XT_CONNMARK_DSCP) {
if (skb->protocol == htons(ETH_P_IP))
dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
else if (skb->protocol == htons(ETH_P_IPV6))
dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
else /* protocol doesn't have diffserv */
break;
newmark = (newmark & ~info->ctmark) |
(info->ctmask | (dscp << info->shift_bits));
}
if (ct->mark != newmark) {
ct->mark = newmark;
nf_conntrack_event_cache(IPCT_MARK, ct);
......@@ -93,20 +106,36 @@ static unsigned int
connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_connmark_tginfo1 *info = par->targinfo;
const struct xt_connmark_tginfo2 info2 = {
const struct xt_connmark_tginfo3 info3 = {
.ctmark = info->ctmark,
.ctmask = info->ctmask,
.nfmask = info->nfmask,
.mode = info->mode,
.func = XT_CONNMARK_VALUE
};
return connmark_tg_shift(skb, &info2);
return connmark_tg_shift(skb, &info3);
}
static unsigned int
connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_connmark_tginfo2 *info = par->targinfo;
const struct xt_connmark_tginfo3 info3 = {
.ctmark = info->ctmark,
.ctmask = info->ctmask,
.nfmask = info->nfmask,
.mode = info->mode,
.func = XT_CONNMARK_VALUE
};
return connmark_tg_shift(skb, &info3);
}
static unsigned int
connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_connmark_tginfo3 *info = par->targinfo;
return connmark_tg_shift(skb, info);
}
......@@ -177,6 +206,16 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
.targetsize = sizeof(struct xt_connmark_tginfo2),
.destroy = connmark_tg_destroy,
.me = THIS_MODULE,
},
{
.name = "CONNMARK",
.revision = 3,
.family = NFPROTO_UNSPEC,
.checkentry = connmark_tg_check,
.target = connmark_tg_v3,
.targetsize = sizeof(struct xt_connmark_tginfo3),
.destroy = connmark_tg_destroy,
.me = THIS_MODULE,
}
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment