Commit 83902db6 authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5

into kernel.bkbits.net:/home/davem/net-2.5
parents 0dd22e54 44389abb
......@@ -316,6 +316,15 @@ M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BONDING DRIVER
P: Chad Tindel
M: ctindel@users.sourceforge.net
P: Jay Vosburgh
M: fubar@us.ibm.com
L: bonding-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/bonding/
S: Supported
BTTV VIDEO4LINUX DRIVER
P: Gerd Knorr
M: kraxel@bytesex.org
......
......@@ -1102,7 +1102,7 @@ static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len)
{
unsigned int size = skb->len + skb->data_len;
unsigned int size = skb->len;
if (likely(size >= len))
return skb;
return skb_pad(skb, len-size);
......
......@@ -122,7 +122,7 @@ static inline void dn_nsp_send(struct sk_buff *skb)
if ((dst = sk->dst_cache) && !dst->obsolete) {
try_again:
skb->dst = dst_clone(dst);
dst->output(skb);
dst_output(skb);
return;
}
......
......@@ -593,7 +593,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
* associations.
*/
skb->dst = dst_clone(dst);
skb->dst->output(skb);
dst_output(skb);
}
......
......@@ -389,7 +389,7 @@ static int dn_route_rx_packet(struct sk_buff *skb)
int err;
if ((err = dn_route_input(skb)) == 0)
return skb->dst->input(skb);
return dst_input(skb);
if (decnet_debug_level & 4) {
char *devname = skb->dev ? skb->dev->name : "???";
......
......@@ -184,14 +184,6 @@ static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
#define IGMP_SIZE (sizeof(struct igmphdr)+sizeof(struct iphdr)+4)
/* Don't just hand NF_HOOK skb->dst->output, in case netfilter hook
changes route */
static inline int
output_maybe_reroute(struct sk_buff *skb)
{
return skb->dst->output(skb);
}
static int igmp_send_report(struct net_device *dev, u32 group, int type)
{
struct sk_buff *skb;
......@@ -255,7 +247,7 @@ static int igmp_send_report(struct net_device *dev, u32 group, int type)
ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
output_maybe_reroute);
dst_output);
}
......
......@@ -19,6 +19,7 @@
* Bill Hawes : Frag accounting and evictor fixes.
* John McDonald : 0 length frag bug.
* Alexey Kuznetsov: SMP races, threading, cleanup.
* Patrick McHardy : LRU queue of frag heads for evictor.
*/
#include <linux/config.h>
......@@ -26,6 +27,7 @@
#include <linux/mm.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/netdevice.h>
......@@ -67,6 +69,7 @@ struct ipfrag_skb_cb
/* Describe an entry in the "incomplete datagrams" queue. */
struct ipq {
struct ipq *next; /* linked list pointers */
struct list_head lru_list; /* lru list member */
u32 saddr;
u32 daddr;
u16 id;
......@@ -94,6 +97,7 @@ struct ipq {
/* Per-bucket lock is easy to add now. */
static struct ipq *ipq_hash[IPQ_HASHSZ];
static rwlock_t ipfrag_lock = RW_LOCK_UNLOCKED;
static LIST_HEAD(ipq_lru_list);
int ip_frag_nqueues = 0;
static __inline__ void __ipq_unlink(struct ipq *qp)
......@@ -101,6 +105,7 @@ static __inline__ void __ipq_unlink(struct ipq *qp)
if(qp->next)
qp->next->pprev = qp->pprev;
*qp->pprev = qp->next;
list_del(&qp->lru_list);
ip_frag_nqueues--;
}
......@@ -202,39 +207,30 @@ static void ipq_kill(struct ipq *ipq)
*/
static void ip_evictor(void)
{
int i, progress;
struct ipq *qp;
struct list_head *tmp;
do {
for(;;) {
if (atomic_read(&ip_frag_mem) <= sysctl_ipfrag_low_thresh)
return;
progress = 0;
/* FIXME: Make LRU queue of frag heads. -DaveM */
for (i = 0; i < IPQ_HASHSZ; i++) {
struct ipq *qp;
if (ipq_hash[i] == NULL)
continue;
read_lock(&ipfrag_lock);
if ((qp = ipq_hash[i]) != NULL) {
/* find the oldest queue for this hash bucket */
while (qp->next)
qp = qp->next;
atomic_inc(&qp->refcnt);
read_unlock(&ipfrag_lock);
spin_lock(&qp->lock);
if (!(qp->last_in&COMPLETE))
ipq_kill(qp);
spin_unlock(&qp->lock);
ipq_put(qp);
IP_INC_STATS_BH(IpReasmFails);
progress = 1;
continue;
}
read_lock(&ipfrag_lock);
if (list_empty(&ipq_lru_list)) {
read_unlock(&ipfrag_lock);
return;
}
} while (progress);
tmp = ipq_lru_list.next;
qp = list_entry(tmp, struct ipq, lru_list);
atomic_inc(&qp->refcnt);
read_unlock(&ipfrag_lock);
spin_lock(&qp->lock);
if (!(qp->last_in&COMPLETE))
ipq_kill(qp);
spin_unlock(&qp->lock);
ipq_put(qp);
IP_INC_STATS_BH(IpReasmFails);
}
}
/*
......@@ -302,6 +298,8 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in)
qp->next->pprev = &qp->next;
ipq_hash[hash] = qp;
qp->pprev = &ipq_hash[hash];
INIT_LIST_HEAD(&qp->lru_list);
list_add_tail(&qp->lru_list, &ipq_lru_list);
ip_frag_nqueues++;
write_unlock(&ipfrag_lock);
return qp;
......@@ -496,6 +494,10 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
if (offset == 0)
qp->last_in |= FIRST_IN;
write_lock(&ipfrag_lock);
list_move_tail(&qp->lru_list, &ipq_lru_list);
write_unlock(&ipfrag_lock);
return;
err:
......
......@@ -344,7 +344,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
}
}
return skb->dst->input(skb);
return dst_input(skb);
inhdr_error:
IP_INC_STATS_BH(IpInHdrErrors);
......
......@@ -1112,9 +1112,9 @@ static inline int ipmr_forward_finish(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
if (skb->len <= dst_pmtu(dst))
return dst->output(skb);
return dst_output(skb);
else
return ip_fragment(skb, dst->output);
return ip_fragment(skb, dst_output);
}
/*
......
......@@ -2409,149 +2409,149 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int *name,
ctl_table ipv4_route_table[] = {
{
.ctl_name = NET_IPV4_ROUTE_FLUSH,
.procname = "flush",
.data = &flush_delay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&ipv4_sysctl_rtcache_flush,
.strategy = &ipv4_sysctl_rtcache_flush_strategy,
.ctl_name = NET_IPV4_ROUTE_FLUSH,
.procname = "flush",
.data = &flush_delay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &ipv4_sysctl_rtcache_flush,
.strategy = &ipv4_sysctl_rtcache_flush_strategy,
},
{
.ctl_name = NET_IPV4_ROUTE_MIN_DELAY,
.procname = "min_delay",
.data = &ip_rt_min_delay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.ctl_name = NET_IPV4_ROUTE_MIN_DELAY,
.procname = "min_delay",
.data = &ip_rt_min_delay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
},
{
.ctl_name = NET_IPV4_ROUTE_MAX_DELAY,
.procname = "max_delay",
.data = &ip_rt_max_delay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.ctl_name = NET_IPV4_ROUTE_MAX_DELAY,
.procname = "max_delay",
.data = &ip_rt_max_delay,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
},
{
.ctl_name = NET_IPV4_ROUTE_GC_THRESH,
.procname = "gc_thresh",
.data = &ipv4_dst_ops.gc_thresh,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_GC_THRESH,
.procname = "gc_thresh",
.data = &ipv4_dst_ops.gc_thresh,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_MAX_SIZE,
.procname = "max_size",
.data = &ip_rt_max_size,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_MAX_SIZE,
.procname = "max_size",
.data = &ip_rt_max_size,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_GC_MIN_INTERVAL,
.procname = "gc_min_interval",
.data = &ip_rt_gc_min_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.ctl_name = NET_IPV4_ROUTE_GC_MIN_INTERVAL,
.procname = "gc_min_interval",
.data = &ip_rt_gc_min_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
},
{
.ctl_name = NET_IPV4_ROUTE_GC_TIMEOUT,
.procname = "gc_timeout",
.data = &ip_rt_gc_timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.ctl_name = NET_IPV4_ROUTE_GC_TIMEOUT,
.procname = "gc_timeout",
.data = &ip_rt_gc_timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
},
{
.ctl_name = NET_IPV4_ROUTE_GC_INTERVAL,
.procname = "gc_interval",
.data = &ip_rt_gc_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.ctl_name = NET_IPV4_ROUTE_GC_INTERVAL,
.procname = "gc_interval",
.data = &ip_rt_gc_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
},
{
.ctl_name = NET_IPV4_ROUTE_REDIRECT_LOAD,
.procname = "redirect_load",
.data = &ip_rt_redirect_load,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_REDIRECT_LOAD,
.procname = "redirect_load",
.data = &ip_rt_redirect_load,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_REDIRECT_NUMBER,
.procname = "redirect_number",
.data = &ip_rt_redirect_number,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_REDIRECT_NUMBER,
.procname = "redirect_number",
.data = &ip_rt_redirect_number,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_REDIRECT_SILENCE,
.procname = "redirect_silence",
.data = &ip_rt_redirect_silence,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_REDIRECT_SILENCE,
.procname = "redirect_silence",
.data = &ip_rt_redirect_silence,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_ERROR_COST,
.procname = "error_cost",
.data = &ip_rt_error_cost,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_ERROR_COST,
.procname = "error_cost",
.data = &ip_rt_error_cost,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_ERROR_BURST,
.procname = "error_burst",
.data = &ip_rt_error_burst,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_ERROR_BURST,
.procname = "error_burst",
.data = &ip_rt_error_burst,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_GC_ELASTICITY,
.procname = "gc_elasticity",
.data = &ip_rt_gc_elasticity,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_GC_ELASTICITY,
.procname = "gc_elasticity",
.data = &ip_rt_gc_elasticity,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_MTU_EXPIRES,
.procname = "mtu_expires",
.data = &ip_rt_mtu_expires,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
.ctl_name = NET_IPV4_ROUTE_MTU_EXPIRES,
.procname = "mtu_expires",
.data = &ip_rt_mtu_expires,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies,
},
{
.ctl_name = NET_IPV4_ROUTE_MIN_PMTU,
.procname = "min_pmtu",
.data = &ip_rt_min_pmtu,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_MIN_PMTU,
.procname = "min_pmtu",
.data = &ip_rt_min_pmtu,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{
.ctl_name = NET_IPV4_ROUTE_MIN_ADVMSS,
.procname = "min_adv_mss",
.data = &ip_rt_min_advmss,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler =&proc_dointvec,
.ctl_name = NET_IPV4_ROUTE_MIN_ADVMSS,
.procname = "min_adv_mss",
.data = &ip_rt_min_advmss,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{ 0 }
{ .ctl_name = 0 }
};
#endif
......
#include <linux/config.h>
#include <net/xfrm.h>
#include <net/ip.h>
......@@ -198,6 +199,49 @@ struct xfrm_type *xfrm_get_type(u8 proto)
return type;
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct xfrm_type *xfrm6_type_map[256];
static rwlock_t xfrm6_type_lock = RW_LOCK_UNLOCKED;
int xfrm6_register_type(struct xfrm_type *type)
{
int err = 0;
write_lock(&xfrm6_type_lock);
if (xfrm6_type_map[type->proto] == NULL)
xfrm6_type_map[type->proto] = type;
else
err = -EEXIST;
write_unlock(&xfrm6_type_lock);
return err;
}
int xfrm6_unregister_type(struct xfrm_type *type)
{
int err = 0;
write_lock(&xfrm6_type_lock);
if (xfrm6_type_map[type->proto] != type)
err = -ENOENT;
else
xfrm6_type_map[type->proto] = NULL;
write_unlock(&xfrm6_type_lock);
return err;
}
struct xfrm_type *xfrm6_get_type(u8 proto)
{
struct xfrm_type *type;
read_lock(&xfrm6_type_lock);
type = xfrm6_type_map[proto];
if (type && !try_module_get(type->owner))
type = NULL;
read_unlock(&xfrm6_type_lock);
return type;
}
#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
void xfrm_put_type(struct xfrm_type *type)
{
module_put(type->owner);
......
/* xfrm_user.c: User interface to configure xfrm engine.
*
* Copyright (C) 2002 David S. Miller (davem@redhat.com)
*
* Changes
*
* Mitsuru KANDA @USAGI : IPv6 Support
* Kazunori MIYAZAWA @USAGI :
* Kunihiro Ishiguro :
*
*/
#include <linux/module.h>
......@@ -17,6 +24,9 @@
#include <linux/ipsec.h>
#include <linux/init.h>
#include <linux/security.h>
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <linux/in6.h>
#endif
#include <net/sock.h>
#include <net/xfrm.h>
......@@ -63,10 +73,14 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
case AF_INET:
break;
case AF_INET6: /* XXX */
case AF_INET6:
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
break;
#else
err = -EAFNOSUPPORT;
goto out;
#endif
/* fallthru */
default:
goto out;
};
......@@ -171,7 +185,19 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
goto error;
err = -ENOENT;
x->type = xfrm_get_type(x->id.proto);
switch (x->props.family) {
case AF_INET:
x->type = xfrm_get_type(x->id.proto);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
x->type = xfrm6_get_type(x->id.proto);
break;
#endif
default:
x->type = NULL;
break;
}
if (x->type == NULL)
goto error;
......@@ -206,8 +232,21 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
if (!x)
return err;
x1 = xfrm_state_lookup(x->props.saddr.xfrm4_addr,
x->id.spi, x->id.proto);
switch (x->props.family) {
case AF_INET:
x1 = xfrm_state_lookup(x->props.saddr.xfrm4_addr,
x->id.spi, x->id.proto);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
x1 = xfrm6_state_lookup((struct in6_addr*)x->props.saddr.a6,
x->id.spi, x->id.proto);
break;
#endif
default:
x1 = NULL;
break;
}
if (x1) {
xfrm_state_put(x);
xfrm_state_put(x1);
......@@ -224,7 +263,19 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
struct xfrm_state *x;
struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
x = xfrm_state_lookup(p->saddr.xfrm4_addr, p->spi, p->proto);
switch (p->family) {
case AF_INET:
x = xfrm_state_lookup(p->saddr.xfrm4_addr, p->spi, p->proto);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
x = xfrm6_state_lookup((struct in6_addr*)p->saddr.a6, p->spi, p->proto);
break;
#endif
default:
x = NULL;
break;
}
if (x == NULL)
return -ESRCH;
......@@ -342,7 +393,19 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
struct sk_buff *resp_skb;
int err;
x = xfrm_state_lookup(p->saddr.xfrm4_addr, p->spi, p->proto);
switch (p->family) {
case AF_INET:
x = xfrm_state_lookup(p->saddr.xfrm4_addr, p->spi, p->proto);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
x = xfrm6_state_lookup((struct in6_addr*)p->saddr.a6, p->spi, p->proto);
break;
#endif
default:
x = NULL;
break;
}
err = -ESRCH;
if (x == NULL)
goto out_noput;
......@@ -393,9 +456,23 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, void **
err = verify_userspi_info(p);
if (err)
goto out_noput;
x = xfrm_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
p->info.sel.daddr.xfrm4_addr,
p->info.sel.saddr.xfrm4_addr, 1);
switch (p->info.family) {
case AF_INET:
x = xfrm_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
p->info.sel.daddr.xfrm4_addr,
p->info.sel.saddr.xfrm4_addr, 1);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
x = xfrm6_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
(struct in6_addr*)p->info.sel.daddr.a6,
(struct in6_addr*)p->info.sel.saddr.a6, 1);
break;
#endif
default:
x = NULL;
break;
}
err = -ENOENT;
if (x == NULL)
goto out_noput;
......
......@@ -11,5 +11,3 @@ ipv6-objs := af_inet6.o ip6_output.o ip6_input.o addrconf.o sit.o \
ip6_flowlabel.o ipv6_syms.o
obj-$(CONFIG_NETFILTER) += netfilter/
obj-y += xfrm_policy.o
......@@ -288,7 +288,7 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
dst_release(xchg(&skb->dst, NULL));
ip6_route_input(skb);
if (skb->dst->error) {
skb->dst->input(skb);
dst_input(skb);
return -1;
}
if (skb->dst->dev->flags&IFF_LOOPBACK) {
......@@ -302,7 +302,7 @@ static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
goto looped_back;
}
skb->dst->input(skb);
dst_input(skb);
return -1;
}
......
......@@ -47,7 +47,7 @@ static inline int ip6_rcv_finish( struct sk_buff *skb)
if (skb->dst == NULL)
ip6_route_input(skb);
return skb->dst->input(skb);
return dst_input(skb);
}
int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
......@@ -235,7 +235,7 @@ int ip6_mc_input(struct sk_buff *skb)
skb2 = skb;
}
dst->output(skb2);
dst_output(skb2);
}
}
#endif
......
......@@ -174,7 +174,7 @@ static inline int ip6_maybe_reroute(struct sk_buff *skb)
}
}
#endif /* CONFIG_NETFILTER */
return skb->dst->output(skb);
return dst_output(skb);
}
/*
......@@ -722,7 +722,7 @@ int ip6_call_ra_chain(struct sk_buff *skb, int sel)
static inline int ip6_forward_finish(struct sk_buff *skb)
{
return skb->dst->output(skb);
return dst_output(skb);
}
int ip6_forward(struct sk_buff *skb)
......
......@@ -4,7 +4,6 @@
#include <net/ipv6.h>
#include <net/addrconf.h>
#include <net/ip6_route.h>
#include <net/xfrm.h>
EXPORT_SYMBOL(ipv6_addr_type);
EXPORT_SYMBOL(icmpv6_send);
......@@ -26,6 +25,3 @@ EXPORT_SYMBOL(inet6_getname);
EXPORT_SYMBOL(inet6_ioctl);
EXPORT_SYMBOL(ipv6_get_saddr);
EXPORT_SYMBOL(ipv6_chk_addr);
EXPORT_SYMBOL(xfrm6_register_type);
EXPORT_SYMBOL(xfrm6_unregister_type);
EXPORT_SYMBOL(xfrm6_get_type);
......@@ -22,6 +22,7 @@
*
* Horst von Brand Add missing #include <linux/string.h>
* Alexey Kuznetsov SMP races, threading, cleanup.
* Patrick McHardy LRU queue of frag heads for evictor.
*/
#include <linux/config.h>
#include <linux/errno.h>
......@@ -31,6 +32,7 @@
#include <linux/sockios.h>
#include <linux/jiffies.h>
#include <linux/net.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/in6.h>
#include <linux/ipv6.h>
......@@ -67,6 +69,7 @@ struct ip6frag_skb_cb
struct frag_queue
{
struct frag_queue *next;
struct list_head lru_list; /* lru list member */
__u32 id; /* fragment id */
struct in6_addr saddr;
......@@ -95,6 +98,7 @@ struct frag_queue
static struct frag_queue *ip6_frag_hash[IP6Q_HASHSZ];
static rwlock_t ip6_frag_lock = RW_LOCK_UNLOCKED;
static LIST_HEAD(ip6_frag_lru_list);
int ip6_frag_nqueues = 0;
static __inline__ void __fq_unlink(struct frag_queue *fq)
......@@ -102,6 +106,7 @@ static __inline__ void __fq_unlink(struct frag_queue *fq)
if(fq->next)
fq->next->pprev = fq->pprev;
*fq->pprev = fq->next;
list_del(&fq->lru_list);
ip6_frag_nqueues--;
}
......@@ -193,38 +198,30 @@ static __inline__ void fq_kill(struct frag_queue *fq)
static void ip6_evictor(void)
{
int i, progress;
struct frag_queue *fq;
struct list_head *tmp;
do {
for(;;) {
if (atomic_read(&ip6_frag_mem) <= sysctl_ip6frag_low_thresh)
return;
progress = 0;
for (i = 0; i < IP6Q_HASHSZ; i++) {
struct frag_queue *fq;
if (ip6_frag_hash[i] == NULL)
continue;
read_lock(&ip6_frag_lock);
if ((fq = ip6_frag_hash[i]) != NULL) {
/* find the oldest queue for this hash bucket */
while (fq->next)
fq = fq->next;
atomic_inc(&fq->refcnt);
read_unlock(&ip6_frag_lock);
spin_lock(&fq->lock);
if (!(fq->last_in&COMPLETE))
fq_kill(fq);
spin_unlock(&fq->lock);
fq_put(fq);
IP6_INC_STATS_BH(Ip6ReasmFails);
progress = 1;
continue;
}
read_lock(&ip6_frag_lock);
if (list_empty(&ip6_frag_lru_list)) {
read_unlock(&ip6_frag_lock);
return;
}
} while (progress);
tmp = ip6_frag_lru_list.next;
fq = list_entry(tmp, struct frag_queue, lru_list);
atomic_inc(&fq->refcnt);
read_unlock(&ip6_frag_lock);
spin_lock(&fq->lock);
if (!(fq->last_in&COMPLETE))
fq_kill(fq);
spin_unlock(&fq->lock);
fq_put(fq);
IP6_INC_STATS_BH(Ip6ReasmFails);
}
}
static void ip6_frag_expire(unsigned long data)
......@@ -294,6 +291,8 @@ static struct frag_queue *ip6_frag_intern(unsigned int hash,
fq->next->pprev = &fq->next;
ip6_frag_hash[hash] = fq;
fq->pprev = &ip6_frag_hash[hash];
INIT_LIST_HEAD(&fq->lru_list);
list_add_tail(&fq->lru_list, &ip6_frag_lru_list);
ip6_frag_nqueues++;
write_unlock(&ip6_frag_lock);
return fq;
......@@ -501,6 +500,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
fq->nhoffset = nhoff;
fq->last_in |= FIRST_IN;
}
write_lock(&ip6_frag_lock);
list_move_tail(&fq->lru_list, &ip6_frag_lru_list);
write_unlock(&ip6_frag_lock);
return;
err:
......
#include <net/xfrm.h>
#include <net/ip.h>
static struct xfrm_type *xfrm6_type_map[256];
static rwlock_t xfrm6_type_lock = RW_LOCK_UNLOCKED;
int xfrm6_register_type(struct xfrm_type *type)
{
int err = 0;
write_lock(&xfrm6_type_lock);
if (xfrm6_type_map[type->proto] == NULL)
xfrm6_type_map[type->proto] = type;
else
err = -EEXIST;
write_unlock(&xfrm6_type_lock);
return err;
}
int xfrm6_unregister_type(struct xfrm_type *type)
{
int err = 0;
write_lock(&xfrm6_type_lock);
if (xfrm6_type_map[type->proto] != type)
err = -ENOENT;
else
xfrm6_type_map[type->proto] = NULL;
write_unlock(&xfrm6_type_lock);
return err;
}
struct xfrm_type *xfrm6_get_type(u8 proto)
{
struct xfrm_type *type;
read_lock(&xfrm6_type_lock);
type = xfrm6_type_map[proto];
if (type && !try_module_get(type->owner))
type = NULL;
read_unlock(&xfrm6_type_lock);
return type;
}
......@@ -10,6 +10,7 @@
* David S. Miller <davem@redhat.com>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
* Kunihiro Ishiguro <kunihiro@ipinfusion.com>
* Kazunori MIYAZAWA / USAGI Project <miyazawa@linux-ipv6.org>
*/
#include <linux/config.h>
......
......@@ -328,6 +328,9 @@ EXPORT_SYMBOL(xfrm_policy_list);
EXPORT_SYMBOL(xfrm6_state_lookup);
EXPORT_SYMBOL(xfrm6_find_acq);
EXPORT_SYMBOL(xfrm6_alloc_spi);
EXPORT_SYMBOL(xfrm6_register_type);
EXPORT_SYMBOL(xfrm6_unregister_type);
EXPORT_SYMBOL(xfrm6_get_type);
#endif
EXPORT_SYMBOL_GPL(xfrm_probe_algs);
......
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