summaryrefslogtreecommitdiffstats
path: root/kernel/linux/net/bridge/netfilter/ebt_mark_m.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/linux/net/bridge/netfilter/ebt_mark_m.c')
-rw-r--r--kernel/linux/net/bridge/netfilter/ebt_mark_m.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/kernel/linux/net/bridge/netfilter/ebt_mark_m.c b/kernel/linux/net/bridge/netfilter/ebt_mark_m.c
index 4972b09..d3f0119 100644
--- a/kernel/linux/net/bridge/netfilter/ebt_mark_m.c
+++ b/kernel/linux/net/bridge/netfilter/ebt_mark_m.c
@@ -13,19 +13,27 @@
#include <linux/module.h>
static int ebt_filter_mark(const struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- const void *data,
- unsigned int datalen, const struct ebt_counter *c)
+ const struct net_device *in, const struct net_device *out, const void *data,
+ unsigned int datalen, const struct ebt_counter *c)
{
struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+ if (info->bitmask & EBT_MARK_OR)
+ return !(!!(skb->nfmark & info->mask) ^ info->invert);
return !(((skb->nfmark & info->mask) == info->mark) ^ info->invert);
}
static int ebt_mark_check(const char *tablename, unsigned int hookmask,
const struct ebt_entry *e, void *data, unsigned int datalen)
{
+ struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
+
+ if (info->bitmask & ~EBT_MARK_MASK)
+ return -EINVAL;
+ if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
+ return -EINVAL;
+ if (!info->bitmask)
+ return -EINVAL;
if (datalen != sizeof(struct ebt_mark_m_info)) {
return -EINVAL;
}