Commit 48bdef02 authored by David S. Miller's avatar David S. Miller

Merge bk://kernel.bkbits.net/jmorris/net-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 317cfe29 92f8b857
......@@ -68,6 +68,8 @@ extern int ipv6_dev_get_saddr(struct net_device *dev,
struct in6_addr *saddr,
int onlink);
extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *);
extern int ipv6_rcv_saddr_equal(const struct sock *sk,
const struct sock *sk2);
extern void addrconf_join_solict(struct net_device *dev,
struct in6_addr *addr);
extern void addrconf_leave_solict(struct net_device *dev,
......
......@@ -79,8 +79,7 @@ extern rwlock_t ip_ra_lock;
extern void ip_mc_dropsocket(struct sock *);
extern void ip_mc_dropdevice(struct net_device *dev);
extern int ip_mc_procinfo(char *, char **, off_t, int);
extern int ip_mcf_procinfo(char *, char **, off_t, int);
extern int igmp_mc_proc_init(void);
/*
* Functions provided by ip.c
......
This diff is collapsed.
......@@ -1314,7 +1314,6 @@ void __init ip_init(void)
inet_initpeers();
#ifdef CONFIG_IP_MULTICAST
proc_net_create("igmp", 0, ip_mc_procinfo);
igmp_mc_proc_init();
#endif
proc_net_create("mcfilter", 0, ip_mcf_procinfo);
}
......@@ -801,7 +801,24 @@ static struct seq_operations raw_seq_ops = {
static int raw_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &raw_seq_ops);
struct seq_file *seq;
int rc = -ENOMEM;
struct raw_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
rc = seq_open(file, &raw_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
kfree(s);
goto out;
}
static struct file_operations raw_seq_fops = {
......@@ -809,7 +826,7 @@ static struct file_operations raw_seq_fops = {
.open = raw_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.release = seq_release_private,
};
int __init raw_proc_init(void)
......
......@@ -66,6 +66,7 @@
#include <net/ndisc.h>
#include <net/ip6_route.h>
#include <net/addrconf.h>
#include <net/tcp.h>
#include <net/ip.h>
#include <linux/if_tunnel.h>
#include <linux/rtnetlink.h>
......@@ -969,6 +970,43 @@ struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *
return ifp;
}
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
return 1;
if (sk2->sk_family == AF_INET6 &&
ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
!(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
return 1;
if (addr_type == IPV6_ADDR_ANY &&
(!ipv6_only_sock(sk) ||
!(sk2->sk_family == AF_INET6 ?
(ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) :
1)))
return 1;
if (sk2->sk_family == AF_INET6 &&
!ipv6_addr_cmp(&np->rcv_saddr,
(sk2->sk_state != TCP_TIME_WAIT ?
&inet6_sk(sk2)->rcv_saddr :
&tcptw_sk(sk)->tw_v6_rcv_saddr)))
return 1;
if (addr_type == IPV6_ADDR_MAPPED &&
!ipv6_only_sock(sk2) &&
(!inet_sk(sk2)->rcv_saddr ||
!inet_sk(sk)->rcv_saddr ||
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
return 1;
return 0;
}
/* Gets referenced address, destroys ifaddr */
void addrconf_dad_failure(struct inet6_ifaddr *ifp)
......
......@@ -85,7 +85,8 @@ extern int udp6_proc_init(void);
extern void udp6_proc_exit(void);
extern int ipv6_misc_proc_init(void);
extern void ipv6_misc_proc_exit(void);
extern int anycast6_get_info(char *, char **, off_t, int);
extern int ac6_proc_init(void);
extern void ac6_proc_exit(void);
extern int if6_proc_init(void);
extern void if6_proc_exit(void);
#endif
......@@ -799,7 +800,7 @@ static int __init inet6_init(void)
if (ipv6_misc_proc_init())
goto proc_misc6_fail;
if (!proc_net_create("anycast6", 0, anycast6_get_info))
if (ac6_proc_init())
goto proc_anycast6_fail;
if (if6_proc_init())
goto proc_if6_fail;
......@@ -825,7 +826,7 @@ static int __init inet6_init(void)
#ifdef CONFIG_PROC_FS
proc_if6_fail:
proc_net_remove("anycast6");
ac6_proc_exit();
proc_anycast6_fail:
ipv6_misc_proc_exit();
proc_misc6_fail:
......@@ -863,7 +864,7 @@ static void inet6_exit(void)
sock_unregister(PF_INET6);
#ifdef CONFIG_PROC_FS
if6_proc_exit();
proc_net_remove("anycast6");
ac6_proc_exit();
ipv6_misc_proc_exit();
udp6_proc_exit();
tcp6_proc_exit();
......
......@@ -29,6 +29,7 @@
#include <linux/route.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/sock.h>
#include <net/snmp.h>
......@@ -435,56 +436,159 @@ int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr)
#ifdef CONFIG_PROC_FS
int anycast6_get_info(char *buffer, char **start, off_t offset, int length)
{
off_t pos=0, begin=0;
struct ifacaddr6 *im;
int len=0;
struct ac6_iter_state {
struct net_device *dev;
read_lock(&dev_base_lock);
for (dev = dev_base; dev; dev = dev->next) {
struct inet6_dev *idev;
};
if ((idev = in6_dev_get(dev)) == NULL)
continue;
read_lock_bh(&idev->lock);
for (im = idev->ac_list; im; im = im->aca_next) {
int i;
len += sprintf(buffer+len,"%-4d %-15s ", dev->ifindex, dev->name);
#define ac6_seq_private(seq) ((struct ac6_iter_state *)&seq->private)
for (i=0; i<16; i++)
len += sprintf(buffer+len, "%02x", im->aca_addr.s6_addr[i]);
len += sprintf(buffer+len, " %5d\n", im->aca_users);
static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq)
{
struct ifacaddr6 *im = NULL;
struct ac6_iter_state *state = ac6_seq_private(seq);
pos=begin+len;
if (pos < offset) {
len=0;
begin=pos;
for (state->dev = dev_base, state->idev = NULL;
state->dev;
state->dev = state->dev->next) {
struct inet6_dev *idev;
idev = in6_dev_get(state->dev);
if (!idev)
continue;
read_lock_bh(&idev->lock);
im = idev->ac_list;
if (im) {
state->idev = idev;
break;
}
if (pos > offset+length) {
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
goto done;
}
return im;
}
static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im)
{
struct ac6_iter_state *state = ac6_seq_private(seq);
im = im->aca_next;
while (!im) {
if (likely(state->idev != NULL)) {
read_unlock_bh(&state->idev->lock);
in6_dev_put(state->idev);
}
read_unlock_bh(&idev->lock);
in6_dev_put(idev);
state->dev = state->dev->next;
if (!state->dev) {
state->idev = NULL;
break;
}
state->idev = in6_dev_get(state->dev);
if (!state->idev)
continue;
read_lock_bh(&state->idev->lock);
im = state->idev->ac_list;
}
return im;
}
done:
static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos)
{
struct ifacaddr6 *im = ac6_get_first(seq);
if (im)
while (pos && (im = ac6_get_next(seq, im)) != NULL)
--pos;
return pos ? NULL : im;
}
static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
{
read_lock(&dev_base_lock);
return *pos ? ac6_get_idx(seq, *pos) : ac6_get_first(seq);
}
static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct ifacaddr6 *im;
im = ac6_get_next(seq, v);
++*pos;
return im;
}
static void ac6_seq_stop(struct seq_file *seq, void *v)
{
struct ac6_iter_state *state = ac6_seq_private(seq);
if (likely(state->idev != NULL)) {
read_unlock_bh(&state->idev->lock);
in6_dev_put(state->idev);
}
read_unlock(&dev_base_lock);
}
*start=buffer+(offset-begin);
len-=(offset-begin);
if(len>length)
len=length;
if (len<0)
len=0;
return len;
static int ac6_seq_show(struct seq_file *seq, void *v)
{
struct ifacaddr6 *im = (struct ifacaddr6 *)v;
struct ac6_iter_state *state = ac6_seq_private(seq);
seq_printf(seq,
"%-4d %-15s "
"%04x%04x%04x%04x%04x%04x%04x%04x "
"%5d\n",
state->dev->ifindex, state->dev->name,
NIP6(im->aca_addr),
im->aca_users);
return 0;
}
static struct seq_operations ac6_seq_ops = {
.start = ac6_seq_start,
.next = ac6_seq_next,
.stop = ac6_seq_stop,
.show = ac6_seq_show,
};
static int ac6_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
struct ac6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
rc = seq_open(file, &ac6_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
kfree(s);
goto out;
}
static struct file_operations ac6_seq_fops = {
.owner = THIS_MODULE,
.open = ac6_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_private,
};
int __init ac6_proc_init(void)
{
struct proc_dir_entry *p;
p = create_proc_entry("anycast6", S_IRUGO, proc_net);
if (p)
p->proc_fops = &ac6_seq_fops;
return 0;
}
void ac6_proc_exit(void)
{
proc_net_remove("anycast6");
}
#endif
......@@ -657,7 +657,25 @@ static struct seq_operations ip6fl_seq_ops = {
static int ip6fl_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &ip6fl_seq_ops);
struct seq_file *seq;
int rc = -ENOMEM;
struct ip6fl_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
rc = seq_open(file, &ip6fl_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
kfree(s);
goto out;
}
static struct file_operations ip6fl_seq_fops = {
......@@ -665,7 +683,7 @@ static struct file_operations ip6fl_seq_fops = {
.open = ip6fl_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.release = seq_release_private,
};
#endif
......
This diff is collapsed.
......@@ -1029,7 +1029,22 @@ static struct seq_operations raw6_seq_ops = {
static int raw6_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &raw6_seq_ops);
struct seq_file *seq;
int rc = -ENOMEM;
struct raw6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
rc = seq_open(file, &raw6_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
return rc;
out_kfree:
kfree(s);
goto out;
}
static struct file_operations raw6_seq_fops = {
......@@ -1037,7 +1052,7 @@ static struct file_operations raw6_seq_fops = {
.open = raw6_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
.release = seq_release_private,
};
int __init raw6_proc_init(void)
......
......@@ -93,43 +93,6 @@ static __inline__ int tcp_v6_sk_hashfn(struct sock *sk)
return tcp_v6_hashfn(laddr, lport, faddr, fport);
}
static inline int ipv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
return 1;
if (sk2->sk_family == AF_INET6 &&
ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
!(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
return 1;
if (addr_type == IPV6_ADDR_ANY &&
(!ipv6_only_sock(sk) ||
!(sk2->sk_family == AF_INET6 ?
(ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) :
1)))
return 1;
if (sk2->sk_family == AF_INET6 &&
!ipv6_addr_cmp(&np->rcv_saddr,
(sk2->sk_state != TCP_TIME_WAIT ?
&inet6_sk(sk2)->rcv_saddr :
&((struct tcp_tw_bucket *)sk)->tw_v6_rcv_saddr)))
return 1;
if (addr_type == IPV6_ADDR_MAPPED &&
!ipv6_only_sock(sk2) &&
(!inet_sk(sk2)->rcv_saddr ||
!inet_sk(sk)->rcv_saddr ||
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
return 1;
return 0;
}
static inline int tcp_v6_bind_conflict(struct sock *sk,
struct tcp_bind_bucket *tb)
{
......
......@@ -59,43 +59,6 @@
DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6);
/* XXX This is identical to tcp_ipv6.c:ipv6_rcv_saddr_equal, put
* XXX it somewhere common. -DaveM
*/
static __inline__ int udv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
return 1;
if (sk2->sk_family == AF_INET6 &&
ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
!(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
return 1;
if (addr_type == IPV6_ADDR_ANY &&
(!ipv6_only_sock(sk) ||
!(sk2->sk_family == AF_INET6 ?
(ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) : 1)))
return 1;
if (sk2->sk_family == AF_INET6 &&
!ipv6_addr_cmp(&inet6_sk(sk)->rcv_saddr,
&inet6_sk(sk2)->rcv_saddr))
return 1;
if (addr_type == IPV6_ADDR_MAPPED &&
!ipv6_only_sock(sk2) &&
(!inet_sk(sk2)->rcv_saddr ||
!inet_sk(sk)->rcv_saddr ||
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
return 1;
return 0;
}
/* Grrr, addr_type already calculated by caller, but I don't want
* to add some silly "cookie" argument to this method just for that.
*/
......@@ -151,7 +114,7 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum)
sk2 != sk &&
sk2->sk_bound_dev_if == sk->sk_bound_dev_if &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
udv6_rcv_saddr_equal(sk, sk2))
ipv6_rcv_saddr_equal(sk, sk2))
goto fail;
}
}
......
......@@ -67,10 +67,8 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
xfrm_vec[xfrm_nr++].xvec = x;
iph = skb->nh.ipv6h;
if (x->props.mode) { /* XXX */
if (iph->nexthdr != IPPROTO_IPV6)
if (nexthdr != IPPROTO_IPV6)
goto drop;
skb->nh.raw = skb->data;
iph = skb->nh.ipv6h;
......
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