aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/netfilter/ebt_mark.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 08:26:19 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 08:26:19 -0700
commitd002ec481c24f325ed6cfcb7810d317c015dd1b5 (patch)
tree71fbdce6aab6ffb5f8590e7ddde7c095a7fa31ab /net/bridge/netfilter/ebt_mark.c
parent5a96c5d0c58ead9a0ece03ffe1c116dea6dafe9c (diff)
parent0a69452cb45add0841c2bc1e75c25f6bd4f1d8d9 (diff)
downloadlinux-d002ec481c24f325ed6cfcb7810d317c015dd1b5.tar.gz
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [XFRM]: BEET mode [TCP]: Kill warning in tcp_clean_rtx_queue(). [NET_SCHED]: Remove old estimator implementation [ATM]: [zatm] always *pcr in alloc_shaper() [ATM]: [ambassador] Change the return type to reflect reality [ATM]: kmalloc to kzalloc patches for drivers/atm [TIPC]: fix printk warning [XFRM]: Clearing xfrm_policy_count[] to zero during flush is incorrect. [XFRM] STATE: Use destination address for src hash. [NEIGH]: always use hash_mask under tbl lock [UDP]: Fix MSG_PROBE crash [UDP6]: Fix flowi clobbering [NET_SCHED]: Revert "HTB: fix incorrect use of RB_EMPTY_NODE" [NETFILTER]: ebt_mark: add or/and/xor action support to mark target [NETFILTER]: ipt_REJECT: remove largely duplicate route_reverse function [NETFILTER]: Honour source routing for LVS-NAT [NETFILTER]: add type parameter to ip_route_me_harder [NETFILTER]: Kconfig: fix xt_physdev dependencies
Diffstat (limited to 'net/bridge/netfilter/ebt_mark.c')
-rw-r--r--net/bridge/netfilter/ebt_mark.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 770c0df972a3bf..b54306a934e581 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -22,24 +22,37 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
const void *data, unsigned int datalen)
{
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+ int action = info->target & -16;
- if ((*pskb)->nfmark != info->mark)
+ if (action == MARK_SET_VALUE)
(*pskb)->nfmark = info->mark;
+ else if (action == MARK_OR_VALUE)
+ (*pskb)->nfmark |= info->mark;
+ else if (action == MARK_AND_VALUE)
+ (*pskb)->nfmark &= info->mark;
+ else
+ (*pskb)->nfmark ^= info->mark;
- return info->target;
+ return info->target | -16;
}
static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
+ int tmp;
if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
return -EINVAL;
- if (BASE_CHAIN && info->target == EBT_RETURN)
+ tmp = info->target | -16;
+ if (BASE_CHAIN && tmp == EBT_RETURN)
return -EINVAL;
CLEAR_BASE_CHAIN_BIT;
- if (INVALID_TARGET)
+ if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
+ return -EINVAL;
+ tmp = info->target & -16;
+ if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
+ tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
return -EINVAL;
return 0;
}