Commit faedca65 authored by Linus Torvalds's avatar Linus Torvalds

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

into home.transmeta.com:/home/torvalds/v2.5/linux
parents da220b09 75552d68
...@@ -826,7 +826,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) ...@@ -826,7 +826,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
* Otherwise we could race with the device. * Otherwise we could race with the device.
*/ */
first_eor = eor; first_eor = eor;
first_len = skb->len - skb->data_len; first_len = skb_headlen(skb);
first_mapping = pci_map_single(cp->pdev, skb->data, first_mapping = pci_map_single(cp->pdev, skb->data,
first_len, PCI_DMA_TODEVICE); first_len, PCI_DMA_TODEVICE);
cp->tx_skb[entry].skb = skb; cp->tx_skb[entry].skb = skb;
......
...@@ -2829,7 +2829,7 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2829,7 +2829,7 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
int i, len = 0; int i, len = 0;
mapping = ace_map_tx_skb(ap, skb, NULL, idx); mapping = ace_map_tx_skb(ap, skb, NULL, idx);
flagsize = ((skb->len - skb->data_len) << 16); flagsize = (skb_headlen(skb) << 16);
if (skb->ip_summed == CHECKSUM_HW) if (skb->ip_summed == CHECKSUM_HW)
flagsize |= BD_FLG_TCP_UDP_SUM; flagsize |= BD_FLG_TCP_UDP_SUM;
#if ACENIC_DO_VLAN #if ACENIC_DO_VLAN
......
...@@ -2199,10 +2199,10 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb) ...@@ -2199,10 +2199,10 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
(tcb->tbd_ptr)->tbd_buf_addr = (tcb->tbd_ptr)->tbd_buf_addr =
cpu_to_le32(pci_map_single(bdp->pdev, skb->data, cpu_to_le32(pci_map_single(bdp->pdev, skb->data,
(skb->len - skb->data_len), skb_headlen(skb),
PCI_DMA_TODEVICE)); PCI_DMA_TODEVICE));
(tcb->tbd_ptr)->tbd_buf_cnt = (tcb->tbd_ptr)->tbd_buf_cnt =
cpu_to_le16(skb->len - skb->data_len); cpu_to_le16(skb_headlen(skb));
for (i = 0; i < skb_shinfo(skb)->nr_frags; for (i = 0; i < skb_shinfo(skb)->nr_frags;
i++, tbd_arr_ptr++, frag++) { i++, tbd_arr_ptr++, frag++) {
......
...@@ -894,7 +894,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -894,7 +894,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* We must give this initial chunk to the device last. /* We must give this initial chunk to the device last.
* Otherwise we could race with the device. * Otherwise we could race with the device.
*/ */
first_len = skb->len - skb->data_len; first_len = skb_headlen(skb);
first_mapping = pci_map_page(gp->pdev, virt_to_page(skb->data), first_mapping = pci_map_page(gp->pdev, virt_to_page(skb->data),
((unsigned long) skb->data & ~PAGE_MASK), ((unsigned long) skb->data & ~PAGE_MASK),
first_len, PCI_DMA_TODEVICE); first_len, PCI_DMA_TODEVICE);
......
...@@ -2319,7 +2319,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2319,7 +2319,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* We must give this initial chunk to the device last. /* We must give this initial chunk to the device last.
* Otherwise we could race with the device. * Otherwise we could race with the device.
*/ */
first_len = skb->len - skb->data_len; first_len = skb_headlen(skb);
first_mapping = hme_dma_map(hp, skb->data, first_len, DMA_TODEVICE); first_mapping = hme_dma_map(hp, skb->data, first_len, DMA_TODEVICE);
entry = NEXT_TX(entry); entry = NEXT_TX(entry);
......
...@@ -1751,7 +1751,7 @@ static void tg3_tx(struct tg3 *tp) ...@@ -1751,7 +1751,7 @@ static void tg3_tx(struct tg3 *tp)
pci_unmap_single(tp->pdev, pci_unmap_single(tp->pdev,
pci_unmap_addr(ri, mapping), pci_unmap_addr(ri, mapping),
(skb->len - skb->data_len), skb_headlen(skb),
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
ri->skb = NULL; ri->skb = NULL;
...@@ -2316,7 +2316,7 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, ...@@ -2316,7 +2316,7 @@ static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
int len; int len;
if (i == 0) if (i == 0)
len = skb->len - skb->data_len; len = skb_headlen(skb);
else else
len = skb_shinfo(skb)->frags[i-1].size; len = skb_shinfo(skb)->frags[i-1].size;
pci_unmap_single(tp->pdev, pci_unmap_single(tp->pdev,
...@@ -2401,7 +2401,7 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev) ...@@ -2401,7 +2401,7 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev)
int would_hit_hwbug; int would_hit_hwbug;
unsigned long flags; unsigned long flags;
len = (skb->len - skb->data_len); len = skb_headlen(skb);
/* No BH disabling for tx_lock here. We are running in BH disabled /* No BH disabling for tx_lock here. We are running in BH disabled
* context and TX reclaim runs via tp->poll inside of a software * context and TX reclaim runs via tp->poll inside of a software
...@@ -2520,7 +2520,7 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev) ...@@ -2520,7 +2520,7 @@ static int tg3_start_xmit_4gbug(struct sk_buff *skb, struct net_device *dev)
i = 0; i = 0;
while (entry != last_plus_one) { while (entry != last_plus_one) {
if (i == 0) if (i == 0)
len = skb->len - skb->data_len; len = skb_headlen(skb);
else else
len = skb_shinfo(skb)->frags[i-1].size; len = skb_shinfo(skb)->frags[i-1].size;
...@@ -2593,7 +2593,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -2593,7 +2593,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 len, entry, base_flags, mss; u32 len, entry, base_flags, mss;
unsigned long flags; unsigned long flags;
len = (skb->len - skb->data_len); len = skb_headlen(skb);
/* No BH disabling for tx_lock here. We are running in BH disabled /* No BH disabling for tx_lock here. We are running in BH disabled
* context and TX reclaim runs via tp->poll inside of a software * context and TX reclaim runs via tp->poll inside of a software
...@@ -2829,7 +2829,7 @@ static void tg3_free_rings(struct tg3 *tp) ...@@ -2829,7 +2829,7 @@ static void tg3_free_rings(struct tg3 *tp)
pci_unmap_single(tp->pdev, pci_unmap_single(tp->pdev,
pci_unmap_addr(txp, mapping), pci_unmap_addr(txp, mapping),
(skb->len - skb->data_len), skb_headlen(skb),
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
txp->skb = NULL; txp->skb = NULL;
......
...@@ -844,7 +844,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -844,7 +844,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
} else { } else {
int i, len; int i, len;
len = skb->len - skb->data_len; len = skb_headlen(skb);
skb_dma = pci_map_single(tp->tx_pdev, skb->data, len, skb_dma = pci_map_single(tp->tx_pdev, skb->data, len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#ifndef KERNEL_IRDA_H #ifndef KERNEL_IRDA_H
#define KERNEL_IRDA_H #define KERNEL_IRDA_H
#include <linux/socket.h> /* only for sa_family_t */
/* Hint bit positions for first hint byte */ /* Hint bit positions for first hint byte */
#define HINT_PNP 0x01 #define HINT_PNP 0x01
#define HINT_PDA 0x02 #define HINT_PDA 0x02
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#define _LINUX_NET_H #define _LINUX_NET_H
#include <linux/config.h> #include <linux/config.h>
#include <linux/socket.h>
#include <linux/wait.h> #include <linux/wait.h>
struct poll_table_struct; struct poll_table_struct;
...@@ -88,6 +87,8 @@ struct socket { ...@@ -88,6 +87,8 @@ struct socket {
struct vm_area_struct; struct vm_area_struct;
struct page; struct page;
struct kiocb; struct kiocb;
struct sockaddr;
struct msghdr;
struct proto_ops { struct proto_ops {
int family; int family;
...@@ -136,6 +137,8 @@ struct net_proto_family { ...@@ -136,6 +137,8 @@ struct net_proto_family {
short encrypt_net; short encrypt_net;
}; };
struct iovec;
extern int sock_wake_async(struct socket *sk, int how, int band); extern int sock_wake_async(struct socket *sk, int how, int band);
extern int sock_register(struct net_proto_family *fam); extern int sock_register(struct net_proto_family *fam);
extern int sock_unregister(int family); extern int sock_unregister(int family);
......
#ifndef __LINUX_NETLINK_H #ifndef __LINUX_NETLINK_H
#define __LINUX_NETLINK_H #define __LINUX_NETLINK_H
#include <linux/socket.h> /* for sa_family_t */
#define NETLINK_ROUTE 0 /* Routing/device hook */ #define NETLINK_ROUTE 0 /* Routing/device hook */
#define NETLINK_SKIP 1 /* Reserved for ENskip */ #define NETLINK_SKIP 1 /* Reserved for ENskip */
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <net/checksum.h> #include <net/checksum.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/snmp.h>
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
#include <linux/ipv6.h> #include <linux/ipv6.h>
#endif #endif
...@@ -639,6 +640,8 @@ DECLARE_SNMP_STAT(struct tcp_mib, tcp_statistics); ...@@ -639,6 +640,8 @@ DECLARE_SNMP_STAT(struct tcp_mib, tcp_statistics);
#define TCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(tcp_statistics, field) #define TCP_INC_STATS_BH(field) SNMP_INC_STATS_BH(tcp_statistics, field)
#define TCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(tcp_statistics, field) #define TCP_INC_STATS_USER(field) SNMP_INC_STATS_USER(tcp_statistics, field)
#define TCP_DEC_STATS(field) SNMP_DEC_STATS(tcp_statistics, field) #define TCP_DEC_STATS(field) SNMP_DEC_STATS(tcp_statistics, field)
#define TCP_ADD_STATS_BH(field, val) SNMP_ADD_STATS_BH(tcp_statistics, field, val)
#define TCP_ADD_STATS_USER(field, val) SNMP_ADD_STATS_USER(tcp_statistics, field, val)
extern __inline__ void tcp_put_port(struct sock *sk); extern __inline__ void tcp_put_port(struct sock *sk);
extern void tcp_inherit_port(struct sock *sk, struct sock *child); extern void tcp_inherit_port(struct sock *sk, struct sock *child);
...@@ -1398,6 +1401,9 @@ static __inline__ void tcp_set_state(struct sock *sk, int state) ...@@ -1398,6 +1401,9 @@ static __inline__ void tcp_set_state(struct sock *sk, int state)
break; break;
case TCP_CLOSE: case TCP_CLOSE:
if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
TCP_INC_STATS(TcpEstabResets);
sk->prot->unhash(sk); sk->prot->unhash(sk);
if (sk->prev && !(sk->userlocks&SOCK_BINDPORT_LOCK)) if (sk->prev && !(sk->userlocks&SOCK_BINDPORT_LOCK))
tcp_put_port(sk); tcp_put_port(sk);
...@@ -1878,4 +1884,13 @@ static inline int tcp_use_frto(const struct sock *sk) ...@@ -1878,4 +1884,13 @@ static inline int tcp_use_frto(const struct sock *sk)
tp->snd_una + tp->snd_wnd)); tp->snd_una + tp->snd_wnd));
} }
static inline void tcp_mib_init(void)
{
/* See RFC 2012 */
TCP_ADD_STATS_USER(TcpRtoAlgorithm, 1);
TCP_ADD_STATS_USER(TcpRtoMin, TCP_RTO_MIN*1000/HZ);
TCP_ADD_STATS_USER(TcpRtoMax, TCP_RTO_MAX*1000/HZ);
TCP_ADD_STATS_USER(TcpMaxConn, -1);
}
#endif /* _TCP_H */ #endif /* _TCP_H */
...@@ -84,6 +84,7 @@ extern struct semaphore xfrm_cfg_sem; ...@@ -84,6 +84,7 @@ extern struct semaphore xfrm_cfg_sem;
/* Full description of state of transformer. */ /* Full description of state of transformer. */
struct xfrm_state struct xfrm_state
{ {
/* Note: bydst is re-used during gc */
struct list_head bydst; struct list_head bydst;
struct list_head byspi; struct list_head byspi;
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <net/p8022.h> #include <net/p8022.h>
#include <net/arp.h> #include <net/arp.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/brlock.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
...@@ -68,7 +67,6 @@ static struct packet_type vlan_packet_type = { ...@@ -68,7 +67,6 @@ static struct packet_type vlan_packet_type = {
.dev =NULL, .dev =NULL,
.func = vlan_skb_recv, /* VLAN receive method */ .func = vlan_skb_recv, /* VLAN receive method */
.data = (void *)(-1), /* Set here '(void *)1' when this code can SHARE SKBs */ .data = (void *)(-1), /* Set here '(void *)1' when this code can SHARE SKBs */
.next = NULL
}; };
/* End of global variables definitions. */ /* End of global variables definitions. */
...@@ -231,9 +229,8 @@ static int unregister_vlan_dev(struct net_device *real_dev, ...@@ -231,9 +229,8 @@ static int unregister_vlan_dev(struct net_device *real_dev,
real_dev->vlan_rx_kill_vid(real_dev, vlan_id); real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
} }
br_write_lock(BR_NETPROTO_LOCK);
grp->vlan_devices[vlan_id] = NULL; grp->vlan_devices[vlan_id] = NULL;
br_write_unlock(BR_NETPROTO_LOCK); synchronize_net();
/* Caller unregisters (and if necessary, puts) /* Caller unregisters (and if necessary, puts)
...@@ -266,7 +263,7 @@ static int unregister_vlan_dev(struct net_device *real_dev, ...@@ -266,7 +263,7 @@ static int unregister_vlan_dev(struct net_device *real_dev,
ret = 1; ret = 1;
} }
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
} }
} }
...@@ -433,6 +430,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -433,6 +430,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
/* set up method calls */ /* set up method calls */
new_dev->init = vlan_dev_init; new_dev->init = vlan_dev_init;
new_dev->destructor = vlan_dev_destruct; new_dev->destructor = vlan_dev_destruct;
new_dev->owner = THIS_MODULE;
/* new_dev->ifindex = 0; it will be set when added to /* new_dev->ifindex = 0; it will be set when added to
* the global list. * the global list.
...@@ -540,16 +538,22 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, ...@@ -540,16 +538,22 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
register_netdevice(new_dev); register_netdevice(new_dev);
rtnl_unlock(); rtnl_unlock();
/* NOTE: We have a reference to the real device, /* NOTE: We have a reference to the real device,
* so hold on to the reference. * so hold on to the reference.
*/ */
MOD_INC_USE_COUNT; /* Add was a success!! */ if (!try_module_get(THIS_MODULE))
goto out_module_dying;
#ifdef VLAN_DEBUG #ifdef VLAN_DEBUG
printk(VLAN_DBG "Allocated new device successfully, returning.\n"); printk(VLAN_DBG "Allocated new device successfully, returning.\n");
#endif #endif
return new_dev; return new_dev;
out_module_dying:
rtnl_lock();
unregister_netdevice(new_dev);
out_free_newdev_priv: out_free_newdev_priv:
kfree(new_dev->priv); kfree(new_dev->priv);
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <net/datalink.h> #include <net/datalink.h>
#include <net/p8022.h> #include <net/p8022.h>
#include <net/arp.h> #include <net/arp.h>
#include <linux/brlock.h>
#include "vlan.h" #include "vlan.h"
#include "vlanproc.h" #include "vlanproc.h"
......
...@@ -220,7 +220,7 @@ int skb_copy_datagram(const struct sk_buff *skb, int offset, char *to, int size) ...@@ -220,7 +220,7 @@ int skb_copy_datagram(const struct sk_buff *skb, int offset, char *to, int size)
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->len - skb->data_len; int start = skb_headlen(skb);
int i, copy = start - offset; int i, copy = start - offset;
/* Copy header. */ /* Copy header. */
...@@ -295,7 +295,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, ...@@ -295,7 +295,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
u8 *to, int len, unsigned int *csump) u8 *to, int len, unsigned int *csump)
{ {
int start = skb->len - skb->data_len; int start = skb_headlen(skb);
int pos = 0; int pos = 0;
int i, copy = start - offset; int i, copy = start - offset;
......
...@@ -932,7 +932,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) ...@@ -932,7 +932,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta)
int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
{ {
int i, copy; int i, copy;
int start = skb->len - skb->data_len; int start = skb_headlen(skb);
if (offset > (int)skb->len - len) if (offset > (int)skb->len - len)
goto fault; goto fault;
...@@ -1009,7 +1009,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) ...@@ -1009,7 +1009,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
unsigned int skb_checksum(const struct sk_buff *skb, int offset, unsigned int skb_checksum(const struct sk_buff *skb, int offset,
int len, unsigned int csum) int len, unsigned int csum)
{ {
int start = skb->len - skb->data_len; int start = skb_headlen(skb);
int i, copy = start - offset; int i, copy = start - offset;
int pos = 0; int pos = 0;
...@@ -1085,7 +1085,7 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset, ...@@ -1085,7 +1085,7 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
u8 *to, int len, unsigned int csum) u8 *to, int len, unsigned int csum)
{ {
int start = skb->len - skb->data_len; int start = skb_headlen(skb);
int i, copy = start - offset; int i, copy = start - offset;
int pos = 0; int pos = 0;
...@@ -1170,9 +1170,9 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) ...@@ -1170,9 +1170,9 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
if (skb->ip_summed == CHECKSUM_HW) if (skb->ip_summed == CHECKSUM_HW)
csstart = skb->h.raw - skb->data; csstart = skb->h.raw - skb->data;
else else
csstart = skb->len - skb->data_len; csstart = skb_headlen(skb);
if (csstart > skb->len - skb->data_len) if (csstart > skb_headlen(skb))
BUG(); BUG();
memcpy(to, skb->data, csstart); memcpy(to, skb->data, csstart);
......
...@@ -1108,6 +1108,8 @@ static int __init init_ipv4_mibs(void) ...@@ -1108,6 +1108,8 @@ static int __init init_ipv4_mibs(void)
} }
} }
(void) tcp_mib_init();
return 0; return 0;
} }
......
...@@ -314,12 +314,14 @@ static void ah_destroy(struct xfrm_state *x) ...@@ -314,12 +314,14 @@ static void ah_destroy(struct xfrm_state *x)
crypto_free_tfm(ahp->tfm); crypto_free_tfm(ahp->tfm);
ahp->tfm = NULL; ahp->tfm = NULL;
} }
kfree(ahp);
} }
static struct xfrm_type ah_type = static struct xfrm_type ah_type =
{ {
.description = "AH4", .description = "AH4",
.owner = THIS_MODULE,
.proto = IPPROTO_AH, .proto = IPPROTO_AH,
.init_state = ah_init_state, .init_state = ah_init_state,
.destructor = ah_destroy, .destructor = ah_destroy,
...@@ -335,7 +337,6 @@ static struct inet_protocol ah4_protocol = { ...@@ -335,7 +337,6 @@ static struct inet_protocol ah4_protocol = {
static int __init ah4_init(void) static int __init ah4_init(void)
{ {
SET_MODULE_OWNER(&ah_type);
if (xfrm_register_type(&ah_type, AF_INET) < 0) { if (xfrm_register_type(&ah_type, AF_INET) < 0) {
printk(KERN_INFO "ip ah init: can't add xfrm type\n"); printk(KERN_INFO "ip ah init: can't add xfrm type\n");
return -EAGAIN; return -EAGAIN;
......
...@@ -452,6 +452,7 @@ void esp_destroy(struct xfrm_state *x) ...@@ -452,6 +452,7 @@ void esp_destroy(struct xfrm_state *x)
kfree(esp->auth.work_icv); kfree(esp->auth.work_icv);
esp->auth.work_icv = NULL; esp->auth.work_icv = NULL;
} }
kfree(esp);
} }
int esp_init_state(struct xfrm_state *x, void *args) int esp_init_state(struct xfrm_state *x, void *args)
...@@ -552,6 +553,7 @@ int esp_init_state(struct xfrm_state *x, void *args) ...@@ -552,6 +553,7 @@ int esp_init_state(struct xfrm_state *x, void *args)
static struct xfrm_type esp_type = static struct xfrm_type esp_type =
{ {
.description = "ESP4", .description = "ESP4",
.owner = THIS_MODULE,
.proto = IPPROTO_ESP, .proto = IPPROTO_ESP,
.init_state = esp_init_state, .init_state = esp_init_state,
.destructor = esp_destroy, .destructor = esp_destroy,
......
...@@ -143,9 +143,15 @@ static int snmp_seq_show(struct seq_file *seq, void *v) ...@@ -143,9 +143,15 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
"InSegs OutSegs RetransSegs InErrs OutRsts\nTcp:"); "InSegs OutSegs RetransSegs InErrs OutRsts\nTcp:");
for (i = 0; for (i = 0;
i < offsetof(struct tcp_mib, __pad) / sizeof(unsigned long); i++) i < offsetof(struct tcp_mib, __pad) / sizeof(unsigned long); i++) {
seq_printf(seq, " %lu", if (i == (offsetof(struct tcp_mib, TcpMaxConn) / sizeof(unsigned long)))
fold_field((void **) tcp_statistics, i)); /* MaxConn field is negative, RFC 2012 */
seq_printf(seq, " %ld",
fold_field((void **) tcp_statistics, i));
else
seq_printf(seq, " %lu",
fold_field((void **) tcp_statistics, i));
}
seq_printf(seq, "\nUdp: InDatagrams NoPorts InErrors OutDatagrams\n" seq_printf(seq, "\nUdp: InDatagrams NoPorts InErrors OutDatagrams\n"
"Udp:"); "Udp:");
......
...@@ -354,7 +354,7 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss) ...@@ -354,7 +354,7 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
static void skb_split(struct sk_buff *skb, struct sk_buff *skb1, u32 len) static void skb_split(struct sk_buff *skb, struct sk_buff *skb1, u32 len)
{ {
int i; int i;
int pos = skb->len - skb->data_len; int pos = skb_headlen(skb);
if (len < pos) { if (len < pos) {
/* Split line is inside header. */ /* Split line is inside header. */
......
...@@ -313,11 +313,13 @@ static void ah6_destroy(struct xfrm_state *x) ...@@ -313,11 +313,13 @@ static void ah6_destroy(struct xfrm_state *x)
crypto_free_tfm(ahp->tfm); crypto_free_tfm(ahp->tfm);
ahp->tfm = NULL; ahp->tfm = NULL;
} }
kfree(ahp);
} }
static struct xfrm_type ah6_type = static struct xfrm_type ah6_type =
{ {
.description = "AH6", .description = "AH6",
.owner = THIS_MODULE,
.proto = IPPROTO_AH, .proto = IPPROTO_AH,
.init_state = ah6_init_state, .init_state = ah6_init_state,
.destructor = ah6_destroy, .destructor = ah6_destroy,
...@@ -333,8 +335,6 @@ static struct inet6_protocol ah6_protocol = { ...@@ -333,8 +335,6 @@ static struct inet6_protocol ah6_protocol = {
int __init ah6_init(void) int __init ah6_init(void)
{ {
SET_MODULE_OWNER(&ah6_type);
if (xfrm_register_type(&ah6_type, AF_INET6) < 0) { if (xfrm_register_type(&ah6_type, AF_INET6) < 0) {
printk(KERN_INFO "ipv6 ah init: can't add xfrm type\n"); printk(KERN_INFO "ipv6 ah init: can't add xfrm type\n");
return -EAGAIN; return -EAGAIN;
......
...@@ -406,6 +406,7 @@ void esp6_destroy(struct xfrm_state *x) ...@@ -406,6 +406,7 @@ void esp6_destroy(struct xfrm_state *x)
kfree(esp->auth.work_icv); kfree(esp->auth.work_icv);
esp->auth.work_icv = NULL; esp->auth.work_icv = NULL;
} }
kfree(esp);
} }
int esp6_init_state(struct xfrm_state *x, void *args) int esp6_init_state(struct xfrm_state *x, void *args)
...@@ -488,6 +489,7 @@ int esp6_init_state(struct xfrm_state *x, void *args) ...@@ -488,6 +489,7 @@ int esp6_init_state(struct xfrm_state *x, void *args)
static struct xfrm_type esp6_type = static struct xfrm_type esp6_type =
{ {
.description = "ESP6", .description = "ESP6",
.owner = THIS_MODULE,
.proto = IPPROTO_ESP, .proto = IPPROTO_ESP,
.init_state = esp6_init_state, .init_state = esp6_init_state,
.destructor = esp6_destroy, .destructor = esp6_destroy,
...@@ -504,7 +506,6 @@ static struct inet6_protocol esp6_protocol = { ...@@ -504,7 +506,6 @@ static struct inet6_protocol esp6_protocol = {
int __init esp6_init(void) int __init esp6_init(void)
{ {
SET_MODULE_OWNER(&esp6_type);
if (xfrm_register_type(&esp6_type, AF_INET6) < 0) { if (xfrm_register_type(&esp6_type, AF_INET6) < 0) {
printk(KERN_INFO "ipv6 esp init: can't add xfrm type\n"); printk(KERN_INFO "ipv6 esp init: can't add xfrm type\n");
return -EAGAIN; return -EAGAIN;
......
...@@ -445,7 +445,7 @@ int xfrm_count_enc_supported(void) ...@@ -445,7 +445,7 @@ int xfrm_count_enc_supported(void)
void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
int offset, int len, icv_update_fn_t icv_update) int offset, int len, icv_update_fn_t icv_update)
{ {
int start = skb->len - skb->data_len; int start = skb_headlen(skb);
int i, copy = start - offset; int i, copy = start - offset;
struct scatterlist sg; struct scatterlist sg;
...@@ -521,7 +521,7 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, ...@@ -521,7 +521,7 @@ void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
int int
skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
{ {
int start = skb->len - skb->data_len; int start = skb_headlen(skb);
int i, copy = start - offset; int i, copy = start - offset;
int elt = 0; int elt = 0;
......
...@@ -963,6 +963,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, ...@@ -963,6 +963,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
* are implied between each two transformations. * are implied between each two transformations.
*/ */
for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) { for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
if (pol->xfrm_vec[i].optional)
continue;
k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family); k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
if (k < 0) if (k < 0)
goto reject; goto reject;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* *
*/ */
#include <linux/workqueue.h>
#include <net/xfrm.h> #include <net/xfrm.h>
#include <linux/pfkeyv2.h> #include <linux/pfkeyv2.h>
#include <linux/ipsec.h> #include <linux/ipsec.h>
...@@ -41,8 +42,48 @@ DECLARE_WAIT_QUEUE_HEAD(km_waitq); ...@@ -41,8 +42,48 @@ DECLARE_WAIT_QUEUE_HEAD(km_waitq);
static rwlock_t xfrm_state_afinfo_lock = RW_LOCK_UNLOCKED; static rwlock_t xfrm_state_afinfo_lock = RW_LOCK_UNLOCKED;
static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO]; static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
static struct work_struct xfrm_state_gc_work;
static struct list_head xfrm_state_gc_list = LIST_HEAD_INIT(xfrm_state_gc_list);
static spinlock_t xfrm_state_gc_lock = SPIN_LOCK_UNLOCKED;
static void __xfrm_state_delete(struct xfrm_state *x); static void __xfrm_state_delete(struct xfrm_state *x);
static void xfrm_state_gc_destroy(struct xfrm_state *x)
{
if (del_timer(&x->timer))
BUG();
if (x->aalg)
kfree(x->aalg);
if (x->ealg)
kfree(x->ealg);
if (x->calg)
kfree(x->calg);
if (x->encap)
kfree(x->encap);
if (x->type) {
x->type->destructor(x);
xfrm_put_type(x->type);
}
kfree(x);
wake_up(&km_waitq);
}
static void xfrm_state_gc_task(void *data)
{
struct xfrm_state *x;
struct list_head *entry, *tmp;
struct list_head gc_list = LIST_HEAD_INIT(gc_list);
spin_lock_bh(&xfrm_state_gc_lock);
list_splice_init(&xfrm_state_gc_list, &gc_list);
spin_unlock_bh(&xfrm_state_gc_lock);
list_for_each_safe(entry, tmp, &gc_list) {
x = list_entry(entry, struct xfrm_state, bydst);
xfrm_state_gc_destroy(x);
}
}
static inline unsigned long make_jiffies(long secs) static inline unsigned long make_jiffies(long secs)
{ {
if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ) if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
...@@ -149,28 +190,17 @@ struct xfrm_state *xfrm_state_alloc(void) ...@@ -149,28 +190,17 @@ struct xfrm_state *xfrm_state_alloc(void)
void __xfrm_state_destroy(struct xfrm_state *x) void __xfrm_state_destroy(struct xfrm_state *x)
{ {
BUG_TRAP(x->km.state == XFRM_STATE_DEAD); BUG_TRAP(x->km.state == XFRM_STATE_DEAD);
if (del_timer(&x->timer))
BUG(); spin_lock_bh(&xfrm_state_gc_lock);
if (x->aalg) list_add(&x->bydst, &xfrm_state_gc_list);
kfree(x->aalg); spin_unlock_bh(&xfrm_state_gc_lock);
if (x->ealg) schedule_work(&xfrm_state_gc_work);
kfree(x->ealg);
if (x->calg)
kfree(x->calg);
if (x->encap)
kfree(x->encap);
if (x->type)
xfrm_put_type(x->type);
kfree(x);
} }
static void __xfrm_state_delete(struct xfrm_state *x) static void __xfrm_state_delete(struct xfrm_state *x)
{ {
int kill = 0;
if (x->km.state != XFRM_STATE_DEAD) { if (x->km.state != XFRM_STATE_DEAD) {
x->km.state = XFRM_STATE_DEAD; x->km.state = XFRM_STATE_DEAD;
kill = 1;
spin_lock(&xfrm_state_lock); spin_lock(&xfrm_state_lock);
list_del(&x->bydst); list_del(&x->bydst);
atomic_dec(&x->refcnt); atomic_dec(&x->refcnt);
...@@ -189,22 +219,17 @@ static void __xfrm_state_delete(struct xfrm_state *x) ...@@ -189,22 +219,17 @@ static void __xfrm_state_delete(struct xfrm_state *x)
*/ */
if (atomic_read(&x->refcnt) > 2) if (atomic_read(&x->refcnt) > 2)
xfrm_flush_bundles(x); xfrm_flush_bundles(x);
}
/* All xfrm_state objects are created by one of two possible /* All xfrm_state objects are created by one of two possible
* paths: * paths:
* *
* 1) xfrm_state_alloc --> xfrm_state_insert * 2) xfrm_state_lookup --> xfrm_state_insert
* 2) xfrm_state_lookup --> xfrm_state_insert *
* * The xfrm_state_lookup or xfrm_state_alloc call gives a
* The xfrm_state_lookup or xfrm_state_alloc call gives a * reference, and that is what we are dropping here.
* reference, and that is what we are dropping here. */
*/ atomic_dec(&x->refcnt);
atomic_dec(&x->refcnt); }
if (kill && x->type)
x->type->destructor(x);
wake_up(&km_waitq);
} }
void xfrm_state_delete(struct xfrm_state *x) void xfrm_state_delete(struct xfrm_state *x)
...@@ -773,5 +798,6 @@ void __init xfrm_state_init(void) ...@@ -773,5 +798,6 @@ void __init xfrm_state_init(void)
INIT_LIST_HEAD(&xfrm_state_bydst[i]); INIT_LIST_HEAD(&xfrm_state_bydst[i]);
INIT_LIST_HEAD(&xfrm_state_byspi[i]); INIT_LIST_HEAD(&xfrm_state_byspi[i]);
} }
INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task, NULL);
} }
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