summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/atm/ioctl.c1
-rw-r--r--net/atm/mpc.c2
-rw-r--r--net/ax25/af_ax25.c7
-rw-r--r--net/ax25/ax25_addr.c30
-rw-r--r--net/ax25/ax25_route.c7
-rw-r--r--net/ax25/ax25_uid.c4
-rw-r--r--net/compat.c44
-rw-r--r--net/core/dst.c3
-rw-r--r--net/core/ethtool.c2
-rw-r--r--net/core/filter.c6
-rw-r--r--net/core/netpoll.c4
-rw-r--r--net/core/pktgen.c2
-rw-r--r--net/core/sock.c11
-rw-r--r--net/core/wireless.c58
-rw-r--r--net/dccp/ccids/ccid3.c163
-rw-r--r--net/dccp/ccids/ccid3.h14
-rw-r--r--net/dccp/ccids/lib/packet_history.h3
-rw-r--r--net/dccp/dccp.h16
-rw-r--r--net/dccp/input.c4
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/minisocks.c1
-rw-r--r--net/dccp/options.c90
-rw-r--r--net/decnet/af_decnet.c40
-rw-r--r--net/decnet/dn_nsp_out.c63
-rw-r--r--net/decnet/dn_route.c3
-rw-r--r--net/ieee80211/Kconfig1
-rw-r--r--net/ieee80211/ieee80211_crypt.c27
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c47
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c133
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c30
-rw-r--r--net/ieee80211/ieee80211_module.c40
-rw-r--r--net/ieee80211/ieee80211_rx.c310
-rw-r--r--net/ieee80211/ieee80211_tx.c66
-rw-r--r--net/ieee80211/ieee80211_wx.c73
-rw-r--r--net/ipv4/af_inet.c13
-rw-r--r--net/ipv4/ah4.c18
-rw-r--r--net/ipv4/esp4.c24
-rw-r--r--net/ipv4/fib_trie.c804
-rw-r--r--net/ipv4/inetpeer.c3
-rw-r--r--net/ipv4/ip_fragment.c2
-rw-r--r--net/ipv4/ipcomp.c3
-rw-r--r--net/ipv4/ipconfig.c1
-rw-r--r--net/ipv4/netfilter/Kconfig20
-rw-r--r--net/ipv4/netfilter/Makefile1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c38
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c147
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c13
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c1
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c1
-rw-r--r--net/ipv4/netfilter/ip_nat_rule.c21
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c8
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c2
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c5
-rw-r--r--net/ipv4/netfilter/ipt_owner.c1
-rw-r--r--net/ipv4/route.c29
-rw-r--r--net/ipv4/tcp.c17
-rw-r--r--net/ipv4/tcp_input.c36
-rw-r--r--net/ipv4/tcp_output.c55
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv6/addrconf.c9
-rw-r--r--net/ipv6/ah6.c18
-rw-r--r--net/ipv6/datagram.c139
-rw-r--r--net/ipv6/esp6.c24
-rw-r--r--net/ipv6/exthdrs.c116
-rw-r--r--net/ipv6/icmp.c22
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_flowlabel.c16
-rw-r--r--net/ipv6/ip6_output.c24
-rw-r--r--net/ipv6/ip6_tunnel.c7
-rw-r--r--net/ipv6/ipcomp6.c3
-rw-r--r--net/ipv6/ipv6_sockglue.c186
-rw-r--r--net/ipv6/ndisc.c16
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c5
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c1
-rw-r--r--net/ipv6/raw.c25
-rw-r--r--net/ipv6/reassembly.c9
-rw-r--r--net/ipv6/tcp_ipv6.c36
-rw-r--r--net/ipv6/udp.c25
-rw-r--r--net/irda/irlan/irlan_filter.c1
-rw-r--r--net/irda/qos.c1
-rw-r--r--net/netfilter/nfnetlink.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c23
-rw-r--r--net/netlink/af_netlink.c59
-rw-r--r--net/netrom/af_netrom.c7
-rw-r--r--net/netrom/nr_loopback.c2
-rw-r--r--net/netrom/nr_route.c8
-rw-r--r--net/packet/af_packet.c6
-rw-r--r--net/rose/af_rose.c6
-rw-r--r--net/rose/rose_route.c14
-rw-r--r--net/rose/rose_subr.c9
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/socket.c3
-rw-r--r--net/sctp/sysctl.c1
-rw-r--r--net/socket.c25
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c5
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c9
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c12
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c8
-rw-r--r--net/sunrpc/cache.c8
-rw-r--r--net/sunrpc/stats.c16
-rw-r--r--net/sunrpc/sunrpc_syms.c6
-rw-r--r--net/sunrpc/svcauth.c1
-rw-r--r--net/sunrpc/svcauth_unix.c1
-rw-r--r--net/xfrm/xfrm_policy.c8
109 files changed, 2000 insertions, 1507 deletions
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4dbb5af..d89056e 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -21,6 +21,7 @@
#include "resources.h"
#include "signaling.h" /* for WAITING and sigd_attach */
+#include "common.h"
static DECLARE_MUTEX(ioctl_mutex);
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 17a81eb..526d953 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -105,7 +105,7 @@ extern void mpc_proc_clean(void);
struct mpoa_client *mpcs = NULL; /* FIXME */
static struct atm_mpoa_qos *qos_head = NULL;
-static struct timer_list mpc_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(mpc_timer, NULL, 0, 0);
static struct mpoa_client *find_mpc_by_itfnum(int itf)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index ea43dfb..ed705dd 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1874,6 +1874,7 @@ static void ax25_info_stop(struct seq_file *seq, void *v)
static int ax25_info_show(struct seq_file *seq, void *v)
{
ax25_cb *ax25 = v;
+ char buf[11];
int k;
@@ -1885,13 +1886,13 @@ static int ax25_info_show(struct seq_file *seq, void *v)
seq_printf(seq, "%8.8lx %s %s%s ",
(long) ax25,
ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
- ax2asc(&ax25->source_addr),
+ ax2asc(buf, &ax25->source_addr),
ax25->iamdigi? "*":"");
- seq_printf(seq, "%s", ax2asc(&ax25->dest_addr));
+ seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr));
for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
seq_printf(seq, ",%s%s",
- ax2asc(&ax25->digipeat->calls[k]),
+ ax2asc(buf, &ax25->digipeat->calls[k]),
ax25->digipeat->repeated[k]? "*":"");
}
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index f4fa6df..0164a15 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -36,9 +36,8 @@ ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}};
/*
* ax25 -> ascii conversion
*/
-char *ax2asc(ax25_address *a)
+char *ax2asc(char *buf, ax25_address *a)
{
- static char buf[11];
char c, *s;
int n;
@@ -68,37 +67,34 @@ char *ax2asc(ax25_address *a)
/*
* ascii -> ax25 conversion
*/
-ax25_address *asc2ax(char *callsign)
+void asc2ax(ax25_address *addr, char *callsign)
{
- static ax25_address addr;
char *s;
int n;
for (s = callsign, n = 0; n < 6; n++) {
if (*s != '\0' && *s != '-')
- addr.ax25_call[n] = *s++;
+ addr->ax25_call[n] = *s++;
else
- addr.ax25_call[n] = ' ';
- addr.ax25_call[n] <<= 1;
- addr.ax25_call[n] &= 0xFE;
+ addr->ax25_call[n] = ' ';
+ addr->ax25_call[n] <<= 1;
+ addr->ax25_call[n] &= 0xFE;
}
if (*s++ == '\0') {
- addr.ax25_call[6] = 0x00;
- return &addr;
+ addr->ax25_call[6] = 0x00;
+ return;
}
- addr.ax25_call[6] = *s++ - '0';
+ addr->ax25_call[6] = *s++ - '0';
if (*s != '\0') {
- addr.ax25_call[6] *= 10;
- addr.ax25_call[6] += *s++ - '0';
+ addr->ax25_call[6] *= 10;
+ addr->ax25_call[6] += *s++ - '0';
}
- addr.ax25_call[6] <<= 1;
- addr.ax25_call[6] &= 0x1E;
-
- return &addr;
+ addr->ax25_call[6] <<= 1;
+ addr->ax25_call[6] &= 0x1E;
}
/*
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index c288526..26b77d9 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -298,6 +298,8 @@ static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
static int ax25_rt_seq_show(struct seq_file *seq, void *v)
{
+ char buf[11];
+
if (v == SEQ_START_TOKEN)
seq_puts(seq, "callsign dev mode digipeaters\n");
else {
@@ -308,7 +310,7 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
callsign = "default";
else
- callsign = ax2asc(&ax25_rt->callsign);
+ callsign = ax2asc(buf, &ax25_rt->callsign);
seq_printf(seq, "%-9s %-4s",
callsign,
@@ -328,7 +330,8 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
if (ax25_rt->digipeat != NULL)
for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
- seq_printf(seq, " %s", ax2asc(&ax25_rt->digipeat->calls[i]));
+ seq_printf(seq, " %s",
+ ax2asc(buf, &ax25_rt->digipeat->calls[i]));
seq_puts(seq, "\n");
}
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index a8b3822..d53cc86 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -168,12 +168,14 @@ static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
static int ax25_uid_seq_show(struct seq_file *seq, void *v)
{
+ char buf[11];
+
if (v == SEQ_START_TOKEN)
seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
else {
struct ax25_uid_assoc *pt = v;
- seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call));
+ seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call));
}
return 0;
}
diff --git a/net/compat.c b/net/compat.c
index d99ab96..e593dac 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -135,13 +135,14 @@ static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *ms
* thus placement) of cmsg headers and length are different for
* 32-bit apps. -DaveM
*/
-int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
+int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
unsigned char *stackbuf, int stackbuf_size)
{
struct compat_cmsghdr __user *ucmsg;
struct cmsghdr *kcmsg, *kcmsg_base;
compat_size_t ucmlen;
__kernel_size_t kcmlen, tmp;
+ int err = -EFAULT;
kcmlen = 0;
kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
@@ -156,6 +157,7 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
CMSG_ALIGN(sizeof(struct cmsghdr)));
+ tmp = CMSG_ALIGN(tmp);
kcmlen += tmp;
ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
}
@@ -167,30 +169,34 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
* until we have successfully copied over all of the data
* from the user.
*/
- if(kcmlen > stackbuf_size)
- kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
- if(kcmsg == NULL)
+ if (kcmlen > stackbuf_size)
+ kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
+ if (kcmsg == NULL)
return -ENOBUFS;
/* Now copy them over neatly. */
memset(kcmsg, 0, kcmlen);
ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
while(ucmsg != NULL) {
- __get_user(ucmlen, &ucmsg->cmsg_len);
+ if (__get_user(ucmlen, &ucmsg->cmsg_len))
+ goto Efault;
+ if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
+ goto Einval;
tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
CMSG_ALIGN(sizeof(struct cmsghdr)));
+ if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
+ goto Einval;
kcmsg->cmsg_len = tmp;
- __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
- __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
-
- /* Copy over the data. */
- if(copy_from_user(CMSG_DATA(kcmsg),
- CMSG_COMPAT_DATA(ucmsg),
- (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg)))))
- goto out_free_efault;
+ tmp = CMSG_ALIGN(tmp);
+ if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
+ __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
+ copy_from_user(CMSG_DATA(kcmsg),
+ CMSG_COMPAT_DATA(ucmsg),
+ (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg)))))
+ goto Efault;
/* Advance. */
- kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
+ kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
}
@@ -199,10 +205,12 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg,
kmsg->msg_controllen = kcmlen;
return 0;
-out_free_efault:
- if(kcmsg_base != (struct cmsghdr *)stackbuf)
- kfree(kcmsg_base);
- return -EFAULT;
+Einval:
+ err = -EINVAL;
+Efault:
+ if (kcmsg_base != (struct cmsghdr *)stackbuf)
+ sock_kfree_s(sk, kcmsg_base, kcmlen);
+ return err;
}
int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
diff --git a/net/core/dst.c b/net/core/dst.c
index 334790d..470c05b 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -39,8 +39,7 @@ static unsigned long dst_gc_timer_inc = DST_GC_MAX;
static void dst_run_gc(unsigned long);
static void ___dst_free(struct dst_entry * dst);
-static struct timer_list dst_gc_timer =
- TIMER_INITIALIZER(dst_run_gc, DST_GC_MIN, 0);
+static DEFINE_TIMER(dst_gc_timer, dst_run_gc, DST_GC_MIN, 0);
static void dst_run_gc(unsigned long dummy)
{
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 289c1b5..404b761 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -695,7 +695,7 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
return ret;
}
-static int ethtool_get_perm_addr(struct net_device *dev, void *useraddr)
+static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
{
struct ethtool_perm_addr epaddr;
u8 *data;
diff --git a/net/core/filter.c b/net/core/filter.c
index cd91a24..079c2ed 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -182,7 +182,7 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
A = ntohl(*(u32 *)ptr);
continue;
}
- return 0;
+ break;
case BPF_LD|BPF_H|BPF_ABS:
k = fentry->k;
load_h:
@@ -191,7 +191,7 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
A = ntohs(*(u16 *)ptr);
continue;
}
- return 0;
+ break;
case BPF_LD|BPF_B|BPF_ABS:
k = fentry->k;
load_b:
@@ -200,7 +200,7 @@ load_b:
A = *(u8 *)ptr;
continue;
}
- return 0;
+ break;
case BPF_LD|BPF_W|BPF_LEN:
A = skb->len;
continue;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a1a9a7a..5265dfd 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -645,10 +645,10 @@ int netpoll_setup(struct netpoll *np)
npinfo->rx_flags = 0;
npinfo->rx_np = NULL;
- npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&npinfo->poll_lock);
npinfo->poll_owner = -1;
npinfo->tries = MAX_RETRIES;
- npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&npinfo->rx_lock);
} else
npinfo = ndev->npinfo;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 8eb083b..b3ad49f 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -503,7 +503,7 @@ static int pg_delay_d = 0;
static int pg_clone_skb_d = 0;
static int debug = 0;
-static spinlock_t _thread_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(_thread_lock);
static struct pktgen_thread *pktgen_threads = NULL;
static char module_fname[128];
diff --git a/net/core/sock.c b/net/core/sock.c
index ccd10fd..ac63b56 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -341,11 +341,11 @@ set_rcvbuf:
sock_reset_flag(sk, SOCK_LINGER);
else {
#if (BITS_PER_LONG == 32)
- if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
+ if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
else
#endif
- sk->sk_lingertime = ling.l_linger * HZ;
+ sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
sock_set_flag(sk, SOCK_LINGER);
}
break;
@@ -1529,6 +1529,8 @@ EXPORT_SYMBOL(proto_register);
void proto_unregister(struct proto *prot)
{
write_lock(&proto_list_lock);
+ list_del(&prot->node);
+ write_unlock(&proto_list_lock);
if (prot->slab != NULL) {
kmem_cache_destroy(prot->slab);
@@ -1550,9 +1552,6 @@ void proto_unregister(struct proto *prot)
kfree(name);
prot->twsk_slab = NULL;
}
-
- list_del(&prot->node);
- write_unlock(&proto_list_lock);
}
EXPORT_SYMBOL(proto_unregister);
@@ -1719,8 +1718,8 @@ EXPORT_SYMBOL(sock_wfree);
EXPORT_SYMBOL(sock_wmalloc);
EXPORT_SYMBOL(sock_i_uid);
EXPORT_SYMBOL(sock_i_ino);
-#ifdef CONFIG_SYSCTL
EXPORT_SYMBOL(sysctl_optmem_max);
+#ifdef CONFIG_SYSCTL
EXPORT_SYMBOL(sysctl_rmem_max);
EXPORT_SYMBOL(sysctl_wmem_max);
#endif
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 5caae23..d17f158 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -58,6 +58,13 @@
* o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus
* Based on patch from Pavel Roskin <proski@gnu.org> :
* o Fix kernel data leak to user space in private handler handling
+ *
+ * v7 - 18.3.05 - Jean II
+ * o Remove (struct iw_point *)->pointer from events and streams
+ * o Remove spy_offset from struct iw_handler_def
+ * o Start deprecating dev->get_wireless_stats, output a warning
+ * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless
+ * o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats)
*/
/***************************** INCLUDES *****************************/
@@ -446,10 +453,14 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
(dev->wireless_handlers->get_wireless_stats != NULL))
return dev->wireless_handlers->get_wireless_stats(dev);
- /* Old location, will be phased out in next WE */
- return (dev->get_wireless_stats ?
- dev->get_wireless_stats(dev) :
- (struct iw_statistics *) NULL);
+ /* Old location, field to be removed in next WE */
+ if(dev->get_wireless_stats) {
+ printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n",
+ dev->name);
+ return dev->get_wireless_stats(dev);
+ }
+ /* Not found */
+ return (struct iw_statistics *) NULL;
}
/* ---------------------------------------------------------------- */
@@ -541,16 +552,18 @@ static __inline__ void wireless_seq_printf_stats(struct seq_file *seq,
dev->name, stats->status, stats->qual.qual,
stats->qual.updated & IW_QUAL_QUAL_UPDATED
? '.' : ' ',
- ((__u8) stats->qual.level),
+ ((__s32) stats->qual.level) -
+ ((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0),
stats->qual.updated & IW_QUAL_LEVEL_UPDATED
? '.' : ' ',
- ((__u8) stats->qual.noise),
+ ((__s32) stats->qual.noise) -
+ ((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0),
stats->qual.updated & IW_QUAL_NOISE_UPDATED
? '.' : ' ',
stats->discard.nwid, stats->discard.code,
stats->discard.fragment, stats->discard.retries,
stats->discard.misc, stats->miss.beacon);
- stats->qual.updated = 0;
+ stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
}
}
@@ -593,6 +606,7 @@ static struct file_operations wireless_seq_fops = {
int __init wireless_proc_init(void)
{
+ /* Create /proc/net/wireless entry */
if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
return -ENOMEM;
@@ -627,9 +641,9 @@ static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
sizeof(struct iw_statistics)))
return -EFAULT;
- /* Check if we need to clear the update flag */
+ /* Check if we need to clear the updated flag */
if(wrq->u.data.flags != 0)
- stats->qual.updated = 0;
+ stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
return 0;
} else
return -EOPNOTSUPP;
@@ -1161,10 +1175,11 @@ void wireless_send_event(struct net_device * dev,
struct iw_event *event; /* Mallocated whole event */
int event_len; /* Its size */
int hdr_len; /* Size of the event header */
+ int wrqu_off = 0; /* Offset in wrqu */
/* Don't "optimise" the following variable, it will crash */
unsigned cmd_index; /* *MUST* be unsigned */
- /* Get the description of the IOCTL */
+ /* Get the description of the Event */
if(cmd <= SIOCIWLAST) {
cmd_index = cmd - SIOCIWFIRST;
if(cmd_index < standard_ioctl_num)
@@ -1207,6 +1222,8 @@ void wireless_send_event(struct net_device * dev,
/* Calculate extra_len - extra is NULL for restricted events */
if(extra != NULL)
extra_len = wrqu->data.length * descr->token_size;
+ /* Always at an offset in wrqu */
+ wrqu_off = IW_EV_POINT_OFF;
#ifdef WE_EVENT_DEBUG
printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len);
#endif /* WE_EVENT_DEBUG */
@@ -1217,7 +1234,7 @@ void wireless_send_event(struct net_device * dev,
event_len = hdr_len + extra_len;
#ifdef WE_EVENT_DEBUG
- printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len);
+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, wrqu_off %d, event_len %d\n", dev->name, cmd, hdr_len, wrqu_off, event_len);
#endif /* WE_EVENT_DEBUG */
/* Create temporary buffer to hold the event */
@@ -1228,7 +1245,7 @@ void wireless_send_event(struct net_device * dev,
/* Fill event */
event->len = event_len;
event->cmd = cmd;
- memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN);
+ memcpy(&event->u, ((char *) wrqu) + wrqu_off, hdr_len - IW_EV_LCP_LEN);
if(extra != NULL)
memcpy(((char *) event) + hdr_len, extra, extra_len);
@@ -1249,7 +1266,7 @@ void wireless_send_event(struct net_device * dev,
* Now, the driver can delegate this task to Wireless Extensions.
* It needs to use those standard spy iw_handler in struct iw_handler_def,
* push data to us via wireless_spy_update() and include struct iw_spy_data
- * in its private part (and advertise it in iw_handler_def->spy_offset).
+ * in its private part (and export it in net_device->wireless_data->spy_data).
* One of the main advantage of centralising spy support here is that
* it becomes much easier to improve and extend it without having to touch
* the drivers. One example is the addition of the Spy-Threshold events.
@@ -1266,10 +1283,7 @@ static inline struct iw_spy_data * get_spydata(struct net_device *dev)
/* This is the new way */
if(dev->wireless_data)
return(dev->wireless_data->spy_data);
-
- /* This is the old way. Doesn't work for multi-headed drivers.
- * It will be removed in the next version of WE. */
- return (dev->priv + dev->wireless_handlers->spy_offset);
+ return NULL;
}
/*------------------------------------------------------------------*/
@@ -1284,10 +1298,6 @@ int iw_handler_set_spy(struct net_device * dev,
struct iw_spy_data * spydata = get_spydata(dev);
struct sockaddr * address = (struct sockaddr *) extra;
- if(!dev->wireless_data)
- /* Help user know that driver needs updating */
- printk(KERN_DEBUG "%s (WE) : Driver using old/buggy spy support, please fix driver !\n",
- dev->name);
/* Make sure driver is not buggy or using the old API */
if(!spydata)
return -EOPNOTSUPP;
@@ -1318,7 +1328,7 @@ int iw_handler_set_spy(struct net_device * dev,
sizeof(struct iw_quality) * IW_MAX_SPY);
#ifdef WE_SPY_DEBUG
- printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length);
+ printk(KERN_DEBUG "iw_handler_set_spy() : wireless_data %p, spydata %p, num %d\n", dev->wireless_data, spydata, wrqu->data.length);
for (i = 0; i < wrqu->data.length; i++)
printk(KERN_DEBUG
"%02X:%02X:%02X:%02X:%02X:%02X \n",
@@ -1371,7 +1381,7 @@ int iw_handler_get_spy(struct net_device * dev,
sizeof(struct iw_quality) * spydata->spy_number);
/* Reset updated flags. */
for(i = 0; i < spydata->spy_number; i++)
- spydata->spy_stat[i].updated = 0;
+ spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED;
return 0;
}
@@ -1486,7 +1496,7 @@ void wireless_spy_update(struct net_device * dev,
return;
#ifdef WE_SPY_DEBUG
- printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]);
+ printk(KERN_DEBUG "wireless_spy_update() : wireless_data %p, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_data, spydata, address[0], address[1], address[2], address[3], address[4], address[5]);
#endif /* WE_SPY_DEBUG */
/* Update all records that match */
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 7bf3b3a..ea30012d 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -43,12 +43,22 @@
#include "ccid3.h"
/*
- * Reason for maths with 10 here is to avoid 32 bit overflow when a is big.
+ * Reason for maths here is to avoid 32 bit overflow when a is big.
+ * With this we get close to the limit.
*/
static inline u32 usecs_div(const u32 a, const u32 b)
{
- const u32 tmp = a * (USEC_PER_SEC / 10);
- return b > 20 ? tmp / (b / 10) : tmp;
+ const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 :
+ a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 :
+ a < (UINT_MAX / (USEC_PER_SEC / 100)) ? 100 :
+ a < (UINT_MAX / (USEC_PER_SEC / 500)) ? 500 :
+ a < (UINT_MAX / (USEC_PER_SEC / 1000)) ? 1000 :
+ a < (UINT_MAX / (USEC_PER_SEC / 5000)) ? 5000 :
+ a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
+ a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
+ 100000;
+ const u32 tmp = a * (USEC_PER_SEC / div);
+ return (b >= 2 * div) ? tmp / (b / div) : tmp;
}
static int ccid3_debug;
@@ -102,8 +112,7 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
static inline void ccid3_hc_tx_set_state(struct sock *sk,
enum ccid3_hc_tx_states state)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
@@ -144,8 +153,7 @@ static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
*/
static void ccid3_hc_tx_update_x(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
/* To avoid large error in calcX */
if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
@@ -159,7 +167,7 @@ static void ccid3_hc_tx_update_x(struct sock *sk)
} else {
struct timeval now;
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
hctx->ccid3hctx_rtt) {
hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv,
@@ -174,9 +182,8 @@ static void ccid3_hc_tx_update_x(struct sock *sk)
static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
{
struct sock *sk = (struct sock *)data;
- struct dccp_sock *dp = dccp_sk(sk);
unsigned long next_tmout = 0;
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
@@ -274,7 +281,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
struct sk_buff *skb, int len)
{
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct dccp_tx_hist_entry *new_packet;
struct timeval now;
long delay;
@@ -307,7 +314,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
}
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
switch (hctx->ccid3hctx_state) {
case TFRC_SSTATE_NO_SENT:
@@ -348,18 +355,20 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
}
/* Can we send? if so add options and add to packet history */
- if (rc == 0)
+ if (rc == 0) {
+ dp->dccps_hc_tx_insert_options = 1;
new_packet->dccphtx_ccval =
DCCP_SKB_CB(skb)->dccpd_ccval =
hctx->ccid3hctx_last_win_count;
+ }
out:
return rc;
}
static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct timeval now;
BUG_ON(hctx == NULL);
@@ -370,7 +379,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
return;
}
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
/* check if we have sent a data packet */
if (len > 0) {
@@ -445,10 +454,11 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct ccid3_options_received *opt_recv;
struct dccp_tx_hist_entry *packet;
+ struct timeval now;
unsigned long next_tmout;
u32 t_elapsed;
u32 pinv;
@@ -471,7 +481,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
opt_recv = &hctx->ccid3hctx_options_received;
- t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
+ t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
x_recv = opt_recv->ccid3or_receive_rate;
pinv = opt_recv->ccid3or_loss_event_rate;
@@ -496,9 +506,14 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
}
/* Update RTT */
- r_sample = timeval_now_delta(&packet->dccphtx_tstamp);
- /* FIXME: */
- // r_sample -= usecs_to_jiffies(t_elapsed * 10);
+ dccp_timestamp(sk, &now);
+ r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
+ if (unlikely(r_sample <= t_elapsed))
+ LIMIT_NETDEBUG(KERN_WARNING
+ "%s: r_sample=%uus, t_elapsed=%uus\n",
+ __FUNCTION__, r_sample, t_elapsed);
+ else
+ r_sample -= t_elapsed;
/* Update RTT estimate by
* If (No feedback recv)
@@ -591,8 +606,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
if (hctx == NULL || !(sk->sk_state == DCCP_OPEN ||
sk->sk_state == DCCP_PARTOPEN))
@@ -606,8 +620,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
unsigned char *value)
{
int rc = 0;
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct ccid3_options_received *opt_recv;
if (hctx == NULL)
@@ -670,11 +684,11 @@ static int ccid3_hc_tx_init(struct sock *sk)
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
- hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx),
- gfp_any());
- if (hctx == NULL)
+ dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
+ if (dp->dccps_hc_tx_ccid_private == NULL)
return -ENOMEM;
+ hctx = ccid3_hc_tx_sk(sk);
memset(hctx, 0, sizeof(*hctx));
if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
@@ -696,7 +710,7 @@ static int ccid3_hc_tx_init(struct sock *sk)
static void ccid3_hc_tx_exit(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
BUG_ON(hctx == NULL);
@@ -738,8 +752,7 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
static inline void ccid3_hc_rx_set_state(struct sock *sk,
enum ccid3_hc_rx_states state)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
@@ -751,14 +764,14 @@ static inline void ccid3_hc_rx_set_state(struct sock *sk,
static void ccid3_hc_rx_send_feedback(struct sock *sk)
{
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
struct dccp_rx_hist_entry *packet;
struct timeval now;
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
switch (hcrx->ccid3hcrx_state) {
case TFRC_RSTATE_NO_DATA:
@@ -767,11 +780,8 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
case TFRC_RSTATE_DATA: {
const u32 delta = timeval_delta(&now,
&hcrx->ccid3hcrx_tstamp_last_feedback);
-
- hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv *
- USEC_PER_SEC);
- if (likely(delta > 1))
- hcrx->ccid3hcrx_x_recv /= delta;
+ hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv,
+ delta);
}
break;
default:
@@ -801,14 +811,14 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
hcrx->ccid3hcrx_pinv = ~0;
else
hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
+ dp->dccps_hc_rx_insert_options = 1;
dccp_send_ack(sk);
}
static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
{
- const struct dccp_sock *dp = dccp_sk(sk);
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
u32 x_recv, pinv;
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN ||
sk->sk_state == DCCP_PARTOPEN))
@@ -837,8 +847,7 @@ static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
u32 rtt, delta, x_recv, fval, p, tmp2;
struct timeval tstamp = { 0, };
@@ -889,10 +898,9 @@ found:
if (rtt == 0)
rtt = 1;
- delta = timeval_now_delta(&hcrx->ccid3hcrx_tstamp_last_feedback);
- x_recv = hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC;
- if (likely(delta > 1))
- x_recv /= delta;
+ dccp_timestamp(sk, &tstamp);
+ delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
+ x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
tmp1 = (u64)x_recv * (u64)rtt;
do_div(tmp1,10000000);
@@ -911,8 +919,7 @@ found:
static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
if (seq_loss != DCCP_MAX_SEQNO + 1 &&
list_empty(&hcrx->ccid3hcrx_li_hist)) {
@@ -930,8 +937,7 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
static void ccid3_hc_rx_detect_loss(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
u8 win_loss;
const u64 seq_loss = dccp_rx_hist_detect_loss(&hcrx->ccid3hcrx_hist,
&hcrx->ccid3hcrx_li_hist,
@@ -942,13 +948,12 @@ static void ccid3_hc_rx_detect_loss(struct sock *sk)
static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
const struct dccp_options_received *opt_recv;
struct dccp_rx_hist_entry *packet;
struct timeval now;
u8 win_count;
- u32 p_prev;
+ u32 p_prev, r_sample, t_elapsed;
int ins;
if (hcrx == NULL)
@@ -957,7 +962,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
- opt_recv = &dp->dccps_options_received;
+ opt_recv = &dccp_sk(sk)->dccps_options_received;
switch (DCCP_SKB_CB(skb)->dccpd_type) {
case DCCP_PKT_ACK:
@@ -967,10 +972,24 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
if (opt_recv->dccpor_timestamp_echo == 0)
break;
p_prev = hcrx->ccid3hcrx_rtt;
- do_gettimeofday(&now);
- hcrx->ccid3hcrx_rtt = timeval_usecs(&now) -
- (opt_recv->dccpor_timestamp_echo -
- opt_recv->dccpor_elapsed_time) * 10;
+ dccp_timestamp(sk, &now);
+ timeval_sub_usecs(&now, opt_recv->dccpor_timestamp_echo * 10);
+ r_sample = timeval_usecs(&now);
+ t_elapsed = opt_recv->dccpor_elapsed_time * 10;
+
+ if (unlikely(r_sample <= t_elapsed))
+ LIMIT_NETDEBUG(KERN_WARNING
+ "%s: r_sample=%uus, t_elapsed=%uus\n",
+ __FUNCTION__, r_sample, t_elapsed);
+ else
+ r_sample -= t_elapsed;
+
+ if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
+ hcrx->ccid3hcrx_rtt = r_sample;
+ else
+ hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
+ r_sample / 10;
+
if (p_prev != hcrx->ccid3hcrx_rtt)
ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
dccp_role(sk), hcrx->ccid3hcrx_rtt,
@@ -985,7 +1004,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
return;
}
- packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp,
+ packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
skb, SLAB_ATOMIC);
if (packet == NULL) {
ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet "
@@ -1017,7 +1036,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
if (ins != 0)
break;
- do_gettimeofday(&now);
+ dccp_timestamp(sk, &now);
if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
hcrx->ccid3hcrx_rtt) {
hcrx->ccid3hcrx_tstamp_last_ack = now;
@@ -1056,11 +1075,11 @@ static int ccid3_hc_rx_init(struct sock *sk)
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
- hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx),
- gfp_any());
- if (hcrx == NULL)
+ dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
+ if (dp->dccps_hc_rx_ccid_private == NULL)
return -ENOMEM;
+ hcrx = ccid3_hc_rx_sk(sk);
memset(hcrx, 0, sizeof(*hcrx));
if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
@@ -1072,18 +1091,16 @@ static int ccid3_hc_rx_init(struct sock *sk)
hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
- /*
- * XXX this seems to be paranoid, need to think more about this, for
- * now start with something different than zero. -acme
- */
- hcrx->ccid3hcrx_rtt = USEC_PER_SEC / 5;
+ dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
+ hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
+ hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */
return 0;
}
static void ccid3_hc_rx_exit(struct sock *sk)
{
+ struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
- struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
@@ -1104,8 +1121,7 @@ static void ccid3_hc_rx_exit(struct sock *sk)
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
+ const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
if (hcrx == NULL)
return;
@@ -1117,8 +1133,7 @@ static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
+ const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
if (hctx == NULL)
return;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index ee8cbac..d16f00d 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -115,7 +115,7 @@ struct ccid3_hc_rx_sock {
u64 ccid3hcrx_seqno_last_counter:48,
ccid3hcrx_state:8,
ccid3hcrx_last_counter:4;
- unsigned long ccid3hcrx_rtt;
+ u32 ccid3hcrx_rtt;
u32 ccid3hcrx_p;
u32 ccid3hcrx_bytes_recv;
struct timeval ccid3hcrx_tstamp_last_feedback;
@@ -128,10 +128,14 @@ struct ccid3_hc_rx_sock {
u32 ccid3hcrx_x_recv;
};
-#define ccid3_hc_tx_field(s,field) (s->dccps_hc_tx_ccid_private == NULL ? 0 : \
- ((struct ccid3_hc_tx_sock *)s->dccps_hc_tx_ccid_private)->ccid3hctx_##field)
+static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_hc_tx_ccid_private;
+}
-#define ccid3_hc_rx_field(s,field) (s->dccps_hc_rx_ccid_private == NULL ? 0 : \
- ((struct ccid3_hc_rx_sock *)s->dccps_hc_rx_ccid_private)->ccid3hcrx_##field)
+static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
+{
+ return dccp_sk(sk)->dccps_hc_rx_ccid_private;
+}
#endif /* _DCCP_CCID3_H_ */
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index fb90a91..b375ebd 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -134,6 +134,7 @@ static inline struct dccp_tx_hist_entry *
static inline struct dccp_rx_hist_entry *
dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
+ const struct sock *sk,
const u32 ndp,
const struct sk_buff *skb,
const unsigned int __nocast prio)
@@ -148,7 +149,7 @@ static inline struct dccp_rx_hist_entry *
entry->dccphrx_ccval = dh->dccph_ccval;
entry->dccphrx_type = dh->dccph_type;
entry->dccphrx_ndp = ndp;
- do_gettimeofday(&(entry->dccphrx_tstamp));
+ dccp_timestamp(sk, &entry->dccphrx_tstamp);
}
return entry;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 33456c0..95c4630b 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -426,10 +426,13 @@ extern struct dccp_ackpkts *
dccp_ackpkts_alloc(unsigned int len,
const unsigned int __nocast priority);
extern void dccp_ackpkts_free(struct dccp_ackpkts *ap);
-extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state);
+extern int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk,
+ u64 ackno, u8 state);
extern void dccp_ackpkts_check_rcv_ackno(struct dccp_ackpkts *ap,
struct sock *sk, u64 ackno);
+extern void dccp_timestamp(const struct sock *sk, struct timeval *tv);
+
static inline suseconds_t timeval_usecs(const struct timeval *tv)
{
return tv->tv_sec * USEC_PER_SEC + tv->tv_usec;
@@ -468,17 +471,6 @@ static inline void timeval_sub_usecs(struct timeval *tv,
}
}
-/*
- * Returns the difference in usecs between timeval
- * passed in and current time
- */
-static inline suseconds_t timeval_now_delta(const struct timeval *tv)
-{
- struct timeval now;
- do_gettimeofday(&now);
- return timeval_delta(&now, tv);
-}
-
#ifdef CONFIG_IP_DCCP_DEBUG
extern void dccp_ackvector_print(const u64 ackno,
const unsigned char *vector, int len);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index ef29cef..c60bc34 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -170,7 +170,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
if (dp->dccps_options.dccpo_send_ack_vector) {
struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
- if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts,
+ if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
DCCP_SKB_CB(skb)->dccpd_seq,
DCCP_ACKPKTS_STATE_RECEIVED)) {
LIMIT_NETDEBUG(KERN_WARNING "DCCP: acknowledgeable "
@@ -498,7 +498,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
* DCCP_ACKPKTS_STATE_ECN_MARKED
*/
if (dp->dccps_options.dccpo_send_ack_vector) {
- if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts,
+ if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
DCCP_SKB_CB(skb)->dccpd_seq,
DCCP_ACKPKTS_STATE_RECEIVED))
goto discard;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 3fc75db..fee9a8c 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1243,6 +1243,7 @@ static int dccp_v4_init_sock(struct sock *sk)
static int dccp_ctl_socket_init = 1;
dccp_options_init(&dp->dccps_options);
+ do_gettimeofday(&dp->dccps_epoch);
if (dp->dccps_options.dccpo_send_ack_vector) {
dp->dccps_hc_rx_ackpkts =
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index ce5dff4..18461bc 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -96,6 +96,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
newdp->dccps_hc_rx_ackpkts = NULL;
newdp->dccps_role = DCCP_ROLE_SERVER;
newicsk->icsk_rto = DCCP_TIMEOUT_INIT;
+ do_gettimeofday(&newdp->dccps_epoch);
if (newdp->dccps_options.dccpo_send_ack_vector) {
newdp->dccps_hc_rx_ackpkts =
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 382c589..d4c4242 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -72,6 +72,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
struct dccp_options_received *opt_recv = &dp->dccps_options_received;
unsigned char opt, len;
unsigned char *value;
+ u32 elapsed_time;
memset(opt_recv, 0, sizeof(*opt_recv));
@@ -139,7 +140,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);
dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
- do_gettimeofday(&dp->dccps_timestamp_time);
+ dccp_timestamp(sk, &dp->dccps_timestamp_time);
dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n",
debug_prefix, opt_recv->dccpor_timestamp,
@@ -159,18 +160,18 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
(unsigned long long)
DCCP_SKB_CB(skb)->dccpd_ack_seq);
- if (len > 4) {
- if (len == 6)
- opt_recv->dccpor_elapsed_time =
- ntohs(*(u16 *)(value + 4));
- else
- opt_recv->dccpor_elapsed_time =
- ntohl(*(u32 *)(value + 4));
- dccp_pr_debug("%sTIMESTAMP_ECHO ELAPSED_TIME=%d\n",
- debug_prefix,
- opt_recv->dccpor_elapsed_time);
- }
+ if (len == 4)
+ break;
+
+ if (len == 6)
+ elapsed_time = ntohs(*(u16 *)(value + 4));
+ else
+ elapsed_time = ntohl(*(u32 *)(value + 4));
+
+ /* Give precedence to the biggest ELAPSED_TIME */
+ if (elapsed_time > opt_recv->dccpor_elapsed_time)
+ opt_recv->dccpor_elapsed_time = elapsed_time;
break;
case DCCPO_ELAPSED_TIME:
if (len != 2 && len != 4)
@@ -180,14 +181,15 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
continue;
if (len == 2)
- opt_recv->dccpor_elapsed_time =
- ntohs(*(u16 *)value);
+ elapsed_time = ntohs(*(u16 *)value);
else
- opt_recv->dccpor_elapsed_time =
- ntohl(*(u32 *)value);
+ elapsed_time = ntohl(*(u32 *)value);
+
+ if (elapsed_time > opt_recv->dccpor_elapsed_time)
+ opt_recv->dccpor_elapsed_time = elapsed_time;
dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix,
- opt_recv->dccpor_elapsed_time);
+ elapsed_time);
break;
/*
* From draft-ietf-dccp-spec-11.txt:
@@ -359,9 +361,13 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
#endif
struct dccp_ackpkts *ap = dp->dccps_hc_rx_ackpkts;
int len = ap->dccpap_buf_vector_len + 2;
- const u32 elapsed_time = timeval_now_delta(&ap->dccpap_time) / 10;
+ struct timeval now;
+ u32 elapsed_time;
unsigned char *to, *from;
+ dccp_timestamp(sk, &now);
+ elapsed_time = timeval_delta(&now, &ap->dccpap_time) / 10;
+
if (elapsed_time != 0)
dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
@@ -426,13 +432,29 @@ static void dccp_insert_option_ack_vector(struct sock *sk, struct sk_buff *skb)
(unsigned long long) ap->dccpap_ack_ackno);
}
+void dccp_timestamp(const struct sock *sk, struct timeval *tv)
+{
+ const struct dccp_sock *dp = dccp_sk(sk);
+
+ do_gettimeofday(tv);
+ tv->tv_sec -= dp->dccps_epoch.tv_sec;
+ tv->tv_usec -= dp->dccps_epoch.tv_usec;
+
+ while (tv->tv_usec < 0) {
+ tv->tv_sec--;
+ tv->tv_usec += USEC_PER_SEC;
+ }
+}
+
+EXPORT_SYMBOL_GPL(dccp_timestamp);
+
void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
{
struct timeval tv;
u32 now;
- do_gettimeofday(&tv);
- now = (tv.tv_sec * USEC_PER_SEC + tv.tv_usec) / 10;
+ dccp_timestamp(sk, &tv);
+ now = timeval_usecs(&tv) / 10;
/* yes this will overflow but that is the point as we want a
* 10 usec 32 bit timer which mean it wraps every 11.9 hours */
@@ -450,13 +472,17 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
"CLIENT TX opt: " : "server TX opt: ";
#endif
+ struct timeval now;
u32 tstamp_echo;
- const u32 elapsed_time =
- timeval_now_delta(&dp->dccps_timestamp_time) / 10;
- const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
- const int len = 6 + elapsed_time_len;
+ u32 elapsed_time;
+ int len, elapsed_time_len;
unsigned char *to;
+ dccp_timestamp(sk, &now);
+ elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10;
+ elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
+ len = 6 + elapsed_time_len;
+
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
"timestamp echo!\n");
@@ -505,13 +531,18 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
(dp->dccps_hc_rx_ackpkts->dccpap_buf_ackno !=
DCCP_MAX_SEQNO + 1))
dccp_insert_option_ack_vector(sk, skb);
-
if (dp->dccps_timestamp_echo != 0)
dccp_insert_option_timestamp_echo(sk, skb);
}
- ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
- ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
+ if (dp->dccps_hc_rx_insert_options) {
+ ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
+ dp->dccps_hc_rx_insert_options = 0;
+ }
+ if (dp->dccps_hc_tx_insert_options) {
+ ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
+ dp->dccps_hc_tx_insert_options = 0;
+ }
/* XXX: insert other options when appropriate */
@@ -616,7 +647,8 @@ static inline int dccp_ackpkts_set_buf_head_state(struct dccp_ackpkts *ap,
/*
* Implements the draft-ietf-dccp-spec-11.txt Appendix A
*/
-int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
+int dccp_ackpkts_add(struct dccp_ackpkts *ap, const struct sock *sk,
+ u64 ackno, u8 state)
{
/*
* Check at the right places if the buffer is full, if it is, tell the
@@ -697,7 +729,7 @@ int dccp_ackpkts_add(struct dccp_ackpkts *ap, u64 ackno, u8 state)
}
ap->dccpap_buf_ackno = ackno;
- do_gettimeofday(&ap->dccpap_time);
+ dccp_timestamp(sk, &ap->dccpap_time);
out:
dccp_pr_debug("");
dccp_ackpkts_print(ap);
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 621680f..348f36b 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1876,8 +1876,27 @@ static inline unsigned int dn_current_mss(struct sock *sk, int flags)
return mss_now;
}
+/*
+ * N.B. We get the timeout wrong here, but then we always did get it
+ * wrong before and this is another step along the road to correcting
+ * it. It ought to get updated each time we pass through the routine,
+ * but in practise it probably doesn't matter too much for now.
+ */
+static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
+ unsigned long datalen, int noblock,
+ int *errcode)
+{
+ struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
+ noblock, errcode);
+ if (skb) {
+ skb->protocol = __constant_htons(ETH_P_DNA_RT);
+ skb->pkt_type = PACKET_OUTGOING;
+ }
+ return skb;
+}
+
static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t size)
+ struct msghdr *msg, size_t size)
{
struct sock *sk = sock->sk;
struct dn_scp *scp = DN_SK(sk);
@@ -1892,7 +1911,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
struct dn_skb_cb *cb;
size_t len;
unsigned char fctype;
- long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
+ long timeo;
if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL|MSG_MORE|MSG_CMSG_COMPAT))
return -EOPNOTSUPP;
@@ -1900,18 +1919,21 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
return -EINVAL;
+ lock_sock(sk);
+ timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
/*
* The only difference between stream sockets and sequenced packet
* sockets is that the stream sockets always behave as if MSG_EOR
* has been set.
*/
if (sock->type == SOCK_STREAM) {
- if (flags & MSG_EOR)
- return -EINVAL;
+ if (flags & MSG_EOR) {
+ err = -EINVAL;
+ goto out;
+ }
flags |= MSG_EOR;
}
- lock_sock(sk);
err = dn_check_state(sk, addr, addr_len, &timeo, flags);
if (err)
@@ -1980,8 +2002,12 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
/*
* Get a suitably sized skb.
+ * 64 is a bit of a hack really, but its larger than any
+ * link-layer headers and has served us well as a good
+ * guess as to their real length.
*/
- skb = dn_alloc_send_skb(sk, &len, flags & MSG_DONTWAIT, timeo, &err);
+ skb = dn_alloc_send_pskb(sk, len + 64 + DN_MAX_NSP_DATA_HEADER,
+ flags & MSG_DONTWAIT, &err);
if (err)
break;
@@ -1991,7 +2017,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
cb = DN_SKB_CB(skb);
- skb_reserve(skb, DN_MAX_NSP_DATA_HEADER);
+ skb_reserve(skb, 64 + DN_MAX_NSP_DATA_HEADER);
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
err = -EFAULT;
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index e0bebf4..53633d3 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -137,69 +137,6 @@ struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri)
}
/*
- * Wrapper for the above, for allocs of data skbs. We try and get the
- * whole size thats been asked for (plus 11 bytes of header). If this
- * fails, then we try for any size over 16 bytes for SOCK_STREAMS.
- */
-struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err)
-{
- int space;
- int len;
- struct sk_buff *skb = NULL;
-
- *err = 0;
-
- while(skb == NULL) {
- if (signal_pending(current)) {
- *err = sock_intr_errno(timeo);
- break;
- }
-
- if (sk->sk_shutdown & SEND_SHUTDOWN) {
- *err = EINVAL;
- break;
- }
-
- if (sk->sk_err)
- break;
-
- len = *size + 11;
- space = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
-
- if (space < len) {
- if ((sk->sk_socket->type == SOCK_STREAM) &&
- (space >= (16 + 11)))
- len = space;
- }
-
- if (space < len) {
- set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
- if (noblock) {
- *err = EWOULDBLOCK;
- break;
- }
-
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- SOCK_SLEEP_PRE(sk)
-
- if ((sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc)) <
- len)
- schedule();
-
- SOCK_SLEEP_POST(sk)
- continue;
- }
-
- if ((skb = dn_alloc_skb(sk, len, sk->sk_allocation)) == NULL)
- continue;
-
- *size = len - 11;
- }
-
- return skb;
-}
-
-/*
* Calculate persist timer based upon the smoothed round
* trip time and the variance. Backoff according to the
* nsp_backoff[] array.
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 2c915f3..3407f19 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -117,8 +117,7 @@ static struct dn_rt_hash_bucket *dn_rt_hash_table;
static unsigned dn_rt_hash_mask;
static struct timer_list dn_route_timer;
-static struct timer_list dn_rt_flush_timer =
- TIMER_INITIALIZER(dn_run_flush, 0, 0);
+static DEFINE_TIMER(dn_rt_flush_timer, dn_run_flush, 0, 0);
int decnet_dst_gc_interval = 2;
static struct dst_ops dn_dst_ops = {
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index 58ed431..91b16fb 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -1,6 +1,5 @@
config IEEE80211
tristate "Generic IEEE 802.11 Networking Stack"
- select NET_RADIO
---help---
This option enables the hardware independent IEEE 802.11
networking stack.
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index 05a6f2f..61a9d92 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -30,7 +30,6 @@ struct ieee80211_crypto_alg {
struct ieee80211_crypto_ops *ops;
};
-
struct ieee80211_crypto {
struct list_head algs;
spinlock_t lock;
@@ -38,8 +37,7 @@ struct ieee80211_crypto {
static struct ieee80211_crypto *hcrypt;
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
- int force)
+void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
@@ -140,7 +138,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
+ (struct ieee80211_crypto_alg *)ptr;
if (alg->ops == ops) {
list_del(&alg->list);
del_alg = alg;
@@ -158,8 +156,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
return del_alg ? 0 : -1;
}
-
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
+struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
{
unsigned long flags;
struct list_head *ptr;
@@ -171,7 +168,7 @@ struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
+ (struct ieee80211_crypto_alg *)ptr;
if (strcmp(alg->ops->name, name) == 0) {
found_alg = alg;
break;
@@ -185,9 +182,13 @@ struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
return NULL;
}
-
-static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
-static void ieee80211_crypt_null_deinit(void *priv) {}
+static void *ieee80211_crypt_null_init(int keyidx)
+{
+ return (void *)1;
+}
+static void ieee80211_crypt_null_deinit(void *priv)
+{
+}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
.name = "NULL",
@@ -204,7 +205,6 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
.owner = THIS_MODULE,
};
-
static int __init ieee80211_crypto_init(void)
{
int ret = -ENOMEM;
@@ -222,11 +222,10 @@ static int __init ieee80211_crypto_init(void)
kfree(hcrypt);
hcrypt = NULL;
}
-out:
+ out:
return ret;
}
-
static void __exit ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
@@ -237,7 +236,7 @@ static void __exit ieee80211_crypto_deinit(void)
for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
ptr = n, n = ptr->next) {
struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
+ (struct ieee80211_crypto_alg *)ptr;
list_del(ptr);
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
"'%s' (deinit)\n", alg->ops->name);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 11d1557..8fc13f4 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -24,7 +24,6 @@
#include <net/ieee80211.h>
-
#include <linux/crypto.h>
#include <asm/scatterlist.h>
@@ -55,7 +54,7 @@ struct ieee80211_ccmp_data {
/* scratch buffers for virt_to_page() (crypto API) */
u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
- tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
+ tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
};
@@ -75,7 +74,7 @@ static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
}
-static void * ieee80211_ccmp_init(int key_idx)
+static void *ieee80211_ccmp_init(int key_idx)
{
struct ieee80211_ccmp_data *priv;
@@ -94,7 +93,7 @@ static void * ieee80211_ccmp_init(int key_idx)
return priv;
-fail:
+ fail:
if (priv) {
if (priv->tfm)
crypto_free_tfm(priv->tfm);
@@ -104,7 +103,6 @@ fail:
return NULL;
}
-
static void ieee80211_ccmp_deinit(void *priv)
{
struct ieee80211_ccmp_data *_priv = priv;
@@ -113,19 +111,16 @@ static void ieee80211_ccmp_deinit(void *priv)
kfree(priv);
}
-
-static inline void xor_block(u8 *b, u8 *a, size_t len)
+static inline void xor_block(u8 * b, u8 * a, size_t len)
{
int i;
for (i = 0; i < len; i++)
b[i] ^= a[i];
}
-
static void ccmp_init_blocks(struct crypto_tfm *tfm,
struct ieee80211_hdr *hdr,
- u8 *pn, size_t dlen, u8 *b0, u8 *auth,
- u8 *s0)
+ u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
{
u8 *pos, qc = 0;
size_t aad_len;
@@ -142,7 +137,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
if (a4_included)
aad_len += 6;
if (qc_included) {
- pos = (u8 *) &hdr->addr4;
+ pos = (u8 *) & hdr->addr4;
if (a4_included)
pos += 6;
qc = *pos & 0x0f;
@@ -169,14 +164,14 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
* QC (if present)
*/
pos = (u8 *) hdr;
- aad[0] = 0; /* aad_len >> 8 */
+ aad[0] = 0; /* aad_len >> 8 */
aad[1] = aad_len & 0xff;
aad[2] = pos[0] & 0x8f;
aad[3] = pos[1] & 0xc7;
memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
- pos = (u8 *) &hdr->seq_ctl;
+ pos = (u8 *) & hdr->seq_ctl;
aad[22] = pos[0] & 0x0f;
- aad[23] = 0; /* all bits masked */
+ aad[23] = 0; /* all bits masked */
memset(aad + 24, 0, 8);
if (a4_included)
memcpy(aad + 24, hdr->addr4, ETH_ALEN);
@@ -196,7 +191,6 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
}
-
static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
@@ -209,8 +203,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
u8 *s0 = key->tx_s0;
if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN ||
- skb->len < hdr_len)
+ skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
return -1;
data_len = skb->len - hdr_len;
@@ -230,13 +223,13 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
*pos++ = key->tx_pn[5];
*pos++ = key->tx_pn[4];
*pos++ = 0;
- *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
+ *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
*pos++ = key->tx_pn[3];
*pos++ = key->tx_pn[2];
*pos++ = key->tx_pn[1];
*pos++ = key->tx_pn[0];
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
@@ -261,7 +254,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
return 0;
}
-
static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
{
struct ieee80211_ccmp_data *key = priv;
@@ -280,7 +272,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return -1;
}
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
@@ -364,8 +356,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return keyidx;
}
-
-static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
+static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
{
struct ieee80211_ccmp_data *data = priv;
int keyidx;
@@ -395,8 +386,7 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
return 0;
}
-
-static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
+static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
{
struct ieee80211_ccmp_data *data = priv;
@@ -419,8 +409,7 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
return CCMP_TK_LEN;
}
-
-static char * ieee80211_ccmp_print_stats(char *p, void *priv)
+static char *ieee80211_ccmp_print_stats(char *p, void *priv)
{
struct ieee80211_ccmp_data *ccmp = priv;
p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
@@ -436,7 +425,6 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
return p;
}
-
static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
.name = "CCMP",
.init = ieee80211_ccmp_init,
@@ -453,18 +441,15 @@ static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
.owner = THIS_MODULE,
};
-
static int __init ieee80211_crypto_ccmp_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
}
-
static void __exit ieee80211_crypto_ccmp_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
}
-
module_init(ieee80211_crypto_ccmp_init);
module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index f91d92c..d4f9164 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -23,7 +23,6 @@
#include <net/ieee80211.h>
-
#include <linux/crypto.h>
#include <asm/scatterlist.h>
#include <linux/crc32.h>
@@ -62,7 +61,7 @@ struct ieee80211_tkip_data {
u8 rx_hdr[16], tx_hdr[16];
};
-static void * ieee80211_tkip_init(int key_idx)
+static void *ieee80211_tkip_init(int key_idx)
{
struct ieee80211_tkip_data *priv;
@@ -88,7 +87,7 @@ static void * ieee80211_tkip_init(int key_idx)
return priv;
-fail:
+ fail:
if (priv) {
if (priv->tfm_michael)
crypto_free_tfm(priv->tfm_michael);
@@ -100,7 +99,6 @@ fail:
return NULL;
}
-
static void ieee80211_tkip_deinit(void *priv)
{
struct ieee80211_tkip_data *_priv = priv;
@@ -111,51 +109,42 @@ static void ieee80211_tkip_deinit(void *priv)
kfree(priv);
}
-
static inline u16 RotR1(u16 val)
{
return (val >> 1) | (val << 15);
}
-
static inline u8 Lo8(u16 val)
{
return val & 0xff;
}
-
static inline u8 Hi8(u16 val)
{
return val >> 8;
}
-
static inline u16 Lo16(u32 val)
{
return val & 0xffff;
}
-
static inline u16 Hi16(u32 val)
{
return val >> 16;
}
-
static inline u16 Mk16(u8 hi, u8 lo)
{
return lo | (((u16) hi) << 8);
}
-
-static inline u16 Mk16_le(u16 *v)
+static inline u16 Mk16_le(u16 * v)
{
return le16_to_cpu(*v);
}
-
-static const u16 Sbox[256] =
-{
+static const u16 Sbox[256] = {
0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
@@ -190,17 +179,16 @@ static const u16 Sbox[256] =
0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
};
-
static inline u16 _S_(u16 v)
{
u16 t = Sbox[Hi8(v)];
return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
}
-
#define PHASE1_LOOP_COUNT 8
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
+static void tkip_mixing_phase1(u16 * TTAK, const u8 * TK, const u8 * TA,
+ u32 IV32)
{
int i, j;
@@ -221,13 +209,12 @@ static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
}
}
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
+static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
u16 IV16)
{
/* Make temporary area overlap WEP seed so that the final copy can be
* avoided on little endian hosts. */
- u16 *PPK = (u16 *) &WEPSeed[4];
+ u16 *PPK = (u16 *) & WEPSeed[4];
/* Step 1 - make copy of TTAK and bring in TSC */
PPK[0] = TTAK[0];
@@ -238,15 +225,15 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
PPK[5] = TTAK[4] + IV16;
/* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
+ PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) & TK[0]));
+ PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) & TK[2]));
+ PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) & TK[4]));
+ PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) & TK[6]));
+ PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) & TK[8]));
+ PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) & TK[10]));
+
+ PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) & TK[12]));
+ PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) & TK[14]));
PPK[2] += RotR1(PPK[1]);
PPK[3] += RotR1(PPK[2]);
PPK[4] += RotR1(PPK[3]);
@@ -257,7 +244,7 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
WEPSeed[0] = Hi8(IV16);
WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
+ WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) & TK[0])) >> 1);
#ifdef __BIG_ENDIAN
{
@@ -281,7 +268,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
skb->len < hdr_len)
return -1;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
if (!tkey->tx_phase1_done) {
tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
tkey->tx_iv32);
@@ -298,7 +285,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
*pos++ = rc4key[0];
*pos++ = rc4key[1];
*pos++ = rc4key[2];
- *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
+ *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
*pos++ = tkey->tx_iv32 & 0xff;
*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
@@ -341,7 +328,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
if (skb->len < hdr_len + 8 + 4)
return -1;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
pos = skb->data + hdr_len;
keyidx = pos[3];
if (!(keyidx & (1 << 5))) {
@@ -427,9 +414,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return keyidx;
}
-
-static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
- u8 *data, size_t data_len, u8 *mic)
+static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
+ u8 * data, size_t data_len, u8 * mic)
{
struct scatterlist sg[2];
@@ -453,37 +439,37 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
return 0;
}
-static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
+static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
{
struct ieee80211_hdr *hdr11;
- hdr11 = (struct ieee80211_hdr *) skb->data;
+ hdr11 = (struct ieee80211_hdr *)skb->data;
switch (le16_to_cpu(hdr11->frame_ctl) &
(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
case IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+ memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
+ memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
break;
case IEEE80211_FCTL_FROMDS:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
+ memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
+ memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
break;
case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
+ memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
+ memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
break;
case 0:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+ memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
+ memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
break;
}
- hdr[12] = 0; /* priority */
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
+ hdr[12] = 0; /* priority */
+ hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
}
-
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
+ void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
u8 *pos;
@@ -504,11 +490,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
return 0;
}
-
#if WIRELESS_EXT >= 18
static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr,
- int keyidx)
+ struct ieee80211_hdr *hdr, int keyidx)
{
union iwreq_data wrqu;
struct iw_michaelmicfailure ev;
@@ -524,12 +508,11 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.length = sizeof(ev);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
+ wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
}
#elif WIRELESS_EXT >= 15
static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr,
- int keyidx)
+ struct ieee80211_hdr *hdr, int keyidx)
{
union iwreq_data wrqu;
char buf[128];
@@ -542,17 +525,16 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
wrqu.data.length = strlen(buf);
wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
}
-#else /* WIRELESS_EXT >= 15 */
+#else /* WIRELESS_EXT >= 15 */
static inline void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr *hdr,
- int keyidx)
+ struct ieee80211_hdr *hdr,
+ int keyidx)
{
}
-#endif /* WIRELESS_EXT >= 15 */
-
+#endif /* WIRELESS_EXT >= 15 */
static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
- int hdr_len, void *priv)
+ int hdr_len, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
u8 mic[8];
@@ -566,7 +548,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
return -1;
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
struct ieee80211_hdr *hdr;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
"MSDU from " MAC_FMT " keyidx=%d\n",
skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
@@ -587,8 +569,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
return 0;
}
-
-static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
+static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
int keyidx;
@@ -603,10 +584,10 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
if (len == TKIP_KEY_LEN) {
memcpy(tkey->key, key, TKIP_KEY_LEN);
tkey->key_set = 1;
- tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
+ tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
if (seq) {
tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- (seq[3] << 8) | seq[2];
+ (seq[3] << 8) | seq[2];
tkey->rx_iv16 = (seq[1] << 8) | seq[0];
}
} else if (len == 0)
@@ -617,8 +598,7 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
return 0;
}
-
-static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
+static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
{
struct ieee80211_tkip_data *tkey = priv;
@@ -647,8 +627,7 @@ static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
return TKIP_KEY_LEN;
}
-
-static char * ieee80211_tkip_print_stats(char *p, void *priv)
+static char *ieee80211_tkip_print_stats(char *p, void *priv)
{
struct ieee80211_tkip_data *tkip = priv;
p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
@@ -674,7 +653,6 @@ static char * ieee80211_tkip_print_stats(char *p, void *priv)
return p;
}
-
static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
.name = "TKIP",
.init = ieee80211_tkip_init,
@@ -686,23 +664,20 @@ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
.set_key = ieee80211_tkip_set_key,
.get_key = ieee80211_tkip_get_key,
.print_stats = ieee80211_tkip_print_stats,
- .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_postfix_len = 8 + 4, /* MIC + ICV */
- .owner = THIS_MODULE,
+ .extra_prefix_len = 4 + 4, /* IV + ExtIV */
+ .extra_postfix_len = 8 + 4, /* MIC + ICV */
+ .owner = THIS_MODULE,
};
-
static int __init ieee80211_crypto_tkip_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
}
-
static void __exit ieee80211_crypto_tkip_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
}
-
module_init(ieee80211_crypto_tkip_init);
module_exit(ieee80211_crypto_tkip_exit);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index bec1d34..b4d2514 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -20,7 +20,6 @@
#include <net/ieee80211.h>
-
#include <linux/crypto.h>
#include <asm/scatterlist.h>
#include <linux/crc32.h>
@@ -29,7 +28,6 @@ MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP crypt: WEP");
MODULE_LICENSE("GPL");
-
struct prism2_wep_data {
u32 iv;
#define WEP_KEY_LEN 13
@@ -39,8 +37,7 @@ struct prism2_wep_data {
struct crypto_tfm *tfm;
};
-
-static void * prism2_wep_init(int keyidx)
+static void *prism2_wep_init(int keyidx)
{
struct prism2_wep_data *priv;
@@ -62,7 +59,7 @@ static void * prism2_wep_init(int keyidx)
return priv;
-fail:
+ fail:
if (priv) {
if (priv->tfm)
crypto_free_tfm(priv->tfm);
@@ -71,7 +68,6 @@ fail:
return NULL;
}
-
static void prism2_wep_deinit(void *priv)
{
struct prism2_wep_data *_priv = priv;
@@ -80,7 +76,6 @@ static void prism2_wep_deinit(void *priv)
kfree(priv);
}
-
/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
* for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
* so the payload length increases with 8 bytes.
@@ -143,7 +138,6 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
return 0;
}
-
/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
* the frame: IV (4 bytes), encrypted payload (including SNAP header),
* ICV (4 bytes). len includes both IV and ICV.
@@ -202,8 +196,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
return 0;
}
-
-static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
+static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv)
{
struct prism2_wep_data *wep = priv;
@@ -216,8 +209,7 @@ static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
return 0;
}
-
-static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
+static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv)
{
struct prism2_wep_data *wep = priv;
@@ -229,16 +221,13 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
return wep->key_len;
}
-
-static char * prism2_wep_print_stats(char *p, void *priv)
+static char *prism2_wep_print_stats(char *p, void *priv)
{
struct prism2_wep_data *wep = priv;
- p += sprintf(p, "key[%d] alg=WEP len=%d\n",
- wep->key_idx, wep->key_len);
+ p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
return p;
}
-
static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
.name = "WEP",
.init = prism2_wep_init,
@@ -250,23 +239,20 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
.set_key = prism2_wep_set_key,
.get_key = prism2_wep_get_key,
.print_stats = prism2_wep_print_stats,
- .extra_prefix_len = 4, /* IV */
- .extra_postfix_len = 4, /* ICV */
+ .extra_prefix_len = 4, /* IV */
+ .extra_postfix_len = 4, /* ICV */
.owner = THIS_MODULE,
};
-
static int __init ieee80211_crypto_wep_init(void)
{
return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
}
-
static void __exit ieee80211_crypto_wep_exit(void)
{
ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
}
-
module_init(ieee80211_crypto_wep_init);
module_exit(ieee80211_crypto_wep_exit);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 553acb2..03a4734 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -54,7 +54,8 @@
#include <net/ieee80211.h>
MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
+MODULE_AUTHOR
+ ("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
MODULE_LICENSE("GPL");
#define DRV_NAME "ieee80211"
@@ -64,9 +65,9 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
if (ieee->networks)
return 0;
- ieee->networks = kmalloc(
- MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
- GFP_KERNEL);
+ ieee->networks =
+ kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
+ GFP_KERNEL);
if (!ieee->networks) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
ieee->dev->name);
@@ -94,10 +95,10 @@ static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
+ list_add_tail(&ieee->networks[i].list,
+ &ieee->network_free_list);
}
-
struct net_device *alloc_ieee80211(int sizeof_priv)
{
struct ieee80211_device *ieee;
@@ -118,8 +119,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
err = ieee80211_networks_allocate(ieee);
if (err) {
- IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
- err);
+ IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
goto failed;
}
ieee80211_networks_initialize(ieee);
@@ -132,7 +132,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee->host_encrypt = 1;
ieee->host_decrypt = 1;
- ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
+ ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
init_timer(&ieee->crypt_deinit_timer);
@@ -141,21 +141,20 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
spin_lock_init(&ieee->lock);
- ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
+ ieee->wpa_enabled = 0;
+ ieee->tkip_countermeasures = 0;
+ ieee->drop_unencrypted = 0;
+ ieee->privacy_invoked = 0;
+ ieee->ieee802_1x = 1;
return dev;
- failed:
+ failed:
if (dev)
free_netdev(dev);
return NULL;
}
-
void free_ieee80211(struct net_device *dev)
{
struct ieee80211_device *ieee = netdev_priv(dev);
@@ -193,7 +192,7 @@ static int show_debug_level(char *page, char **start, off_t offset,
return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
}
-static int store_debug_level(struct file *file, const char __user *buffer,
+static int store_debug_level(struct file *file, const char __user * buffer,
unsigned long count, void *data)
{
char buf[] = "0x00000000";
@@ -264,13 +263,12 @@ static void __exit ieee80211_exit(void)
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
-
module_exit(ieee80211_exit);
module_init(ieee80211_init);
#endif
-
-const char *escape_essid(const char *essid, u8 essid_len) {
+const char *escape_essid(const char *essid, u8 essid_len)
+{
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = essid;
char *d = escaped;
@@ -280,7 +278,7 @@ const char *escape_essid(const char *essid, u8 essid_len) {
return escaped;
}
- essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
+ essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
while (essid_len--) {
if (*s == '\0') {
*d++ = '\\';
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index d582faa..f7dcd85 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -52,11 +52,14 @@ static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
netif_rx(skb);
}
-
/* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *
-ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
- unsigned int frag, u8 *src, u8 *dst)
+static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
+ ieee80211_device
+ *ieee,
+ unsigned int seq,
+ unsigned int frag,
+ u8 * src,
+ u8 * dst)
{
struct ieee80211_frag_entry *entry;
int i;
@@ -65,10 +68,9 @@ ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
entry = &ieee->frag_cache[i];
if (entry->skb != NULL &&
time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- IEEE80211_DEBUG_FRAG(
- "expiring fragment cache entry "
- "seq=%u last_frag=%u\n",
- entry->seq, entry->last_frag);
+ IEEE80211_DEBUG_FRAG("expiring fragment cache entry "
+ "seq=%u last_frag=%u\n",
+ entry->seq, entry->last_frag);
dev_kfree_skb_any(entry->skb);
entry->skb = NULL;
}
@@ -84,9 +86,8 @@ ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
}
/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *
-ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr *hdr)
+static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
+ struct ieee80211_hdr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
@@ -101,9 +102,9 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(ieee->dev->mtu +
sizeof(struct ieee80211_hdr) +
- 8 /* LLC */ +
- 2 /* alignment */ +
- 8 /* WEP */ + ETH_ALEN /* WDS */);
+ 8 /* LLC */ +
+ 2 /* alignment */ +
+ 8 /* WEP */ + ETH_ALEN /* WDS */ );
if (skb == NULL)
return NULL;
@@ -135,7 +136,6 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
return skb;
}
-
/* Called only as a tasklet (software IRQ) */
static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
struct ieee80211_hdr *hdr)
@@ -151,9 +151,8 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
hdr->addr1);
if (entry == NULL) {
- IEEE80211_DEBUG_FRAG(
- "could not invalidate fragment cache "
- "entry (seq=%u)\n", seq);
+ IEEE80211_DEBUG_FRAG("could not invalidate fragment cache "
+ "entry (seq=%u)\n", seq);
return -1;
}
@@ -161,7 +160,6 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
return 0;
}
-
#ifdef NOT_YET
/* ieee80211_rx_frame_mgtmt
*
@@ -201,7 +199,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
return 0;
}
- if (ieee->iw_mode == IW_MODE_MASTER) {
+ if (ieee->iw_mode == IW_MODE_MASTER) {
if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
printk(KERN_DEBUG "%s: unknown management frame "
"(type=0x%02x, stype=0x%02x) dropped\n",
@@ -219,14 +217,13 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
}
#endif
-
/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
static unsigned char bridge_tunnel_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+ { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
/* No encapsulation header if EtherType < 0x600 (=length) */
/* Called by ieee80211_rx_frame_decrypt */
@@ -241,7 +238,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
/* check that the frame is unicast frame to us */
@@ -271,7 +268,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
static inline int
-ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
+ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_crypt_data *crypt)
{
struct ieee80211_hdr *hdr;
@@ -280,12 +277,11 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- if (ieee->tkip_countermeasures &&
- strcmp(crypt->ops->name, "TKIP") == 0) {
+ if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"received packet from " MAC_FMT "\n",
@@ -299,9 +295,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
atomic_dec(&crypt->refcnt);
if (res < 0) {
- IEEE80211_DEBUG_DROP(
- "decryption failed (SA=" MAC_FMT
- ") res=%d\n", MAC_ARG(hdr->addr2), res);
+ IEEE80211_DEBUG_DROP("decryption failed (SA=" MAC_FMT
+ ") res=%d\n", MAC_ARG(hdr->addr2), res);
if (res == -2)
IEEE80211_DEBUG_DROP("Decryption failed ICV "
"mismatch (key %d)\n",
@@ -313,11 +308,11 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
return res;
}
-
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
- int keyidx, struct ieee80211_crypt_data *crypt)
+ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
+ struct sk_buff *skb, int keyidx,
+ struct ieee80211_crypt_data *crypt)
{
struct ieee80211_hdr *hdr;
int res, hdrlen;
@@ -325,7 +320,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
atomic_inc(&crypt->refcnt);
@@ -341,7 +336,6 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
return 0;
}
-
/* All received frames are sent to this function. @skb contains the frame in
* IEEE 802.11 format, i.e., in the format it was sent over air.
* This function is called only as a tasklet (software IRQ). */
@@ -373,8 +367,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
stats = &ieee->stats;
if (skb->len < 10) {
- printk(KERN_INFO "%s: SKB length < 10\n",
- dev->name);
+ printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
goto rx_dropped;
}
@@ -399,8 +392,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* Update spy records */
wireless_spy_update(dev, hdr->addr2, &wstats);
}
-#endif /* IW_WIRELESS_SPY */
-#endif /* WIRELESS_EXT > 15 */
+#endif /* IW_WIRELESS_SPY */
+#endif /* WIRELESS_EXT > 15 */
hostap_update_rx_stats(local->ap, hdr, rx_stats);
#endif
@@ -429,8 +422,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* stations that do not support WEP key mapping). */
if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
- (void) hostap_handle_sta_crypto(local, hdr, &crypt,
- &sta);
+ (void)hostap_handle_sta_crypto(local, hdr, &crypt,
+ &sta);
#endif
/* allow NULL decrypt to indicate an station specific override
@@ -451,13 +444,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
goto rx_dropped;
}
}
-
#ifdef NOT_YET
if (type != WLAN_FC_TYPE_DATA) {
if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
- (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- {
+ (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
"from " MAC_FMT "\n", dev->name,
MAC_ARG(hdr->addr2));
@@ -507,9 +498,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
}
if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
- (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
- ieee->stadev &&
- memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
+ (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
+ IEEE80211_FCTL_FROMDS && ieee->stadev
+ && memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
/* Frame from BSSID of the AP for which we are a client */
skb->dev = dev = ieee->stadev;
stats = hostap_get_stats(dev);
@@ -521,8 +512,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
#ifdef NOT_YET
if ((ieee->iw_mode == IW_MODE_MASTER ||
- ieee->iw_mode == IW_MODE_REPEAT) &&
- !from_assoc_ap) {
+ ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
wds != NULL)) {
case AP_RX_CONTINUE_NOT_AUTHORIZED:
@@ -546,11 +536,10 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
stype != IEEE80211_STYPE_DATA_CFPOLL &&
stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
if (stype != IEEE80211_STYPE_NULLFUNC)
- IEEE80211_DEBUG_DROP(
- "RX: dropped data frame "
- "with no data (type=0x%02x, "
- "subtype=0x%02x, len=%d)\n",
- type, stype, skb->len);
+ IEEE80211_DEBUG_DROP("RX: dropped data frame "
+ "with no data (type=0x%02x, "
+ "subtype=0x%02x, len=%d)\n",
+ type, stype, skb->len);
goto rx_dropped;
}
@@ -560,7 +549,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
(keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
// PR: FIXME: hostap has additional conditions in the "if" below:
@@ -614,7 +603,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
ieee80211_frag_cache_invalidate(ieee, hdr);
}
@@ -624,28 +613,26 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr *) skb->data;
+ hdr = (struct ieee80211_hdr *)skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
- if (/*ieee->ieee802_1x &&*/
- ieee80211_is_eapol_frame(ieee, skb)) {
+ if ( /*ieee->ieee802_1x && */
+ ieee80211_is_eapol_frame(ieee, skb)) {
/* pass unencrypted EAPOL frames even if encryption is
* configured */
} else {
- IEEE80211_DEBUG_DROP(
- "encryption configured, but RX "
- "frame not encrypted (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ IEEE80211_DEBUG_DROP("encryption configured, but RX "
+ "frame not encrypted (SA=" MAC_FMT
+ ")\n", MAC_ARG(hdr->addr2));
goto rx_dropped;
}
}
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
!ieee80211_is_eapol_frame(ieee, skb)) {
- IEEE80211_DEBUG_DROP(
- "dropped unencrypted RX data "
- "frame from " MAC_FMT
- " (drop_unencrypted=1)\n",
- MAC_ARG(hdr->addr2));
+ IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
+ "frame from " MAC_FMT
+ " (drop_unencrypted=1)\n",
+ MAC_ARG(hdr->addr2));
goto rx_dropped;
}
@@ -673,8 +660,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
} else if (!frame_authorized) {
printk(KERN_DEBUG "%s: dropped frame from "
"unauthorized port (IEEE 802.1X): "
- "ethertype=0x%04x\n",
- dev->name, ethertype);
+ "ethertype=0x%04x\n", dev->name, ethertype);
goto rx_dropped;
}
}
@@ -702,8 +688,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
#ifdef NOT_YET
if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS) &&
- skb->len >= ETH_HLEN + ETH_ALEN) {
+ IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
/* Non-standard frame: get addr4 from its bogus location after
* the payload */
memcpy(skb->data + ETH_ALEN,
@@ -716,8 +701,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
stats->rx_bytes += skb->len;
#ifdef NOT_YET
- if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
- ieee->ap->bridge_packets) {
+ if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
if (dst[0] & 0x01) {
/* copy multicast frame both to the higher layers and
* to the wireless media */
@@ -743,25 +727,24 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
skb2->dev = dev;
dev_queue_xmit(skb2);
}
-
#endif
if (skb) {
skb->protocol = eth_type_trans(skb, dev);
memset(skb->cb, 0, sizeof(skb->cb));
skb->dev = dev;
- skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
+ skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
netif_rx(skb);
}
- rx_exit:
+ rx_exit:
#ifdef NOT_YET
if (sta)
hostap_handle_sta_release(sta);
#endif
return 1;
- rx_dropped:
+ rx_dropped:
stats->rx_dropped++;
/* Returning 0 indicates to caller that we have not handled the SKB--
@@ -785,22 +768,21 @@ static inline int ieee80211_is_ofdm_rate(u8 rate)
case IEEE80211_OFDM_RATE_54MB:
return 1;
}
- return 0;
+ return 0;
}
-
-static inline int ieee80211_network_init(
- struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
+static inline int ieee80211_network_init(struct ieee80211_device *ieee,
+ struct ieee80211_probe_response
+ *beacon,
+ struct ieee80211_network *network,
+ struct ieee80211_rx_stats *stats)
{
#ifdef CONFIG_IEEE80211_DEBUG
char rates_str[64];
char *p;
#endif
struct ieee80211_info_element *info_element;
- u16 left;
+ u16 left;
u8 i;
/* Pull out fixed field data */
@@ -810,7 +792,7 @@ static inline int ieee80211_network_init(
network->time_stamp[0] = beacon->time_stamp[0];
network->time_stamp[1] = beacon->time_stamp[1];
network->beacon_interval = beacon->beacon_interval;
- /* Where to pull this? beacon->listen_interval;*/
+ /* Where to pull this? beacon->listen_interval; */
network->listen_interval = 0x0A;
network->rates_len = network->rates_ex_len = 0;
network->last_associate = 0;
@@ -824,18 +806,20 @@ static inline int ieee80211_network_init(
} else
network->flags |= NETWORK_HAS_CCK;
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
+ network->wpa_ie_len = 0;
+ network->rsn_ie_len = 0;
- info_element = &beacon->info_element;
+ info_element = &beacon->info_element;
left = stats->len - ((void *)info_element - (void *)beacon);
while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
- info_element->len + sizeof(struct ieee80211_info_element),
- left);
+ if (sizeof(struct ieee80211_info_element_hdr) +
+ info_element->len > left) {
+ IEEE80211_DEBUG_SCAN
+ ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
+ info_element->len +
+ sizeof(struct ieee80211_info_element), left);
return 1;
- }
+ }
switch (info_element->id) {
case MFIE_TYPE_SSID:
@@ -846,10 +830,11 @@ static inline int ieee80211_network_init(
}
network->ssid_len = min(info_element->len,
- (u8)IW_ESSID_MAX_SIZE);
- memcpy(network->ssid, info_element->data, network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
+ (u8) IW_ESSID_MAX_SIZE);
+ memcpy(network->ssid, info_element->data,
+ network->ssid_len);
+ if (network->ssid_len < IW_ESSID_MAX_SIZE)
+ memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
@@ -860,18 +845,23 @@ static inline int ieee80211_network_init(
#ifdef CONFIG_IEEE80211_DEBUG
p = rates_str;
#endif
- network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
+ network->rates_len =
+ min(info_element->len, MAX_RATES_LENGTH);
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
+ p += snprintf(p,
+ sizeof(rates_str) - (p -
+ rates_str),
+ "%02X ", network->rates[i]);
#endif
- if (ieee80211_is_ofdm_rate(info_element->data[i])) {
+ if (ieee80211_is_ofdm_rate
+ (info_element->data[i])) {
network->flags |= NETWORK_HAS_OFDM;
if (info_element->data[i] &
IEEE80211_BASIC_RATE_MASK)
network->flags &=
- ~NETWORK_HAS_CCK;
+ ~NETWORK_HAS_CCK;
}
}
@@ -883,18 +873,23 @@ static inline int ieee80211_network_init(
#ifdef CONFIG_IEEE80211_DEBUG
p = rates_str;
#endif
- network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
+ network->rates_ex_len =
+ min(info_element->len, MAX_RATES_EX_LENGTH);
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
+ p += snprintf(p,
+ sizeof(rates_str) - (p -
+ rates_str),
+ "%02X ", network->rates[i]);
#endif
- if (ieee80211_is_ofdm_rate(info_element->data[i])) {
+ if (ieee80211_is_ofdm_rate
+ (info_element->data[i])) {
network->flags |= NETWORK_HAS_OFDM;
if (info_element->data[i] &
IEEE80211_BASIC_RATE_MASK)
network->flags &=
- ~NETWORK_HAS_CCK;
+ ~NETWORK_HAS_CCK;
}
}
@@ -903,14 +898,14 @@ static inline int ieee80211_network_init(
break;
case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
+ IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
info_element->data[0]);
if (stats->freq == IEEE80211_24GHZ_BAND)
network->channel = info_element->data[0];
break;
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
+ case MFIE_TYPE_FH_SET:
+ IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
break;
case MFIE_TYPE_CF_SET:
@@ -932,13 +927,13 @@ static inline int ieee80211_network_init(
case MFIE_TYPE_GENERIC:
IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
info_element->len);
- if (info_element->len >= 4 &&
+ if (info_element->len >= 4 &&
info_element->data[0] == 0x00 &&
info_element->data[1] == 0x50 &&
info_element->data[2] == 0xf2 &&
info_element->data[3] == 0x01) {
network->wpa_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
+ MAX_WPA_IE_LEN);
memcpy(network->wpa_ie, info_element,
network->wpa_ie_len);
}
@@ -948,7 +943,7 @@ static inline int ieee80211_network_init(
IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
info_element->len);
network->rsn_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
+ MAX_WPA_IE_LEN);
memcpy(network->rsn_ie, info_element,
network->rsn_ie_len);
break;
@@ -956,14 +951,14 @@ static inline int ieee80211_network_init(
default:
IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
info_element->id);
- break;
- }
+ break;
+ }
left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
+ info_element->len;
info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
- }
+ &info_element->data[info_element->len];
+ }
network->mode = 0;
if (stats->freq == IEEE80211_52GHZ_BAND)
@@ -1032,10 +1027,13 @@ static inline void update_network(struct ieee80211_network *dst,
/* dst->last_associate is not overwritten */
}
-static inline void ieee80211_process_probe_response(
- struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_rx_stats *stats)
+static inline void ieee80211_process_probe_response(struct ieee80211_device
+ *ieee,
+ struct
+ ieee80211_probe_response
+ *beacon,
+ struct ieee80211_rx_stats
+ *stats)
{
struct ieee80211_network network;
struct ieee80211_network *target;
@@ -1045,33 +1043,35 @@ static inline void ieee80211_process_probe_response(
#endif
unsigned long flags;
- IEEE80211_DEBUG_SCAN(
- "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data, info_element->len),
- MAC_ARG(beacon->header.addr3),
- (beacon->capability & (1<<0xf)) ? '1' : '0',
- (beacon->capability & (1<<0xe)) ? '1' : '0',
- (beacon->capability & (1<<0xd)) ? '1' : '0',
- (beacon->capability & (1<<0xc)) ? '1' : '0',
- (beacon->capability & (1<<0xb)) ? '1' : '0',
- (beacon->capability & (1<<0xa)) ? '1' : '0',
- (beacon->capability & (1<<0x9)) ? '1' : '0',
- (beacon->capability & (1<<0x8)) ? '1' : '0',
- (beacon->capability & (1<<0x7)) ? '1' : '0',
- (beacon->capability & (1<<0x6)) ? '1' : '0',
- (beacon->capability & (1<<0x5)) ? '1' : '0',
- (beacon->capability & (1<<0x4)) ? '1' : '0',
- (beacon->capability & (1<<0x3)) ? '1' : '0',
- (beacon->capability & (1<<0x2)) ? '1' : '0',
- (beacon->capability & (1<<0x1)) ? '1' : '0',
- (beacon->capability & (1<<0x0)) ? '1' : '0');
+ IEEE80211_DEBUG_SCAN("'%s' (" MAC_FMT
+ "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ escape_essid(info_element->data,
+ info_element->len),
+ MAC_ARG(beacon->header.addr3),
+ (beacon->capability & (1 << 0xf)) ? '1' : '0',
+ (beacon->capability & (1 << 0xe)) ? '1' : '0',
+ (beacon->capability & (1 << 0xd)) ? '1' : '0',
+ (beacon->capability & (1 << 0xc)) ? '1' : '0',
+ (beacon->capability & (1 << 0xb)) ? '1' : '0',
+ (beacon->capability & (1 << 0xa)) ? '1' : '0',
+ (beacon->capability & (1 << 0x9)) ? '1' : '0',
+ (beacon->capability & (1 << 0x8)) ? '1' : '0',
+ (beacon->capability & (1 << 0x7)) ? '1' : '0',
+ (beacon->capability & (1 << 0x6)) ? '1' : '0',
+ (beacon->capability & (1 << 0x5)) ? '1' : '0',
+ (beacon->capability & (1 << 0x4)) ? '1' : '0',
+ (beacon->capability & (1 << 0x3)) ? '1' : '0',
+ (beacon->capability & (1 << 0x2)) ? '1' : '0',
+ (beacon->capability & (1 << 0x1)) ? '1' : '0',
+ (beacon->capability & (1 << 0x0)) ? '1' : '0');
if (ieee80211_network_init(ieee, beacon, &network, stats)) {
IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
escape_essid(info_element->data,
info_element->len),
MAC_ARG(beacon->header.addr3),
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+ WLAN_FC_GET_STYPE(beacon->header.
+ frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
return;
@@ -1117,13 +1117,13 @@ static inline void ieee80211_process_probe_response(
list_del(ieee->network_free_list.next);
}
-
#ifdef CONFIG_IEEE80211_DEBUG
IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
escape_essid(network.ssid,
network.ssid_len),
MAC_ARG(network.bssid),
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+ WLAN_FC_GET_STYPE(beacon->header.
+ frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
#endif
@@ -1134,7 +1134,8 @@ static inline void ieee80211_process_probe_response(
escape_essid(target->ssid,
target->ssid_len),
MAC_ARG(target->bssid),
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+ WLAN_FC_GET_STYPE(beacon->header.
+ frame_ctl) ==
IEEE80211_STYPE_PROBE_RESP ?
"PROBE RESPONSE" : "BEACON");
update_network(target, &network);
@@ -1162,16 +1163,20 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
WLAN_FC_GET_STYPE(header->frame_ctl));
IEEE80211_DEBUG_SCAN("Probe response\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
+ ieee80211_process_probe_response(ieee,
+ (struct
+ ieee80211_probe_response *)
+ header, stats);
break;
case IEEE80211_STYPE_BEACON:
IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
WLAN_FC_GET_STYPE(header->frame_ctl));
IEEE80211_DEBUG_SCAN("Beacon\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
+ ieee80211_process_probe_response(ieee,
+ (struct
+ ieee80211_probe_response *)
+ header, stats);
break;
default:
@@ -1184,6 +1189,5 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
}
}
-
EXPORT_SYMBOL(ieee80211_rx_mgt);
EXPORT_SYMBOL(ieee80211_rx);
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index b7ea3e2..c9aaff3 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -45,10 +45,8 @@
#include <net/ieee80211.h>
-
/*
-
802.11 Data Frame
,-------------------------------------------------------------------.
@@ -82,7 +80,6 @@ Desc. | IV | Encrypted | ICV |
`-----------------------'
Total: 8 non-data bytes
-
802.3 Ethernet Data Frame
,-----------------------------------------.
@@ -131,7 +128,7 @@ payload of each frame is reduced to 492 bytes.
static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
+static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
{
struct ieee80211_snap_hdr *snap;
u8 *oui;
@@ -149,17 +146,15 @@ static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
snap->oui[1] = oui[1];
snap->oui[2] = oui[2];
- *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
+ *(u16 *) (data + SNAP_SIZE) = htons(h_proto);
return SNAP_SIZE + sizeof(u16);
}
-static inline int ieee80211_encrypt_fragment(
- struct ieee80211_device *ieee,
- struct sk_buff *frag,
- int hdr_len)
+static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
+ struct sk_buff *frag, int hdr_len)
{
- struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
+ struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
int res;
#ifdef CONFIG_IEEE80211_CRYPT_TKIP
@@ -167,7 +162,7 @@ static inline int ieee80211_encrypt_fragment(
if (ieee->tkip_countermeasures &&
crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct ieee80211_hdr *) frag->data;
+ header = (struct ieee80211_hdr *)frag->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to " MAC_FMT "\n",
@@ -200,8 +195,8 @@ static inline int ieee80211_encrypt_fragment(
return 0;
}
-
-void ieee80211_txb_free(struct ieee80211_txb *txb) {
+void ieee80211_txb_free(struct ieee80211_txb *txb)
+{
int i;
if (unlikely(!txb))
return;
@@ -216,9 +211,8 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
{
struct ieee80211_txb *txb;
int i;
- txb = kmalloc(
- sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
- gfp_mask);
+ txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
+ gfp_mask);
if (!txb)
return NULL;
@@ -243,8 +237,7 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
}
/* SKBs are added to the ieee->tx_queue. */
-int ieee80211_xmit(struct sk_buff *skb,
- struct net_device *dev)
+int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ieee80211_device *ieee = netdev_priv(dev);
struct ieee80211_txb *txb = NULL;
@@ -255,21 +248,20 @@ int ieee80211_xmit(struct sk_buff *skb,
int ether_type, encrypt;
int bytes, fc, hdr_len;
struct sk_buff *skb_frag;
- struct ieee80211_hdr header = { /* Ensure zero initialized */
+ struct ieee80211_hdr header = { /* Ensure zero initialized */
.duration_id = 0,
.seq_ctl = 0
};
u8 dest[ETH_ALEN], src[ETH_ALEN];
- struct ieee80211_crypt_data* crypt;
+ struct ieee80211_crypt_data *crypt;
spin_lock_irqsave(&ieee->lock, flags);
/* If there is no driver handler to take the TXB, dont' bother
* creating it... */
if (!ieee->hard_start_xmit) {
- printk(KERN_WARNING "%s: No xmit handler.\n",
- ieee->dev->name);
+ printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
goto success;
}
@@ -284,7 +276,7 @@ int ieee80211_xmit(struct sk_buff *skb,
crypt = ieee->crypt[ieee->tx_keyidx];
encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- ieee->host_encrypt && crypt && crypt->ops;
+ ieee->host_encrypt && crypt && crypt->ops;
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -294,7 +286,7 @@ int ieee80211_xmit(struct sk_buff *skb,
/* Save source and destination addresses */
memcpy(&dest, skb->data, ETH_ALEN);
- memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
+ memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
/* Advance the SKB to the start of the payload */
skb_pull(skb, sizeof(struct ethhdr));
@@ -304,7 +296,7 @@ int ieee80211_xmit(struct sk_buff *skb,
if (encrypt)
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
- IEEE80211_FCTL_PROTECTED;
+ IEEE80211_FCTL_PROTECTED;
else
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
@@ -327,8 +319,7 @@ int ieee80211_xmit(struct sk_buff *skb,
/* Determine fragmentation size based on destination (multicast
* and broadcast are not fragmented) */
- if (is_multicast_ether_addr(dest) ||
- is_broadcast_ether_addr(dest))
+ if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
frag_size = MAX_FRAG_THRESHOLD;
else
frag_size = ieee->fts;
@@ -345,7 +336,7 @@ int ieee80211_xmit(struct sk_buff *skb,
/* Each fragment may need to have room for encryptiong pre/postfix */
if (encrypt)
bytes_per_frag -= crypt->ops->extra_prefix_len +
- crypt->ops->extra_postfix_len;
+ crypt->ops->extra_postfix_len;
/* Number of fragments is the total bytes_per_frag /
* payload_per_fragment */
@@ -380,19 +371,19 @@ int ieee80211_xmit(struct sk_buff *skb,
/* If this is not the last fragment, then add the MOREFRAGS
* bit to the frame control */
if (i != nr_frags - 1) {
- frag_hdr->frame_ctl = cpu_to_le16(
- fc | IEEE80211_FCTL_MOREFRAGS);
+ frag_hdr->frame_ctl =
+ cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
bytes = bytes_per_frag;
} else {
/* The last fragment takes the remaining length */
bytes = bytes_last_frag;
}
- /* Put a SNAP header on the first fragment */
+ /* Put a SNAP header on the first fragment */
if (i == 0) {
- ieee80211_put_snap(
- skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
+ ieee80211_put_snap(skb_put
+ (skb_frag, SNAP_SIZE + sizeof(u16)),
+ ether_type);
bytes -= SNAP_SIZE + sizeof(u16);
}
@@ -410,14 +401,13 @@ int ieee80211_xmit(struct sk_buff *skb,
skb_put(skb_frag, 4);
}
-
- success:
+ success:
spin_unlock_irqrestore(&ieee->lock, flags);
dev_kfree_skb_any(skb);
if (txb) {
- if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
+ if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
stats->tx_packets++;
stats->tx_bytes += txb->payload_size;
return 0;
@@ -427,7 +417,7 @@ int ieee80211_xmit(struct sk_buff *skb,
return 0;
- failed:
+ failed:
spin_unlock_irqrestore(&ieee->lock, flags);
netif_stop_queue(dev);
stats->tx_errors++;
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 2cd571c..94882f3 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -29,19 +29,20 @@
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
******************************************************************************/
-#include <linux/wireless.h>
-#include <linux/version.h>
+
#include <linux/kmod.h>
#include <linux/module.h>
#include <net/ieee80211.h>
+#include <linux/wireless.h>
+
static const char *ieee80211_modes[] = {
"?", "a", "b", "ab", "g", "ag", "bg", "abg"
};
#define MAX_CUSTOM_LEN 64
static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
+ char *start, char *stop,
struct ieee80211_network *network)
{
char custom[MAX_CUSTOM_LEN];
@@ -65,29 +66,28 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
iwe.u.data.length = sizeof("<hidden>");
start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
} else {
- iwe.u.data.length = min(network->ssid_len, (u8)32);
+ iwe.u.data.length = min(network->ssid_len, (u8) 32);
start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
}
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
+ snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
+ ieee80211_modes[network->mode]);
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- if (network->capability &
- (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+ /* Add mode */
+ iwe.cmd = SIOCGIWMODE;
+ if (network->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
if (network->capability & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- start = iwe_stream_add_event(start, stop, &iwe,
- IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
}
- /* Add frequency/channel */
+ /* Add frequency/channel */
iwe.cmd = SIOCGIWFREQ;
/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
iwe.u.freq.e = 3; */
@@ -109,7 +109,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
max_rate = 0;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- for (i = 0, j = 0; i < network->rates_len; ) {
+ for (i = 0, j = 0; i < network->rates_len;) {
if (j < network->rates_ex_len &&
((network->rates_ex[j] & 0x7F) <
(network->rates[i] & 0x7F)))
@@ -132,8 +132,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
iwe.u.bitrate.value = max_rate * 500000;
- start = iwe_stream_add_event(start, stop, &iwe,
- IW_EV_PARAM_LEN);
+ start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
iwe.cmd = IWEVCUSTOM;
iwe.u.data.length = p - custom;
@@ -163,7 +162,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom);
- if (ieee->wpa_enabled && network->wpa_ie_len){
+ if (ieee->wpa_enabled && network->wpa_ie_len) {
char buf[MAX_WPA_IE_LEN * 2 + 30];
u8 *p = buf;
@@ -178,7 +177,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
start = iwe_stream_add_point(start, stop, &iwe, buf);
}
- if (ieee->wpa_enabled && network->rsn_ie_len){
+ if (ieee->wpa_enabled && network->rsn_ie_len) {
char buf[MAX_WPA_IE_LEN * 2 + 30];
u8 *p = buf;
@@ -198,12 +197,12 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = IWEVCUSTOM;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
+ " Last beacon: %lums ago",
+ (jiffies - network->last_scanned) / (HZ / 100));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(start, stop, &iwe, custom);
-
return start;
}
@@ -228,18 +227,19 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
time_after(network->last_scanned + ieee->scan_age, jiffies))
ev = ipw2100_translate_scan(ieee, ev, stop, network);
else
- IEEE80211_DEBUG_SCAN(
- "Not showing network '%s ("
- MAC_FMT ")' due to age (%lums).\n",
- escape_essid(network->ssid,
- network->ssid_len),
- MAC_ARG(network->bssid),
- (jiffies - network->last_scanned) / (HZ / 100));
+ IEEE80211_DEBUG_SCAN("Not showing network '%s ("
+ MAC_FMT ")' due to age (%lums).\n",
+ escape_essid(network->ssid,
+ network->ssid_len),
+ MAC_ARG(network->bssid),
+ (jiffies -
+ network->last_scanned) / (HZ /
+ 100));
}
spin_unlock_irqrestore(&ieee->lock, flags);
- wrqu->data.length = ev - extra;
+ wrqu->data.length = ev - extra;
wrqu->data.flags = 0;
IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
@@ -291,8 +291,8 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
if (ieee->crypt[i] != NULL) {
if (key_provided)
break;
- ieee80211_crypt_delayed_deinit(
- ieee, &ieee->crypt[i]);
+ ieee80211_crypt_delayed_deinit(ieee,
+ &ieee->crypt[i]);
}
}
@@ -305,8 +305,6 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
goto done;
}
-
-
sec.enabled = 1;
sec.flags |= SEC_ENABLED;
@@ -340,8 +338,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
new_crypt = NULL;
printk(KERN_WARNING "%s: could not initialize WEP: "
- "load module ieee80211_crypt_wep\n",
- dev->name);
+ "load module ieee80211_crypt_wep\n", dev->name);
return -EOPNOTSUPP;
}
*crypt = new_crypt;
@@ -358,7 +355,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
key, escape_essid(sec.keys[key], len),
erq->length, len);
sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
+ (*crypt)->ops->set_key(sec.keys[key], len, NULL,
(*crypt)->priv);
sec.flags |= (1 << key);
/* This ensures a key will be activated if no key is
@@ -381,15 +378,15 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
/* No key data - just set the default TX key index */
if (key_provided) {
- IEEE80211_DEBUG_WX(
- "Setting key %d to default Tx key.\n", key);
+ IEEE80211_DEBUG_WX
+ ("Setting key %d to default Tx key.\n", key);
ieee->tx_keyidx = key;
sec.active_key = key;
sec.flags |= SEC_ACTIVE_KEY;
}
}
- done:
+ done:
ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
sec.flags |= SEC_AUTH_MODE;
@@ -399,7 +396,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
/* For now we just support WEP, so only set that security level...
* TODO: When WPA is added this is one place that needs to change */
sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
+ sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
if (ieee->set_security)
ieee->set_security(dev, &sec);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index bf147f8..a9d84f9 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1248,11 +1248,6 @@ module_init(inet_init);
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
-#ifdef CONFIG_IP_FIB_TRIE
-extern int fib_stat_proc_init(void);
-extern void fib_stat_proc_exit(void);
-#endif
-
static int __init ipv4_proc_init(void)
{
int rc = 0;
@@ -1265,19 +1260,11 @@ static int __init ipv4_proc_init(void)
goto out_udp;
if (fib_proc_init())
goto out_fib;
-#ifdef CONFIG_IP_FIB_TRIE
- if (fib_stat_proc_init())
- goto out_fib_stat;
-#endif
if (ip_misc_proc_init())
goto out_misc;
out:
return rc;
out_misc:
-#ifdef CONFIG_IP_FIB_TRIE
- fib_stat_proc_exit();
-out_fib_stat:
-#endif
fib_proc_exit();
out_fib:
udp4_proc_exit();
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 514c85b..035ad2c 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -263,10 +263,8 @@ static int ah_init_state(struct xfrm_state *x)
error:
if (ahp) {
- if (ahp->work_icv)
- kfree(ahp->work_icv);
- if (ahp->tfm)
- crypto_free_tfm(ahp->tfm);
+ kfree(ahp->work_icv);
+ crypto_free_tfm(ahp->tfm);
kfree(ahp);
}
return -EINVAL;
@@ -279,14 +277,10 @@ static void ah_destroy(struct xfrm_state *x)
if (!ahp)
return;
- if (ahp->work_icv) {
- kfree(ahp->work_icv);
- ahp->work_icv = NULL;
- }
- if (ahp->tfm) {
- crypto_free_tfm(ahp->tfm);
- ahp->tfm = NULL;
- }
+ kfree(ahp->work_icv);
+ ahp->work_icv = NULL;
+ crypto_free_tfm(ahp->tfm);
+ ahp->tfm = NULL;
kfree(ahp);
}
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index b31ffc5..1b5a09d 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -343,22 +343,14 @@ static void esp_destroy(struct xfrm_state *x)
if (!esp)
return;
- if (esp->conf.tfm) {
- crypto_free_tfm(esp->conf.tfm);
- esp->conf.tfm = NULL;
- }
- if (esp->conf.ivec) {
- kfree(esp->conf.ivec);
- esp->conf.ivec = NULL;
- }
- if (esp->auth.tfm) {
- crypto_free_tfm(esp->auth.tfm);
- esp->auth.tfm = NULL;
- }
- if (esp->auth.work_icv) {
- kfree(esp->auth.work_icv);
- esp->auth.work_icv = NULL;
- }
+ crypto_free_tfm(esp->conf.tfm);
+ esp->conf.tfm = NULL;
+ kfree(esp->conf.ivec);
+ esp->conf.ivec = NULL;
+ crypto_free_tfm(esp->auth.tfm);
+ esp->auth.tfm = NULL;
+ kfree(esp->auth.work_icv);
+ esp->auth.work_icv = NULL;
kfree(esp);
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index b2dea4e..1b63b48 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -43,7 +43,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#define VERSION "0.402"
+#define VERSION "0.403"
#include <linux/config.h>
#include <asm/uaccess.h>
@@ -164,7 +164,6 @@ static struct node *resize(struct trie *t, struct tnode *tn);
static struct tnode *inflate(struct trie *t, struct tnode *tn);
static struct tnode *halve(struct trie *t, struct tnode *tn);
static void tnode_free(struct tnode *tn);
-static void trie_dump_seq(struct seq_file *seq, struct trie *t);
static kmem_cache_t *fn_alias_kmem __read_mostly;
static struct trie *trie_local = NULL, *trie_main = NULL;
@@ -1971,558 +1970,525 @@ struct fib_table * __init fib_hash_init(int id)
return tb;
}
-/* Trie dump functions */
+#ifdef CONFIG_PROC_FS
+/* Depth first Trie walk iterator */
+struct fib_trie_iter {
+ struct tnode *tnode;
+ struct trie *trie;
+ unsigned index;
+ unsigned depth;
+};
-static void putspace_seq(struct seq_file *seq, int n)
+static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
{
- while (n--)
- seq_printf(seq, " ");
-}
+ struct tnode *tn = iter->tnode;
+ unsigned cindex = iter->index;
+ struct tnode *p;
-static void printbin_seq(struct seq_file *seq, unsigned int v, int bits)
-{
- while (bits--)
- seq_printf(seq, "%s", (v & (1<<bits))?"1":"0");
-}
+ pr_debug("get_next iter={node=%p index=%d depth=%d}\n",
+ iter->tnode, iter->index, iter->depth);
+rescan:
+ while (cindex < (1<<tn->bits)) {
+ struct node *n = tnode_get_child(tn, cindex);
-static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
- int pend, int cindex, int bits)
-{
- putspace_seq(seq, indent);
- if (IS_LEAF(n))
- seq_printf(seq, "|");
- else
- seq_printf(seq, "+");
- if (bits) {
- seq_printf(seq, "%d/", cindex);
- printbin_seq(seq, cindex, bits);
- seq_printf(seq, ": ");
- } else
- seq_printf(seq, "<root>: ");
- seq_printf(seq, "%s:%p ", IS_LEAF(n)?"Leaf":"Internal node", n);
+ if (n) {
+ if (IS_LEAF(n)) {
+ iter->tnode = tn;
+ iter->index = cindex + 1;
+ } else {
+ /* push down one level */
+ iter->tnode = (struct tnode *) n;
+ iter->index = 0;
+ ++iter->depth;
+ }
+ return n;
+ }
- if (IS_LEAF(n)) {
- struct leaf *l = (struct leaf *)n;
- struct fib_alias *fa;
- int i;
+ ++cindex;
+ }
- seq_printf(seq, "key=%d.%d.%d.%d\n",
- n->key >> 24, (n->key >> 16) % 256, (n->key >> 8) % 256, n->key % 256);
-
- for (i = 32; i >= 0; i--)
- if (find_leaf_info(&l->list, i)) {
- struct list_head *fa_head = get_fa_head(l, i);
-
- if (!fa_head)
- continue;
-
- if (list_empty(fa_head))
- continue;
-
- putspace_seq(seq, indent+2);
- seq_printf(seq, "{/%d...dumping}\n", i);
-
- list_for_each_entry_rcu(fa, fa_head, fa_list) {
- putspace_seq(seq, indent+2);
- if (fa->fa_info == NULL) {
- seq_printf(seq, "Error fa_info=NULL\n");
- continue;
- }
- if (fa->fa_info->fib_nh == NULL) {
- seq_printf(seq, "Error _fib_nh=NULL\n");
- continue;
- }
-
- seq_printf(seq, "{type=%d scope=%d TOS=%d}\n",
- fa->fa_type,
- fa->fa_scope,
- fa->fa_tos);
- }
- }
- } else {
- struct tnode *tn = (struct tnode *)n;
- int plen = ((struct tnode *)n)->pos;
- t_key prf = MASK_PFX(n->key, plen);
-
- seq_printf(seq, "key=%d.%d.%d.%d/%d\n",
- prf >> 24, (prf >> 16) % 256, (prf >> 8) % 256, prf % 256, plen);
-
- putspace_seq(seq, indent); seq_printf(seq, "| ");
- seq_printf(seq, "{key prefix=%08x/", tn->key & TKEY_GET_MASK(0, tn->pos));
- printbin_seq(seq, tkey_extract_bits(tn->key, 0, tn->pos), tn->pos);
- seq_printf(seq, "}\n");
- putspace_seq(seq, indent); seq_printf(seq, "| ");
- seq_printf(seq, "{pos=%d", tn->pos);
- seq_printf(seq, " (skip=%d bits)", tn->pos - pend);
- seq_printf(seq, " bits=%d (%u children)}\n", tn->bits, (1 << tn->bits));
- putspace_seq(seq, indent); seq_printf(seq, "| ");
- seq_printf(seq, "{empty=%d full=%d}\n", tn->empty_children, tn->full_children);
+ /* Current node exhausted, pop back up */
+ p = NODE_PARENT(tn);
+ if (p) {
+ cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
+ tn = p;
+ --iter->depth;
+ goto rescan;
}
+
+ /* got root? */
+ return NULL;
}
-static void trie_dump_seq(struct seq_file *seq, struct trie *t)
+static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
+ struct trie *t)
{
- struct node *n;
- int cindex = 0;
- int indent = 1;
- int pend = 0;
- int depth = 0;
- struct tnode *tn;
-
- rcu_read_lock();
- n = rcu_dereference(t->trie);
- seq_printf(seq, "------ trie_dump of t=%p ------\n", t);
+ struct node *n = rcu_dereference(t->trie);
- if (!n) {
- seq_printf(seq, "------ trie is empty\n");
-
- rcu_read_unlock();
- return;
+ if (n && IS_TNODE(n)) {
+ iter->tnode = (struct tnode *) n;
+ iter->trie = t;
+ iter->index = 0;
+ iter->depth = 0;
+ return n;
}
+ return NULL;
+}
- printnode_seq(seq, indent, n, pend, cindex, 0);
-
- if (!IS_TNODE(n)) {
- rcu_read_unlock();
- return;
- }
-
- tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
- putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
- indent += 3;
- depth++;
-
- while (tn && cindex < (1 << tn->bits)) {
- struct node *child = rcu_dereference(tn->child[cindex]);
- if (!child)
- cindex++;
- else {
- /* Got a child */
- printnode_seq(seq, indent, child, pend,
- cindex, tn->bits);
-
- if (IS_LEAF(child))
- cindex++;
-
- else {
- /*
- * New tnode. Decend one level
- */
-
- depth++;
- n = child;
- tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
- putspace_seq(seq, indent);
- seq_printf(seq, "\\--\n");
- indent += 3;
- cindex = 0;
- }
- }
-
- /*
- * Test if we are done
- */
-
- while (cindex >= (1 << tn->bits)) {
- /*
- * Move upwards and test for root
- * pop off all traversed nodes
- */
+static void trie_collect_stats(struct trie *t, struct trie_stat *s)
+{
+ struct node *n;
+ struct fib_trie_iter iter;
- if (NODE_PARENT(tn) == NULL) {
- tn = NULL;
- break;
- }
+ memset(s, 0, sizeof(*s));
- cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
- cindex++;
- tn = NODE_PARENT(tn);
- pend = tn->pos + tn->bits;
- indent -= 3;
- depth--;
+ rcu_read_lock();
+ for (n = fib_trie_get_first(&iter, t); n;
+ n = fib_trie_get_next(&iter)) {
+ if (IS_LEAF(n)) {
+ s->leaves++;
+ s->totdepth += iter.depth;
+ if (iter.depth > s->maxdepth)
+ s->maxdepth = iter.depth;
+ } else {
+ const struct tnode *tn = (const struct tnode *) n;
+ int i;
+
+ s->tnodes++;
+ s->nodesizes[tn->bits]++;
+ for (i = 0; i < (1<<tn->bits); i++)
+ if (!tn->child[i])
+ s->nullpointers++;
}
}
rcu_read_unlock();
}
-static struct trie_stat *trie_stat_new(void)
+/*
+ * This outputs /proc/net/fib_triestats
+ */
+static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
{
- struct trie_stat *s;
- int i;
+ unsigned i, max, pointers, bytes, avdepth;
- s = kmalloc(sizeof(struct trie_stat), GFP_KERNEL);
- if (!s)
- return NULL;
+ if (stat->leaves)
+ avdepth = stat->totdepth*100 / stat->leaves;
+ else
+ avdepth = 0;
- s->totdepth = 0;
- s->maxdepth = 0;
- s->tnodes = 0;
- s->leaves = 0;
- s->nullpointers = 0;
+ seq_printf(seq, "\tAver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
+ seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth);
- for (i = 0; i < MAX_CHILDS; i++)
- s->nodesizes[i] = 0;
+ seq_printf(seq, "\tLeaves: %u\n", stat->leaves);
- return s;
-}
+ bytes = sizeof(struct leaf) * stat->leaves;
+ seq_printf(seq, "\tInternal nodes: %d\n\t", stat->tnodes);
+ bytes += sizeof(struct tnode) * stat->tnodes;
-static struct trie_stat *trie_collect_stats(struct trie *t)
-{
- struct node *n;
- struct trie_stat *s = trie_stat_new();
- int cindex = 0;
- int pend = 0;
- int depth = 0;
+ max = MAX_CHILDS-1;
+ while (max >= 0 && stat->nodesizes[max] == 0)
+ max--;
- if (!s)
- return NULL;
+ pointers = 0;
+ for (i = 1; i <= max; i++)
+ if (stat->nodesizes[i] != 0) {
+ seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
+ pointers += (1<<i) * stat->nodesizes[i];
+ }
+ seq_putc(seq, '\n');
+ seq_printf(seq, "\tPointers: %d\n", pointers);
- rcu_read_lock();
- n = rcu_dereference(t->trie);
+ bytes += sizeof(struct node *) * pointers;
+ seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
+ seq_printf(seq, "Total size: %d kB\n", (bytes + 1023) / 1024);
- if (!n)
- return s;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+ seq_printf(seq, "Counters:\n---------\n");
+ seq_printf(seq,"gets = %d\n", t->stats.gets);
+ seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
+ seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
+ seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
+ seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
+ seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
+#ifdef CLEAR_STATS
+ memset(&(t->stats), 0, sizeof(t->stats));
+#endif
+#endif /* CONFIG_IP_FIB_TRIE_STATS */
+}
- if (IS_TNODE(n)) {
- struct tnode *tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
- s->nodesizes[tn->bits]++;
- depth++;
-
- while (tn && cindex < (1 << tn->bits)) {
- struct node *ch = rcu_dereference(tn->child[cindex]);
- if (ch) {
-
- /* Got a child */
-
- if (IS_LEAF(tn->child[cindex])) {
- cindex++;
-
- /* stats */
- if (depth > s->maxdepth)
- s->maxdepth = depth;
- s->totdepth += depth;
- s->leaves++;
- } else {
- /*
- * New tnode. Decend one level
- */
-
- s->tnodes++;
- s->nodesizes[tn->bits]++;
- depth++;
-
- n = ch;
- tn = (struct tnode *)n;
- pend = tn->pos+tn->bits;
-
- cindex = 0;
- }
- } else {
- cindex++;
- s->nullpointers++;
- }
+static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+{
+ struct trie_stat *stat;
- /*
- * Test if we are done
- */
+ stat = kmalloc(sizeof(*stat), GFP_KERNEL);
+ if (!stat)
+ return -ENOMEM;
- while (cindex >= (1 << tn->bits)) {
- /*
- * Move upwards and test for root
- * pop off all traversed nodes
- */
+ seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+ sizeof(struct leaf), sizeof(struct tnode));
- if (NODE_PARENT(tn) == NULL) {
- tn = NULL;
- n = NULL;
- break;
- }
+ if (trie_local) {
+ seq_printf(seq, "Local:\n");
+ trie_collect_stats(trie_local, stat);
+ trie_show_stats(seq, stat);
+ }
- cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
- tn = NODE_PARENT(tn);
- cindex++;
- n = (struct node *)tn;
- pend = tn->pos+tn->bits;
- depth--;
- }
- }
+ if (trie_main) {
+ seq_printf(seq, "Main:\n");
+ trie_collect_stats(trie_main, stat);
+ trie_show_stats(seq, stat);
}
+ kfree(stat);
- rcu_read_unlock();
- return s;
+ return 0;
}
-#ifdef CONFIG_PROC_FS
-
-static struct fib_alias *fib_triestat_get_first(struct seq_file *seq)
+static int fib_triestat_seq_open(struct inode *inode, struct file *file)
{
- return NULL;
+ return single_open(file, fib_triestat_seq_show, NULL);
}
-static struct fib_alias *fib_triestat_get_next(struct seq_file *seq)
+static struct file_operations fib_triestat_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_triestat_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
+ loff_t pos)
{
+ loff_t idx = 0;
+ struct node *n;
+
+ for (n = fib_trie_get_first(iter, trie_local);
+ n; ++idx, n = fib_trie_get_next(iter)) {
+ if (pos == idx)
+ return n;
+ }
+
+ for (n = fib_trie_get_first(iter, trie_main);
+ n; ++idx, n = fib_trie_get_next(iter)) {
+ if (pos == idx)
+ return n;
+ }
return NULL;
}
-static void *fib_triestat_seq_start(struct seq_file *seq, loff_t *pos)
+static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
{
- if (!ip_fib_main_table)
- return NULL;
-
- if (*pos)
- return fib_triestat_get_next(seq);
- else
+ rcu_read_lock();
+ if (*pos == 0)
return SEQ_START_TOKEN;
+ return fib_trie_get_idx(seq->private, *pos - 1);
}
-static void *fib_triestat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
+ struct fib_trie_iter *iter = seq->private;
+ void *l = v;
+
++*pos;
if (v == SEQ_START_TOKEN)
- return fib_triestat_get_first(seq);
- else
- return fib_triestat_get_next(seq);
-}
+ return fib_trie_get_idx(iter, 0);
-static void fib_triestat_seq_stop(struct seq_file *seq, void *v)
-{
+ v = fib_trie_get_next(iter);
+ BUG_ON(v == l);
+ if (v)
+ return v;
-}
+ /* continue scan in next trie */
+ if (iter->trie == trie_local)
+ return fib_trie_get_first(iter, trie_main);
-/*
- * This outputs /proc/net/fib_triestats
- *
- * It always works in backward compatibility mode.
- * The format of the file is not supposed to be changed.
- */
+ return NULL;
+}
-static void collect_and_show(struct trie *t, struct seq_file *seq)
+static void fib_trie_seq_stop(struct seq_file *seq, void *v)
{
- int bytes = 0; /* How many bytes are used, a ref is 4 bytes */
- int i, max, pointers;
- struct trie_stat *stat;
- int avdepth;
-
- stat = trie_collect_stats(t);
-
- bytes = 0;
- seq_printf(seq, "trie=%p\n", t);
-
- if (stat) {
- if (stat->leaves)
- avdepth = stat->totdepth*100 / stat->leaves;
- else
- avdepth = 0;
- seq_printf(seq, "Aver depth: %d.%02d\n", avdepth / 100, avdepth % 100);
- seq_printf(seq, "Max depth: %4d\n", stat->maxdepth);
+ rcu_read_unlock();
+}
- seq_printf(seq, "Leaves: %d\n", stat->leaves);
- bytes += sizeof(struct leaf) * stat->leaves;
- seq_printf(seq, "Internal nodes: %d\n", stat->tnodes);
- bytes += sizeof(struct tnode) * stat->tnodes;
+static void seq_indent(struct seq_file *seq, int n)
+{
+ while (n-- > 0) seq_puts(seq, " ");
+}
- max = MAX_CHILDS-1;
+static inline const char *rtn_scope(enum rt_scope_t s)
+{
+ static char buf[32];
- while (max >= 0 && stat->nodesizes[max] == 0)
- max--;
- pointers = 0;
+ switch(s) {
+ case RT_SCOPE_UNIVERSE: return "universe";
+ case RT_SCOPE_SITE: return "site";
+ case RT_SCOPE_LINK: return "link";
+ case RT_SCOPE_HOST: return "host";
+ case RT_SCOPE_NOWHERE: return "nowhere";
+ default:
+ snprintf(buf, sizeof(buf), "scope=%d", s);
+ return buf;
+ }
+}
- for (i = 1; i <= max; i++)
- if (stat->nodesizes[i] != 0) {
- seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
- pointers += (1<<i) * stat->nodesizes[i];
- }
- seq_printf(seq, "\n");
- seq_printf(seq, "Pointers: %d\n", pointers);
- bytes += sizeof(struct node *) * pointers;
- seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
- seq_printf(seq, "Total size: %d kB\n", bytes / 1024);
+static const char *rtn_type_names[__RTN_MAX] = {
+ [RTN_UNSPEC] = "UNSPEC",
+ [RTN_UNICAST] = "UNICAST",
+ [RTN_LOCAL] = "LOCAL",
+ [RTN_BROADCAST] = "BROADCAST",
+ [RTN_ANYCAST] = "ANYCAST",
+ [RTN_MULTICAST] = "MULTICAST",
+ [RTN_BLACKHOLE] = "BLACKHOLE",
+ [RTN_UNREACHABLE] = "UNREACHABLE",
+ [RTN_PROHIBIT] = "PROHIBIT",
+ [RTN_THROW] = "THROW",
+ [RTN_NAT] = "NAT",
+ [RTN_XRESOLVE] = "XRESOLVE",
+};
- kfree(stat);
- }
+static inline const char *rtn_type(unsigned t)
+{
+ static char buf[32];
-#ifdef CONFIG_IP_FIB_TRIE_STATS
- seq_printf(seq, "Counters:\n---------\n");
- seq_printf(seq,"gets = %d\n", t->stats.gets);
- seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
- seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
- seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
- seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
- seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
-#ifdef CLEAR_STATS
- memset(&(t->stats), 0, sizeof(t->stats));
-#endif
-#endif /* CONFIG_IP_FIB_TRIE_STATS */
+ if (t < __RTN_MAX && rtn_type_names[t])
+ return rtn_type_names[t];
+ snprintf(buf, sizeof(buf), "type %d", t);
+ return buf;
}
-static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+/* Pretty print the trie */
+static int fib_trie_seq_show(struct seq_file *seq, void *v)
{
- char bf[128];
+ const struct fib_trie_iter *iter = seq->private;
+ struct node *n = v;
- if (v == SEQ_START_TOKEN) {
- seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
- sizeof(struct leaf), sizeof(struct tnode));
- if (trie_local)
- collect_and_show(trie_local, seq);
+ if (v == SEQ_START_TOKEN)
+ return 0;
- if (trie_main)
- collect_and_show(trie_main, seq);
- } else {
- snprintf(bf, sizeof(bf), "*\t%08X\t%08X", 200, 400);
+ if (IS_TNODE(n)) {
+ struct tnode *tn = (struct tnode *) n;
+ t_key prf = ntohl(MASK_PFX(tn->key, tn->pos));
- seq_printf(seq, "%-127s\n", bf);
+ if (!NODE_PARENT(n)) {
+ if (iter->trie == trie_local)
+ seq_puts(seq, "<local>:\n");
+ else
+ seq_puts(seq, "<main>:\n");
+ } else {
+ seq_indent(seq, iter->depth-1);
+ seq_printf(seq, " +-- %d.%d.%d.%d/%d\n",
+ NIPQUAD(prf), tn->pos);
+ }
+ } else {
+ struct leaf *l = (struct leaf *) n;
+ int i;
+ u32 val = ntohl(l->key);
+
+ seq_indent(seq, iter->depth);
+ seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val));
+ for (i = 32; i >= 0; i--) {
+ struct leaf_info *li = find_leaf_info(&l->list, i);
+ if (li) {
+ struct fib_alias *fa;
+ list_for_each_entry_rcu(fa, &li->falh, fa_list) {
+ seq_indent(seq, iter->depth+1);
+ seq_printf(seq, " /%d %s %s", i,
+ rtn_scope(fa->fa_scope),
+ rtn_type(fa->fa_type));
+ if (fa->fa_tos)
+ seq_printf(seq, "tos =%d\n",
+ fa->fa_tos);
+ seq_putc(seq, '\n');
+ }
+ }
+ }
}
+
return 0;
}
-static struct seq_operations fib_triestat_seq_ops = {
- .start = fib_triestat_seq_start,
- .next = fib_triestat_seq_next,
- .stop = fib_triestat_seq_stop,
- .show = fib_triestat_seq_show,
+static struct seq_operations fib_trie_seq_ops = {
+ .start = fib_trie_seq_start,
+ .next = fib_trie_seq_next,
+ .stop = fib_trie_seq_stop,
+ .show = fib_trie_seq_show,
};
-static int fib_triestat_seq_open(struct inode *inode, struct file *file)
+static int fib_trie_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
+ struct fib_trie_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
- rc = seq_open(file, &fib_triestat_seq_ops);
+ if (!s)
+ goto out;
+
+ rc = seq_open(file, &fib_trie_seq_ops);
if (rc)
goto out_kfree;
- seq = file->private_data;
+ 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 fib_triestat_seq_fops = {
- .owner = THIS_MODULE,
- .open = fib_triestat_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
+static struct file_operations fib_trie_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_trie_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
.release = seq_release_private,
};
-int __init fib_stat_proc_init(void)
-{
- if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops))
- return -ENOMEM;
- return 0;
-}
-
-void __init fib_stat_proc_exit(void)
+static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
{
- proc_net_remove("fib_triestat");
-}
+ static unsigned type2flags[RTN_MAX + 1] = {
+ [7] = RTF_REJECT, [8] = RTF_REJECT,
+ };
+ unsigned flags = type2flags[type];
-static struct fib_alias *fib_trie_get_first(struct seq_file *seq)
-{
- return NULL;
+ if (fi && fi->fib_nh->nh_gw)
+ flags |= RTF_GATEWAY;
+ if (mask == 0xFFFFFFFF)
+ flags |= RTF_HOST;
+ flags |= RTF_UP;
+ return flags;
}
-static struct fib_alias *fib_trie_get_next(struct seq_file *seq)
+/*
+ * This outputs /proc/net/route.
+ * The format of the file is not supposed to be changed
+ * and needs to be same as fib_hash output to avoid breaking
+ * legacy utilities
+ */
+static int fib_route_seq_show(struct seq_file *seq, void *v)
{
- return NULL;
-}
+ struct leaf *l = v;
+ int i;
+ char bf[128];
-static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
-{
- if (!ip_fib_main_table)
- return NULL;
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
+ "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
+ "\tWindow\tIRTT");
+ return 0;
+ }
- if (*pos)
- return fib_trie_get_next(seq);
- else
- return SEQ_START_TOKEN;
-}
+ if (IS_TNODE(l))
+ return 0;
-static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- ++*pos;
- if (v == SEQ_START_TOKEN)
- return fib_trie_get_first(seq);
- else
- return fib_trie_get_next(seq);
+ for (i=32; i>=0; i--) {
+ struct leaf_info *li = find_leaf_info(&l->list, i);
+ struct fib_alias *fa;
+ u32 mask, prefix;
-}
+ if (!li)
+ continue;
-static void fib_trie_seq_stop(struct seq_file *seq, void *v)
-{
-}
+ mask = inet_make_mask(li->plen);
+ prefix = htonl(l->key);
-/*
- * This outputs /proc/net/fib_trie.
- *
- * It always works in backward compatibility mode.
- * The format of the file is not supposed to be changed.
- */
+ list_for_each_entry_rcu(fa, &li->falh, fa_list) {
+ const struct fib_info *fi = rcu_dereference(fa->fa_info);
+ unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
-static int fib_trie_seq_show(struct seq_file *seq, void *v)
-{
- char bf[128];
+ if (fa->fa_type == RTN_BROADCAST
+ || fa->fa_type == RTN_MULTICAST)
+ continue;
- if (v == SEQ_START_TOKEN) {
- if (trie_local)
- trie_dump_seq(seq, trie_local);
+ if (fi)
+ snprintf(bf, sizeof(bf),
+ "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
+ fi->fib_dev ? fi->fib_dev->name : "*",
+ prefix,
+ fi->fib_nh->nh_gw, flags, 0, 0,
+ fi->fib_priority,
+ mask,
+ (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
+ fi->fib_window,
+ fi->fib_rtt >> 3);
+ else
+ snprintf(bf, sizeof(bf),
+ "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
+ prefix, 0, flags, 0, 0, 0,
+ mask, 0, 0, 0);
- if (trie_main)
- trie_dump_seq(seq, trie_main);
- } else {
- snprintf(bf, sizeof(bf),
- "*\t%08X\t%08X", 200, 400);
- seq_printf(seq, "%-127s\n", bf);
+ seq_printf(seq, "%-127s\n", bf);
+ }
}
return 0;
}
-static struct seq_operations fib_trie_seq_ops = {
- .start = fib_trie_seq_start,
- .next = fib_trie_seq_next,
- .stop = fib_trie_seq_stop,
- .show = fib_trie_seq_show,
+static struct seq_operations fib_route_seq_ops = {
+ .start = fib_trie_seq_start,
+ .next = fib_trie_seq_next,
+ .stop = fib_trie_seq_stop,
+ .show = fib_route_seq_show,
};
-static int fib_trie_seq_open(struct inode *inode, struct file *file)
+static int fib_route_seq_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int rc = -ENOMEM;
+ struct fib_trie_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);
- rc = seq_open(file, &fib_trie_seq_ops);
+ if (!s)
+ goto out;
+
+ rc = seq_open(file, &fib_route_seq_ops);
if (rc)
goto out_kfree;
- seq = file->private_data;
+ 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 fib_trie_seq_fops = {
- .owner = THIS_MODULE,
- .open = fib_trie_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release= seq_release_private,
+static struct file_operations fib_route_fops = {
+ .owner = THIS_MODULE,
+ .open = fib_route_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
};
int __init fib_proc_init(void)
{
- if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_seq_fops))
- return -ENOMEM;
+ if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_fops))
+ goto out1;
+
+ if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_fops))
+ goto out2;
+
+ if (!proc_net_fops_create("route", S_IRUGO, &fib_route_fops))
+ goto out3;
+
return 0;
+
+out3:
+ proc_net_remove("fib_triestat");
+out2:
+ proc_net_remove("fib_trie");
+out1:
+ return -ENOMEM;
}
void __init fib_proc_exit(void)
{
proc_net_remove("fib_trie");
+ proc_net_remove("fib_triestat");
+ proc_net_remove("route");
}
#endif /* CONFIG_PROC_FS */
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index f84ba9c..2fc3fd3 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -100,8 +100,7 @@ DEFINE_SPINLOCK(inet_peer_unused_lock);
#define PEER_MAX_CLEANUP_WORK 30
static void peer_check_expire(unsigned long dummy);
-static struct timer_list peer_periodic_timer =
- TIMER_INITIALIZER(peer_check_expire, 0, 0);
+static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
/* Exported for sysctl_net_ipv4. */
int inet_peer_gc_mintime = 10 * HZ,
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 9e6e683..e7d26d9 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -457,7 +457,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
if (pskb_pull(skb, ihl) == NULL)
goto err;
- if (pskb_trim(skb, end-offset))
+ if (pskb_trim_rcsum(skb, end-offset))
goto err;
/* Find out which fragments are in front and at the back of us
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index dcb7ee6..fc718df 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -345,8 +345,7 @@ static void ipcomp_free_tfms(struct crypto_tfm **tfms)
for_each_cpu(cpu) {
struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
- if (tfm)
- crypto_free_tfm(tfm);
+ crypto_free_tfm(tfm);
}
free_percpu(tfms);
}
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 63e1066..953129d 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -54,6 +54,7 @@
#include <linux/major.h>
#include <linux/root_dev.h>
#include <linux/delay.h>
+#include <linux/nfs_fs.h>
#include <net/arp.h>
#include <net/ip.h>
#include <net/ipconfig.h>
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index e046f55..30aa8e2 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -34,6 +34,7 @@ config IP_NF_CT_ACCT
config IP_NF_CONNTRACK_MARK
bool 'Connection mark tracking support'
+ depends on IP_NF_CONNTRACK
help
This option enables support for connection marks, used by the
`CONNMARK' target and `connmark' match. Similar to the mark value
@@ -85,6 +86,25 @@ config IP_NF_IRC
To compile it as a module, choose M here. If unsure, say Y.
+config IP_NF_NETBIOS_NS
+ tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
+ depends on IP_NF_CONNTRACK && EXPERIMENTAL
+ help
+ NetBIOS name service requests are sent as broadcast messages from an
+ unprivileged port and responded to with unicast messages to the
+ same port. This make them hard to firewall properly because connection
+ tracking doesn't deal with broadcasts. This helper tracks locally
+ originating NetBIOS name service requests and the corresponding
+ responses. It relies on correct IP address configuration, specifically
+ netmask and broadcast address. When properly configured, the output
+ of "ip address show" should look similar to this:
+
+ $ ip -4 address show eth0
+ 4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
+ inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config IP_NF_TFTP
tristate "TFTP protocol support"
depends on IP_NF_CONNTRACK
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index a7bd38f..1ba0db7 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
+obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
# NAT helpers
obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index be4c9eb..dc20881 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -108,6 +108,7 @@ static int help(struct sk_buff **pskb,
}
exp->expectfn = NULL;
+ exp->flags = 0;
exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
exp->tuple.src.u.tcp.port = 0;
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index a064860..19cba16 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -197,7 +197,7 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,
/* ip_conntrack_expect helper functions */
-static void unlink_expect(struct ip_conntrack_expect *exp)
+void ip_ct_unlink_expect(struct ip_conntrack_expect *exp)
{
ASSERT_WRITE_LOCK(&ip_conntrack_lock);
IP_NF_ASSERT(!timer_pending(&exp->timeout));
@@ -207,18 +207,12 @@ static void unlink_expect(struct ip_conntrack_expect *exp)
ip_conntrack_expect_put(exp);
}
-void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp)
-{
- unlink_expect(exp);
- ip_conntrack_expect_put(exp);
-}
-
static void expectation_timed_out(unsigned long ul_expect)
{
struct ip_conntrack_expect *exp = (void *)ul_expect;
write_lock_bh(&ip_conntrack_lock);
- unlink_expect(exp);
+ ip_ct_unlink_expect(exp);
write_unlock_bh(&ip_conntrack_lock);
ip_conntrack_expect_put(exp);
}
@@ -264,10 +258,14 @@ find_expectation(const struct ip_conntrack_tuple *tuple)
master ct never got confirmed, we'd hold a reference to it
and weird things would happen to future packets). */
if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
- && is_confirmed(i->master)
- && del_timer(&i->timeout)) {
- unlink_expect(i);
- return i;
+ && is_confirmed(i->master)) {
+ if (i->flags & IP_CT_EXPECT_PERMANENT) {
+ atomic_inc(&i->use);
+ return i;
+ } else if (del_timer(&i->timeout)) {
+ ip_ct_unlink_expect(i);
+ return i;
+ }
}
}
return NULL;
@@ -284,7 +282,7 @@ void ip_ct_remove_expectations(struct ip_conntrack *ct)
list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) {
if (i->master == ct && del_timer(&i->timeout)) {
- unlink_expect(i);
+ ip_ct_unlink_expect(i);
ip_conntrack_expect_put(i);
}
}
@@ -925,7 +923,7 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
/* choose the the oldest expectation to evict */
list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
if (expect_matches(i, exp) && del_timer(&i->timeout)) {
- unlink_expect(i);
+ ip_ct_unlink_expect(i);
write_unlock_bh(&ip_conntrack_lock);
ip_conntrack_expect_put(i);
return;
@@ -934,6 +932,9 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
write_unlock_bh(&ip_conntrack_lock);
}
+/* We don't increase the master conntrack refcount for non-fulfilled
+ * conntracks. During the conntrack destruction, the expectations are
+ * always killed before the conntrack itself */
struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
{
struct ip_conntrack_expect *new;
@@ -944,17 +945,14 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
return NULL;
}
new->master = me;
- atomic_inc(&new->master->ct_general.use);
atomic_set(&new->use, 1);
return new;
}
void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
{
- if (atomic_dec_and_test(&exp->use)) {
- ip_conntrack_put(exp->master);
+ if (atomic_dec_and_test(&exp->use))
kmem_cache_free(ip_conntrack_expect_cachep, exp);
- }
}
static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
@@ -982,7 +980,7 @@ static void evict_oldest_expect(struct ip_conntrack *master)
list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
if (i->master == master) {
if (del_timer(&i->timeout)) {
- unlink_expect(i);
+ ip_ct_unlink_expect(i);
ip_conntrack_expect_put(i);
}
break;
@@ -1099,7 +1097,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
/* Get rid of expectations */
list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) {
if (exp->master->helper == me && del_timer(&exp->timeout)) {
- unlink_expect(exp);
+ ip_ct_unlink_expect(exp);
ip_conntrack_expect_put(exp);
}
}
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 3a2627d..1b79ec3 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -421,6 +421,7 @@ static int help(struct sk_buff **pskb,
{ 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
exp->expectfn = NULL;
+ exp->flags = 0;
/* Now, NAT might want to mangle the packet, and register the
* (possibly changed) expectation itself. */
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index 25438ee..d7a8a98 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -221,6 +221,7 @@ static int help(struct sk_buff **pskb,
{ { 0, { 0 } },
{ 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
exp->expectfn = NULL;
+ exp->flags = 0;
if (ip_nat_irc_hook)
ret = ip_nat_irc_hook(pskb, ctinfo,
addr_beg_p - ib_ptr,
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
new file mode 100644
index 0000000..bb72466
--- /dev/null
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -0,0 +1,147 @@
+/*
+ * NetBIOS name service broadcast connection tracking helper
+ *
+ * (c) 2005 Patrick McHardy <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+/*
+ * This helper tracks locally originating NetBIOS name service
+ * requests by issuing permanent expectations (valid until
+ * timing out) matching all reply connections from the
+ * destination network. The only NetBIOS specific thing is
+ * actually the port number.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <net/route.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
+MODULE_LICENSE("GPL");
+
+static unsigned int timeout = 3;
+module_param(timeout, int, 0600);
+MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
+
+static int help(struct sk_buff **pskb,
+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+{
+ struct ip_conntrack_expect *exp;
+ struct iphdr *iph = (*pskb)->nh.iph;
+ struct udphdr _uh, *uh;
+ struct rtable *rt = (struct rtable *)(*pskb)->dst;
+ struct in_device *in_dev;
+ u_int32_t mask = 0;
+
+ /* we're only interested in locally generated packets */
+ if ((*pskb)->sk == NULL)
+ goto out;
+ if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
+ goto out;
+ if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
+ goto out;
+
+ rcu_read_lock();
+ in_dev = __in_dev_get(rt->u.dst.dev);
+ if (in_dev != NULL) {
+ for_primary_ifa(in_dev) {
+ if (ifa->ifa_broadcast == iph->daddr) {
+ mask = ifa->ifa_mask;
+ break;
+ }
+ } endfor_ifa(in_dev);
+ }
+ rcu_read_unlock();
+
+ if (mask == 0)
+ goto out;
+
+ uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh);
+ BUG_ON(uh == NULL);
+
+ exp = ip_conntrack_expect_alloc(ct);
+ if (exp == NULL)
+ goto out;
+ memset(&exp->tuple, 0, sizeof(exp->tuple));
+ exp->tuple.src.ip = iph->daddr & mask;
+ exp->tuple.dst.ip = iph->saddr;
+ exp->tuple.dst.u.udp.port = uh->source;
+ exp->tuple.dst.protonum = IPPROTO_UDP;
+
+ memset(&exp->mask, 0, sizeof(exp->mask));
+ exp->mask.src.ip = mask;
+ exp->mask.dst.ip = 0xFFFFFFFF;
+ exp->mask.dst.u.udp.port = 0xFFFF;
+ exp->mask.dst.protonum = 0xFF;
+
+ exp->expectfn = NULL;
+ exp->flags = IP_CT_EXPECT_PERMANENT;
+
+ ip_conntrack_expect_related(exp);
+ ip_conntrack_expect_put(exp);
+
+ ip_ct_refresh_acct(ct, ctinfo, NULL, timeout * HZ);
+out:
+ return NF_ACCEPT;
+}
+
+static struct ip_conntrack_helper helper = {
+ .name = "netbios-ns",
+ .tuple = {
+ .src = {
+ .u = {
+ .udp = {
+ .port = __constant_htons(137),
+ }
+ }
+ },
+ .dst = {
+ .protonum = IPPROTO_UDP,
+ },
+ },
+ .mask = {
+ .src = {
+ .u = {
+ .udp = {
+ .port = 0xFFFF,
+ }
+ }
+ },
+ .dst = {
+ .protonum = 0xFF,
+ },
+ },
+ .max_expected = 1,
+ .me = THIS_MODULE,
+ .help = help,
+};
+
+static int __init init(void)
+{
+ helper.timeout = timeout;
+ return ip_conntrack_helper_register(&helper);
+}
+
+static void __exit fini(void)
+{
+ ip_conntrack_helper_unregister(&helper);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index a4e9278..15aef35 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1349,8 +1349,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list,
list) {
if (exp->master->helper == h
- && del_timer(&exp->timeout))
- __ip_ct_expect_unlink_destroy(exp);
+ && del_timer(&exp->timeout)) {
+ ip_ct_unlink_expect(exp);
+ ip_conntrack_expect_put(exp);
+ }
}
write_unlock(&ip_conntrack_lock);
} else {
@@ -1358,8 +1360,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
write_lock_bh(&ip_conntrack_lock);
list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list,
list) {
- if (del_timer(&exp->timeout))
- __ip_ct_expect_unlink_destroy(exp);
+ if (del_timer(&exp->timeout)) {
+ ip_ct_unlink_expect(exp);
+ ip_conntrack_expect_put(exp);
+ }
}
write_unlock_bh(&ip_conntrack_lock);
}
@@ -1413,6 +1417,7 @@ ctnetlink_create_expect(struct nfattr *cda[])
}
exp->expectfn = NULL;
+ exp->flags = 0;
exp->master = ct;
memcpy(&exp->tuple, &tuple, sizeof(struct ip_conntrack_tuple));
memcpy(&exp->mask, &mask, sizeof(struct ip_conntrack_tuple));
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index f23ef1f..1985abc 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -349,6 +349,7 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
return 0;
nfattr_failure:
+ read_unlock_bh(&tcp_lock);
return -1;
}
#endif
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index ee5895a..ae3e3e6 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -998,7 +998,7 @@ EXPORT_SYMBOL(ip_conntrack_expect_related);
EXPORT_SYMBOL(ip_conntrack_unexpect_related);
EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
-EXPORT_SYMBOL_GPL(__ip_ct_expect_unlink_destroy);
+EXPORT_SYMBOL_GPL(ip_ct_unlink_expect);
EXPORT_SYMBOL(ip_conntrack_tuple_taken);
EXPORT_SYMBOL(ip_ct_gather_frags);
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index f8ff170..d2b5905 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -75,6 +75,7 @@ static int tftp_help(struct sk_buff **pskb,
exp->mask.dst.u.udp.port = 0xffff;
exp->mask.dst.protonum = 0xff;
exp->expectfn = NULL;
+ exp->flags = 0;
DEBUGP("expect: ");
DUMP_TUPLE(&exp->tuple);
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
index 60d70fa..cb66b8b 100644
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -255,6 +255,27 @@ alloc_null_binding(struct ip_conntrack *conntrack,
return ip_nat_setup_info(conntrack, &range, hooknum);
}
+unsigned int
+alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
+ struct ip_nat_info *info,
+ unsigned int hooknum)
+{
+ u_int32_t ip
+ = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
+ ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
+ : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
+ u_int16_t all
+ = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
+ ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
+ : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
+ struct ip_nat_range range
+ = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
+
+ DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
+ conntrack, NIPQUAD(ip));
+ return ip_nat_setup_info(conntrack, &range, hooknum);
+}
+
int ip_nat_rule_find(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 89db052..0ff368b 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -123,8 +123,12 @@ ip_nat_fn(unsigned int hooknum,
if (!ip_nat_initialized(ct, maniptype)) {
unsigned int ret;
- /* LOCAL_IN hook doesn't have a chain! */
- if (hooknum == NF_IP_LOCAL_IN)
+ if (unlikely(is_confirmed(ct)))
+ /* NAT module was loaded late */
+ ret = alloc_null_binding_confirmed(ct, info,
+ hooknum);
+ else if (hooknum == NF_IP_LOCAL_IN)
+ /* LOCAL_IN hook doesn't have a chain! */
ret = alloc_null_binding(ct, info, hooknum);
else
ret = ip_nat_rule_find(pskb, hooknum,
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 2d05caf..7d38913 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -144,7 +144,7 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip,
memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
c->num_total_nodes = i->num_total_nodes;
c->num_local_nodes = i->num_local_nodes;
- memcpy(&c->local_nodes, &i->local_nodes, sizeof(&c->local_nodes));
+ memcpy(&c->local_nodes, &i->local_nodes, sizeof(c->local_nodes));
c->hash_mode = i->hash_mode;
c->hash_initval = i->hash_initval;
atomic_set(&c->refcount, 1);
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f115a84..f057025 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -92,10 +92,7 @@ static inline struct rtable *route_reverse(struct sk_buff *skb,
fl.fl_ip_sport = tcph->dest;
fl.fl_ip_dport = tcph->source;
- if (xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0)) {
- dst_release(&rt->u.dst);
- rt = NULL;
- }
+ xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
return rt;
}
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index c1889f8..0cee286 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/file.h>
+#include <linux/rcupdate.h>
#include <net/sock.h>
#include <linux/netfilter_ipv4/ipt_owner.h>
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8c0b14e..8549f26 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1760,6 +1760,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
goto cleanup;
}
+ atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
if (res->fi->fib_nhs > 1)
@@ -1820,7 +1821,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
if (err)
return err;
- atomic_set(&rth->u.dst.__refcnt, 1);
/* put it into the cache */
hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
@@ -1834,8 +1834,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
u32 daddr, u32 saddr, u32 tos)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
- struct rtable* rth = NULL;
- unsigned char hop, hopcount, lasthop;
+ struct rtable* rth = NULL, *rtres;
+ unsigned char hop, hopcount;
int err = -EINVAL;
unsigned int hash;
@@ -1844,8 +1844,6 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
else
hopcount = 1;
- lasthop = hopcount - 1;
-
/* distinguish between multipath and singlepath */
if (hopcount < 2)
return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
@@ -1855,6 +1853,10 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
for (hop = 0; hop < hopcount; hop++) {
res->nh_sel = hop;
+ /* put reference to previous result */
+ if (hop)
+ ip_rt_put(rtres);
+
/* create a routing cache entry */
err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
&rth);
@@ -1863,7 +1865,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
/* put it into the cache */
hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
- err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
+ err = rt_intern_hash(hash, rth, &rtres);
if (err)
return err;
@@ -1873,13 +1875,8 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
FIB_RES_NETMASK(*res),
res->prefixlen,
&FIB_RES_NH(*res));
-
- /* only for the last hop the reference count is handled
- * outside
- */
- if (hop == lasthop)
- atomic_set(&(skb->dst->__refcnt), 1);
}
+ skb->dst = &rtres->u.dst;
return err;
#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
@@ -2208,6 +2205,7 @@ static inline int __mkroute_output(struct rtable **result,
goto cleanup;
}
+ atomic_set(&rth->u.dst.__refcnt, 1);
rth->u.dst.flags= DST_HOST;
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
if (res->fi) {
@@ -2290,8 +2288,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
if (err == 0) {
u32 tos = RT_FL_TOS(oldflp);
- atomic_set(&rth->u.dst.__refcnt, 1);
-
hash = rt_hash_code(oldflp->fl4_dst,
oldflp->fl4_src ^ (oldflp->oif << 5), tos);
err = rt_intern_hash(hash, rth, rp);
@@ -2326,6 +2322,10 @@ static inline int ip_mkroute_output(struct rtable** rp,
dev2nexthop = FIB_RES_DEV(*res);
dev_hold(dev2nexthop);
+ /* put reference to previous result */
+ if (hop)
+ ip_rt_put(*rp);
+
err = __mkroute_output(&rth, res, fl, oldflp,
dev2nexthop, flags);
@@ -2350,7 +2350,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
if (err != 0)
return err;
}
- atomic_set(&(*rp)->u.dst.__refcnt, 1);
return err;
} else {
return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 02fdda6..f3f0013 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -552,8 +552,7 @@ new_segment:
tcp_mark_push(tp, skb);
goto new_segment;
}
- if (sk->sk_forward_alloc < copy &&
- !sk_stream_mem_schedule(sk, copy, 0))
+ if (!sk_stream_wmem_schedule(sk, copy))
goto wait_for_memory;
if (can_coalesce) {
@@ -770,19 +769,23 @@ new_segment:
if (off == PAGE_SIZE) {
put_page(page);
TCP_PAGE(sk) = page = NULL;
+ off = 0;
}
- }
+ } else
+ off = 0;
+
+ if (copy > PAGE_SIZE - off)
+ copy = PAGE_SIZE - off;
+
+ if (!sk_stream_wmem_schedule(sk, copy))
+ goto wait_for_memory;
if (!page) {
/* Allocate new cache page. */
if (!(page = sk_stream_alloc_page(sk)))
goto wait_for_memory;
- off = 0;
}
- if (copy > PAGE_SIZE - off)
- copy = PAGE_SIZE - off;
-
/* Time to copy data. We are close to
* the end! */
err = skb_copy_to_page(sk, from, skb, page,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 1afb080..29222b96 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -923,14 +923,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int flag = 0;
int i;
- /* So, SACKs for already sent large segments will be lost.
- * Not good, but alternative is to resegment the queue. */
- if (sk->sk_route_caps & NETIF_F_TSO) {
- sk->sk_route_caps &= ~NETIF_F_TSO;
- sock_set_flag(sk, SOCK_NO_LARGESEND);
- tp->mss_cache = tp->mss_cache;
- }
-
if (!tp->sacked_out)
tp->fackets_out = 0;
prior_fackets = tp->fackets_out;
@@ -978,20 +970,40 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
flag |= FLAG_DATA_LOST;
sk_stream_for_retrans_queue(skb, sk) {
- u8 sacked = TCP_SKB_CB(skb)->sacked;
- int in_sack;
+ int in_sack, pcount;
+ u8 sacked;
/* The retransmission queue is always in order, so
* we can short-circuit the walk early.
*/
- if(!before(TCP_SKB_CB(skb)->seq, end_seq))
+ if (!before(TCP_SKB_CB(skb)->seq, end_seq))
break;
- fack_count += tcp_skb_pcount(skb);
+ pcount = tcp_skb_pcount(skb);
+
+ if (pcount > 1 &&
+ (after(start_seq, TCP_SKB_CB(skb)->seq) ||
+ before(end_seq, TCP_SKB_CB(skb)->end_seq))) {
+ unsigned int pkt_len;
+
+ if (after(start_seq, TCP_SKB_CB(skb)->seq))
+ pkt_len = (start_seq -
+ TCP_SKB_CB(skb)->seq);
+ else
+ pkt_len = (end_seq -
+ TCP_SKB_CB(skb)->seq);
+ if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size))
+ break;
+ pcount = tcp_skb_pcount(skb);
+ }
+
+ fack_count += pcount;
in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
!before(end_seq, TCP_SKB_CB(skb)->end_seq);
+ sacked = TCP_SKB_CB(skb)->sacked;
+
/* Account D-SACK for retransmitted packet. */
if ((dup_sack && in_sack) &&
(sacked & TCPCB_RETRANS) &&
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 75b6811..15e1134 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -428,11 +428,11 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned
* packet to the list. This won't be called frequently, I hope.
* Remember, these are still headerless SKBs at this point.
*/
-static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now)
+int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now)
{
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *buff;
- int nsize;
+ int nsize, old_factor;
u16 flags;
nsize = skb_headlen(skb) - len;
@@ -490,18 +490,29 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned
tp->left_out -= tcp_skb_pcount(skb);
}
+ old_factor = tcp_skb_pcount(skb);
+
/* Fix up tso_factor for both original and new SKB. */
tcp_set_skb_tso_segs(sk, skb, mss_now);
tcp_set_skb_tso_segs(sk, buff, mss_now);
- if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
- tp->lost_out += tcp_skb_pcount(skb);
- tp->left_out += tcp_skb_pcount(skb);
- }
+ /* If this packet has been sent out already, we must
+ * adjust the various packet counters.
+ */
+ if (!before(tp->snd_nxt, TCP_SKB_CB(buff)->end_seq)) {
+ int diff = old_factor - tcp_skb_pcount(skb) -
+ tcp_skb_pcount(buff);
- if (TCP_SKB_CB(buff)->sacked&TCPCB_LOST) {
- tp->lost_out += tcp_skb_pcount(buff);
- tp->left_out += tcp_skb_pcount(buff);
+ tp->packets_out -= diff;
+ if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
+ tp->lost_out -= diff;
+ tp->left_out -= diff;
+ }
+ if (diff > 0) {
+ tp->fackets_out -= diff;
+ if ((int)tp->fackets_out < 0)
+ tp->fackets_out = 0;
+ }
}
/* Link BUFF into the send queue. */
@@ -1350,12 +1361,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
BUG();
-
- if (sk->sk_route_caps & NETIF_F_TSO) {
- sk->sk_route_caps &= ~NETIF_F_TSO;
- sock_set_flag(sk, SOCK_NO_LARGESEND);
- }
-
if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
return -ENOMEM;
}
@@ -1370,22 +1375,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
return -EAGAIN;
if (skb->len > cur_mss) {
- int old_factor = tcp_skb_pcount(skb);
- int diff;
-
if (tcp_fragment(sk, skb, cur_mss, cur_mss))
return -ENOMEM; /* We'll try again later. */
-
- /* New SKB created, account for it. */
- diff = old_factor - tcp_skb_pcount(skb) -
- tcp_skb_pcount(skb->next);
- tp->packets_out -= diff;
-
- if (diff > 0) {
- tp->fackets_out -= diff;
- if ((int)tp->fackets_out < 0)
- tp->fackets_out = 0;
- }
}
/* Collapse two adjacent packets if worthwhile and we can. */
@@ -1993,12 +1984,6 @@ int tcp_write_wakeup(struct sock *sk)
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
if (tcp_fragment(sk, skb, seg_size, mss))
return -1;
- /* SWS override triggered forced fragmentation.
- * Disable TSO, the connection is too sick. */
- if (sk->sk_route_caps & NETIF_F_TSO) {
- sock_set_flag(sk, SOCK_NO_LARGESEND);
- sk->sk_route_caps &= ~NETIF_F_TSO;
- }
} else if (!tcp_skb_pcount(skb))
tcp_set_skb_tso_segs(sk, skb, mss);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e5beca7..e0bd101 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1141,7 +1141,7 @@ int udp_rcv(struct sk_buff *skb)
if (ulen > len || ulen < sizeof(*uh))
goto short_packet;
- if (pskb_trim(skb, ulen))
+ if (pskb_trim_rcsum(skb, ulen))
goto short_packet;
if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 937ad32..2fea3f4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -123,8 +123,7 @@ DEFINE_RWLOCK(addrconf_lock);
static void addrconf_verify(unsigned long);
-static struct timer_list addr_chk_timer =
- TIMER_INITIALIZER(addrconf_verify, 0, 0);
+static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
static DEFINE_SPINLOCK(addrconf_verify_lock);
static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
@@ -3593,10 +3592,8 @@ void __exit addrconf_cleanup(void)
rtnl_unlock();
#ifdef CONFIG_IPV6_PRIVACY
- if (likely(md5_tfm != NULL)) {
- crypto_free_tfm(md5_tfm);
- md5_tfm = NULL;
- }
+ crypto_free_tfm(md5_tfm);
+ md5_tfm = NULL;
#endif
#ifdef CONFIG_PROC_FS
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 0ebfad9..f362973 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -401,10 +401,8 @@ static int ah6_init_state(struct xfrm_state *x)
error:
if (ahp) {
- if (ahp->work_icv)
- kfree(ahp->work_icv);
- if (ahp->tfm)
- crypto_free_tfm(ahp->tfm);
+ kfree(ahp->work_icv);
+ crypto_free_tfm(ahp->tfm);
kfree(ahp);
}
return -EINVAL;
@@ -417,14 +415,10 @@ static void ah6_destroy(struct xfrm_state *x)
if (!ahp)
return;
- if (ahp->work_icv) {
- kfree(ahp->work_icv);
- ahp->work_icv = NULL;
- }
- if (ahp->tfm) {
- crypto_free_tfm(ahp->tfm);
- ahp->tfm = NULL;
- }
+ kfree(ahp->work_icv);
+ ahp->work_icv = NULL;
+ crypto_free_tfm(ahp->tfm);
+ ahp->tfm = NULL;
kfree(ahp);
}
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 01468fa..cc51840 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -175,10 +175,8 @@ ipv4_connected:
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
goto out;
- }
/* source address lookup done in ip6_dst_lookup */
@@ -390,32 +388,101 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
}
+ if (np->rxopt.bits.rxtclass) {
+ int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff;
+ put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
+ }
+
if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
}
+
+ /* HbH is allowed only once */
if (np->rxopt.bits.hopopts && opt->hop) {
u8 *ptr = skb->nh.raw + opt->hop;
put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
}
- if (np->rxopt.bits.dstopts && opt->dst0) {
+
+ if (opt->lastopt &&
+ (np->rxopt.bits.dstopts || np->rxopt.bits.srcrt)) {
+ /*
+ * Silly enough, but we need to reparse in order to
+ * report extension headers (except for HbH)
+ * in order.
+ *
+ * Also note that IPV6_RECVRTHDRDSTOPTS is NOT
+ * (and WILL NOT be) defined because
+ * IPV6_RECVDSTOPTS is more generic. --yoshfuji
+ */
+ unsigned int off = sizeof(struct ipv6hdr);
+ u8 nexthdr = skb->nh.ipv6h->nexthdr;
+
+ while (off <= opt->lastopt) {
+ unsigned len;
+ u8 *ptr = skb->nh.raw + off;
+
+ switch(nexthdr) {
+ case IPPROTO_DSTOPTS:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 3;
+ if (np->rxopt.bits.dstopts)
+ put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, len, ptr);
+ break;
+ case IPPROTO_ROUTING:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 3;
+ if (np->rxopt.bits.srcrt)
+ put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, len, ptr);
+ break;
+ case IPPROTO_AH:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 2;
+ break;
+ default:
+ nexthdr = ptr[0];
+ len = (ptr[1] + 1) << 3;
+ break;
+ }
+
+ off += len;
+ }
+ }
+
+ /* socket options in old style */
+ if (np->rxopt.bits.rxoinfo) {
+ struct in6_pktinfo src_info;
+
+ src_info.ipi6_ifindex = opt->iif;
+ ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
+ }
+ if (np->rxopt.bits.rxohlim) {
+ int hlim = skb->nh.ipv6h->hop_limit;
+ put_cmsg(msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
+ }
+ if (np->rxopt.bits.ohopopts && opt->hop) {
+ u8 *ptr = skb->nh.raw + opt->hop;
+ put_cmsg(msg, SOL_IPV6, IPV6_2292HOPOPTS, (ptr[1]+1)<<3, ptr);
+ }
+ if (np->rxopt.bits.odstopts && opt->dst0) {
u8 *ptr = skb->nh.raw + opt->dst0;
- put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
- if (np->rxopt.bits.srcrt && opt->srcrt) {
+ if (np->rxopt.bits.osrcrt && opt->srcrt) {
struct ipv6_rt_hdr *rthdr = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt);
- put_cmsg(msg, SOL_IPV6, IPV6_RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292RTHDR, (rthdr->hdrlen+1) << 3, rthdr);
}
- if (np->rxopt.bits.dstopts && opt->dst1) {
+ if (np->rxopt.bits.odstopts && opt->dst1) {
u8 *ptr = skb->nh.raw + opt->dst1;
- put_cmsg(msg, SOL_IPV6, IPV6_DSTOPTS, (ptr[1]+1)<<3, ptr);
+ put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr);
}
return 0;
}
int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
struct ipv6_txoptions *opt,
- int *hlimit)
+ int *hlimit, int *tclass)
{
struct in6_pktinfo *src_info;
struct cmsghdr *cmsg;
@@ -438,6 +505,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
switch (cmsg->cmsg_type) {
case IPV6_PKTINFO:
+ case IPV6_2292PKTINFO:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct in6_pktinfo))) {
err = -EINVAL;
goto exit_f;
@@ -492,6 +560,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
break;
+ case IPV6_2292HOPOPTS:
case IPV6_HOPOPTS:
if (opt->hopopt || cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
err = -EINVAL;
@@ -512,7 +581,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
opt->hopopt = hdr;
break;
- case IPV6_DSTOPTS:
+ case IPV6_2292DSTOPTS:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
err = -EINVAL;
goto exit_f;
@@ -536,6 +605,33 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
opt->dst1opt = hdr;
break;
+ case IPV6_DSTOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_opt_hdr))) {
+ err = -EINVAL;
+ goto exit_f;
+ }
+
+ hdr = (struct ipv6_opt_hdr *)CMSG_DATA(cmsg);
+ len = ((hdr->hdrlen + 1) << 3);
+ if (cmsg->cmsg_len < CMSG_LEN(len)) {
+ err = -EINVAL;
+ goto exit_f;
+ }
+ if (!capable(CAP_NET_RAW)) {
+ err = -EPERM;
+ goto exit_f;
+ }
+ if (cmsg->cmsg_type == IPV6_DSTOPTS) {
+ opt->opt_flen += len;
+ opt->dst1opt = hdr;
+ } else {
+ opt->opt_nflen += len;
+ opt->dst0opt = hdr;
+ }
+ break;
+
+ case IPV6_2292RTHDR:
case IPV6_RTHDR:
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
err = -EINVAL;
@@ -568,7 +664,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
opt->opt_nflen += len;
opt->srcrt = rthdr;
- if (opt->dst1opt) {
+ if (cmsg->cmsg_type == IPV6_2292RTHDR && opt->dst1opt) {
int dsthdrlen = ((opt->dst1opt->hdrlen+1)<<3);
opt->opt_nflen += dsthdrlen;
@@ -579,6 +675,7 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
break;
+ case IPV6_2292HOPLIMIT:
case IPV6_HOPLIMIT:
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
err = -EINVAL;
@@ -588,6 +685,24 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
*hlimit = *(int *)CMSG_DATA(cmsg);
break;
+ case IPV6_TCLASS:
+ {
+ int tc;
+
+ err = -EINVAL;
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+ goto exit_f;
+ }
+
+ tc = *(int *)CMSG_DATA(cmsg);
+ if (tc < 0 || tc > 0xff)
+ goto exit_f;
+
+ err = 0;
+ *tclass = tc;
+
+ break;
+ }
default:
LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n",
cmsg->cmsg_type);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index e8bff9d..9b27460 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -276,22 +276,14 @@ static void esp6_destroy(struct xfrm_state *x)
if (!esp)
return;
- if (esp->conf.tfm) {
- crypto_free_tfm(esp->conf.tfm);
- esp->conf.tfm = NULL;
- }
- if (esp->conf.ivec) {
- kfree(esp->conf.ivec);
- esp->conf.ivec = NULL;
- }
- if (esp->auth.tfm) {
- crypto_free_tfm(esp->auth.tfm);
- esp->auth.tfm = NULL;
- }
- if (esp->auth.work_icv) {
- kfree(esp->auth.work_icv);
- esp->auth.work_icv = NULL;
- }
+ crypto_free_tfm(esp->conf.tfm);
+ esp->conf.tfm = NULL;
+ kfree(esp->conf.ivec);
+ esp->conf.ivec = NULL;
+ crypto_free_tfm(esp->auth.tfm);
+ esp->auth.tfm = NULL;
+ kfree(esp->auth.work_icv);
+ esp->auth.work_icv = NULL;
kfree(esp);
}
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 5be6da2..4712272 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -164,6 +164,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
return -1;
}
+ opt->lastopt = skb->h.raw - skb->nh.raw;
opt->dst1 = skb->h.raw - skb->nh.raw;
if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
@@ -243,6 +244,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
looped_back:
if (hdr->segments_left == 0) {
+ opt->lastopt = skb->h.raw - skb->nh.raw;
opt->srcrt = skb->h.raw - skb->nh.raw;
skb->h.raw += (hdr->hdrlen + 1) << 3;
opt->dst0 = opt->dst1;
@@ -459,11 +461,10 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
}
- if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
- __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
- if (skb->ip_summed == CHECKSUM_HW)
- skb->ip_summed = CHECKSUM_NONE;
- }
+
+ if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
+ goto drop;
+
return 1;
drop:
@@ -539,10 +540,15 @@ void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto,
struct in6_addr **daddr)
{
- if (opt->srcrt)
+ if (opt->srcrt) {
ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
- if (opt->dst0opt)
- ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+ /*
+ * IPV6_RTHDRDSTOPTS is ignored
+ * unless IPV6_RTHDR is set (RFC3542).
+ */
+ if (opt->dst0opt)
+ ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
+ }
if (opt->hopopt)
ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
}
@@ -573,3 +579,97 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
}
return opt2;
}
+
+static int ipv6_renew_option(void *ohdr,
+ struct ipv6_opt_hdr __user *newopt, int newoptlen,
+ int inherit,
+ struct ipv6_opt_hdr **hdr,
+ char **p)
+{
+ if (inherit) {
+ if (ohdr) {
+ memcpy(*p, ohdr, ipv6_optlen((struct ipv6_opt_hdr *)ohdr));
+ *hdr = (struct ipv6_opt_hdr *)*p;
+ *p += CMSG_ALIGN(ipv6_optlen(*(struct ipv6_opt_hdr **)hdr));
+ }
+ } else {
+ if (newopt) {
+ if (copy_from_user(*p, newopt, newoptlen))
+ return -EFAULT;
+ *hdr = (struct ipv6_opt_hdr *)*p;
+ if (ipv6_optlen(*(struct ipv6_opt_hdr **)hdr) > newoptlen)
+ return -EINVAL;
+ *p += CMSG_ALIGN(newoptlen);
+ }
+ }
+ return 0;
+}
+
+struct ipv6_txoptions *
+ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
+ int newtype,
+ struct ipv6_opt_hdr __user *newopt, int newoptlen)
+{
+ int tot_len = 0;
+ char *p;
+ struct ipv6_txoptions *opt2;
+ int err;
+
+ if (newtype != IPV6_HOPOPTS && opt->hopopt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
+ if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
+ if (newtype != IPV6_RTHDR && opt->srcrt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
+ if (newtype != IPV6_DSTOPTS && opt->dst1opt)
+ tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
+ if (newopt && newoptlen)
+ tot_len += CMSG_ALIGN(newoptlen);
+
+ if (!tot_len)
+ return NULL;
+
+ opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
+ if (!opt2)
+ return ERR_PTR(-ENOBUFS);
+
+ memset(opt2, 0, tot_len);
+
+ opt2->tot_len = tot_len;
+ p = (char *)(opt2 + 1);
+
+ err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
+ newtype != IPV6_HOPOPTS,
+ &opt2->hopopt, &p);
+ if (err)
+ goto out;
+
+ err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
+ newtype != IPV6_RTHDRDSTOPTS,
+ &opt2->dst0opt, &p);
+ if (err)
+ goto out;
+
+ err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
+ newtype != IPV6_RTHDR,
+ (struct ipv6_opt_hdr **)opt2->srcrt, &p);
+ if (err)
+ goto out;
+
+ err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
+ newtype != IPV6_DSTOPTS,
+ &opt2->dst1opt, &p);
+ if (err)
+ goto out;
+
+ opt2->opt_nflen = (opt2->hopopt ? ipv6_optlen(opt2->hopopt) : 0) +
+ (opt2->dst0opt ? ipv6_optlen(opt2->dst0opt) : 0) +
+ (opt2->srcrt ? ipv6_optlen(opt2->srcrt) : 0);
+ opt2->opt_flen = (opt2->dst1opt ? ipv6_optlen(opt2->dst1opt) : 0);
+
+ return opt2;
+out:
+ sock_kfree_s(sk, p, tot_len);
+ return ERR_PTR(err);
+}
+
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 5176fc6..b7185fb 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
int iif = 0;
int addr_type = 0;
int len;
- int hlimit;
+ int hlimit, tclass;
int err = 0;
if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -374,7 +374,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if (err)
goto out;
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
- goto out_dst_release;
+ goto out;
if (ipv6_addr_is_multicast(&fl.fl6_dst))
hlimit = np->mcast_hops;
@@ -385,6 +385,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
if (hlimit < 0)
hlimit = ipv6_get_hoplimit(dst->dev);
+ tclass = np->cork.tclass;
+ if (tclass < 0)
+ tclass = 0;
+
msg.skb = skb;
msg.offset = skb->nh.raw - skb->data;
@@ -400,7 +404,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
err = ip6_append_data(sk, icmpv6_getfrag, &msg,
len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr),
- hlimit, NULL, &fl, (struct rt6_info*)dst,
+ hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
MSG_DONTWAIT);
if (err) {
ip6_flush_pending_frames(sk);
@@ -434,6 +438,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
struct dst_entry *dst;
int err = 0;
int hlimit;
+ int tclass;
saddr = &skb->nh.ipv6h->daddr;
@@ -464,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (err)
goto out;
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
- goto out_dst_release;
+ goto out;
if (ipv6_addr_is_multicast(&fl.fl6_dst))
hlimit = np->mcast_hops;
@@ -475,13 +480,17 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (hlimit < 0)
hlimit = ipv6_get_hoplimit(dst->dev);
+ tclass = np->cork.tclass;
+ if (tclass < 0)
+ tclass = 0;
+
idev = in6_dev_get(skb->dev);
msg.skb = skb;
msg.offset = 0;
err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
- sizeof(struct icmp6hdr), hlimit, NULL, &fl,
+ sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
(struct rt6_info*)dst, MSG_DONTWAIT);
if (err) {
@@ -496,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
out_put:
if (likely(idev != NULL))
in6_dev_put(idev);
-out_dst_release:
dst_release(dst);
out:
icmpv6_xmit_unlock();
@@ -549,7 +557,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
read_lock(&raw_v6_lock);
if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
- skb->dev->ifindex))) {
+ IP6CB(skb)->iif))) {
rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
sk = sk_next(sk);
}
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 16af874..4fcc5a7 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -92,7 +92,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
static __u32 rt_sernum;
-static struct timer_list ip6_fib_timer = TIMER_INITIALIZER(fib6_run_gc, 0, 0);
+static DEFINE_TIMER(ip6_fib_timer, fib6_run_gc, 0, 0);
struct fib6_walker_t fib6_walker_list = {
.prev = &fib6_walker_list,
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index b6c73da5..f841bde 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -50,7 +50,7 @@ static atomic_t fl_size = ATOMIC_INIT(0);
static struct ip6_flowlabel *fl_ht[FL_HASH_MASK+1];
static void ip6_fl_gc(unsigned long dummy);
-static struct timer_list ip6_fl_gc_timer = TIMER_INITIALIZER(ip6_fl_gc, 0, 0);
+static DEFINE_TIMER(ip6_fl_gc_timer, ip6_fl_gc, 0, 0);
/* FL hash table lock: it protects only of GC */
@@ -225,16 +225,20 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
struct ip6_flowlabel * fl,
struct ipv6_txoptions * fopt)
{
- struct ipv6_txoptions * fl_opt = fl->opt;
+ struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
- if (fopt == NULL || fopt->opt_flen == 0)
- return fl_opt;
+ if (fopt == NULL || fopt->opt_flen == 0) {
+ if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
+ return fl_opt;
+ }
if (fl_opt != NULL) {
opt_space->hopopt = fl_opt->hopopt;
- opt_space->dst0opt = fl_opt->dst0opt;
+ opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
opt_space->srcrt = fl_opt->srcrt;
opt_space->opt_nflen = fl_opt->opt_nflen;
+ if (fl_opt->dst0opt && !fl_opt->srcrt)
+ opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
} else {
if (fopt->opt_nflen == 0)
return fopt;
@@ -310,7 +314,7 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *
msg.msg_control = (void*)(fl->opt+1);
flowi.oif = 0;
- err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+ err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk, &junk);
if (err)
goto done;
err = -EINVAL;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 01ef94f..2f589f2 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -166,7 +166,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
struct ipv6hdr *hdr;
u8 proto = fl->proto;
int seg_len = skb->len;
- int hlimit;
+ int hlimit, tclass;
u32 mtu;
if (opt) {
@@ -202,7 +202,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
* Fill in the IPv6 header
*/
- *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
hlimit = -1;
if (np)
hlimit = np->hop_limit;
@@ -211,6 +210,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
if (hlimit < 0)
hlimit = ipv6_get_hoplimit(dst->dev);
+ tclass = -1;
+ if (np)
+ tclass = np->tclass;
+ if (tclass < 0)
+ tclass = 0;
+
+ *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
+
hdr->payload_len = htons(seg_len);
hdr->nexthdr = proto;
hdr->hop_limit = hlimit;
@@ -762,10 +769,11 @@ out_err_release:
return err;
}
-int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb),
- void *from, int length, int transhdrlen,
- int hlimit, struct ipv6_txoptions *opt, struct flowi *fl, struct rt6_info *rt,
- unsigned int flags)
+int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
+ int offset, int len, int odd, struct sk_buff *skb),
+ void *from, int length, int transhdrlen,
+ int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl,
+ struct rt6_info *rt, unsigned int flags)
{
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
@@ -803,6 +811,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
np->cork.rt = rt;
inet->cork.fl = *fl;
np->cork.hop_limit = hlimit;
+ np->cork.tclass = tclass;
inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path);
if (dst_allfrag(rt->u.dst.path))
inet->cork.flags |= IPCORK_ALLFRAG;
@@ -1084,7 +1093,8 @@ int ip6_push_pending_frames(struct sock *sk)
skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr));
- *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
+ *(u32*)hdr = fl->fl6_flowlabel |
+ htonl(0x60000000 | ((int)np->cork.tclass << 20));
if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 0961372..cf94372 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -673,11 +673,12 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
if ((dst = ip6_tnl_dst_check(t)) != NULL)
dst_hold(dst);
- else
+ else {
dst = ip6_route_output(NULL, &fl);
- if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
- goto tx_err_link_failure;
+ if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0) < 0)
+ goto tx_err_link_failure;
+ }
tdev = dst->dev;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 135383e..85bfbc6 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -341,8 +341,7 @@ static void ipcomp6_free_tfms(struct crypto_tfm **tfms)
for_each_cpu(cpu) {
struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
- if (tfm)
- crypto_free_tfm(tfm);
+ crypto_free_tfm(tfm);
}
free_percpu(tfms);
}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 76466af..8567873 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -210,39 +210,139 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = 0;
break;
- case IPV6_PKTINFO:
+ case IPV6_RECVPKTINFO:
np->rxopt.bits.rxinfo = valbool;
retv = 0;
break;
+
+ case IPV6_2292PKTINFO:
+ np->rxopt.bits.rxoinfo = valbool;
+ retv = 0;
+ break;
- case IPV6_HOPLIMIT:
+ case IPV6_RECVHOPLIMIT:
np->rxopt.bits.rxhlim = valbool;
retv = 0;
break;
- case IPV6_RTHDR:
+ case IPV6_2292HOPLIMIT:
+ np->rxopt.bits.rxohlim = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_RECVRTHDR:
if (val < 0 || val > 2)
goto e_inval;
np->rxopt.bits.srcrt = val;
retv = 0;
break;
- case IPV6_HOPOPTS:
+ case IPV6_2292RTHDR:
+ if (val < 0 || val > 2)
+ goto e_inval;
+ np->rxopt.bits.osrcrt = val;
+ retv = 0;
+ break;
+
+ case IPV6_RECVHOPOPTS:
np->rxopt.bits.hopopts = valbool;
retv = 0;
break;
- case IPV6_DSTOPTS:
+ case IPV6_2292HOPOPTS:
+ np->rxopt.bits.ohopopts = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_RECVDSTOPTS:
np->rxopt.bits.dstopts = valbool;
retv = 0;
break;
+ case IPV6_2292DSTOPTS:
+ np->rxopt.bits.odstopts = valbool;
+ retv = 0;
+ break;
+
+ case IPV6_TCLASS:
+ if (val < 0 || val > 0xff)
+ goto e_inval;
+ np->tclass = val;
+ retv = 0;
+ break;
+
+ case IPV6_RECVTCLASS:
+ np->rxopt.bits.rxtclass = valbool;
+ retv = 0;
+ break;
+
case IPV6_FLOWINFO:
np->rxopt.bits.rxflow = valbool;
retv = 0;
break;
- case IPV6_PKTOPTIONS:
+ case IPV6_HOPOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ case IPV6_RTHDR:
+ case IPV6_DSTOPTS:
+ {
+ struct ipv6_txoptions *opt;
+ if (optlen == 0)
+ optval = 0;
+
+ /* hop-by-hop / destination options are privileged option */
+ retv = -EPERM;
+ if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
+ break;
+
+ retv = -EINVAL;
+ if (optlen & 0x7 || optlen > 8 * 255)
+ break;
+
+ opt = ipv6_renew_options(sk, np->opt, optname,
+ (struct ipv6_opt_hdr __user *)optval,
+ optlen);
+ if (IS_ERR(opt)) {
+ retv = PTR_ERR(opt);
+ break;
+ }
+
+ /* routing header option needs extra check */
+ if (optname == IPV6_RTHDR && opt->srcrt) {
+ struct ipv6_rt_hdr *rthdr = opt->srcrt;
+ if (rthdr->type)
+ goto sticky_done;
+ if ((rthdr->hdrlen & 1) ||
+ (rthdr->hdrlen >> 1) != rthdr->segments_left)
+ goto sticky_done;
+ }
+
+ retv = 0;
+ if (sk->sk_type == SOCK_STREAM) {
+ if (opt) {
+ struct tcp_sock *tp = tcp_sk(sk);
+ if (!((1 << sk->sk_state) &
+ (TCPF_LISTEN | TCPF_CLOSE))
+ && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
+ tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
+ tcp_sync_mss(sk, tp->pmtu_cookie);
+ }
+ }
+ opt = xchg(&np->opt, opt);
+ sk_dst_reset(sk);
+ } else {
+ write_lock(&sk->sk_dst_lock);
+ opt = xchg(&np->opt, opt);
+ write_unlock(&sk->sk_dst_lock);
+ sk_dst_reset(sk);
+ }
+sticky_done:
+ if (opt)
+ sock_kfree_s(sk, opt, opt->tot_len);
+ break;
+ }
+
+ case IPV6_2292PKTOPTIONS:
{
struct ipv6_txoptions *opt = NULL;
struct msghdr msg;
@@ -276,7 +376,7 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
msg.msg_controllen = optlen;
msg.msg_control = (void*)(opt+1);
- retv = datagram_send_ctl(&msg, &fl, opt, &junk);
+ retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
if (retv)
goto done;
update:
@@ -529,6 +629,17 @@ e_inval:
return -EINVAL;
}
+int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
+ char __user *optval, int len)
+{
+ if (!hdr)
+ return 0;
+ len = min_t(int, len, ipv6_optlen(hdr));
+ if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
+ return -EFAULT;
+ return len;
+}
+
int ipv6_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
{
@@ -567,7 +678,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
return err;
}
- case IPV6_PKTOPTIONS:
+ case IPV6_2292PKTOPTIONS:
{
struct msghdr msg;
struct sk_buff *skb;
@@ -601,6 +712,16 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
int hlim = np->mcast_hops;
put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
}
+ if (np->rxopt.bits.rxoinfo) {
+ struct in6_pktinfo src_info;
+ src_info.ipi6_ifindex = np->mcast_oif;
+ ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
+ put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
+ }
+ if (np->rxopt.bits.rxohlim) {
+ int hlim = np->mcast_hops;
+ put_cmsg(&msg, SOL_IPV6, IPV6_2292HOPLIMIT, sizeof(hlim), &hlim);
+ }
}
len -= msg.msg_controllen;
return put_user(len, optlen);
@@ -625,26 +746,67 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
val = np->ipv6only;
break;
- case IPV6_PKTINFO:
+ case IPV6_RECVPKTINFO:
val = np->rxopt.bits.rxinfo;
break;
- case IPV6_HOPLIMIT:
+ case IPV6_2292PKTINFO:
+ val = np->rxopt.bits.rxoinfo;
+ break;
+
+ case IPV6_RECVHOPLIMIT:
val = np->rxopt.bits.rxhlim;
break;
- case IPV6_RTHDR:
+ case IPV6_2292HOPLIMIT:
+ val = np->rxopt.bits.rxohlim;
+ break;
+
+ case IPV6_RECVRTHDR:
val = np->rxopt.bits.srcrt;
break;
+ case IPV6_2292RTHDR:
+ val = np->rxopt.bits.osrcrt;
+ break;
+
case IPV6_HOPOPTS:
+ case IPV6_RTHDRDSTOPTS:
+ case IPV6_RTHDR:
+ case IPV6_DSTOPTS:
+ {
+
+ lock_sock(sk);
+ len = ipv6_getsockopt_sticky(sk, np->opt->hopopt,
+ optval, len);
+ release_sock(sk);
+ return put_user(len, optlen);
+ }
+
+ case IPV6_RECVHOPOPTS:
val = np->rxopt.bits.hopopts;
break;
- case IPV6_DSTOPTS:
+ case IPV6_2292HOPOPTS:
+ val = np->rxopt.bits.ohopopts;
+ break;
+
+ case IPV6_RECVDSTOPTS:
val = np->rxopt.bits.dstopts;
break;
+ case IPV6_2292DSTOPTS:
+ val = np->rxopt.bits.odstopts;
+ break;
+
+ case IPV6_TCLASS:
+ val = np->tclass;
+ break;
+
+ case IPV6_RECVTCLASS:
+ val = np->rxopt.bits.rxtclass;
+ break;
+
case IPV6_FLOWINFO:
val = np->rxopt.bits.rxflow;
break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a7eae30..555a313 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -447,10 +447,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err < 0) {
- dst_release(dst);
+ if (err < 0)
return;
- }
if (inc_opt) {
if (dev->addr_len)
@@ -539,10 +537,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err < 0) {
- dst_release(dst);
+ if (err < 0)
return;
- }
len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
send_llinfo = dev->addr_len && !ipv6_addr_any(saddr);
@@ -616,10 +612,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err < 0) {
- dst_release(dst);
+ if (err < 0)
return;
- }
len = sizeof(struct icmp6hdr);
if (dev->addr_len)
@@ -1353,10 +1347,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
return;
err = xfrm_lookup(&dst, &fl, NULL, 0);
- if (err) {
- dst_release(dst);
+ if (err)
return;
- }
rt = (struct rt6_info *) dst;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 14316c3..b03e87a 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -100,11 +100,8 @@ static void send_reset(struct sk_buff *oldskb)
dst = ip6_route_output(NULL, &fl);
if (dst == NULL)
return;
- if (dst->error ||
- xfrm_lookup(&dst, &fl, NULL, 0)) {
- dst_release(dst);
+ if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
return;
- }
hh_len = (dst->dev->hard_header_len + 15)&~15;
nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 9b91dec..4de4cda 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/file.h>
+#include <linux/rcupdate.h>
#include <net/sock.h>
#include <linux/netfilter_ipv6/ip6t_owner.h>
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 7a58632..5aa3691 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -166,7 +166,7 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
if (sk == NULL)
goto out;
- sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, skb->dev->ifindex);
+ sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
while (sk) {
delivered = 1;
@@ -178,7 +178,7 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
rawv6_rcv(sk, clone);
}
sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
- skb->dev->ifindex);
+ IP6CB(skb)->iif);
}
out:
read_unlock(&raw_v6_lock);
@@ -655,6 +655,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct flowi fl;
int addr_len = msg->msg_namelen;
int hlimit = -1;
+ int tclass = -1;
u16 proto;
int err;
@@ -740,7 +741,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions);
- err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+ err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
@@ -755,8 +756,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
}
if (opt == NULL)
opt = np->opt;
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
+ opt = fl6_merge_options(&opt_space, flowlabel, opt);
fl.proto = proto;
rawv6_probe_proto_opt(&fl, msg);
@@ -782,10 +782,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
goto out;
- }
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst))
@@ -798,6 +796,12 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
hlimit = ipv6_get_hoplimit(dst->dev);
}
+ if (tclass < 0) {
+ tclass = np->cork.tclass;
+ if (tclass < 0)
+ tclass = 0;
+ }
+
if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
@@ -806,8 +810,9 @@ back_from_confirm:
err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, (struct rt6_info*)dst, msg->msg_flags);
} else {
lock_sock(sk);
- err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, len, 0,
- hlimit, opt, &fl, (struct rt6_info*)dst, msg->msg_flags);
+ err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
+ len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst,
+ msg->msg_flags);
if (err)
ip6_flush_pending_frames(sk);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 9d9e043..e4fe9ee 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -479,12 +479,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
/* Point into the IP datagram 'data' part. */
if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
goto err;
- if (end-offset < skb->len) {
- if (pskb_trim(skb, end - offset))
- goto err;
- if (skb->ip_summed != CHECKSUM_UNNECESSARY)
- skb->ip_summed = CHECKSUM_NONE;
- }
+
+ if (pskb_trim_rcsum(skb, end - offset))
+ goto err;
/* Find out which fragments are in front and at the back of us
* in the chain of fragments so far. We must know where to put
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 794734f..80643e6 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -632,10 +632,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
goto failure;
- }
if (saddr == NULL) {
saddr = &fl.fl6_src;
@@ -849,7 +847,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
if (dst == NULL) {
opt = np->opt;
if (opt == NULL &&
- np->rxopt.bits.srcrt == 2 &&
+ np->rxopt.bits.osrcrt == 2 &&
treq->pktopts) {
struct sk_buff *pktopts = treq->pktopts;
struct inet6_skb_parm *rxopt = IP6CB(pktopts);
@@ -888,7 +886,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
}
done:
- dst_release(dst);
if (opt && opt != np->opt)
sock_kfree_s(sk, opt, opt->tot_len);
return err;
@@ -915,11 +912,10 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
struct inet6_skb_parm *opt = IP6CB(skb);
if (np->rxopt.all) {
- if ((opt->hop && np->rxopt.bits.hopopts) ||
- ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) &&
- np->rxopt.bits.rxflow) ||
- (opt->srcrt && np->rxopt.bits.srcrt) ||
- ((opt->dst1 || opt->dst0) && np->rxopt.bits.dstopts))
+ if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
+ ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
+ (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
+ ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
return 1;
}
return 0;
@@ -1001,10 +997,8 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
/* sk = NULL, but it is safe for now. RST socket required. */
if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
- if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
- dst_release(buff->dst);
+ if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
return;
- }
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
@@ -1068,10 +1062,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
fl.fl_ip_sport = t1->source;
if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
- if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0) {
- dst_release(buff->dst);
+ if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
return;
- }
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
return;
@@ -1190,8 +1182,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
TCP_ECN_create_request(req, skb->h.th);
treq->pktopts = NULL;
if (ipv6_opt_accepted(sk, skb) ||
- np->rxopt.bits.rxinfo ||
- np->rxopt.bits.rxhlim) {
+ np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+ np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
atomic_inc(&skb->users);
treq->pktopts = skb;
}
@@ -1288,7 +1280,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (sk_acceptq_is_full(sk))
goto out_overflow;
- if (np->rxopt.bits.srcrt == 2 &&
+ if (np->rxopt.bits.osrcrt == 2 &&
opt == NULL && treq->pktopts) {
struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
if (rxopt->srcrt)
@@ -1544,9 +1536,9 @@ ipv6_pktoptions:
tp = tcp_sk(sk);
if (TCP_SKB_CB(opt_skb)->end_seq == tp->rcv_nxt &&
!((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {
- if (np->rxopt.bits.rxinfo)
+ if (np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo)
np->mcast_oif = inet6_iif(opt_skb);
- if (np->rxopt.bits.rxhlim)
+ if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
np->mcast_hops = opt_skb->nh.ipv6h->hop_limit;
if (ipv6_opt_accepted(sk, opt_skb)) {
skb_set_owner_r(opt_skb, sk);
@@ -1734,7 +1726,6 @@ static int tcp_v6_rebuild_header(struct sock *sk)
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
sk->sk_err_soft = -err;
- dst_release(dst);
return err;
}
@@ -1787,7 +1778,6 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
sk->sk_route_caps = 0;
- dst_release(dst);
return err;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 390d750..69b1468 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -483,7 +483,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
}
if (ulen < skb->len) {
- if (__pskb_trim(skb, ulen))
+ if (pskb_trim_rcsum(skb, ulen))
goto discard;
saddr = &skb->nh.ipv6h->saddr;
daddr = &skb->nh.ipv6h->daddr;
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
int addr_len = msg->msg_namelen;
int ulen = len;
int hlimit = -1;
+ int tclass = -1;
int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
int err;
@@ -758,7 +759,7 @@ do_udp_sendmsg:
memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(*opt);
- err = datagram_send_ctl(msg, fl, opt, &hlimit);
+ err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
if (err < 0) {
fl6_sock_release(flowlabel);
return err;
@@ -773,8 +774,7 @@ do_udp_sendmsg:
}
if (opt == NULL)
opt = np->opt;
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
+ opt = fl6_merge_options(&opt_space, flowlabel, opt);
fl->proto = IPPROTO_UDP;
ipv6_addr_copy(&fl->fl6_dst, daddr);
@@ -799,10 +799,8 @@ do_udp_sendmsg:
if (final_p)
ipv6_addr_copy(&fl->fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) {
- dst_release(dst);
+ if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
goto out;
- }
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl->fl6_dst))
@@ -815,6 +813,12 @@ do_udp_sendmsg:
hlimit = ipv6_get_hoplimit(dst->dev);
}
+ if (tclass < 0) {
+ tclass = np->tclass;
+ if (tclass < 0)
+ tclass = 0;
+ }
+
if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
back_from_confirm:
@@ -834,9 +838,10 @@ back_from_confirm:
do_append_data:
up->len += ulen;
- err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr),
- hlimit, opt, fl, (struct rt6_info*)dst,
- corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
+ err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
+ sizeof(struct udphdr), hlimit, tclass, opt, fl,
+ (struct rt6_info*)dst,
+ corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
if (err)
udp_v6_flush_pending_frames(sk);
else if (!corkreq)
diff --git a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
index 343c5d4..ca7d358 100644
--- a/net/irda/irlan/irlan_filter.c
+++ b/net/irda/irlan/irlan_filter.c
@@ -27,6 +27,7 @@
#include <linux/seq_file.h>
#include <net/irda/irlan_common.h>
+#include <net/irda/irlan_filter.h>
/*
* Function irlan_filter_request (self, skb)
diff --git a/net/irda/qos.c b/net/irda/qos.c
index df732d5..ddfb5c5 100644
--- a/net/irda/qos.c
+++ b/net/irda/qos.c
@@ -37,6 +37,7 @@
#include <net/irda/parameters.h>
#include <net/irda/qos.h>
#include <net/irda/irlap.h>
+#include <net/irda/irlap_frame.h>
/*
* Maximum values of the baud rate we negociate with the other end.
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index e089f17..49a3900 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -344,14 +344,14 @@ static void nfnetlink_rcv(struct sock *sk, int len)
} while(nfnl && nfnl->sk_receive_queue.qlen);
}
-void __exit nfnetlink_exit(void)
+static void __exit nfnetlink_exit(void)
{
printk("Removing netfilter NETLINK layer.\n");
sock_release(nfnl->sk_socket);
return;
}
-int __init nfnetlink_init(void)
+static int __init nfnetlink_init(void)
{
printk("Netfilter messages via NETLINK v%s.\n", nfversion);
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index e3a5285..f81fe8c 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -76,17 +76,6 @@ typedef int (*nfqnl_cmpfn)(struct nfqnl_queue_entry *, unsigned long);
static DEFINE_RWLOCK(instances_lock);
-u_int64_t htonll(u_int64_t in)
-{
- u_int64_t out;
- int i;
-
- for (i = 0; i < sizeof(u_int64_t); i++)
- ((u_int8_t *)&out)[sizeof(u_int64_t)-1] = ((u_int8_t *)&in)[i];
-
- return out;
-}
-
#define INSTANCE_BUCKETS 16
static struct hlist_head instance_table[INSTANCE_BUCKETS];
@@ -382,6 +371,12 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
break;
case NFQNL_COPY_PACKET:
+ if (entry->skb->ip_summed == CHECKSUM_HW &&
+ (*errp = skb_checksum_help(entry->skb,
+ entry->info->outdev == NULL))) {
+ spin_unlock_bh(&queue->lock);
+ return NULL;
+ }
if (queue->copy_range == 0
|| queue->copy_range > entry->skb->len)
data_len = entry->skb->len;
@@ -497,8 +492,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
if (entry->skb->tstamp.off_sec) {
struct nfqnl_msg_packet_timestamp ts;
- ts.sec = htonll(skb_tv_base.tv_sec + entry->skb->tstamp.off_sec);
- ts.usec = htonll(skb_tv_base.tv_usec + entry->skb->tstamp.off_usec);
+ ts.sec = cpu_to_be64(skb_tv_base.tv_sec + entry->skb->tstamp.off_sec);
+ ts.usec = cpu_to_be64(skb_tv_base.tv_usec + entry->skb->tstamp.off_usec);
NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
}
@@ -647,7 +642,7 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
if (!skb_make_writable(&e->skb, data_len))
return -ENOMEM;
memcpy(e->skb->data, data, data_len);
-
+ e->skb->ip_summed = CHECKSUM_NONE;
return 0;
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 62435ff..a64e1d5 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -398,24 +398,13 @@ static int netlink_create(struct socket *sock, int protocol)
if (nl_table[protocol].registered &&
try_module_get(nl_table[protocol].module))
module = nl_table[protocol].module;
- else
- err = -EPROTONOSUPPORT;
groups = nl_table[protocol].groups;
netlink_unlock_table();
- if (err || (err = __netlink_create(sock, protocol) < 0))
+ if ((err = __netlink_create(sock, protocol) < 0))
goto out_module;
nlk = nlk_sk(sock->sk);
-
- nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
- if (nlk->groups == NULL) {
- err = -ENOMEM;
- goto out_module;
- }
- memset(nlk->groups, 0, NLGRPSZ(groups));
- nlk->ngroups = groups;
-
nlk->module = module;
out:
return err;
@@ -534,6 +523,29 @@ netlink_update_subscriptions(struct sock *sk, unsigned int subscriptions)
nlk->subscriptions = subscriptions;
}
+static int netlink_alloc_groups(struct sock *sk)
+{
+ struct netlink_sock *nlk = nlk_sk(sk);
+ unsigned int groups;
+ int err = 0;
+
+ netlink_lock_table();
+ groups = nl_table[sk->sk_protocol].groups;
+ if (!nl_table[sk->sk_protocol].registered)
+ err = -ENOENT;
+ netlink_unlock_table();
+
+ if (err)
+ return err;
+
+ nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
+ if (nlk->groups == NULL)
+ return -ENOMEM;
+ memset(nlk->groups, 0, NLGRPSZ(groups));
+ nlk->ngroups = groups;
+ return 0;
+}
+
static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
struct sock *sk = sock->sk;
@@ -545,8 +557,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len
return -EINVAL;
/* Only superuser is allowed to listen multicasts */
- if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_RECV))
- return -EPERM;
+ if (nladdr->nl_groups) {
+ if (!netlink_capable(sock, NL_NONROOT_RECV))
+ return -EPERM;
+ if (nlk->groups == NULL) {
+ err = netlink_alloc_groups(sk);
+ if (err)
+ return err;
+ }
+ }
if (nlk->pid) {
if (nladdr->nl_pid != nlk->pid)
@@ -559,7 +578,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len
return err;
}
- if (!nladdr->nl_groups && !(u32)nlk->groups[0])
+ if (!nladdr->nl_groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
return 0;
netlink_table_grab();
@@ -620,7 +639,7 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr
nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
} else {
nladdr->nl_pid = nlk->pid;
- nladdr->nl_groups = nlk->groups[0];
+ nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
}
return 0;
}
@@ -976,6 +995,11 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
if (!netlink_capable(sock, NL_NONROOT_RECV))
return -EPERM;
+ if (nlk->groups == NULL) {
+ err = netlink_alloc_groups(sk);
+ if (err)
+ return err;
+ }
if (!val || val - 1 >= nlk->ngroups)
return -EINVAL;
netlink_table_grab();
@@ -1483,8 +1507,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
s,
s->sk_protocol,
nlk->pid,
- nlk->flags & NETLINK_KERNEL_SOCKET ?
- 0 : (unsigned int)nlk->groups[0],
+ nlk->groups ? (u32)nlk->groups[0] : 0,
atomic_read(&s->sk_rmem_alloc),
atomic_read(&s->sk_wmem_alloc),
nlk->cb,
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 4b53de9..f4578c7 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1261,6 +1261,7 @@ static int nr_info_show(struct seq_file *seq, void *v)
struct net_device *dev;
struct nr_sock *nr;
const char *devname;
+ char buf[11];
if (v == SEQ_START_TOKEN)
seq_puts(seq,
@@ -1276,11 +1277,11 @@ static int nr_info_show(struct seq_file *seq, void *v)
else
devname = dev->name;
- seq_printf(seq, "%-9s ", ax2asc(&nr->user_addr));
- seq_printf(seq, "%-9s ", ax2asc(&nr->dest_addr));
+ seq_printf(seq, "%-9s ", ax2asc(buf, &nr->user_addr));
+ seq_printf(seq, "%-9s ", ax2asc(buf, &nr->dest_addr));
seq_printf(seq,
"%-9s %-3s %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %ld\n",
- ax2asc(&nr->source_addr),
+ ax2asc(buf, &nr->source_addr),
devname,
nr->my_index,
nr->my_id,
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
index 165b2ab..e856ae1 100644
--- a/net/netrom/nr_loopback.c
+++ b/net/netrom/nr_loopback.c
@@ -17,7 +17,7 @@
static void nr_loopback_timer(unsigned long);
static struct sk_buff_head loopback_queue;
-static struct timer_list loopback_timer = TIMER_INITIALIZER(nr_loopback_timer, 0, 0);
+static DEFINE_TIMER(loopback_timer, nr_loopback_timer, 0, 0);
void __init nr_loopback_init(void)
{
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 7a86b36..b3b9097 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -881,6 +881,7 @@ static void nr_node_stop(struct seq_file *seq, void *v)
static int nr_node_show(struct seq_file *seq, void *v)
{
+ char buf[11];
int i;
if (v == SEQ_START_TOKEN)
@@ -890,7 +891,7 @@ static int nr_node_show(struct seq_file *seq, void *v)
struct nr_node *nr_node = v;
nr_node_lock(nr_node);
seq_printf(seq, "%-9s %-7s %d %d",
- ax2asc(&nr_node->callsign),
+ ax2asc(buf, &nr_node->callsign),
(nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
nr_node->which + 1,
nr_node->count);
@@ -964,6 +965,7 @@ static void nr_neigh_stop(struct seq_file *seq, void *v)
static int nr_neigh_show(struct seq_file *seq, void *v)
{
+ char buf[11];
int i;
if (v == SEQ_START_TOKEN)
@@ -973,7 +975,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d",
nr_neigh->number,
- ax2asc(&nr_neigh->callsign),
+ ax2asc(buf, &nr_neigh->callsign),
nr_neigh->dev ? nr_neigh->dev->name : "???",
nr_neigh->quality,
nr_neigh->locked,
@@ -983,7 +985,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
if (nr_neigh->digipeat != NULL) {
for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
seq_printf(seq, " %s",
- ax2asc(&nr_neigh->digipeat->calls[i]));
+ ax2asc(buf, &nr_neigh->digipeat->calls[i]));
}
seq_puts(seq, "\n");
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ba99709..8690f17 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1535,8 +1535,7 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
static void packet_mm_open(struct vm_area_struct *vma)
{
struct file *file = vma->vm_file;
- struct inode *inode = file->f_dentry->d_inode;
- struct socket * sock = SOCKET_I(inode);
+ struct socket * sock = file->private_data;
struct sock *sk = sock->sk;
if (sk)
@@ -1546,8 +1545,7 @@ static void packet_mm_open(struct vm_area_struct *vma)
static void packet_mm_close(struct vm_area_struct *vma)
{
struct file *file = vma->vm_file;
- struct inode *inode = file->f_dentry->d_inode;
- struct socket * sock = SOCKET_I(inode);
+ struct socket * sock = file->private_data;
struct sock *sk = sock->sk;
if (sk)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index c6e59f8..3077878 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1363,6 +1363,8 @@ static void rose_info_stop(struct seq_file *seq, void *v)
static int rose_info_show(struct seq_file *seq, void *v)
{
+ char buf[11];
+
if (v == SEQ_START_TOKEN)
seq_puts(seq,
"dest_addr dest_call src_addr src_call dev lci neigh st vs vr va t t1 t2 t3 hb idle Snd-Q Rcv-Q inode\n");
@@ -1380,12 +1382,12 @@ static int rose_info_show(struct seq_file *seq, void *v)
seq_printf(seq, "%-10s %-9s ",
rose2asc(&rose->dest_addr),
- ax2asc(&rose->dest_call));
+ ax2asc(buf, &rose->dest_call));
if (ax25cmp(&rose->source_call, &null_ax25_address) == 0)
callsign = "??????-?";
else
- callsign = ax2asc(&rose->source_call);
+ callsign = ax2asc(buf, &rose->source_call);
seq_printf(seq,
"%-10s %-9s %-5s %3.3X %05d %d %d %d %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n",
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 4510cd76..e556d92 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -851,6 +851,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
unsigned char cause, diagnostic;
struct net_device *dev;
int len, res = 0;
+ char buf[11];
#if 0
if (call_in_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT)
@@ -876,7 +877,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
if (rose_neigh == NULL) {
printk("rose_route : unknown neighbour or device %s\n",
- ax2asc(&ax25->dest_addr));
+ ax2asc(buf, &ax25->dest_addr));
goto out;
}
@@ -1178,6 +1179,7 @@ static void rose_neigh_stop(struct seq_file *seq, void *v)
static int rose_neigh_show(struct seq_file *seq, void *v)
{
+ char buf[11];
int i;
if (v == SEQ_START_TOKEN)
@@ -1189,7 +1191,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
/* if (!rose_neigh->loopback) { */
seq_printf(seq, "%05d %-9s %-4s %3d %3d %3s %3s %3lu %3lu",
rose_neigh->number,
- (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(&rose_neigh->callsign),
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
rose_neigh->dev ? rose_neigh->dev->name : "???",
rose_neigh->count,
rose_neigh->use,
@@ -1200,7 +1202,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
if (rose_neigh->digipeat != NULL) {
for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
- seq_printf(seq, " %s", ax2asc(&rose_neigh->digipeat->calls[i]));
+ seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i]));
}
seq_puts(seq, "\n");
@@ -1260,6 +1262,8 @@ static void rose_route_stop(struct seq_file *seq, void *v)
static int rose_route_show(struct seq_file *seq, void *v)
{
+ char buf[11];
+
if (v == SEQ_START_TOKEN)
seq_puts(seq,
"lci address callsign neigh <-> lci address callsign neigh\n");
@@ -1271,7 +1275,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
"%3.3X %-10s %-9s %05d ",
rose_route->lci1,
rose2asc(&rose_route->src_addr),
- ax2asc(&rose_route->src_call),
+ ax2asc(buf, &rose_route->src_call),
rose_route->neigh1->number);
else
seq_puts(seq,
@@ -1282,7 +1286,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
"%3.3X %-10s %-9s %05d\n",
rose_route->lci2,
rose2asc(&rose_route->dest_addr),
- ax2asc(&rose_route->dest_call),
+ ax2asc(buf, &rose_route->dest_call),
rose_route->neigh2->number);
else
seq_puts(seq,
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index a29a3a9..36a7794 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -337,13 +337,13 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
memcpy(callsign, p + 12, l - 10);
callsign[l - 10] = '\0';
- facilities->source_call = *asc2ax(callsign);
+ asc2ax(&facilities->source_call, callsign);
}
if (*p == FAC_CCITT_SRC_NSAP) {
memcpy(&facilities->dest_addr, p + 7, ROSE_ADDR_LEN);
memcpy(callsign, p + 12, l - 10);
callsign[l - 10] = '\0';
- facilities->dest_call = *asc2ax(callsign);
+ asc2ax(&facilities->dest_call, callsign);
}
p += l + 2;
n += l + 2;
@@ -400,6 +400,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
{
unsigned char *p = buffer + 1;
char *callsign;
+ char buf[11];
int len, nb;
/* National Facilities */
@@ -456,7 +457,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
*p++ = FAC_CCITT_DEST_NSAP;
- callsign = ax2asc(&rose->dest_call);
+ callsign = ax2asc(buf, &rose->dest_call);
*p++ = strlen(callsign) + 10;
*p++ = (strlen(callsign) + 9) * 2; /* ??? */
@@ -471,7 +472,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
*p++ = FAC_CCITT_SRC_NSAP;
- callsign = ax2asc(&rose->source_call);
+ callsign = ax2asc(buf, &rose->source_call);
*p++ = strlen(callsign) + 10;
*p++ = (strlen(callsign) + 9) * 2; /* ??? */
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 737681c..31570b9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1194,7 +1194,7 @@ EXPORT_SYMBOL(psched_time_base);
* with 32-bit get_cycles(). Safe up to 4GHz CPU.
*/
static void psched_tick(unsigned long);
-static struct timer_list psched_timer = TIMER_INITIALIZER(psched_tick, 0, 0);
+static DEFINE_TIMER(psched_timer, psched_tick, 0, 0);
static void psched_tick(unsigned long dummy)
{
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index e47ac0d..e22ccd6 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -193,8 +193,7 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
sctp_unhash_endpoint(ep);
/* Free up the HMAC transform. */
- if (sctp_sk(ep->base.sk)->hmac)
- sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac);
+ sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac);
/* Cleanup. */
sctp_inq_free(&ep->base.inqueue);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 4454afe..91ec8c9 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4194,8 +4194,7 @@ out:
sctp_release_sock(sk);
return err;
cleanup:
- if (tfm)
- sctp_crypto_free_tfm(tfm);
+ sctp_crypto_free_tfm(tfm);
goto out;
}
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index dc48934..75b28dd 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -42,6 +42,7 @@
*/
#include <net/sctp/structs.h>
+#include <net/sctp/sctp.h>
#include <linux/sysctl.h>
static ctl_handler sctp_sysctl_jiffies_ms;
diff --git a/net/socket.c b/net/socket.c
index 94fe638..c699e93 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -667,7 +667,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
}
iocb->private = x;
x->kiocb = iocb;
- sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode);
+ sock = iocb->ki_filp->private_data;
x->async_msg.msg_name = NULL;
x->async_msg.msg_namelen = 0;
@@ -709,7 +709,7 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
}
iocb->private = x;
x->kiocb = iocb;
- sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode);
+ sock = iocb->ki_filp->private_data;
x->async_msg.msg_name = NULL;
x->async_msg.msg_namelen = 0;
@@ -732,7 +732,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
struct socket *sock;
int flags;
- sock = SOCKET_I(file->f_dentry->d_inode);
+ sock = file->private_data;
flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
if (more)
@@ -741,14 +741,14 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
return sock->ops->sendpage(sock, page, offset, size, flags);
}
-static int sock_readv_writev(int type, struct inode * inode,
+static int sock_readv_writev(int type,
struct file * file, const struct iovec * iov,
long count, size_t size)
{
struct msghdr msg;
struct socket *sock;
- sock = SOCKET_I(inode);
+ sock = file->private_data;
msg.msg_name = NULL;
msg.msg_namelen = 0;
@@ -775,7 +775,7 @@ static ssize_t sock_readv(struct file *file, const struct iovec *vector,
int i;
for (i = 0 ; i < count ; i++)
tot_len += vector[i].iov_len;
- return sock_readv_writev(VERIFY_WRITE, file->f_dentry->d_inode,
+ return sock_readv_writev(VERIFY_WRITE,
file, vector, count, tot_len);
}
@@ -786,7 +786,7 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
int i;
for (i = 0 ; i < count ; i++)
tot_len += vector[i].iov_len;
- return sock_readv_writev(VERIFY_READ, file->f_dentry->d_inode,
+ return sock_readv_writev(VERIFY_READ,
file, vector, count, tot_len);
}
@@ -840,7 +840,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
void __user *argp = (void __user *)arg;
int pid, err;
- sock = SOCKET_I(file->f_dentry->d_inode);
+ sock = file->private_data;
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
err = dev_ioctl(cmd, argp);
} else
@@ -939,13 +939,13 @@ static unsigned int sock_poll(struct file *file, poll_table * wait)
/*
* We can't return errors to poll, so it's either yes or no.
*/
- sock = SOCKET_I(file->f_dentry->d_inode);
+ sock = file->private_data;
return sock->ops->poll(file, sock, wait);
}
static int sock_mmap(struct file * file, struct vm_area_struct * vma)
{
- struct socket *sock = SOCKET_I(file->f_dentry->d_inode);
+ struct socket *sock = file->private_data;
return sock->ops->mmap(file, sock, vma);
}
@@ -995,7 +995,7 @@ static int sock_fasync(int fd, struct file *filp, int on)
return -ENOMEM;
}
- sock = SOCKET_I(filp->f_dentry->d_inode);
+ sock = filp->private_data;
if ((sk=sock->sk) == NULL) {
kfree(fna);
@@ -1745,10 +1745,11 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
goto out_freeiov;
ctl_len = msg_sys.msg_controllen;
if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
- err = cmsghdr_from_user_compat_to_kern(&msg_sys, ctl, sizeof(ctl));
+ err = cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl, sizeof(ctl));
if (err)
goto out_freeiov;
ctl_buf = msg_sys.msg_control;
+ ctl_len = msg_sys.msg_controllen;
} else if (ctl_len) {
if (ctl_len > sizeof(ctl))
{
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index 5a7265a..ee6ae74 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -160,7 +160,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
" unsupported checksum %d", cksumtype);
goto out;
}
- if (!(tfm = crypto_alloc_tfm(cksumname, 0)))
+ if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP)))
goto out;
cksum->len = crypto_tfm_alg_digestsize(tfm);
if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL)
@@ -199,8 +199,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
crypto_digest_final(tfm, cksum->data);
code = 0;
out:
- if (tfm)
- crypto_free_tfm(tfm);
+ crypto_free_tfm(tfm);
return code;
}
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index cf72651..606a8a8 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -185,12 +185,9 @@ static void
gss_delete_sec_context_kerberos(void *internal_ctx) {
struct krb5_ctx *kctx = internal_ctx;
- if (kctx->seq)
- crypto_free_tfm(kctx->seq);
- if (kctx->enc)
- crypto_free_tfm(kctx->enc);
- if (kctx->mech_used.data)
- kfree(kctx->mech_used.data);
+ crypto_free_tfm(kctx->seq);
+ crypto_free_tfm(kctx->enc);
+ kfree(kctx->mech_used.data);
kfree(kctx);
}
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index dad0599..6c97d61 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -214,14 +214,10 @@ static void
gss_delete_sec_context_spkm3(void *internal_ctx) {
struct spkm3_ctx *sctx = internal_ctx;
- if(sctx->derived_integ_key)
- crypto_free_tfm(sctx->derived_integ_key);
- if(sctx->derived_conf_key)
- crypto_free_tfm(sctx->derived_conf_key);
- if(sctx->share_key.data)
- kfree(sctx->share_key.data);
- if(sctx->mech_used.data)
- kfree(sctx->mech_used.data);
+ crypto_free_tfm(sctx->derived_integ_key);
+ crypto_free_tfm(sctx->derived_conf_key);
+ kfree(sctx->share_key.data);
+ kfree(sctx->mech_used.data);
kfree(sctx);
}
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 5c8fe3b..e330819 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -250,6 +250,7 @@ out:
}
static struct cache_detail rsi_cache = {
+ .owner = THIS_MODULE,
.hash_size = RSI_HASHMAX,
.hash_table = rsi_table,
.name = "auth.rpcsec.init",
@@ -436,6 +437,7 @@ out:
}
static struct cache_detail rsc_cache = {
+ .owner = THIS_MODULE,
.hash_size = RSC_HASHMAX,
.hash_table = rsc_table,
.name = "auth.rpcsec.context",
@@ -1074,7 +1076,9 @@ gss_svc_init(void)
void
gss_svc_shutdown(void)
{
- cache_unregister(&rsc_cache);
- cache_unregister(&rsi_cache);
+ if (cache_unregister(&rsc_cache))
+ printk(KERN_ERR "auth_rpcgss: failed to unregister rsc cache\n");
+ if (cache_unregister(&rsi_cache))
+ printk(KERN_ERR "auth_rpcgss: failed to unregister rsi cache\n");
svc_auth_unregister(RPC_AUTH_GSS);
}
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 900f5bc..f509e99 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -177,7 +177,7 @@ void cache_register(struct cache_detail *cd)
cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc);
if (cd->proc_ent) {
struct proc_dir_entry *p;
- cd->proc_ent->owner = THIS_MODULE;
+ cd->proc_ent->owner = cd->owner;
cd->channel_ent = cd->content_ent = NULL;
p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR,
@@ -185,7 +185,7 @@ void cache_register(struct cache_detail *cd)
cd->flush_ent = p;
if (p) {
p->proc_fops = &cache_flush_operations;
- p->owner = THIS_MODULE;
+ p->owner = cd->owner;
p->data = cd;
}
@@ -195,7 +195,7 @@ void cache_register(struct cache_detail *cd)
cd->channel_ent = p;
if (p) {
p->proc_fops = &cache_file_operations;
- p->owner = THIS_MODULE;
+ p->owner = cd->owner;
p->data = cd;
}
}
@@ -205,7 +205,7 @@ void cache_register(struct cache_detail *cd)
cd->content_ent = p;
if (p) {
p->proc_fops = &content_file_operations;
- p->owner = THIS_MODULE;
+ p->owner = cd->owner;
p->data = cd;
}
}
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 9b67dc1..4979f22 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -35,13 +35,13 @@ static int rpc_proc_show(struct seq_file *seq, void *v) {
int i, j;
seq_printf(seq,
- "net %d %d %d %d\n",
+ "net %u %u %u %u\n",
statp->netcnt,
statp->netudpcnt,
statp->nettcpcnt,
statp->nettcpconn);
seq_printf(seq,
- "rpc %d %d %d\n",
+ "rpc %u %u %u\n",
statp->rpccnt,
statp->rpcretrans,
statp->rpcauthrefresh);
@@ -50,10 +50,10 @@ static int rpc_proc_show(struct seq_file *seq, void *v) {
const struct rpc_version *vers = prog->version[i];
if (!vers)
continue;
- seq_printf(seq, "proc%d %d",
+ seq_printf(seq, "proc%u %u",
vers->number, vers->nrprocs);
for (j = 0; j < vers->nrprocs; j++)
- seq_printf(seq, " %d",
+ seq_printf(seq, " %u",
vers->procs[j].p_count);
seq_putc(seq, '\n');
}
@@ -83,13 +83,13 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
int i, j;
seq_printf(seq,
- "net %d %d %d %d\n",
+ "net %u %u %u %u\n",
statp->netcnt,
statp->netudpcnt,
statp->nettcpcnt,
statp->nettcpconn);
seq_printf(seq,
- "rpc %d %d %d %d %d\n",
+ "rpc %u %u %u %u %u\n",
statp->rpccnt,
statp->rpcbadfmt+statp->rpcbadauth+statp->rpcbadclnt,
statp->rpcbadfmt,
@@ -99,9 +99,9 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) {
for (i = 0; i < prog->pg_nvers; i++) {
if (!(vers = prog->pg_vers[i]) || !(proc = vers->vs_proc))
continue;
- seq_printf(seq, "proc%d %d", i, vers->vs_nproc);
+ seq_printf(seq, "proc%d %u", i, vers->vs_nproc);
for (j = 0; j < vers->vs_nproc; j++, proc++)
- seq_printf(seq, " %d", proc->pc_count);
+ seq_printf(seq, " %u", proc->pc_count);
seq_putc(seq, '\n');
}
}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 62a0734..ed48ff0 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -176,8 +176,10 @@ cleanup_sunrpc(void)
{
unregister_rpc_pipefs();
rpc_destroy_mempool();
- cache_unregister(&auth_domain_cache);
- cache_unregister(&ip_map_cache);
+ if (cache_unregister(&auth_domain_cache))
+ printk(KERN_ERR "sunrpc: failed to unregister auth_domain cache\n");
+ if (cache_unregister(&ip_map_cache))
+ printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n");
#ifdef RPC_DEBUG
rpc_unregister_sysctl();
#endif
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index bde8147..dda4f0c 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -143,6 +143,7 @@ static void auth_domain_drop(struct cache_head *item, struct cache_detail *cd)
struct cache_detail auth_domain_cache = {
+ .owner = THIS_MODULE,
.hash_size = DN_HASHMAX,
.hash_table = auth_domain_table,
.name = "auth.domain",
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index d6baf6f..cac2e77 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -242,6 +242,7 @@ static int ip_map_show(struct seq_file *m,
struct cache_detail ip_map_cache = {
+ .owner = THIS_MODULE,
.hash_size = IP_HASHMAX,
.hash_table = ip_table,
.name = "auth.unix.ip",
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 83c8135..fda737d 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -765,8 +765,8 @@ restart:
switch (policy->action) {
case XFRM_POLICY_BLOCK:
/* Prohibit the flow */
- xfrm_pol_put(policy);
- return -EPERM;
+ err = -EPERM;
+ goto error;
case XFRM_POLICY_ALLOW:
if (policy->xfrm_nr == 0) {
@@ -782,8 +782,8 @@ restart:
*/
dst = xfrm_find_bundle(fl, policy, family);
if (IS_ERR(dst)) {
- xfrm_pol_put(policy);
- return PTR_ERR(dst);
+ err = PTR_ERR(dst);
+ goto error;
}
if (dst)
OpenPOWER on IntegriCloud