summaryrefslogtreecommitdiffstats
path: root/kernel/linux2.5/net
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/linux2.5/net')
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/Kconfig20
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/Makefile9
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebt_arp.c45
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebt_ip.c2
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebt_pkttype.c59
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebtable_broute.c15
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebtable_filter.c19
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebtable_nat.c21
-rw-r--r--kernel/linux2.5/net/bridge/netfilter/ebtables.c21
9 files changed, 171 insertions, 40 deletions
diff --git a/kernel/linux2.5/net/bridge/netfilter/Kconfig b/kernel/linux2.5/net/bridge/netfilter/Kconfig
index 0f34466..4b6a1ed 100644
--- a/kernel/linux2.5/net/bridge/netfilter/Kconfig
+++ b/kernel/linux2.5/net/bridge/netfilter/Kconfig
@@ -49,7 +49,7 @@ config BRIDGE_EBT_LOG
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
-config BRIDGE_EBT_IPF
+config BRIDGE_EBT_IP
tristate "ebt: IP filter support"
depends on BRIDGE_NF_EBTABLES
help
@@ -59,7 +59,7 @@ config BRIDGE_EBT_IPF
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
-config BRIDGE_EBT_ARPF
+config BRIDGE_EBT_ARP
tristate "ebt: ARP filter support"
depends on BRIDGE_NF_EBTABLES
help
@@ -69,7 +69,7 @@ config BRIDGE_EBT_ARPF
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
-config BRIDGE_EBT_VLANF
+config BRIDGE_EBT_VLAN
tristate "ebt: 802.1Q VLAN filter support"
depends on BRIDGE_NF_EBTABLES
help
@@ -79,7 +79,7 @@ config BRIDGE_EBT_VLANF
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
-config BRIDGE_EBT_MARKF
+config BRIDGE_EBT_MARK
tristate "ebt: mark filter support"
depends on BRIDGE_NF_EBTABLES
help
@@ -91,6 +91,18 @@ config BRIDGE_EBT_MARKF
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
+config BRIDGE_EBT_PKTTYPE
+ tristate "ebt: packet type filter support"
+ depends on BRIDGE_NF_EBTABLES
+ help
+ This option adds the packet type match, which allows matching on the
+ type of packet based on its Ethernet "class" (as determined by
+ the generic networking code): broadcast, multicast,
+ for this host alone or for another host.
+
+ If you want to compile it as a module, say M here and read
+ <file:Documentation/modules.txt>. If unsure, say `N'.
+
config BRIDGE_EBT_SNAT
tristate "ebt: snat target support"
depends on BRIDGE_NF_EBTABLES
diff --git a/kernel/linux2.5/net/bridge/netfilter/Makefile b/kernel/linux2.5/net/bridge/netfilter/Makefile
index 0989ba8..871252b 100644
--- a/kernel/linux2.5/net/bridge/netfilter/Makefile
+++ b/kernel/linux2.5/net/bridge/netfilter/Makefile
@@ -6,10 +6,11 @@ obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o
obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o
obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o
-obj-$(CONFIG_BRIDGE_EBT_IPF) += ebt_ip.o
-obj-$(CONFIG_BRIDGE_EBT_ARPF) += ebt_arp.o
-obj-$(CONFIG_BRIDGE_EBT_VLANF) += ebt_vlan.o
-obj-$(CONFIG_BRIDGE_EBT_MARKF) += ebt_mark_m.o
+obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o
+obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o
+obj-$(CONFIG_BRIDGE_EBT_VLAN) += ebt_vlan.o
+obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o
+obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o
obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o
obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o
obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebt_arp.c b/kernel/linux2.5/net/bridge/netfilter/ebt_arp.c
index 35d2608..0d1650b 100644
--- a/kernel/linux2.5/net/bridge/netfilter/ebt_arp.c
+++ b/kernel/linux2.5/net/bridge/netfilter/ebt_arp.c
@@ -13,6 +13,7 @@
#include <linux/netfilter_bridge/ebt_arp.h>
#include <linux/if_arp.h>
#include <linux/module.h>
+#include <linux/if_ether.h>
static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *data, unsigned int datalen)
@@ -61,6 +62,50 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
return EBT_NOMATCH;
}
}
+
+ if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC))
+ {
+ uint32_t arp_len = sizeof(struct arphdr) +
+ (2 * (((*skb).nh.arph)->ar_hln)) +
+ (2 * (((*skb).nh.arph)->ar_pln));
+ unsigned char dst[ETH_ALEN];
+ unsigned char src[ETH_ALEN];
+
+ /* Make sure the packet is long enough */
+ if ((((*skb).nh.raw) + arp_len) > (*skb).tail)
+ return EBT_NOMATCH;
+ /* MAC addresses are 6 bytes */
+ if (((*skb).nh.arph)->ar_hln != ETH_ALEN)
+ return EBT_NOMATCH;
+ if (info->bitmask & EBT_ARP_SRC_MAC) {
+ uint8_t verdict, i;
+ memcpy(&src, ((*skb).nh.raw) +
+ sizeof(struct arphdr),
+ ETH_ALEN);
+ verdict = 0;
+ for (i = 0; i < 6; i++)
+ verdict |= (src[i] ^ info->smaddr[i]) &
+ info->smmsk[i];
+ if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
+ return EBT_NOMATCH;
+ }
+
+ if (info->bitmask & EBT_ARP_DST_MAC) {
+ uint8_t verdict, i;
+ memcpy(&dst, ((*skb).nh.raw) +
+ sizeof(struct arphdr) +
+ (((*skb).nh.arph)->ar_hln) +
+ (((*skb).nh.arph)->ar_pln),
+ ETH_ALEN);
+ verdict = 0;
+ for (i = 0; i < 6; i++)
+ verdict |= (dst[i] ^ info->dmaddr[i]) &
+ info->dmmsk[i];
+ if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
+ return EBT_NOMATCH;
+ }
+ }
+
return EBT_MATCH;
}
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebt_ip.c b/kernel/linux2.5/net/bridge/netfilter/ebt_ip.c
index 9f7f6cf..e61899b 100644
--- a/kernel/linux2.5/net/bridge/netfilter/ebt_ip.c
+++ b/kernel/linux2.5/net/bridge/netfilter/ebt_ip.c
@@ -86,7 +86,7 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask,
if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
return -EINVAL;
if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
- if (!(info->bitmask & EBT_IPROTO))
+ if (info->bitmask & EBT_IPROTO)
return -EINVAL;
if (info->protocol != IPPROTO_TCP &&
info->protocol != IPPROTO_UDP)
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebt_pkttype.c b/kernel/linux2.5/net/bridge/netfilter/ebt_pkttype.c
new file mode 100644
index 0000000..f6458ad
--- /dev/null
+++ b/kernel/linux2.5/net/bridge/netfilter/ebt_pkttype.c
@@ -0,0 +1,59 @@
+/*
+ * ebt_pkttype
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2003
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_pkttype.h>
+#include <linux/module.h>
+
+static int ebt_filter_pkttype(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *data,
+ unsigned int datalen)
+{
+ struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data;
+
+ return (skb->pkt_type != info->pkt_type) ^ info->invert;
+}
+
+static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
+ const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+ struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data;
+
+ if (datalen != sizeof(struct ebt_pkttype_info))
+ return -EINVAL;
+ if (info->invert != 0 && info->invert != 1)
+ return -EINVAL;
+ /* Allow any pkt_type value */
+ return 0;
+}
+
+static struct ebt_match filter_pkttype =
+{
+ .name = EBT_PKTTYPE_MATCH,
+ .match = ebt_filter_pkttype,
+ .check = ebt_pkttype_check,
+ .me = THIS_MODULE,
+};
+
+static int __init init(void)
+{
+ return ebt_register_match(&filter_pkttype);
+}
+
+static void __exit fini(void)
+{
+ ebt_unregister_match(&filter_pkttype);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebtable_broute.c b/kernel/linux2.5/net/bridge/netfilter/ebtable_broute.c
index c1fb15b..1767c94 100644
--- a/kernel/linux2.5/net/bridge/netfilter/ebtable_broute.c
+++ b/kernel/linux2.5/net/bridge/netfilter/ebtable_broute.c
@@ -14,14 +14,13 @@
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/module.h>
#include <linux/if_bridge.h>
-#include <linux/brlock.h>
/* EBT_ACCEPT means the frame will be bridged
* EBT_DROP means the frame will be routed
*/
static struct ebt_entries initial_chain = {
- .name = "BROUTING",
- .policy = EBT_ACCEPT,
+ .name = "BROUTING",
+ .policy = EBT_ACCEPT,
};
static struct ebt_replace initial_table =
@@ -30,9 +29,9 @@ static struct ebt_replace initial_table =
.valid_hooks = 1 << NF_BR_BROUTING,
.entries_size = sizeof(struct ebt_entries),
.hook_entry = {
- [NF_BR_BROUTING] = &initial_chain
+ [NF_BR_BROUTING] = &initial_chain,
},
- .entries = (char *)&initial_chain
+ .entries = (char *)&initial_chain,
};
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
@@ -49,6 +48,7 @@ static struct ebt_table broute_table =
.valid_hooks = 1 << NF_BR_BROUTING,
.lock = RW_LOCK_UNLOCKED,
.check = check,
+ .me = THIS_MODULE,
};
static int ebt_broute(struct sk_buff **pskb)
@@ -69,18 +69,15 @@ static int __init init(void)
ret = ebt_register_table(&broute_table);
if (ret < 0)
return ret;
- br_write_lock_bh(BR_NETPROTO_LOCK);
/* see br_input.c */
br_should_route_hook = ebt_broute;
- br_write_unlock_bh(BR_NETPROTO_LOCK);
return ret;
}
static void __exit fini(void)
{
- br_write_lock_bh(BR_NETPROTO_LOCK);
br_should_route_hook = NULL;
- br_write_unlock_bh(BR_NETPROTO_LOCK);
+ synchronize_net();
ebt_unregister_table(&broute_table);
}
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebtable_filter.c b/kernel/linux2.5/net/bridge/netfilter/ebtable_filter.c
index ba6de32..ce60c4e 100644
--- a/kernel/linux2.5/net/bridge/netfilter/ebtable_filter.c
+++ b/kernel/linux2.5/net/bridge/netfilter/ebtable_filter.c
@@ -18,16 +18,16 @@ static struct ebt_entries initial_chains[] =
{
{
.name = "INPUT",
- .policy = EBT_ACCEPT
+ .policy = EBT_ACCEPT,
},
{
.name = "FORWARD",
- .policy = EBT_ACCEPT
+ .policy = EBT_ACCEPT,
},
{
.name = "OUTPUT",
- .policy = EBT_ACCEPT
- }
+ .policy = EBT_ACCEPT,
+ },
};
static struct ebt_replace initial_table =
@@ -40,7 +40,7 @@ static struct ebt_replace initial_table =
[NF_BR_FORWARD] = &initial_chains[1],
[NF_BR_LOCAL_OUT] = &initial_chains[2],
},
- .entries = (char *)initial_chains
+ .entries = (char *)initial_chains,
};
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
@@ -56,7 +56,8 @@ static struct ebt_table frame_filter =
.table = &initial_table,
.valid_hooks = FILTER_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED,
- .check = check
+ .check = check,
+ .me = THIS_MODULE,
};
static unsigned int
@@ -77,14 +78,14 @@ static struct nf_hook_ops ebt_ops_filter[] = {
.hook = ebt_hook,
.pf = PF_BRIDGE,
.hooknum = NF_BR_FORWARD,
- .priority = NF_BR_PRI_FILTER_BRIDGED
+ .priority = NF_BR_PRI_FILTER_BRIDGED,
},
{
.hook = ebt_hook,
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_OUT,
- .priority = NF_BR_PRI_FILTER_OTHER
- }
+ .priority = NF_BR_PRI_FILTER_OTHER,
+ },
};
static int __init init(void)
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebtable_nat.c b/kernel/linux2.5/net/bridge/netfilter/ebtable_nat.c
index 184d802..8dcf545 100644
--- a/kernel/linux2.5/net/bridge/netfilter/ebtable_nat.c
+++ b/kernel/linux2.5/net/bridge/netfilter/ebtable_nat.c
@@ -17,15 +17,15 @@ static struct ebt_entries initial_chains[] =
{
{
.name = "PREROUTING",
- .policy = EBT_ACCEPT
+ .policy = EBT_ACCEPT,
},
{
.name = "OUTPUT",
- .policy = EBT_ACCEPT
+ .policy = EBT_ACCEPT,
},
{
.name = "POSTROUTING",
- .policy = EBT_ACCEPT
+ .policy = EBT_ACCEPT,
}
};
@@ -37,9 +37,9 @@ static struct ebt_replace initial_table =
.hook_entry = {
[NF_BR_PRE_ROUTING] = &initial_chains[0],
[NF_BR_LOCAL_OUT] = &initial_chains[1],
- [NF_BR_POST_ROUTING] = &initial_chains[2]
+ [NF_BR_POST_ROUTING] = &initial_chains[2],
},
- .entries = (char *)initial_chains
+ .entries = (char *)initial_chains,
};
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
@@ -55,7 +55,8 @@ static struct ebt_table frame_nat =
.table = &initial_table,
.valid_hooks = NAT_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED,
- .check = check
+ .check = check,
+ .me = THIS_MODULE,
};
static unsigned int
@@ -77,20 +78,20 @@ static struct nf_hook_ops ebt_ops_nat[] = {
.hook = ebt_nat_dst,
.pf = PF_BRIDGE,
.hooknum = NF_BR_LOCAL_OUT,
- .priority = NF_BR_PRI_NAT_DST_OTHER
+ .priority = NF_BR_PRI_NAT_DST_OTHER,
},
{
.hook = ebt_nat_src,
.pf = PF_BRIDGE,
.hooknum = NF_BR_POST_ROUTING,
- .priority = NF_BR_PRI_NAT_SRC
+ .priority = NF_BR_PRI_NAT_SRC,
},
{
.hook = ebt_nat_dst,
.pf = PF_BRIDGE,
.hooknum = NF_BR_PRE_ROUTING,
- .priority = NF_BR_PRI_NAT_DST_BRIDGED
- }
+ .priority = NF_BR_PRI_NAT_DST_BRIDGED,
+ },
};
static int __init init(void)
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebtables.c b/kernel/linux2.5/net/bridge/netfilter/ebtables.c
index e297900..8729898 100644
--- a/kernel/linux2.5/net/bridge/netfilter/ebtables.c
+++ b/kernel/linux2.5/net/bridge/netfilter/ebtables.c
@@ -175,6 +175,10 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
char *base;
struct ebt_table_info *private = table->private;
+ /* FIXME: Push down to extensions --RR */
+ if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
+ return NF_DROP;
+
read_lock_bh(&table->lock);
cb_base = COUNTER_BASE(private->counters, private->nentries,
smp_processor_id());
@@ -969,8 +973,10 @@ static int do_replace(void *user, unsigned int len)
goto free_counterstmp;
t = find_table_lock(tmp.name, &ret, &ebt_mutex);
- if (!t)
+ if (!t) {
+ ret = -ENOENT;
goto free_iterate;
+ }
/* the table doesn't like it */
if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
@@ -984,6 +990,12 @@ static int do_replace(void *user, unsigned int len)
/* we have the mutex lock, so no danger in reading this pointer */
table = t->private;
+ /* make sure the table can only be rmmod'ed if it contains no rules */
+ if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
+ ret = -ENOENT;
+ goto free_unlock;
+ } else if (table->nentries && !newinfo->nentries)
+ module_put(t->me);
/* we need an atomic snapshot of the counters */
write_lock_bh(&t->lock);
if (tmp.num_counters)
@@ -1168,6 +1180,11 @@ int ebt_register_table(struct ebt_table *table)
goto free_unlock;
}
+ /* Hold a reference count if the chains aren't empty */
+ if (newinfo->nentries && !try_module_get(table->me)) {
+ ret = -ENOENT;
+ goto free_unlock;
+ }
list_prepend(&ebt_tables, table);
up(&ebt_mutex);
return 0;
@@ -1196,8 +1213,6 @@ void ebt_unregister_table(struct ebt_table *table)
down(&ebt_mutex);
LIST_DELETE(&ebt_tables, table);
up(&ebt_mutex);
- EBT_ENTRY_ITERATE(table->private->entries,
- table->private->entries_size, ebt_cleanup_entry, NULL);
if (table->private->entries)
vfree(table->private->entries);
if (table->private->chainstack) {