Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6

This commit is contained in:
David S. Miller 2009-12-15 21:08:53 -08:00
commit 81e839efc2
10 changed files with 59 additions and 11 deletions

View file

@ -49,6 +49,8 @@ o oprofile 0.9 # oprofiled --version
o udev 081 # udevinfo -V o udev 081 # udevinfo -V
o grub 0.93 # grub --version o grub 0.93 # grub --version
o mcelog 0.6 o mcelog 0.6
o iptables 1.4.1 # iptables -V
Kernel compilation Kernel compilation
================== ==================

View file

@ -337,6 +337,7 @@ enum ip_defrag_users {
IP_DEFRAG_CALL_RA_CHAIN, IP_DEFRAG_CALL_RA_CHAIN,
IP_DEFRAG_CONNTRACK_IN, IP_DEFRAG_CONNTRACK_IN,
IP_DEFRAG_CONNTRACK_OUT, IP_DEFRAG_CONNTRACK_OUT,
IP_DEFRAG_CONNTRACK_BRIDGE_IN,
IP_DEFRAG_VS_IN, IP_DEFRAG_VS_IN,
IP_DEFRAG_VS_OUT, IP_DEFRAG_VS_OUT,
IP_DEFRAG_VS_FWD IP_DEFRAG_VS_FWD

View file

@ -350,8 +350,16 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
struct inet_frag_queue; struct inet_frag_queue;
enum ip6_defrag_users {
IP6_DEFRAG_LOCAL_DELIVER,
IP6_DEFRAG_CONNTRACK_IN,
IP6_DEFRAG_CONNTRACK_OUT,
IP6_DEFRAG_CONNTRACK_BRIDGE_IN,
};
struct ip6_create_arg { struct ip6_create_arg {
__be32 id; __be32 id;
u32 user;
struct in6_addr *src; struct in6_addr *src;
struct in6_addr *dst; struct in6_addr *dst;
}; };

View file

@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
extern int nf_ct_frag6_init(void); extern int nf_ct_frag6_init(void);
extern void nf_ct_frag6_cleanup(void); extern void nf_ct_frag6_cleanup(void);
extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb); extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
struct net_device *in, struct net_device *in,
struct net_device *out, struct net_device *out,

View file

@ -14,6 +14,7 @@
#include <net/route.h> #include <net/route.h>
#include <net/ip.h> #include <net/ip.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv4.h>
#include <net/netfilter/ipv4/nf_defrag_ipv4.h> #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
@ -34,6 +35,20 @@ static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
return err; return err;
} }
static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
struct sk_buff *skb)
{
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge &&
skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
return IP_DEFRAG_CONNTRACK_BRIDGE_IN;
#endif
if (hooknum == NF_INET_PRE_ROUTING)
return IP_DEFRAG_CONNTRACK_IN;
else
return IP_DEFRAG_CONNTRACK_OUT;
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct net_device *in,
@ -50,10 +65,8 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
#endif #endif
/* Gather fragments. */ /* Gather fragments. */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
if (nf_ct_ipv4_gather_frags(skb, enum ip_defrag_users user = nf_ct_defrag_user(hooknum, skb);
hooknum == NF_INET_PRE_ROUTING ? if (nf_ct_ipv4_gather_frags(skb, user))
IP_DEFRAG_CONNTRACK_IN :
IP_DEFRAG_CONNTRACK_OUT))
return NF_STOLEN; return NF_STOLEN;
} }
return NF_ACCEPT; return NF_ACCEPT;

View file

@ -20,6 +20,7 @@
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/inet_frag.h> #include <net/inet_frag.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter_ipv6.h> #include <linux/netfilter_ipv6.h>
#include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_helper.h>
@ -187,6 +188,21 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
return nf_conntrack_confirm(skb); return nf_conntrack_confirm(skb);
} }
static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
struct sk_buff *skb)
{
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge &&
skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
return IP6_DEFRAG_CONNTRACK_BRIDGE_IN;
#endif
if (hooknum == NF_INET_PRE_ROUTING)
return IP6_DEFRAG_CONNTRACK_IN;
else
return IP6_DEFRAG_CONNTRACK_OUT;
}
static unsigned int ipv6_defrag(unsigned int hooknum, static unsigned int ipv6_defrag(unsigned int hooknum,
struct sk_buff *skb, struct sk_buff *skb,
const struct net_device *in, const struct net_device *in,
@ -199,8 +215,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
if (skb->nfct) if (skb->nfct)
return NF_ACCEPT; return NF_ACCEPT;
reasm = nf_ct_frag6_gather(skb); reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
/* queued */ /* queued */
if (reasm == NULL) if (reasm == NULL)
return NF_STOLEN; return NF_STOLEN;

View file

@ -168,13 +168,14 @@ static void nf_ct_frag6_expire(unsigned long data)
/* Creation primitives. */ /* Creation primitives. */
static __inline__ struct nf_ct_frag6_queue * static __inline__ struct nf_ct_frag6_queue *
fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
{ {
struct inet_frag_queue *q; struct inet_frag_queue *q;
struct ip6_create_arg arg; struct ip6_create_arg arg;
unsigned int hash; unsigned int hash;
arg.id = id; arg.id = id;
arg.user = user;
arg.src = src; arg.src = src;
arg.dst = dst; arg.dst = dst;
@ -559,7 +560,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
return 0; return 0;
} }
struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
{ {
struct sk_buff *clone; struct sk_buff *clone;
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
@ -605,7 +606,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh) if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
nf_ct_frag6_evictor(); nf_ct_frag6_evictor();
fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
if (fq == NULL) { if (fq == NULL) {
pr_debug("Can't find and can't create new queue\n"); pr_debug("Can't find and can't create new queue\n");
goto ret_orig; goto ret_orig;

View file

@ -72,6 +72,7 @@ struct frag_queue
struct inet_frag_queue q; struct inet_frag_queue q;
__be32 id; /* fragment id */ __be32 id; /* fragment id */
u32 user;
struct in6_addr saddr; struct in6_addr saddr;
struct in6_addr daddr; struct in6_addr daddr;
@ -141,7 +142,7 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
struct ip6_create_arg *arg = a; struct ip6_create_arg *arg = a;
fq = container_of(q, struct frag_queue, q); fq = container_of(q, struct frag_queue, q);
return (fq->id == arg->id && return (fq->id == arg->id && fq->user == arg->user &&
ipv6_addr_equal(&fq->saddr, arg->src) && ipv6_addr_equal(&fq->saddr, arg->src) &&
ipv6_addr_equal(&fq->daddr, arg->dst)); ipv6_addr_equal(&fq->daddr, arg->dst));
} }
@ -163,6 +164,7 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
struct ip6_create_arg *arg = a; struct ip6_create_arg *arg = a;
fq->id = arg->id; fq->id = arg->id;
fq->user = arg->user;
ipv6_addr_copy(&fq->saddr, arg->src); ipv6_addr_copy(&fq->saddr, arg->src);
ipv6_addr_copy(&fq->daddr, arg->dst); ipv6_addr_copy(&fq->daddr, arg->dst);
} }
@ -243,6 +245,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
unsigned int hash; unsigned int hash;
arg.id = id; arg.id = id;
arg.user = IP6_DEFRAG_LOCAL_DELIVER;
arg.src = src; arg.src = src;
arg.dst = dst; arg.dst = dst;

View file

@ -1366,6 +1366,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
== sysctl_ip_vs_sync_threshold[0])) || == sysctl_ip_vs_sync_threshold[0])) ||
((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
((cp->state == IP_VS_TCP_S_FIN_WAIT) || ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
(cp->state == IP_VS_TCP_S_CLOSE) ||
(cp->state == IP_VS_TCP_S_CLOSE_WAIT) || (cp->state == IP_VS_TCP_S_CLOSE_WAIT) ||
(cp->state == IP_VS_TCP_S_TIME_WAIT))))) (cp->state == IP_VS_TCP_S_TIME_WAIT)))))
ip_vs_sync_conn(cp); ip_vs_sync_conn(cp);

View file

@ -2714,6 +2714,8 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr)))) if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr))))
return -EINVAL; return -EINVAL;
memset(usvc, 0, sizeof(*usvc));
usvc->af = nla_get_u16(nla_af); usvc->af = nla_get_u16(nla_af);
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
if (usvc->af != AF_INET && usvc->af != AF_INET6) if (usvc->af != AF_INET && usvc->af != AF_INET6)
@ -2901,6 +2903,8 @@ static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest,
if (!(nla_addr && nla_port)) if (!(nla_addr && nla_port))
return -EINVAL; return -EINVAL;
memset(udest, 0, sizeof(*udest));
nla_memcpy(&udest->addr, nla_addr, sizeof(udest->addr)); nla_memcpy(&udest->addr, nla_addr, sizeof(udest->addr));
udest->port = nla_get_u16(nla_port); udest->port = nla_get_u16(nla_port);