summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/linux/include/linux/netfilter_bridge/ebt_mark_m.h4
-rw-r--r--kernel/linux/net/bridge/netfilter/ebt_mark_m.c16
2 files changed, 16 insertions, 4 deletions
diff --git a/kernel/linux/include/linux/netfilter_bridge/ebt_mark_m.h b/kernel/linux/include/linux/netfilter_bridge/ebt_mark_m.h
index 576d33b..b6cb4ed 100644
--- a/kernel/linux/include/linux/netfilter_bridge/ebt_mark_m.h
+++ b/kernel/linux/include/linux/netfilter_bridge/ebt_mark_m.h
@@ -1,10 +1,14 @@
#ifndef __LINUX_BRIDGE_EBT_MARK_M_H
#define __LINUX_BRIDGE_EBT_MARK_M_H
+#define EBT_MARK_AND 0x01
+#define EBT_MARK_OR 0x02
+#define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR)
struct ebt_mark_m_info
{
unsigned long mark, mask;
__u8 invert;
+ __u8 bitmask;
};
#define EBT_MARK_MATCH "mark_m"
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;
}