Commit eb693d29 authored by Linus Torvalds's avatar Linus Torvalds

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

parents 6dec3cf5 01d40f28
...@@ -548,6 +548,14 @@ config SUNGEM ...@@ -548,6 +548,14 @@ config SUNGEM
Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also
<http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>. <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
config CASSINI
tristate "Sun Cassini support"
depends on NET_ETHERNET && PCI
select CRC32
help
Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
<http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
config NET_VENDOR_3COM config NET_VENDOR_3COM
bool "3COM cards" bool "3COM cards"
depends on NET_ETHERNET && (ISA || EISA || MCA || PCI) depends on NET_ETHERNET && (ISA || EISA || MCA || PCI)
......
...@@ -28,6 +28,7 @@ obj-$(CONFIG_SUNQE) += sunqe.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_SUNQE) += sunqe.o
obj-$(CONFIG_SUNBMAC) += sunbmac.o obj-$(CONFIG_SUNBMAC) += sunbmac.o
obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o
obj-$(CONFIG_CASSINI) += cassini.o
obj-$(CONFIG_MACE) += mace.o obj-$(CONFIG_MACE) += mace.o
obj-$(CONFIG_BMAC) += bmac.o obj-$(CONFIG_BMAC) += bmac.o
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -111,7 +111,9 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) ...@@ -111,7 +111,9 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
return (struct ethhdr *)skb->mac.raw; return (struct ethhdr *)skb->mac.raw;
} }
#ifdef CONFIG_SYSCTL
extern struct ctl_table ether_table[]; extern struct ctl_table ether_table[];
#endif #endif
#endif
#endif /* _LINUX_IF_ETHER_H */ #endif /* _LINUX_IF_ETHER_H */
...@@ -265,6 +265,8 @@ struct net_device ...@@ -265,6 +265,8 @@ struct net_device
* the interface. * the interface.
*/ */
char name[IFNAMSIZ]; char name[IFNAMSIZ];
/* device name hash chain */
struct hlist_node name_hlist;
/* /*
* I/O specific fields * I/O specific fields
...@@ -292,6 +294,21 @@ struct net_device ...@@ -292,6 +294,21 @@ struct net_device
/* ------- Fields preinitialized in Space.c finish here ------- */ /* ------- Fields preinitialized in Space.c finish here ------- */
/* Net device features */
unsigned long features;
#define NETIF_F_SG 1 /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */
#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
#define NETIF_F_LLTX 4096 /* LockLess TX */
struct net_device *next_sched; struct net_device *next_sched;
/* Interface index. Unique device identifier */ /* Interface index. Unique device identifier */
...@@ -316,9 +333,6 @@ struct net_device ...@@ -316,9 +333,6 @@ struct net_device
* will (read: may be cleaned up at will). * will (read: may be cleaned up at will).
*/ */
/* These may be needed for future network-power-down code. */
unsigned long trans_start; /* Time (in jiffies) of last Tx */
unsigned long last_rx; /* Time of last Rx */
unsigned short flags; /* interface flags (a la BSD) */ unsigned short flags; /* interface flags (a la BSD) */
unsigned short gflags; unsigned short gflags;
...@@ -328,15 +342,12 @@ struct net_device ...@@ -328,15 +342,12 @@ struct net_device
unsigned mtu; /* interface MTU value */ unsigned mtu; /* interface MTU value */
unsigned short type; /* interface hardware type */ unsigned short type; /* interface hardware type */
unsigned short hard_header_len; /* hardware hdr length */ unsigned short hard_header_len; /* hardware hdr length */
void *priv; /* pointer to private data */
struct net_device *master; /* Pointer to master device of a group, struct net_device *master; /* Pointer to master device of a group,
* which this device is member of. * which this device is member of.
*/ */
/* Interface address info. */ /* Interface address info. */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
unsigned char addr_len; /* hardware address length */ unsigned char addr_len; /* hardware address length */
unsigned short dev_id; /* for shared network cards */ unsigned short dev_id; /* for shared network cards */
...@@ -346,8 +357,6 @@ struct net_device ...@@ -346,8 +357,6 @@ struct net_device
int promiscuity; int promiscuity;
int allmulti; int allmulti;
int watchdog_timeo;
struct timer_list watchdog_timer;
/* Protocol specific pointers */ /* Protocol specific pointers */
...@@ -358,32 +367,62 @@ struct net_device ...@@ -358,32 +367,62 @@ struct net_device
void *ec_ptr; /* Econet specific data */ void *ec_ptr; /* Econet specific data */
void *ax25_ptr; /* AX.25 specific data */ void *ax25_ptr; /* AX.25 specific data */
struct list_head poll_list; /* Link to poll list */ /*
* Cache line mostly used on receive path (including eth_type_trans())
*/
struct list_head poll_list ____cacheline_aligned_in_smp;
/* Link to poll list */
int (*poll) (struct net_device *dev, int *quota);
int quota; int quota;
int weight; int weight;
unsigned long last_rx; /* Time of last Rx */
/* Interface address info used in eth_type_trans() */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
because most packets are unicast) */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
/*
* Cache line mostly used on queue transmit path (qdisc)
*/
/* device queue lock */
spinlock_t queue_lock ____cacheline_aligned_in_smp;
struct Qdisc *qdisc; struct Qdisc *qdisc;
struct Qdisc *qdisc_sleeping; struct Qdisc *qdisc_sleeping;
struct Qdisc *qdisc_ingress;
struct list_head qdisc_list; struct list_head qdisc_list;
unsigned long tx_queue_len; /* Max frames per queue allowed */ unsigned long tx_queue_len; /* Max frames per queue allowed */
/* ingress path synchronizer */ /* ingress path synchronizer */
spinlock_t ingress_lock; spinlock_t ingress_lock;
struct Qdisc *qdisc_ingress;
/*
* One part is mostly used on xmit path (device)
*/
/* hard_start_xmit synchronizer */ /* hard_start_xmit synchronizer */
spinlock_t xmit_lock; spinlock_t xmit_lock ____cacheline_aligned_in_smp;
/* cpu id of processor entered to hard_start_xmit or -1, /* cpu id of processor entered to hard_start_xmit or -1,
if nobody entered there. if nobody entered there.
*/ */
int xmit_lock_owner; int xmit_lock_owner;
/* device queue lock */ void *priv; /* pointer to private data */
spinlock_t queue_lock; int (*hard_start_xmit) (struct sk_buff *skb,
struct net_device *dev);
/* These may be needed for future network-power-down code. */
unsigned long trans_start; /* Time (in jiffies) of last Tx */
int watchdog_timeo; /* used by dev_watchdog() */
struct timer_list watchdog_timer;
/*
* refcnt is a very hot point, so align it on SMP
*/
/* Number of references to this device */ /* Number of references to this device */
atomic_t refcnt; atomic_t refcnt ____cacheline_aligned_in_smp;
/* delayed register/unregister */ /* delayed register/unregister */
struct list_head todo_list; struct list_head todo_list;
/* device name hash chain */
struct hlist_node name_hlist;
/* device index hash chain */ /* device index hash chain */
struct hlist_node index_hlist; struct hlist_node index_hlist;
...@@ -396,21 +435,6 @@ struct net_device ...@@ -396,21 +435,6 @@ struct net_device
NETREG_RELEASED, /* called free_netdev */ NETREG_RELEASED, /* called free_netdev */
} reg_state; } reg_state;
/* Net device features */
unsigned long features;
#define NETIF_F_SG 1 /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */
#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */
#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */
#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */
#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */
#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */
#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */
#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */
#define NETIF_F_LLTX 4096 /* LockLess TX */
/* Called after device is detached from network. */ /* Called after device is detached from network. */
void (*uninit)(struct net_device *dev); void (*uninit)(struct net_device *dev);
/* Called after last user reference disappears. */ /* Called after last user reference disappears. */
...@@ -419,10 +443,7 @@ struct net_device ...@@ -419,10 +443,7 @@ struct net_device
/* Pointers to interface service routines. */ /* Pointers to interface service routines. */
int (*open)(struct net_device *dev); int (*open)(struct net_device *dev);
int (*stop)(struct net_device *dev); int (*stop)(struct net_device *dev);
int (*hard_start_xmit) (struct sk_buff *skb,
struct net_device *dev);
#define HAVE_NETDEV_POLL #define HAVE_NETDEV_POLL
int (*poll) (struct net_device *dev, int *quota);
int (*hard_header) (struct sk_buff *skb, int (*hard_header) (struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
unsigned short type, unsigned short type,
......
...@@ -392,6 +392,7 @@ ...@@ -392,6 +392,7 @@
#define PCI_DEVICE_ID_NS_87560_USB 0x0012 #define PCI_DEVICE_ID_NS_87560_USB 0x0012
#define PCI_DEVICE_ID_NS_83815 0x0020 #define PCI_DEVICE_ID_NS_83815 0x0020
#define PCI_DEVICE_ID_NS_83820 0x0022 #define PCI_DEVICE_ID_NS_83820 0x0022
#define PCI_DEVICE_ID_NS_SATURN 0x0035
#define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500 #define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500
#define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501 #define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501
#define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502 #define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502
...@@ -983,6 +984,7 @@ ...@@ -983,6 +984,7 @@
#define PCI_DEVICE_ID_SUN_SABRE 0xa000 #define PCI_DEVICE_ID_SUN_SABRE 0xa000
#define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001 #define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001
#define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801 #define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801
#define PCI_DEVICE_ID_SUN_CASSINI 0xabba
#define PCI_VENDOR_ID_CMD 0x1095 #define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_640 0x0640 #define PCI_DEVICE_ID_CMD_640 0x0640
......
...@@ -100,8 +100,7 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, ...@@ -100,8 +100,7 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,
continue; continue;
if (to->sat_addr.s_net == ATADDR_ANYNET && if (to->sat_addr.s_net == ATADDR_ANYNET &&
to->sat_addr.s_node == ATADDR_BCAST && to->sat_addr.s_node == ATADDR_BCAST)
at->src_net == atif->address.s_net)
goto found; goto found;
if (to->sat_addr.s_net == at->src_net && if (to->sat_addr.s_net == at->src_net &&
...@@ -1443,8 +1442,10 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1443,8 +1442,10 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
else else
atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode);
/* Not ours, so we route the packet via the correct AppleTalk iface */
if (!atif) { if (!atif) {
/* Not ours, so we route the packet via the correct
* AppleTalk iface
*/
atalk_route_packet(skb, dev, ddp, &ddphv, origlen); atalk_route_packet(skb, dev, ddp, &ddphv, origlen);
goto out; goto out;
} }
...@@ -1592,9 +1593,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr ...@@ -1592,9 +1593,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) {
rt = atrtr_find(&usat->sat_addr); rt = atrtr_find(&usat->sat_addr);
if (!rt)
return -ENETUNREACH;
dev = rt->dev; dev = rt->dev;
} else { } else {
struct atalk_addr at_hint; struct atalk_addr at_hint;
...@@ -1603,11 +1601,12 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr ...@@ -1603,11 +1601,12 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
at_hint.s_net = at->src_net; at_hint.s_net = at->src_net;
rt = atrtr_find(&at_hint); rt = atrtr_find(&at_hint);
if (!rt)
return -ENETUNREACH;
dev = rt->dev; dev = rt->dev;
} }
if (!rt)
return -ENETUNREACH;
dev = rt->dev;
SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n",
sk, size, dev->name); sk, size, dev->name);
...@@ -1677,6 +1676,20 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr ...@@ -1677,6 +1676,20 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
/* loop back */ /* loop back */
skb_orphan(skb); skb_orphan(skb);
if (ddp->deh_dnode == ATADDR_BCAST) {
struct atalk_addr at_lo;
at_lo.s_node = 0;
at_lo.s_net = 0;
rt = atrtr_find(&at_lo);
if (!rt) {
kfree_skb(skb);
return -ENETUNREACH;
}
dev = rt->dev;
skb->dev = dev;
}
ddp_dl->request(ddp_dl, skb, dev->dev_addr); ddp_dl->request(ddp_dl, skb, dev->dev_addr);
} else { } else {
SOCK_DEBUG(sk, "SK %p: send out.\n", sk); SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
......
...@@ -50,8 +50,10 @@ void atm_reset_addr(struct atm_dev *dev) ...@@ -50,8 +50,10 @@ void atm_reset_addr(struct atm_dev *dev)
struct atm_dev_addr *this, *p; struct atm_dev_addr *this, *p;
spin_lock_irqsave(&dev->lock, flags); spin_lock_irqsave(&dev->lock, flags);
list_for_each_entry_safe(this, p, &dev->local, entry) list_for_each_entry_safe(this, p, &dev->local, entry) {
kfree(this); list_del(&this->entry);
kfree(this);
}
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
notify_sigd(dev); notify_sigd(dev);
} }
......
...@@ -178,8 +178,6 @@ static void vcc_destroy_socket(struct sock *sk) ...@@ -178,8 +178,6 @@ static void vcc_destroy_socket(struct sock *sk)
if (vcc->push) if (vcc->push)
vcc->push(vcc, NULL); /* atmarpd has no push */ vcc->push(vcc, NULL); /* atmarpd has no push */
vcc_remove_socket(sk); /* no more receive */
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
atm_return(vcc,skb->truesize); atm_return(vcc,skb->truesize);
kfree_skb(skb); kfree_skb(skb);
...@@ -188,6 +186,8 @@ static void vcc_destroy_socket(struct sock *sk) ...@@ -188,6 +186,8 @@ static void vcc_destroy_socket(struct sock *sk)
module_put(vcc->dev->ops->owner); module_put(vcc->dev->ops->owner);
atm_dev_put(vcc->dev); atm_dev_put(vcc->dev);
} }
vcc_remove_socket(sk);
} }
......
...@@ -105,17 +105,35 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -105,17 +105,35 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (!error) if (!error)
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
goto done; goto done;
default: case ATM_SETBACKEND:
case ATM_NEWBACKENDIF:
{
atm_backend_t backend;
error = get_user(backend, (atm_backend_t __user *) argp);
if (error)
goto done;
switch (backend) {
case ATM_BACKEND_PPP:
request_module("pppoatm");
break;
case ATM_BACKEND_BR2684:
request_module("br2684");
break;
}
}
break;
case ATMMPC_CTRL:
case ATMMPC_DATA:
request_module("mpoa");
break;
case ATMARPD_CTRL:
request_module("clip");
break;
case ATMLEC_CTRL:
request_module("lec");
break; break;
} }
if (cmd == ATMMPC_CTRL || cmd == ATMMPC_DATA)
request_module("mpoa");
if (cmd == ATMARPD_CTRL)
request_module("clip");
if (cmd == ATMLEC_CTRL)
request_module("lec");
error = -ENOIOCTLCMD; error = -ENOIOCTLCMD;
down(&ioctl_mutex); down(&ioctl_mutex);
......
...@@ -217,8 +217,9 @@ void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type, ...@@ -217,8 +217,9 @@ void sigd_enq(struct atm_vcc *vcc,enum atmsvc_msg_type type,
static void purge_vcc(struct atm_vcc *vcc) static void purge_vcc(struct atm_vcc *vcc)
{ {
if (sk_atm(vcc)->sk_family == PF_ATMSVC && if (sk_atm(vcc)->sk_family == PF_ATMSVC &&
!test_bit(ATM_VF_META,&vcc->flags)) { !test_bit(ATM_VF_META, &vcc->flags)) {
set_bit(ATM_VF_RELEASED,&vcc->flags); set_bit(ATM_VF_RELEASED, &vcc->flags);
clear_bit(ATM_VF_REGIS, &vcc->flags);
vcc_release_async(vcc, -EUNATCH); vcc_release_async(vcc, -EUNATCH);
} }
} }
...@@ -243,8 +244,7 @@ static void sigd_close(struct atm_vcc *vcc) ...@@ -243,8 +244,7 @@ static void sigd_close(struct atm_vcc *vcc)
sk_for_each(s, node, head) { sk_for_each(s, node, head) {
struct atm_vcc *vcc = atm_sk(s); struct atm_vcc *vcc = atm_sk(s);
if (vcc->dev) purge_vcc(vcc);
purge_vcc(vcc);
} }
} }
read_unlock(&vcc_sklist_lock); read_unlock(&vcc_sklist_lock);
......
...@@ -302,6 +302,7 @@ static int svc_listen(struct socket *sock,int backlog) ...@@ -302,6 +302,7 @@ static int svc_listen(struct socket *sock,int backlog)
error = -EINVAL; error = -EINVAL;
goto out; goto out;
} }
vcc_insert_socket(sk);
set_bit(ATM_VF_WAITING, &vcc->flags); set_bit(ATM_VF_WAITING, &vcc->flags);
prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local); sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
......
...@@ -211,74 +211,45 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) ...@@ -211,74 +211,45 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
struct iovec *to, int len) struct iovec *to, int len)
{ {
int start = skb_headlen(skb); int i, err, fraglen, end = 0;
int i, copy = start - offset; struct sk_buff *next = skb_shinfo(skb)->frag_list;
next_skb:
/* Copy header. */ fraglen = skb_headlen(skb);
if (copy > 0) { i = -1;
if (copy > len)
copy = len;
if (memcpy_toiovec(to, skb->data + offset, copy))
goto fault;
if ((len -= copy) == 0)
return 0;
offset += copy;
}
/* Copy paged appendix. Hmm... why does this look so complicated? */ while (1) {
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int start = end;
int end;
BUG_TRAP(start <= offset + len);
end = start + skb_shinfo(skb)->frags[i].size; if ((end += fraglen) > offset) {
if ((copy = end - offset) > 0) { int copy = end - offset, o = offset - start;
int err;
u8 *vaddr;
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
struct page *page = frag->page;
if (copy > len) if (copy > len)
copy = len; copy = len;
vaddr = kmap(page); if (i == -1)
err = memcpy_toiovec(to, vaddr + frag->page_offset + err = memcpy_toiovec(to, skb->data + o, copy);
offset - start, copy); else {
kunmap(page); skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
struct page *page = frag->page;
void *p = kmap(page) + frag->page_offset + o;
err = memcpy_toiovec(to, p, copy);
kunmap(page);
}
if (err) if (err)
goto fault; goto fault;
if (!(len -= copy)) if (!(len -= copy))
return 0; return 0;
offset += copy; offset += copy;
} }
start = end; if (++i >= skb_shinfo(skb)->nr_frags)
break;
fraglen = skb_shinfo(skb)->frags[i].size;
} }
if (next) {
if (skb_shinfo(skb)->frag_list) { skb = next;
struct sk_buff *list = skb_shinfo(skb)->frag_list; BUG_ON(skb_shinfo(skb)->frag_list);
next = skb->next;
for (; list; list = list->next) { goto next_skb;
int end;
BUG_TRAP(start <= offset + len);
end = start + list->len;
if ((copy = end - offset) > 0) {
if (copy > len)
copy = len;
if (skb_copy_datagram_iovec(list,
offset - start,
to, copy))
goto fault;
if ((len -= copy) == 0)
return 0;
offset += copy;
}
start = end;
}
} }
if (!len)
return 0;
fault: fault:
return -EFAULT; return -EFAULT;
} }
......
...@@ -1259,6 +1259,8 @@ int dev_queue_xmit(struct sk_buff *skb) ...@@ -1259,6 +1259,8 @@ int dev_queue_xmit(struct sk_buff *skb)
if (skb_checksum_help(skb, 0)) if (skb_checksum_help(skb, 0))
goto out_kfree_skb; goto out_kfree_skb;
spin_lock_prefetch(&dev->queue_lock);
/* Disable soft irqs for various locks below. Also /* Disable soft irqs for various locks below. Also
* stops preemption for RCU. * stops preemption for RCU.
*/ */
......
...@@ -660,16 +660,20 @@ struct sock *sk_alloc(int family, unsigned int __nocast priority, ...@@ -660,16 +660,20 @@ struct sock *sk_alloc(int family, unsigned int __nocast priority,
sock_lock_init(sk); sock_lock_init(sk);
} }
if (security_sk_alloc(sk, family, priority)) { if (security_sk_alloc(sk, family, priority))
if (slab != NULL) goto out_free;
kmem_cache_free(slab, sk);
else if (!try_module_get(prot->owner))
kfree(sk); goto out_free;
sk = NULL;
} else
__module_get(prot->owner);
} }
return sk; return sk;
out_free:
if (slab != NULL)
kmem_cache_free(slab, sk);
else
kfree(sk);
return NULL;
} }
void sk_free(struct sock *sk) void sk_free(struct sock *sk)
......
...@@ -146,6 +146,19 @@ int eth_rebuild_header(struct sk_buff *skb) ...@@ -146,6 +146,19 @@ int eth_rebuild_header(struct sk_buff *skb)
return 0; return 0;
} }
static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b)
{
const unsigned short *dest = (unsigned short *) __a;
const unsigned short *devaddr = (unsigned short *) __b;
unsigned int res;
BUILD_BUG_ON(ETH_ALEN != 6);
res = ((dest[0] ^ devaddr[0]) |
(dest[1] ^ devaddr[1]) |
(dest[2] ^ devaddr[2])) != 0;
return res;
}
/* /*
* Determine the packet's protocol ID. The rule here is that we * Determine the packet's protocol ID. The rule here is that we
...@@ -158,16 +171,15 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -158,16 +171,15 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
struct ethhdr *eth; struct ethhdr *eth;
unsigned char *rawp; unsigned char *rawp;
skb->mac.raw=skb->data; skb->mac.raw = skb->data;
skb_pull(skb,ETH_HLEN); skb_pull(skb,ETH_HLEN);
eth = eth_hdr(skb); eth = eth_hdr(skb);
if(*eth->h_dest&1) if (*eth->h_dest&1) {
{ if (!compare_eth_addr(eth->h_dest, dev->broadcast))
if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0) skb->pkt_type = PACKET_BROADCAST;
skb->pkt_type=PACKET_BROADCAST;
else else
skb->pkt_type=PACKET_MULTICAST; skb->pkt_type = PACKET_MULTICAST;
} }
/* /*
...@@ -178,10 +190,9 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -178,10 +190,9 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
* seems to set IFF_PROMISC. * seems to set IFF_PROMISC.
*/ */
else if(1 /*dev->flags&IFF_PROMISC*/) else if(1 /*dev->flags&IFF_PROMISC*/) {
{ if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr)))
if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN)) skb->pkt_type = PACKET_OTHERHOST;
skb->pkt_type=PACKET_OTHERHOST;
} }
if (ntohs(eth->h_proto) >= 1536) if (ntohs(eth->h_proto) >= 1536)
......
...@@ -190,15 +190,16 @@ void tcp_select_initial_window(int __space, __u32 mss, ...@@ -190,15 +190,16 @@ void tcp_select_initial_window(int __space, __u32 mss,
} }
/* Set initial window to value enough for senders, /* Set initial window to value enough for senders,
* following RFC1414. Senders, not following this RFC, * following RFC2414. Senders, not following this RFC,
* will be satisfied with 2. * will be satisfied with 2.
*/ */
if (mss > (1<<*rcv_wscale)) { if (mss > (1<<*rcv_wscale)) {
int init_cwnd = 4; int init_cwnd;
if (mss > 1460*3)
if (mss > 1460)
init_cwnd = 2; init_cwnd = 2;
else if (mss > 1460) else
init_cwnd = 3; init_cwnd = (mss > 1095) ? 3 : 4;
if (*rcv_wnd > init_cwnd*mss) if (*rcv_wnd > init_cwnd*mss)
*rcv_wnd = init_cwnd*mss; *rcv_wnd = init_cwnd*mss;
} }
......
...@@ -1472,22 +1472,25 @@ static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 ...@@ -1472,22 +1472,25 @@ static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62
static int __init rose_proto_init(void) static int __init rose_proto_init(void)
{ {
int i; int i;
int rc = proto_register(&rose_proto, 0); int rc;
if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) {
printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n");
rc = -EINVAL;
goto out;
}
rc = proto_register(&rose_proto, 0);
if (rc != 0) if (rc != 0)
goto out; goto out;
rose_callsign = null_ax25_address; rose_callsign = null_ax25_address;
if (rose_ndevs > 0x7FFFFFFF/sizeof(struct net_device *)) {
printk(KERN_ERR "ROSE: rose_proto_init - rose_ndevs parameter to large\n");
return -1;
}
dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL); dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device *), GFP_KERNEL);
if (dev_rose == NULL) { if (dev_rose == NULL) {
printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n");
return -1; rc = -ENOMEM;
goto out_proto_unregister;
} }
memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device*)); memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device*));
...@@ -1500,10 +1503,12 @@ static int __init rose_proto_init(void) ...@@ -1500,10 +1503,12 @@ static int __init rose_proto_init(void)
name, rose_setup); name, rose_setup);
if (!dev) { if (!dev) {
printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n"); printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate memory\n");
rc = -ENOMEM;
goto fail; goto fail;
} }
if (register_netdev(dev)) { rc = register_netdev(dev);
printk(KERN_ERR "ROSE: netdevice regeistration failed\n"); if (rc) {
printk(KERN_ERR "ROSE: netdevice registration failed\n");
free_netdev(dev); free_netdev(dev);
goto fail; goto fail;
} }
...@@ -1536,8 +1541,9 @@ static int __init rose_proto_init(void) ...@@ -1536,8 +1541,9 @@ static int __init rose_proto_init(void)
free_netdev(dev_rose[i]); free_netdev(dev_rose[i]);
} }
kfree(dev_rose); kfree(dev_rose);
out_proto_unregister:
proto_unregister(&rose_proto); proto_unregister(&rose_proto);
return -ENOMEM; goto out;
} }
module_init(rose_proto_init); module_init(rose_proto_init);
......
...@@ -1145,8 +1145,11 @@ static int __sock_create(int family, int type, int protocol, struct socket **res ...@@ -1145,8 +1145,11 @@ static int __sock_create(int family, int type, int protocol, struct socket **res
if (!try_module_get(net_families[family]->owner)) if (!try_module_get(net_families[family]->owner))
goto out_release; goto out_release;
if ((err = net_families[family]->create(sock, protocol)) < 0) if ((err = net_families[family]->create(sock, protocol)) < 0) {
sock->ops = NULL;
goto out_module_put; goto out_module_put;
}
/* /*
* Now to bump the refcnt of the [loadable] module that owns this * Now to bump the refcnt of the [loadable] module that owns this
* socket at sock_release time we decrement its refcnt. * socket at sock_release time we decrement its refcnt.
...@@ -1360,16 +1363,16 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _ ...@@ -1360,16 +1363,16 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
newsock->type = sock->type; newsock->type = sock->type;
newsock->ops = sock->ops; newsock->ops = sock->ops;
err = security_socket_accept(sock, newsock);
if (err)
goto out_release;
/* /*
* We don't need try_module_get here, as the listening socket (sock) * We don't need try_module_get here, as the listening socket (sock)
* has the protocol module (sock->ops->owner) held. * has the protocol module (sock->ops->owner) held.
*/ */
__module_get(newsock->ops->owner); __module_get(newsock->ops->owner);
err = security_socket_accept(sock, newsock);
if (err)
goto out_release;
err = sock->ops->accept(sock, newsock, sock->file->f_flags); err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0) if (err < 0)
goto out_release; goto out_release;
......
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