Commit ec2319ca authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 26e9ff17 5438f37d
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#ifndef _SPARC64_BUG_H #ifndef _SPARC64_BUG_H
#define _SPARC64_BUG_H #define _SPARC64_BUG_H
#include <linux/compiler.h>
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
extern void do_BUG(const char *file, int line); extern void do_BUG(const char *file, int line);
#define BUG() do { \ #define BUG() do { \
......
...@@ -103,7 +103,7 @@ union ip_conntrack_nat_help { ...@@ -103,7 +103,7 @@ union ip_conntrack_nat_help {
#include <linux/types.h> #include <linux/types.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#ifdef CONFIG_NF_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
#define IP_NF_ASSERT(x) \ #define IP_NF_ASSERT(x) \
do { \ do { \
if (!(x)) \ if (!(x)) \
......
#ifndef _IPT_ADDRTYPE_H
#define _IPT_ADDRTYPE_H
struct ipt_addrtype_info {
u_int16_t source; /* source-type mask */
u_int16_t dest; /* dest-type mask */
u_int32_t invert_source;
u_int32_t invert_dest;
};
#endif
#ifndef _IPT_REALM_H
#define _IPT_REALM_H
struct ipt_realm_info {
u_int32_t id;
u_int32_t mask;
u_int8_t invert;
};
#endif /* _IPT_REALM_H */
...@@ -1109,6 +1109,14 @@ static inline void nf_conntrack_get(struct nf_ct_info *nfct) ...@@ -1109,6 +1109,14 @@ static inline void nf_conntrack_get(struct nf_ct_info *nfct)
if (nfct) if (nfct)
atomic_inc(&nfct->master->use); atomic_inc(&nfct->master->use);
} }
static inline void nf_reset(struct sk_buff *skb)
{
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
}
#ifdef CONFIG_BRIDGE_NETFILTER #ifdef CONFIG_BRIDGE_NETFILTER
static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
...@@ -1121,9 +1129,10 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge) ...@@ -1121,9 +1129,10 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
if (nf_bridge) if (nf_bridge)
atomic_inc(&nf_bridge->use); atomic_inc(&nf_bridge->use);
} }
#endif #endif /* CONFIG_BRIDGE_NETFILTER */
#else /* CONFIG_NETFILTER */
#endif static inline void nf_reset(struct sk_buff *skb) {}
#endif /* CONFIG_NETFILTER */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */ #endif /* _LINUX_SKBUFF_H */
...@@ -643,13 +643,7 @@ int ipgre_rcv(struct sk_buff *skb) ...@@ -643,13 +643,7 @@ int ipgre_rcv(struct sk_buff *skb)
skb->dev = tunnel->dev; skb->dev = tunnel->dev;
dst_release(skb->dst); dst_release(skb->dst);
skb->dst = NULL; skb->dst = NULL;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
ipgre_ecn_decapsulate(iph, skb); ipgre_ecn_decapsulate(iph, skb);
netif_rx(skb); netif_rx(skb);
read_unlock(&ipgre_lock); read_unlock(&ipgre_lock);
...@@ -877,13 +871,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -877,13 +871,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
} }
} }
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
IPTUNNEL_XMIT(); IPTUNNEL_XMIT();
tunnel->recursion--; tunnel->recursion--;
......
...@@ -202,17 +202,13 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) ...@@ -202,17 +202,13 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
nf_debug_ip_local_deliver(skb); nf_debug_ip_local_deliver(skb);
skb->nf_debug = 0;
#endif /*CONFIG_NETFILTER_DEBUG*/ #endif /*CONFIG_NETFILTER_DEBUG*/
__skb_pull(skb, ihl); __skb_pull(skb, ihl);
#ifdef CONFIG_NETFILTER
/* Free reference early: we don't need it any more, and it may /* Free reference early: we don't need it any more, and it may
hold ip_conntrack module loaded indefinitely. */ hold ip_conntrack module loaded indefinitely. */
nf_conntrack_put(skb->nfct); nf_reset(skb);
skb->nfct = NULL;
#endif /*CONFIG_NETFILTER*/
/* Point into the IP datagram, just past the header. */ /* Point into the IP datagram, just past the header. */
skb->h.raw = skb->data; skb->h.raw = skb->data;
......
...@@ -497,13 +497,7 @@ static int ipip_rcv(struct sk_buff *skb) ...@@ -497,13 +497,7 @@ static int ipip_rcv(struct sk_buff *skb)
skb->dev = tunnel->dev; skb->dev = tunnel->dev;
dst_release(skb->dst); dst_release(skb->dst);
skb->dst = NULL; skb->dst = NULL;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
ipip_ecn_decapsulate(iph, skb); ipip_ecn_decapsulate(iph, skb);
netif_rx(skb); netif_rx(skb);
read_unlock(&ipip_lock); read_unlock(&ipip_lock);
...@@ -648,13 +642,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -648,13 +642,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if ((iph->ttl = tiph->ttl) == 0) if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = old_iph->ttl; iph->ttl = old_iph->ttl;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
IPTUNNEL_XMIT(); IPTUNNEL_XMIT();
tunnel->recursion--; tunnel->recursion--;
......
...@@ -1105,10 +1105,7 @@ static void ip_encap(struct sk_buff *skb, u32 saddr, u32 daddr) ...@@ -1105,10 +1105,7 @@ static void ip_encap(struct sk_buff *skb, u32 saddr, u32 daddr)
skb->h.ipiph = skb->nh.iph; skb->h.ipiph = skb->nh.iph;
skb->nh.iph = iph; skb->nh.iph = iph;
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#endif
} }
static inline int ipmr_forward_finish(struct sk_buff *skb) static inline int ipmr_forward_finish(struct sk_buff *skb)
...@@ -1461,10 +1458,7 @@ int pim_rcv_v1(struct sk_buff * skb) ...@@ -1461,10 +1458,7 @@ int pim_rcv_v1(struct sk_buff * skb)
skb->dst = NULL; skb->dst = NULL;
((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len; ((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
((struct net_device_stats*)reg_dev->priv)->rx_packets++; ((struct net_device_stats*)reg_dev->priv)->rx_packets++;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#endif
netif_rx(skb); netif_rx(skb);
dev_put(reg_dev); dev_put(reg_dev);
return 0; return 0;
...@@ -1520,10 +1514,7 @@ static int pim_rcv(struct sk_buff * skb) ...@@ -1520,10 +1514,7 @@ static int pim_rcv(struct sk_buff * skb)
((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len; ((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
((struct net_device_stats*)reg_dev->priv)->rx_packets++; ((struct net_device_stats*)reg_dev->priv)->rx_packets++;
skb->dst = NULL; skb->dst = NULL;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#endif
netif_rx(skb); netif_rx(skb);
dev_put(reg_dev); dev_put(reg_dev);
return 0; return 0;
......
...@@ -603,5 +603,29 @@ config IP_NF_RAW ...@@ -603,5 +603,29 @@ config IP_NF_RAW
<file:Documentation/modules.txt>. If unsure, say `N'. <file:Documentation/modules.txt>. If unsure, say `N'.
help help
config IP_NF_MATCH_ADDRTYPE
tristate 'address type match support'
depends on IP_NF_IPTABLES
help
This option allows you to match what routing thinks of an address,
eg. UNICAST, LOCAL, BROADCAST, ...
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
config IP_NF_MATCH_REALM
tristate 'realm match support'
depends on IP_NF_IPTABLES
select NET_CLS_ROUTE
help
This option adds a `realm' match, which allows you to use the realm
key from the routing subsytem inside iptables.
This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option
in tc world.
If you want to compile it as a module, say M here and read
Documentation/modules.txt. If unsure, say `N'.
endmenu endmenu
...@@ -64,6 +64,8 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o ...@@ -64,6 +64,8 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
......
...@@ -107,7 +107,7 @@ static int help(struct sk_buff *skb, ...@@ -107,7 +107,7 @@ static int help(struct sk_buff *skb,
exp->mask.dst.u.tcp.port = 0xFFFF; exp->mask.dst.u.tcp.port = 0xFFFF;
exp_amanda_info = &exp->help.exp_amanda_info; exp_amanda_info = &exp->help.exp_amanda_info;
exp_amanda_info->offset = data - amanda_buffer; exp_amanda_info->offset = tmp - amanda_buffer;
exp_amanda_info->port = port; exp_amanda_info->port = port;
exp_amanda_info->len = len; exp_amanda_info->len = len;
......
...@@ -174,13 +174,12 @@ static void ...@@ -174,13 +174,12 @@ static void
destroy_expect(struct ip_conntrack_expect *exp) destroy_expect(struct ip_conntrack_expect *exp)
{ {
DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use)); DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use));
IP_NF_ASSERT(atomic_read(&exp->use)); IP_NF_ASSERT(atomic_read(&exp->use) == 0);
IP_NF_ASSERT(!timer_pending(&exp->timeout)); IP_NF_ASSERT(!timer_pending(&exp->timeout));
kfree(exp); kfree(exp);
} }
inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
{ {
IP_NF_ASSERT(exp); IP_NF_ASSERT(exp);
...@@ -716,7 +715,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -716,7 +715,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
conntrack, expected); conntrack, expected);
/* Welcome, Mr. Bond. We've been expecting you... */ /* Welcome, Mr. Bond. We've been expecting you... */
IP_NF_ASSERT(master_ct(conntrack));
__set_bit(IPS_EXPECTED_BIT, &conntrack->status); __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected; conntrack->master = expected;
expected->sibling = conntrack; expected->sibling = conntrack;
...@@ -949,9 +947,8 @@ ip_conntrack_expect_insert(struct ip_conntrack_expect *new, ...@@ -949,9 +947,8 @@ ip_conntrack_expect_insert(struct ip_conntrack_expect *new,
atomic_set(&new->use, 1); atomic_set(&new->use, 1);
/* add to expected list for this connection */ /* add to expected list for this connection */
list_add(&new->expected_list, &related_to->sibling_list); list_add_tail(&new->expected_list, &related_to->sibling_list);
/* add to global list of expectations */ /* add to global list of expectations */
list_prepend(&ip_conntrack_expect_list, &new->list); list_prepend(&ip_conntrack_expect_list, &new->list);
/* add and start timer if required */ /* add and start timer if required */
if (related_to->helper->timeout) { if (related_to->helper->timeout) {
...@@ -1005,7 +1002,6 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, ...@@ -1005,7 +1002,6 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
} else if (related_to->helper->max_expected && } else if (related_to->helper->max_expected &&
related_to->expecting >= related_to->helper->max_expected) { related_to->expecting >= related_to->helper->max_expected) {
struct list_head *cur_item;
/* old == NULL */ /* old == NULL */
if (!(related_to->helper->flags & if (!(related_to->helper->flags &
IP_CT_HELPER_F_REUSE_EXPECT)) { IP_CT_HELPER_F_REUSE_EXPECT)) {
...@@ -1031,21 +1027,14 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, ...@@ -1031,21 +1027,14 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
/* choose the the oldest expectation to evict */ /* choose the the oldest expectation to evict */
list_for_each(cur_item, &related_to->sibling_list) { list_for_each_entry(old, &related_to->sibling_list,
struct ip_conntrack_expect *cur; expected_list)
if (old->sibling == NULL)
cur = list_entry(cur_item,
struct ip_conntrack_expect,
expected_list);
if (cur->sibling == NULL) {
old = cur;
break; break;
}
}
/* (!old) cannot happen, since related_to->expecting is the /* We cannot fail since related_to->expecting is the number
* number of unconfirmed expects */ * of unconfirmed expectations */
IP_NF_ASSERT(old); IP_NF_ASSERT(old && old->sibling == NULL);
/* newnat14 does not reuse the real allocated memory /* newnat14 does not reuse the real allocated memory
* structures but rather unexpects the old and * structures but rather unexpects the old and
......
...@@ -503,7 +503,7 @@ static int init_or_cleanup(int init) ...@@ -503,7 +503,7 @@ static int init_or_cleanup(int init)
if (ret < 0) if (ret < 0)
goto cleanup_nothing; goto cleanup_nothing;
proc = proc_net_create("ip_conntrack",0,list_conntracks); proc = proc_net_create("ip_conntrack", 0440, list_conntracks);
if (!proc) goto cleanup_init; if (!proc) goto cleanup_init;
proc->owner = THIS_MODULE; proc->owner = THIS_MODULE;
......
...@@ -528,6 +528,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, ...@@ -528,6 +528,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
MUST_BE_WRITE_LOCKED(&ip_nat_lock); MUST_BE_WRITE_LOCKED(&ip_nat_lock);
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_POST_ROUTING
|| hooknum == NF_IP_LOCAL_IN
|| hooknum == NF_IP_LOCAL_OUT); || hooknum == NF_IP_LOCAL_OUT);
IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS); IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
...@@ -816,7 +817,7 @@ do_bindings(struct ip_conntrack *ct, ...@@ -816,7 +817,7 @@ do_bindings(struct ip_conntrack *ct,
/* Have to grab read lock before sibling_list traversal */ /* Have to grab read lock before sibling_list traversal */
READ_LOCK(&ip_conntrack_lock); READ_LOCK(&ip_conntrack_lock);
list_for_each(cur_item, &ct->sibling_list) { list_for_each_prev(cur_item, &ct->sibling_list) {
exp = list_entry(cur_item, struct ip_conntrack_expect, exp = list_entry(cur_item, struct ip_conntrack_expect,
expected_list); expected_list);
...@@ -899,10 +900,10 @@ icmp_reply_translation(struct sk_buff **pskb, ...@@ -899,10 +900,10 @@ icmp_reply_translation(struct sk_buff **pskb,
/* Must be RELATED */ /* Must be RELATED */
IP_NF_ASSERT((*pskb)->nfct IP_NF_ASSERT((*pskb)->nfct
- (struct ip_conntrack *)(*pskb)->nfct->master - ((struct ip_conntrack *)(*pskb)->nfct->master)->infos
== IP_CT_RELATED == IP_CT_RELATED
|| (*pskb)->nfct || (*pskb)->nfct
- (struct ip_conntrack *)(*pskb)->nfct->master - ((struct ip_conntrack *)(*pskb)->nfct->master)->infos
== IP_CT_RELATED+IP_CT_IS_REPLY); == IP_CT_RELATED+IP_CT_IS_REPLY);
/* Redirects on non-null nats must be dropped, else they'll /* Redirects on non-null nats must be dropped, else they'll
......
...@@ -1731,6 +1731,15 @@ static inline int print_name(const char *i, ...@@ -1731,6 +1731,15 @@ static inline int print_name(const char *i,
return 0; return 0;
} }
static inline int print_target(const struct ipt_target *t,
off_t start_offset, char *buffer, int length,
off_t *pos, unsigned int *count)
{
if (t == &ipt_standard_target || t == &ipt_error_target)
return 0;
return print_name((char *)t, start_offset, buffer, length, pos, count);
}
static int ipt_get_tables(char *buffer, char **start, off_t offset, int length) static int ipt_get_tables(char *buffer, char **start, off_t offset, int length)
{ {
off_t pos = 0; off_t pos = 0;
...@@ -1757,7 +1766,7 @@ static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) ...@@ -1757,7 +1766,7 @@ static int ipt_get_targets(char *buffer, char **start, off_t offset, int length)
if (down_interruptible(&ipt_mutex) != 0) if (down_interruptible(&ipt_mutex) != 0)
return 0; return 0;
LIST_FIND(&ipt_target, print_name, void *, LIST_FIND(&ipt_target, print_target, struct ipt_target *,
offset, buffer, length, &pos, &count); offset, buffer, length, &pos, &count);
up(&ipt_mutex); up(&ipt_mutex);
......
...@@ -54,15 +54,17 @@ checkentry(const char *tablename, ...@@ -54,15 +54,17 @@ checkentry(const char *tablename,
return 0; return 0;
} }
if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) { if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
printk(KERN_ERR "CLASSIFY: only valid in POST_ROUTING.\n"); (1 << NF_IP_POST_ROUTING))) {
printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD "
"and POST_ROUTING.\n");
return 0; return 0;
} }
if (strcmp(tablename, "mangle") != 0) { if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "CLASSIFY: can only be called from " printk(KERN_ERR "CLASSIFY: can only be called from "
"\"mangle\" table, not \"%s\".\n", "\"mangle\" table, not \"%s\".\n",
tablename); tablename);
return 0; return 0;
} }
......
...@@ -142,12 +142,8 @@ static void send_reset(struct sk_buff *oldskb, int hook) ...@@ -142,12 +142,8 @@ static void send_reset(struct sk_buff *oldskb, int hook)
nskb->dst = &rt->u.dst; nskb->dst = &rt->u.dst;
/* This packet will not be the same as the other: clear nf fields */ /* This packet will not be the same as the other: clear nf fields */
nf_conntrack_put(nskb->nfct); nf_reset(nskb);
nskb->nfct = NULL;
nskb->nfcache = 0; nskb->nfcache = 0;
#ifdef CONFIG_NETFILTER_DEBUG
nskb->nf_debug = 0;
#endif
nskb->nfmark = 0; nskb->nfmark = 0;
#ifdef CONFIG_BRIDGE_NETFILTER #ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(nskb->nf_bridge); nf_bridge_put(nskb->nf_bridge);
......
/*
* iptables module to match inet_addr_type() of an ip.
*
* Copyright (c) 2004 Patrick McHardy <kaber@trash.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#include <net/route.h>
#include <linux/netfilter_ipv4/ipt_addrtype.h>
#include <linux/netfilter_ipv4/ip_tables.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("iptables addrtype match");
static inline int match_type(u_int32_t addr, u_int16_t mask)
{
return !!(mask & (1 << inet_addr_type(addr)));
}
static int match(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const void *matchinfo,
int offset, int *hotdrop)
{
const struct ipt_addrtype_info *info = matchinfo;
const struct iphdr *iph = skb->nh.iph;
int ret = 1;
if (info->source)
ret &= match_type(iph->saddr, info->source)^info->invert_source;
if (info->dest)
ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
return ret;
}
static int checkentry(const char *tablename, const struct ipt_ip *ip,
void *matchinfo, unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
return 0;
}
return 1;
}
static struct ipt_match addrtype_match = {
.name = "addrtype",
.match = match,
.checkentry = checkentry,
.me = THIS_MODULE
};
static int __init init(void)
{
return ipt_register_match(&addrtype_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&addrtype_match);
}
module_init(init);
module_exit(fini);
...@@ -41,17 +41,17 @@ match(const struct sk_buff *skb, ...@@ -41,17 +41,17 @@ match(const struct sk_buff *skb,
struct ip_conntrack_expect *exp; struct ip_conntrack_expect *exp;
struct ip_conntrack *ct; struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
int ret = 0; int ret = info->invert;
ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
if (!ct) { if (!ct) {
DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
return 0; return ret;
} }
if (!ct->master) { if (!ct->master) {
DEBUGP("ipt_helper: conntrack %p has no master\n", ct); DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
return 0; return ret;
} }
exp = ct->master; exp = ct->master;
...@@ -71,8 +71,11 @@ match(const struct sk_buff *skb, ...@@ -71,8 +71,11 @@ match(const struct sk_buff *skb,
DEBUGP("master's name = %s , info->name = %s\n", DEBUGP("master's name = %s , info->name = %s\n",
exp->expectant->helper->name, info->name); exp->expectant->helper->name, info->name);
ret = !strncmp(exp->expectant->helper->name, info->name, if (info->name[0] == '\0')
strlen(exp->expectant->helper->name)) ^ info->invert; ret ^= 1;
else
ret ^= !strncmp(exp->expectant->helper->name, info->name,
strlen(exp->expectant->helper->name));
out_unlock: out_unlock:
READ_UNLOCK(&ip_conntrack_lock); READ_UNLOCK(&ip_conntrack_lock);
return ret; return ret;
...@@ -92,10 +95,6 @@ static int check(const char *tablename, ...@@ -92,10 +95,6 @@ static int check(const char *tablename,
if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info)))
return 0; return 0;
/* verify that we actually should match anything */
if ( strlen(info->name) == 0 )
return 0;
return 1; return 1;
} }
...@@ -108,7 +107,6 @@ static struct ipt_match helper_match = { ...@@ -108,7 +107,6 @@ static struct ipt_match helper_match = {
static int __init init(void) static int __init init(void)
{ {
need_ip_conntrack();
return ipt_register_match(&helper_match); return ipt_register_match(&helper_match);
} }
......
...@@ -184,7 +184,15 @@ checkentry(const char *tablename, ...@@ -184,7 +184,15 @@ checkentry(const char *tablename,
IPT_ALIGN(sizeof(struct ipt_owner_info))); IPT_ALIGN(sizeof(struct ipt_owner_info)));
return 0; return 0;
} }
#ifdef CONFIG_SMP
/* files->file_lock can not be used in a BH */
if (((struct ipt_owner_info *)matchinfo)->match
& (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
printk("ipt_owner: pid, sid and command matching is broken "
"on SMP.\n");
return 0;
}
#endif
return 1; return 1;
} }
......
/* IP tables module for matching the routing realm
*
* $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $
*
* (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/route.h>
#include <linux/netfilter_ipv4/ipt_realm.h>
#include <linux/netfilter_ipv4/ip_tables.h>
MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("iptables realm match");
static int
match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
int offset,
int *hotdrop)
{
const struct ipt_realm_info *info = matchinfo;
struct dst_entry *dst = skb->dst;
return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
}
static int check(const char *tablename,
const struct ipt_ip *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (hook_mask
& ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
(1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) {
printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
"LOCAL_IN or FORWARD.\n");
return 0;
}
if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) {
printk("ipt_realm: invalid matchsize.\n");
return 0;
}
return 1;
}
static struct ipt_match realm_match = {
.name = "realm",
.match = match,
.checkentry = check,
.me = THIS_MODULE
};
static int __init init(void)
{
return ipt_register_match(&realm_match);
}
static void __exit fini(void)
{
ipt_unregister_match(&realm_match);
}
module_init(init);
module_exit(fini);
...@@ -173,7 +173,9 @@ ipt_local_hook(unsigned int hook, ...@@ -173,7 +173,9 @@ ipt_local_hook(unsigned int hook,
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE
&& ((*pskb)->nh.iph->saddr != saddr && ((*pskb)->nh.iph->saddr != saddr
|| (*pskb)->nh.iph->daddr != daddr || (*pskb)->nh.iph->daddr != daddr
#ifdef CONFIG_IP_ROUTE_FWMARK
|| (*pskb)->nfmark != nfmark || (*pskb)->nfmark != nfmark
#endif
|| (*pskb)->nh.iph->tos != tos)) || (*pskb)->nh.iph->tos != tos))
return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
......
...@@ -32,43 +32,64 @@ static struct ...@@ -32,43 +32,64 @@ static struct
struct ipt_replace repl; struct ipt_replace repl;
struct ipt_standard entries[2]; struct ipt_standard entries[2];
struct ipt_error term; struct ipt_error term;
} initial_table __initdata } initial_table __initdata = {
= { { "raw", RAW_VALID_HOOKS, 3, .repl = {
sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), .name = "raw",
{ [NF_IP_PRE_ROUTING] 0, .valid_hooks = RAW_VALID_HOOKS,
[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, .num_entries = 3,
{ [NF_IP_PRE_ROUTING] 0, .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, .hook_entry = {
0, NULL, { } }, [NF_IP_PRE_ROUTING] = 0,
{ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
/* PRE_ROUTING */ .underflow = {
{ { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, [NF_IP_PRE_ROUTING] = 0,
0, [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
sizeof(struct ipt_entry), },
sizeof(struct ipt_standard), .entries = {
0, { 0, 0 }, { } }, /* PRE_ROUTING */
{ { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, {
-NF_ACCEPT - 1 } }, .entry = {
/* LOCAL_OUT */ .target_offset = sizeof(struct ipt_entry),
{ { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, .next_offset = sizeof(struct ipt_standard),
0, },
sizeof(struct ipt_entry), .target = {
sizeof(struct ipt_standard), .target = {
0, { 0, 0 }, { } }, .u.target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
{ { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, },
-NF_ACCEPT - 1 } } .verdict = -NF_ACCEPT - 1,
}, },
/* ERROR */ },
{ { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
0, /* LOCAL_OUT */
sizeof(struct ipt_entry), {
sizeof(struct ipt_error), .entry = {
0, { 0, 0 }, { } }, .target_offset = sizeof(struct ipt_entry),
{ { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, .next_offset = sizeof(struct ipt_standard),
{ } }, },
"ERROR" .target = {
} .target = {
} .u.target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
},
.verdict = -NF_ACCEPT - 1,
},
},
},
/* ERROR */
.term = {
.entry = {
.target_offset = sizeof(struct ipt_entry),
.next_offset = sizeof(struct ipt_error),
},
.target = {
.target = {
.u.user = {
.target_size = IPT_ALIGN(sizeof(struct ipt_error_target)),
.name = IPT_ERROR_TARGET,
},
},
.errorname = "ERROR",
},
}
}; };
static struct ipt_table packet_raw = { static struct ipt_table packet_raw = {
......
...@@ -722,13 +722,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -722,13 +722,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
ipv6h->nexthdr = proto; ipv6h->nexthdr = proto;
ipv6_addr_copy(&ipv6h->saddr, &fl.fl6_src); ipv6_addr_copy(&ipv6h->saddr, &fl.fl6_src);
ipv6_addr_copy(&ipv6h->daddr, &fl.fl6_dst); ipv6_addr_copy(&ipv6h->daddr, &fl.fl6_dst);
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
pkt_len = skb->len; pkt_len = skb->len;
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
skb->dst->dev, dst_output); skb->dst->dev, dst_output);
......
...@@ -1845,6 +1845,15 @@ static inline int print_name(const char *i, ...@@ -1845,6 +1845,15 @@ static inline int print_name(const char *i,
return 0; return 0;
} }
static inline int print_target(const struct ip6t_target *t,
off_t start_offset, char *buffer, int length,
off_t *pos, unsigned int *count)
{
if (t == &ip6t_standard_target || t == &ip6t_error_target)
return 0;
return print_name((char *)t, start_offset, buffer, length, pos, count);
}
static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length) static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length)
{ {
off_t pos = 0; off_t pos = 0;
...@@ -1871,7 +1880,7 @@ static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length ...@@ -1871,7 +1880,7 @@ static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length
if (down_interruptible(&ip6t_mutex) != 0) if (down_interruptible(&ip6t_mutex) != 0)
return 0; return 0;
LIST_FIND(&ip6t_target, print_name, char *, LIST_FIND(&ip6t_target, print_target, struct ip6t_target *,
offset, buffer, length, &pos, &count); offset, buffer, length, &pos, &count);
up(&ip6t_mutex); up(&ip6t_mutex);
......
...@@ -143,7 +143,14 @@ checkentry(const char *tablename, ...@@ -143,7 +143,14 @@ checkentry(const char *tablename,
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info))) if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
return 0; return 0;
#ifdef CONFIG_SMP
/* files->file_lock can not be used in a BH */
if (((struct ip6t_owner_info *)matchinfo)->match
& (IP6T_OWNER_PID|IP6T_OWNER_SID)) {
printk("ip6t_owner: pid and sid matching is broken on SMP.\n");
return 0;
}
#endif
return 1; return 1;
} }
......
...@@ -388,13 +388,7 @@ static int ipip6_rcv(struct sk_buff *skb) ...@@ -388,13 +388,7 @@ static int ipip6_rcv(struct sk_buff *skb)
skb->dev = tunnel->dev; skb->dev = tunnel->dev;
dst_release(skb->dst); dst_release(skb->dst);
skb->dst = NULL; skb->dst = NULL;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
ipip6_ecn_decapsulate(iph, skb); ipip6_ecn_decapsulate(iph, skb);
netif_rx(skb); netif_rx(skb);
read_unlock(&ipip6_lock); read_unlock(&ipip6_lock);
...@@ -580,13 +574,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -580,13 +574,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if ((iph->ttl = tiph->ttl) == 0) if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = iph6->hop_limit; iph->ttl = iph6->hop_limit;
#ifdef CONFIG_NETFILTER nf_reset(skb);
nf_conntrack_put(skb->nfct);
skb->nfct = NULL;
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = 0;
#endif
#endif
IPTUNNEL_XMIT(); IPTUNNEL_XMIT();
tunnel->recursion--; tunnel->recursion--;
......
...@@ -242,6 +242,7 @@ config NET_CLS_TCINDEX ...@@ -242,6 +242,7 @@ config NET_CLS_TCINDEX
config NET_CLS_ROUTE4 config NET_CLS_ROUTE4
tristate "Routing table based classifier" tristate "Routing table based classifier"
depends on NET_CLS depends on NET_CLS
select NET_CLS_ROUTE
help help
If you say Y here, you will be able to classify outgoing packets If you say Y here, you will be able to classify outgoing packets
according to the route table entry they matched. If unsure, say Y. according to the route table entry they matched. If unsure, say Y.
...@@ -251,8 +252,7 @@ config NET_CLS_ROUTE4 ...@@ -251,8 +252,7 @@ config NET_CLS_ROUTE4
config NET_CLS_ROUTE config NET_CLS_ROUTE
bool bool
depends on NET_CLS_ROUTE4 default n
default y
config NET_CLS_FW config NET_CLS_FW
tristate "Firewall based classifier" tristate "Firewall based classifier"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment