From: Florian Westphal Date: Thu, 19 Dec 2013 17:25:15 +0000 (+0100) Subject: netfilter: ctnetlink: honor CTA_MARK_MASK when setting ctmark X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=534473c6080e01395058445135df29a8eb638c77;p=linux-beck.git netfilter: ctnetlink: honor CTA_MARK_MASK when setting ctmark Useful to only set a particular range of the conntrack mark while leaving exisiting parts of the value alone, e.g. when setting conntrack marks via NFQUEUE. Follows same scheme as MARK/CONNMARK targets, i.e. the mask defines those bits that should be altered. No mask is equal to '~0', ie. the old value is replaced by new one. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 08870b859046..bb322d0beb48 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -2118,8 +2118,16 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) return err; } #if defined(CONFIG_NF_CONNTRACK_MARK) - if (cda[CTA_MARK]) - ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); + if (cda[CTA_MARK]) { + u32 mask = 0, mark, newmark; + if (cda[CTA_MARK_MASK]) + mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK])); + + mark = ntohl(nla_get_be32(cda[CTA_MARK])); + newmark = (ct->mark & mask) ^ mark; + if (newmark != ct->mark) + ct->mark = newmark; + } #endif return 0; }