Commit 76abf3e7 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

parents d90d4392 7957aed7
...@@ -1086,7 +1086,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen) ...@@ -1086,7 +1086,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
} }
if (tp && tp->pos + tp->bits > 32) if (tp && tp->pos + tp->bits > 32)
printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n", printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
tp, tp->pos, tp->bits, key, plen); tp, tp->pos, tp->bits, key, plen);
/* Rebalance the trie */ /* Rebalance the trie */
...@@ -1832,16 +1832,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi ...@@ -1832,16 +1832,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
i++; i++;
continue; continue;
} }
if (fa->fa_info->fib_nh == NULL) { BUG_ON(!fa->fa_info);
printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
i++;
continue;
}
if (fa->fa_info == NULL) {
printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
i++;
continue;
}
if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid, if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
...@@ -1964,7 +1955,7 @@ struct fib_table * __init fib_hash_init(int id) ...@@ -1964,7 +1955,7 @@ struct fib_table * __init fib_hash_init(int id)
trie_main = t; trie_main = t;
if (id == RT_TABLE_LOCAL) if (id == RT_TABLE_LOCAL)
printk("IPv4 FIB: Using LC-trie version %s\n", VERSION); printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
return tb; return tb;
} }
......
...@@ -384,7 +384,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, ...@@ -384,7 +384,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
newtp->frto_counter = 0; newtp->frto_counter = 0;
newtp->frto_highmark = 0; newtp->frto_highmark = 0;
newicsk->icsk_ca_ops = &tcp_reno; newicsk->icsk_ca_ops = &tcp_init_congestion_ops;
tcp_set_ca_state(newsk, TCP_CA_Open); tcp_set_ca_state(newsk, TCP_CA_Open);
tcp_init_xmit_timers(newsk); tcp_init_xmit_timers(newsk);
......
...@@ -36,6 +36,11 @@ ...@@ -36,6 +36,11 @@
* Michal Ostrowski : Module initialization cleanup. * Michal Ostrowski : Module initialization cleanup.
* Ulises Alonso : Frame number limit removal and * Ulises Alonso : Frame number limit removal and
* packet_set_ring memory leak. * packet_set_ring memory leak.
* Eric Biederman : Allow for > 8 byte hardware addresses.
* The convention is that longer addresses
* will simply extend the hardware address
* byte arrays at the end of sockaddr_ll
* and packet_mreq.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -161,7 +166,17 @@ struct packet_mclist ...@@ -161,7 +166,17 @@ struct packet_mclist
int count; int count;
unsigned short type; unsigned short type;
unsigned short alen; unsigned short alen;
unsigned char addr[8]; unsigned char addr[MAX_ADDR_LEN];
};
/* identical to struct packet_mreq except it has
* a longer address field.
*/
struct packet_mreq_max
{
int mr_ifindex;
unsigned short mr_type;
unsigned short mr_alen;
unsigned char mr_address[MAX_ADDR_LEN];
}; };
#endif #endif
#ifdef CONFIG_PACKET_MMAP #ifdef CONFIG_PACKET_MMAP
...@@ -716,6 +731,8 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -716,6 +731,8 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
err = -EINVAL; err = -EINVAL;
if (msg->msg_namelen < sizeof(struct sockaddr_ll)) if (msg->msg_namelen < sizeof(struct sockaddr_ll))
goto out; goto out;
if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
goto out;
ifindex = saddr->sll_ifindex; ifindex = saddr->sll_ifindex;
proto = saddr->sll_protocol; proto = saddr->sll_protocol;
addr = saddr->sll_addr; addr = saddr->sll_addr;
...@@ -744,6 +761,12 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -744,6 +761,12 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
if (dev->hard_header) { if (dev->hard_header) {
int res; int res;
err = -EINVAL; err = -EINVAL;
if (saddr) {
if (saddr->sll_halen != dev->addr_len)
goto out_free;
if (saddr->sll_hatype != dev->type)
goto out_free;
}
res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
if (sock->type != SOCK_DGRAM) { if (sock->type != SOCK_DGRAM) {
skb->tail = skb->data; skb->tail = skb->data;
...@@ -1045,6 +1068,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1045,6 +1068,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sk_buff *skb; struct sk_buff *skb;
int copied, err; int copied, err;
struct sockaddr_ll *sll;
err = -EINVAL; err = -EINVAL;
if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
...@@ -1056,16 +1080,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1056,16 +1080,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
return -ENODEV; return -ENODEV;
#endif #endif
/*
* If the address length field is there to be filled in, we fill
* it in now.
*/
if (sock->type == SOCK_PACKET)
msg->msg_namelen = sizeof(struct sockaddr_pkt);
else
msg->msg_namelen = sizeof(struct sockaddr_ll);
/* /*
* Call the generic datagram receiver. This handles all sorts * Call the generic datagram receiver. This handles all sorts
* of horrible races and re-entrancy so we can forget about it * of horrible races and re-entrancy so we can forget about it
...@@ -1086,6 +1100,17 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1086,6 +1100,17 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
if(skb==NULL) if(skb==NULL)
goto out; goto out;
/*
* If the address length field is there to be filled in, we fill
* it in now.
*/
sll = (struct sockaddr_ll*)skb->cb;
if (sock->type == SOCK_PACKET)
msg->msg_namelen = sizeof(struct sockaddr_pkt);
else
msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
/* /*
* You lose any data beyond the buffer you gave. If it worries a * You lose any data beyond the buffer you gave. If it worries a
* user program they can ask the device for its MTU anyway. * user program they can ask the device for its MTU anyway.
...@@ -1166,7 +1191,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -1166,7 +1191,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */ sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */
sll->sll_halen = 0; sll->sll_halen = 0;
} }
*uaddr_len = sizeof(*sll); *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
return 0; return 0;
} }
...@@ -1199,7 +1224,7 @@ static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, i ...@@ -1199,7 +1224,7 @@ static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, i
} }
} }
static int packet_mc_add(struct sock *sk, struct packet_mreq *mreq) static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
{ {
struct packet_sock *po = pkt_sk(sk); struct packet_sock *po = pkt_sk(sk);
struct packet_mclist *ml, *i; struct packet_mclist *ml, *i;
...@@ -1249,7 +1274,7 @@ done: ...@@ -1249,7 +1274,7 @@ done:
return err; return err;
} }
static int packet_mc_drop(struct sock *sk, struct packet_mreq *mreq) static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
{ {
struct packet_mclist *ml, **mlp; struct packet_mclist *ml, **mlp;
...@@ -1315,11 +1340,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv ...@@ -1315,11 +1340,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
case PACKET_ADD_MEMBERSHIP: case PACKET_ADD_MEMBERSHIP:
case PACKET_DROP_MEMBERSHIP: case PACKET_DROP_MEMBERSHIP:
{ {
struct packet_mreq mreq; struct packet_mreq_max mreq;
if (optlen<sizeof(mreq)) int len = optlen;
memset(&mreq, 0, sizeof(mreq));
if (len < sizeof(struct packet_mreq))
return -EINVAL; return -EINVAL;
if (copy_from_user(&mreq,optval,sizeof(mreq))) if (len > sizeof(mreq))
len = sizeof(mreq);
if (copy_from_user(&mreq,optval,len))
return -EFAULT; return -EFAULT;
if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
return -EINVAL;
if (optname == PACKET_ADD_MEMBERSHIP) if (optname == PACKET_ADD_MEMBERSHIP)
ret = packet_mc_add(sk, &mreq); ret = packet_mc_add(sk, &mreq);
else else
......
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