diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_event.c | 33 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 30 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_ftp.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_irc.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_netbios_ns.c | 19 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_tftp.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_MASQUERADE.c | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_REDIRECT.c | 16 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 83 |
9 files changed, 129 insertions, 76 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d6da0939216d..b61b4e8e36fd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -558,6 +558,35 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
558 | hci_dev_unlock(hdev); | 558 | hci_dev_unlock(hdev); |
559 | } | 559 | } |
560 | 560 | ||
561 | /* Extended Inquiry Result */ | ||
562 | static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
563 | { | ||
564 | struct inquiry_data data; | ||
565 | struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1); | ||
566 | int num_rsp = *((__u8 *) skb->data); | ||
567 | |||
568 | BT_DBG("%s num_rsp %d", hdev->name, num_rsp); | ||
569 | |||
570 | if (!num_rsp) | ||
571 | return; | ||
572 | |||
573 | hci_dev_lock(hdev); | ||
574 | |||
575 | for (; num_rsp; num_rsp--) { | ||
576 | bacpy(&data.bdaddr, &info->bdaddr); | ||
577 | data.pscan_rep_mode = info->pscan_rep_mode; | ||
578 | data.pscan_period_mode = info->pscan_period_mode; | ||
579 | data.pscan_mode = 0x00; | ||
580 | memcpy(data.dev_class, info->dev_class, 3); | ||
581 | data.clock_offset = info->clock_offset; | ||
582 | data.rssi = info->rssi; | ||
583 | info++; | ||
584 | hci_inquiry_cache_update(hdev, &data); | ||
585 | } | ||
586 | |||
587 | hci_dev_unlock(hdev); | ||
588 | } | ||
589 | |||
561 | /* Connect Request */ | 590 | /* Connect Request */ |
562 | static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 591 | static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
563 | { | 592 | { |
@@ -940,6 +969,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
940 | hci_inquiry_result_with_rssi_evt(hdev, skb); | 969 | hci_inquiry_result_with_rssi_evt(hdev, skb); |
941 | break; | 970 | break; |
942 | 971 | ||
972 | case HCI_EV_EXTENDED_INQUIRY_RESULT: | ||
973 | hci_extended_inquiry_result_evt(hdev, skb); | ||
974 | break; | ||
975 | |||
943 | case HCI_EV_CONN_REQUEST: | 976 | case HCI_EV_CONN_REQUEST: |
944 | hci_conn_request_evt(hdev, skb); | 977 | hci_conn_request_evt(hdev, skb); |
945 | break; | 978 | break; |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 90e19eb6d3cc..f49e7e938bfb 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -363,6 +363,11 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr | |||
363 | goto done; | 363 | goto done; |
364 | } | 364 | } |
365 | 365 | ||
366 | if (sk->sk_type != SOCK_STREAM) { | ||
367 | err = -EINVAL; | ||
368 | goto done; | ||
369 | } | ||
370 | |||
366 | write_lock_bh(&rfcomm_sk_list.lock); | 371 | write_lock_bh(&rfcomm_sk_list.lock); |
367 | 372 | ||
368 | if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { | 373 | if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { |
@@ -393,13 +398,17 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a | |||
393 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc)) | 398 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc)) |
394 | return -EINVAL; | 399 | return -EINVAL; |
395 | 400 | ||
396 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) | 401 | lock_sock(sk); |
397 | return -EBADFD; | ||
398 | 402 | ||
399 | if (sk->sk_type != SOCK_STREAM) | 403 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) { |
400 | return -EINVAL; | 404 | err = -EBADFD; |
405 | goto done; | ||
406 | } | ||
401 | 407 | ||
402 | lock_sock(sk); | 408 | if (sk->sk_type != SOCK_STREAM) { |
409 | err = -EINVAL; | ||
410 | goto done; | ||
411 | } | ||
403 | 412 | ||
404 | sk->sk_state = BT_CONNECT; | 413 | sk->sk_state = BT_CONNECT; |
405 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); | 414 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); |
@@ -410,6 +419,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a | |||
410 | err = bt_sock_wait_state(sk, BT_CONNECTED, | 419 | err = bt_sock_wait_state(sk, BT_CONNECTED, |
411 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | 420 | sock_sndtimeo(sk, flags & O_NONBLOCK)); |
412 | 421 | ||
422 | done: | ||
413 | release_sock(sk); | 423 | release_sock(sk); |
414 | return err; | 424 | return err; |
415 | } | 425 | } |
@@ -428,6 +438,11 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) | |||
428 | goto done; | 438 | goto done; |
429 | } | 439 | } |
430 | 440 | ||
441 | if (sk->sk_type != SOCK_STREAM) { | ||
442 | err = -EINVAL; | ||
443 | goto done; | ||
444 | } | ||
445 | |||
431 | if (!rfcomm_pi(sk)->channel) { | 446 | if (!rfcomm_pi(sk)->channel) { |
432 | bdaddr_t *src = &bt_sk(sk)->src; | 447 | bdaddr_t *src = &bt_sk(sk)->src; |
433 | u8 channel; | 448 | u8 channel; |
@@ -472,6 +487,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
472 | goto done; | 487 | goto done; |
473 | } | 488 | } |
474 | 489 | ||
490 | if (sk->sk_type != SOCK_STREAM) { | ||
491 | err = -EINVAL; | ||
492 | goto done; | ||
493 | } | ||
494 | |||
475 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | 495 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
476 | 496 | ||
477 | BT_DBG("sk %p timeo %ld", sk, timeo); | 497 | BT_DBG("sk %p timeo %ld", sk, timeo); |
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 1b79ec36085f..d77d6b3f5f80 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c | |||
@@ -29,9 +29,9 @@ static char *ftp_buffer; | |||
29 | static DEFINE_SPINLOCK(ip_ftp_lock); | 29 | static DEFINE_SPINLOCK(ip_ftp_lock); |
30 | 30 | ||
31 | #define MAX_PORTS 8 | 31 | #define MAX_PORTS 8 |
32 | static int ports[MAX_PORTS]; | 32 | static short ports[MAX_PORTS]; |
33 | static int ports_c; | 33 | static int ports_c; |
34 | module_param_array(ports, int, &ports_c, 0400); | 34 | module_param_array(ports, short, &ports_c, 0400); |
35 | 35 | ||
36 | static int loose; | 36 | static int loose; |
37 | module_param(loose, int, 0600); | 37 | module_param(loose, int, 0600); |
@@ -450,7 +450,7 @@ out_update_nl: | |||
450 | } | 450 | } |
451 | 451 | ||
452 | static struct ip_conntrack_helper ftp[MAX_PORTS]; | 452 | static struct ip_conntrack_helper ftp[MAX_PORTS]; |
453 | static char ftp_names[MAX_PORTS][10]; | 453 | static char ftp_names[MAX_PORTS][sizeof("ftp-65535")]; |
454 | 454 | ||
455 | /* Not __exit: called from init() */ | 455 | /* Not __exit: called from init() */ |
456 | static void fini(void) | 456 | static void fini(void) |
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index d7a8a98c05e1..15457415a4f3 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
35 | 35 | ||
36 | #define MAX_PORTS 8 | 36 | #define MAX_PORTS 8 |
37 | static int ports[MAX_PORTS]; | 37 | static short ports[MAX_PORTS]; |
38 | static int ports_c; | 38 | static int ports_c; |
39 | static int max_dcc_channels = 8; | 39 | static int max_dcc_channels = 8; |
40 | static unsigned int dcc_timeout = 300; | 40 | static unsigned int dcc_timeout = 300; |
@@ -52,7 +52,7 @@ EXPORT_SYMBOL_GPL(ip_nat_irc_hook); | |||
52 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | 52 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); |
53 | MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); | 53 | MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); |
54 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
55 | module_param_array(ports, int, &ports_c, 0400); | 55 | module_param_array(ports, short, &ports_c, 0400); |
56 | MODULE_PARM_DESC(ports, "port numbers of IRC servers"); | 56 | MODULE_PARM_DESC(ports, "port numbers of IRC servers"); |
57 | module_param(max_dcc_channels, int, 0400); | 57 | module_param(max_dcc_channels, int, 0400); |
58 | MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); | 58 | MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); |
@@ -240,7 +240,7 @@ static int help(struct sk_buff **pskb, | |||
240 | } | 240 | } |
241 | 241 | ||
242 | static struct ip_conntrack_helper irc_helpers[MAX_PORTS]; | 242 | static struct ip_conntrack_helper irc_helpers[MAX_PORTS]; |
243 | static char irc_names[MAX_PORTS][10]; | 243 | static char irc_names[MAX_PORTS][sizeof("irc-65535")]; |
244 | 244 | ||
245 | static void fini(void); | 245 | static void fini(void); |
246 | 246 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c index bb7246683b74..71ef19d126d0 100644 --- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c +++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/inetdevice.h> | 23 | #include <linux/inetdevice.h> |
24 | #include <linux/in.h> | 24 | #include <linux/in.h> |
25 | #include <linux/ip.h> | 25 | #include <linux/ip.h> |
26 | #include <linux/udp.h> | ||
27 | #include <net/route.h> | 26 | #include <net/route.h> |
28 | 27 | ||
29 | #include <linux/netfilter.h> | 28 | #include <linux/netfilter.h> |
@@ -31,6 +30,8 @@ | |||
31 | #include <linux/netfilter_ipv4/ip_conntrack.h> | 30 | #include <linux/netfilter_ipv4/ip_conntrack.h> |
32 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 31 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
33 | 32 | ||
33 | #define NMBD_PORT 137 | ||
34 | |||
34 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | 35 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); |
35 | MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); | 36 | MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); |
36 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
@@ -44,7 +45,6 @@ static int help(struct sk_buff **pskb, | |||
44 | { | 45 | { |
45 | struct ip_conntrack_expect *exp; | 46 | struct ip_conntrack_expect *exp; |
46 | struct iphdr *iph = (*pskb)->nh.iph; | 47 | struct iphdr *iph = (*pskb)->nh.iph; |
47 | struct udphdr _uh, *uh; | ||
48 | struct rtable *rt = (struct rtable *)(*pskb)->dst; | 48 | struct rtable *rt = (struct rtable *)(*pskb)->dst; |
49 | struct in_device *in_dev; | 49 | struct in_device *in_dev; |
50 | u_int32_t mask = 0; | 50 | u_int32_t mask = 0; |
@@ -72,20 +72,15 @@ static int help(struct sk_buff **pskb, | |||
72 | if (mask == 0) | 72 | if (mask == 0) |
73 | goto out; | 73 | goto out; |
74 | 74 | ||
75 | uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh); | ||
76 | BUG_ON(uh == NULL); | ||
77 | |||
78 | exp = ip_conntrack_expect_alloc(ct); | 75 | exp = ip_conntrack_expect_alloc(ct); |
79 | if (exp == NULL) | 76 | if (exp == NULL) |
80 | goto out; | 77 | goto out; |
81 | memset(&exp->tuple, 0, sizeof(exp->tuple)); | ||
82 | exp->tuple.src.ip = iph->daddr & mask; | ||
83 | exp->tuple.dst.ip = iph->saddr; | ||
84 | exp->tuple.dst.u.udp.port = uh->source; | ||
85 | exp->tuple.dst.protonum = IPPROTO_UDP; | ||
86 | 78 | ||
87 | memset(&exp->mask, 0, sizeof(exp->mask)); | 79 | exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
80 | exp->tuple.src.u.udp.port = ntohs(NMBD_PORT); | ||
81 | |||
88 | exp->mask.src.ip = mask; | 82 | exp->mask.src.ip = mask; |
83 | exp->mask.src.u.udp.port = 0xFFFF; | ||
89 | exp->mask.dst.ip = 0xFFFFFFFF; | 84 | exp->mask.dst.ip = 0xFFFFFFFF; |
90 | exp->mask.dst.u.udp.port = 0xFFFF; | 85 | exp->mask.dst.u.udp.port = 0xFFFF; |
91 | exp->mask.dst.protonum = 0xFF; | 86 | exp->mask.dst.protonum = 0xFF; |
@@ -107,7 +102,7 @@ static struct ip_conntrack_helper helper = { | |||
107 | .src = { | 102 | .src = { |
108 | .u = { | 103 | .u = { |
109 | .udp = { | 104 | .udp = { |
110 | .port = __constant_htons(137), | 105 | .port = __constant_htons(NMBD_PORT), |
111 | } | 106 | } |
112 | } | 107 | } |
113 | }, | 108 | }, |
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index d2b590533452..a78736b8525d 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c | |||
@@ -26,9 +26,9 @@ MODULE_DESCRIPTION("tftp connection tracking helper"); | |||
26 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
27 | 27 | ||
28 | #define MAX_PORTS 8 | 28 | #define MAX_PORTS 8 |
29 | static int ports[MAX_PORTS]; | 29 | static short ports[MAX_PORTS]; |
30 | static int ports_c; | 30 | static int ports_c; |
31 | module_param_array(ports, int, &ports_c, 0400); | 31 | module_param_array(ports, short, &ports_c, 0400); |
32 | MODULE_PARM_DESC(ports, "port numbers of tftp servers"); | 32 | MODULE_PARM_DESC(ports, "port numbers of tftp servers"); |
33 | 33 | ||
34 | #if 0 | 34 | #if 0 |
@@ -100,7 +100,7 @@ static int tftp_help(struct sk_buff **pskb, | |||
100 | } | 100 | } |
101 | 101 | ||
102 | static struct ip_conntrack_helper tftp[MAX_PORTS]; | 102 | static struct ip_conntrack_helper tftp[MAX_PORTS]; |
103 | static char tftp_names[MAX_PORTS][10]; | 103 | static char tftp_names[MAX_PORTS][sizeof("tftp-65535")]; |
104 | 104 | ||
105 | static void fini(void) | 105 | static void fini(void) |
106 | { | 106 | { |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 2f3e181c8e97..275a174c6fe6 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -90,6 +90,12 @@ masquerade_target(struct sk_buff **pskb, | |||
90 | IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED | 90 | IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED |
91 | || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); | 91 | || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); |
92 | 92 | ||
93 | /* Source address is 0.0.0.0 - locally generated packet that is | ||
94 | * probably not supposed to be masqueraded. | ||
95 | */ | ||
96 | if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == 0) | ||
97 | return NF_ACCEPT; | ||
98 | |||
93 | mr = targinfo; | 99 | mr = targinfo; |
94 | rt = (struct rtable *)(*pskb)->dst; | 100 | rt = (struct rtable *)(*pskb)->dst; |
95 | newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE); | 101 | newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE); |
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index d2e13447678e..715cb613405c 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -88,14 +88,18 @@ redirect_target(struct sk_buff **pskb, | |||
88 | newdst = htonl(0x7F000001); | 88 | newdst = htonl(0x7F000001); |
89 | else { | 89 | else { |
90 | struct in_device *indev; | 90 | struct in_device *indev; |
91 | struct in_ifaddr *ifa; | ||
91 | 92 | ||
92 | /* Device might not have an associated in_device. */ | 93 | newdst = 0; |
93 | indev = (struct in_device *)(*pskb)->dev->ip_ptr; | 94 | |
94 | if (indev == NULL || indev->ifa_list == NULL) | 95 | rcu_read_lock(); |
95 | return NF_DROP; | 96 | indev = __in_dev_get((*pskb)->dev); |
97 | if (indev && (ifa = indev->ifa_list)) | ||
98 | newdst = ifa->ifa_local; | ||
99 | rcu_read_unlock(); | ||
96 | 100 | ||
97 | /* Grab first address on interface. */ | 101 | if (!newdst) |
98 | newdst = indev->ifa_list->ifa_local; | 102 | return NF_DROP; |
99 | } | 103 | } |
100 | 104 | ||
101 | /* Transfer from original range. */ | 105 | /* Transfer from original range. */ |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 51885b5f744e..30ec3efc48a6 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -512,15 +512,14 @@ svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv) | |||
512 | static void | 512 | static void |
513 | svc_udp_data_ready(struct sock *sk, int count) | 513 | svc_udp_data_ready(struct sock *sk, int count) |
514 | { | 514 | { |
515 | struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data); | 515 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
516 | 516 | ||
517 | if (!svsk) | 517 | if (svsk) { |
518 | goto out; | 518 | dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n", |
519 | dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n", | 519 | svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags)); |
520 | svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags)); | 520 | set_bit(SK_DATA, &svsk->sk_flags); |
521 | set_bit(SK_DATA, &svsk->sk_flags); | 521 | svc_sock_enqueue(svsk); |
522 | svc_sock_enqueue(svsk); | 522 | } |
523 | out: | ||
524 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 523 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
525 | wake_up_interruptible(sk->sk_sleep); | 524 | wake_up_interruptible(sk->sk_sleep); |
526 | } | 525 | } |
@@ -540,7 +539,7 @@ svc_write_space(struct sock *sk) | |||
540 | } | 539 | } |
541 | 540 | ||
542 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) { | 541 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) { |
543 | printk(KERN_WARNING "RPC svc_write_space: some sleeping on %p\n", | 542 | dprintk("RPC svc_write_space: someone sleeping on %p\n", |
544 | svsk); | 543 | svsk); |
545 | wake_up_interruptible(sk->sk_sleep); | 544 | wake_up_interruptible(sk->sk_sleep); |
546 | } | 545 | } |
@@ -692,31 +691,29 @@ svc_udp_init(struct svc_sock *svsk) | |||
692 | static void | 691 | static void |
693 | svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | 692 | svc_tcp_listen_data_ready(struct sock *sk, int count_unused) |
694 | { | 693 | { |
695 | struct svc_sock *svsk; | 694 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
696 | 695 | ||
697 | dprintk("svc: socket %p TCP (listen) state change %d\n", | 696 | dprintk("svc: socket %p TCP (listen) state change %d\n", |
698 | sk, sk->sk_state); | 697 | sk, sk->sk_state); |
699 | 698 | ||
700 | if (sk->sk_state != TCP_LISTEN) { | 699 | /* |
701 | /* | 700 | * This callback may called twice when a new connection |
702 | * This callback may called twice when a new connection | 701 | * is established as a child socket inherits everything |
703 | * is established as a child socket inherits everything | 702 | * from a parent LISTEN socket. |
704 | * from a parent LISTEN socket. | 703 | * 1) data_ready method of the parent socket will be called |
705 | * 1) data_ready method of the parent socket will be called | 704 | * when one of child sockets become ESTABLISHED. |
706 | * when one of child sockets become ESTABLISHED. | 705 | * 2) data_ready method of the child socket may be called |
707 | * 2) data_ready method of the child socket may be called | 706 | * when it receives data before the socket is accepted. |
708 | * when it receives data before the socket is accepted. | 707 | * In case of 2, we should ignore it silently. |
709 | * In case of 2, we should ignore it silently. | 708 | */ |
710 | */ | 709 | if (sk->sk_state == TCP_LISTEN) { |
711 | goto out; | 710 | if (svsk) { |
712 | } | 711 | set_bit(SK_CONN, &svsk->sk_flags); |
713 | if (!(svsk = (struct svc_sock *) sk->sk_user_data)) { | 712 | svc_sock_enqueue(svsk); |
714 | printk("svc: socket %p: no user data\n", sk); | 713 | } else |
715 | goto out; | 714 | printk("svc: socket %p: no user data\n", sk); |
716 | } | 715 | } |
717 | set_bit(SK_CONN, &svsk->sk_flags); | 716 | |
718 | svc_sock_enqueue(svsk); | ||
719 | out: | ||
720 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 717 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
721 | wake_up_interruptible_all(sk->sk_sleep); | 718 | wake_up_interruptible_all(sk->sk_sleep); |
722 | } | 719 | } |
@@ -727,18 +724,17 @@ svc_tcp_listen_data_ready(struct sock *sk, int count_unused) | |||
727 | static void | 724 | static void |
728 | svc_tcp_state_change(struct sock *sk) | 725 | svc_tcp_state_change(struct sock *sk) |
729 | { | 726 | { |
730 | struct svc_sock *svsk; | 727 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
731 | 728 | ||
732 | dprintk("svc: socket %p TCP (connected) state change %d (svsk %p)\n", | 729 | dprintk("svc: socket %p TCP (connected) state change %d (svsk %p)\n", |
733 | sk, sk->sk_state, sk->sk_user_data); | 730 | sk, sk->sk_state, sk->sk_user_data); |
734 | 731 | ||
735 | if (!(svsk = (struct svc_sock *) sk->sk_user_data)) { | 732 | if (!svsk) |
736 | printk("svc: socket %p: no user data\n", sk); | 733 | printk("svc: socket %p: no user data\n", sk); |
737 | goto out; | 734 | else { |
735 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
736 | svc_sock_enqueue(svsk); | ||
738 | } | 737 | } |
739 | set_bit(SK_CLOSE, &svsk->sk_flags); | ||
740 | svc_sock_enqueue(svsk); | ||
741 | out: | ||
742 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 738 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
743 | wake_up_interruptible_all(sk->sk_sleep); | 739 | wake_up_interruptible_all(sk->sk_sleep); |
744 | } | 740 | } |
@@ -746,15 +742,14 @@ svc_tcp_state_change(struct sock *sk) | |||
746 | static void | 742 | static void |
747 | svc_tcp_data_ready(struct sock *sk, int count) | 743 | svc_tcp_data_ready(struct sock *sk, int count) |
748 | { | 744 | { |
749 | struct svc_sock * svsk; | 745 | struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; |
750 | 746 | ||
751 | dprintk("svc: socket %p TCP data ready (svsk %p)\n", | 747 | dprintk("svc: socket %p TCP data ready (svsk %p)\n", |
752 | sk, sk->sk_user_data); | 748 | sk, sk->sk_user_data); |
753 | if (!(svsk = (struct svc_sock *)(sk->sk_user_data))) | 749 | if (svsk) { |
754 | goto out; | 750 | set_bit(SK_DATA, &svsk->sk_flags); |
755 | set_bit(SK_DATA, &svsk->sk_flags); | 751 | svc_sock_enqueue(svsk); |
756 | svc_sock_enqueue(svsk); | 752 | } |
757 | out: | ||
758 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 753 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) |
759 | wake_up_interruptible(sk->sk_sleep); | 754 | wake_up_interruptible(sk->sk_sleep); |
760 | } | 755 | } |