aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-13 20:07:20 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-13 20:07:20 -0400
commitd8ac10639b6a1ed900efbee38c18baaca31e64dc (patch)
tree511a3a60a0828df91658c50a4bffce481ced2454
parentb24fd48a0b9afe9a16bec94ab10d7e83c1b57ce6 (diff)
parent033d974405276c22609c45d50167dd11df20aa82 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
-rw-r--r--drivers/bluetooth/hci_usb.c19
-rw-r--r--drivers/bluetooth/hci_usb.h5
-rw-r--r--include/net/bluetooth/hci.h11
-rw-r--r--net/bluetooth/hci_event.c33
-rw-r--r--net/bluetooth/rfcomm/sock.c30
-rw-r--r--net/dccp/input.c9
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c19
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c6
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c6
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c16
12 files changed, 130 insertions, 36 deletions
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 67d96b5cbb96..57c48bbf6fe6 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,13 +65,15 @@
65#endif 65#endif
66 66
67static int ignore = 0; 67static int ignore = 0;
68static int ignore_csr = 0;
69static int ignore_sniffer = 0;
68static int reset = 0; 70static int reset = 0;
69 71
70#ifdef CONFIG_BT_HCIUSB_SCO 72#ifdef CONFIG_BT_HCIUSB_SCO
71static int isoc = 2; 73static int isoc = 2;
72#endif 74#endif
73 75
74#define VERSION "2.8" 76#define VERSION "2.9"
75 77
76static struct usb_driver hci_usb_driver; 78static struct usb_driver hci_usb_driver;
77 79
@@ -98,6 +100,9 @@ static struct usb_device_id bluetooth_ids[] = {
98MODULE_DEVICE_TABLE (usb, bluetooth_ids); 100MODULE_DEVICE_TABLE (usb, bluetooth_ids);
99 101
100static struct usb_device_id blacklist_ids[] = { 102static struct usb_device_id blacklist_ids[] = {
103 /* CSR BlueCore devices */
104 { USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },
105
101 /* Broadcom BCM2033 without firmware */ 106 /* Broadcom BCM2033 without firmware */
102 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, 107 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
103 108
@@ -836,6 +841,12 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
836 if (ignore || id->driver_info & HCI_IGNORE) 841 if (ignore || id->driver_info & HCI_IGNORE)
837 return -ENODEV; 842 return -ENODEV;
838 843
844 if (ignore_csr && id->driver_info & HCI_CSR)
845 return -ENODEV;
846
847 if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
848 return -ENODEV;
849
839 if (intf->cur_altsetting->desc.bInterfaceNumber > 0) 850 if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
840 return -ENODEV; 851 return -ENODEV;
841 852
@@ -1061,6 +1072,12 @@ module_exit(hci_usb_exit);
1061module_param(ignore, bool, 0644); 1072module_param(ignore, bool, 0644);
1062MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); 1073MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1063 1074
1075module_param(ignore_csr, bool, 0644);
1076MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1077
1078module_param(ignore_sniffer, bool, 0644);
1079MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
1080
1064module_param(reset, bool, 0644); 1081module_param(reset, bool, 0644);
1065MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); 1082MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
1066 1083
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
index 29936b43d4f8..37100a6ea1a8 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -31,9 +31,10 @@
31#define HCI_IGNORE 0x01 31#define HCI_IGNORE 0x01
32#define HCI_RESET 0x02 32#define HCI_RESET 0x02
33#define HCI_DIGIANSWER 0x04 33#define HCI_DIGIANSWER 0x04
34#define HCI_SNIFFER 0x08 34#define HCI_CSR 0x08
35#define HCI_BROKEN_ISOC 0x10 35#define HCI_SNIFFER 0x10
36#define HCI_BCM92035 0x20 36#define HCI_BCM92035 0x20
37#define HCI_BROKEN_ISOC 0x40
37 38
38#define HCI_MAX_IFACE_NUM 3 39#define HCI_MAX_IFACE_NUM 3
39 40
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 371e7d3f2e6f..fa2d12b0579b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -463,6 +463,17 @@ struct inquiry_info_with_rssi_and_pscan_mode {
463 __s8 rssi; 463 __s8 rssi;
464} __attribute__ ((packed)); 464} __attribute__ ((packed));
465 465
466#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2F
467struct extended_inquiry_info {
468 bdaddr_t bdaddr;
469 __u8 pscan_rep_mode;
470 __u8 pscan_period_mode;
471 __u8 dev_class[3];
472 __u16 clock_offset;
473 __s8 rssi;
474 __u8 data[240];
475} __attribute__ ((packed));
476
466#define HCI_EV_CONN_COMPLETE 0x03 477#define HCI_EV_CONN_COMPLETE 0x03
467struct hci_ev_conn_complete { 478struct hci_ev_conn_complete {
468 __u8 status; 479 __u8 status;
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 */
562static 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 */
562static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 591static 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
422done:
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/dccp/input.c b/net/dccp/input.c
index c60bc3433f5e..c74034cf7ede 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -50,7 +50,8 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
50 return; 50 return;
51 } 51 }
52 52
53 dccp_set_state(sk, DCCP_CLOSING); 53 if (sk->sk_state != DCCP_CLOSING)
54 dccp_set_state(sk, DCCP_CLOSING);
54 dccp_send_close(sk, 0); 55 dccp_send_close(sk, 0);
55} 56}
56 57
@@ -561,6 +562,12 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
561 return 0; 562 return 0;
562 } 563 }
563 564
565 if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) {
566 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
567 DCCP_PKT_SYNCACK);
568 goto discard;
569 }
570
564 switch (sk->sk_state) { 571 switch (sk->sk_state) {
565 case DCCP_CLOSED: 572 case DCCP_CLOSED:
566 return 1; 573 return 1;
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;
29static DEFINE_SPINLOCK(ip_ftp_lock); 29static DEFINE_SPINLOCK(ip_ftp_lock);
30 30
31#define MAX_PORTS 8 31#define MAX_PORTS 8
32static int ports[MAX_PORTS]; 32static short ports[MAX_PORTS];
33static int ports_c; 33static int ports_c;
34module_param_array(ports, int, &ports_c, 0400); 34module_param_array(ports, short, &ports_c, 0400);
35 35
36static int loose; 36static int loose;
37module_param(loose, int, 0600); 37module_param(loose, int, 0600);
@@ -450,7 +450,7 @@ out_update_nl:
450} 450}
451 451
452static struct ip_conntrack_helper ftp[MAX_PORTS]; 452static struct ip_conntrack_helper ftp[MAX_PORTS];
453static char ftp_names[MAX_PORTS][10]; 453static char ftp_names[MAX_PORTS][sizeof("ftp-65535")];
454 454
455/* Not __exit: called from init() */ 455/* Not __exit: called from init() */
456static void fini(void) 456static 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
37static int ports[MAX_PORTS]; 37static short ports[MAX_PORTS];
38static int ports_c; 38static int ports_c;
39static int max_dcc_channels = 8; 39static int max_dcc_channels = 8;
40static unsigned int dcc_timeout = 300; 40static unsigned int dcc_timeout = 300;
@@ -52,7 +52,7 @@ EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
52MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 52MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
53MODULE_DESCRIPTION("IRC (DCC) connection tracking helper"); 53MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
54MODULE_LICENSE("GPL"); 54MODULE_LICENSE("GPL");
55module_param_array(ports, int, &ports_c, 0400); 55module_param_array(ports, short, &ports_c, 0400);
56MODULE_PARM_DESC(ports, "port numbers of IRC servers"); 56MODULE_PARM_DESC(ports, "port numbers of IRC servers");
57module_param(max_dcc_channels, int, 0400); 57module_param(max_dcc_channels, int, 0400);
58MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session"); 58MODULE_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
242static struct ip_conntrack_helper irc_helpers[MAX_PORTS]; 242static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
243static char irc_names[MAX_PORTS][10]; 243static char irc_names[MAX_PORTS][sizeof("irc-65535")];
244 244
245static void fini(void); 245static 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
34MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 35MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
35MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); 36MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
36MODULE_LICENSE("GPL"); 37MODULE_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");
26MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
27 27
28#define MAX_PORTS 8 28#define MAX_PORTS 8
29static int ports[MAX_PORTS]; 29static short ports[MAX_PORTS];
30static int ports_c; 30static int ports_c;
31module_param_array(ports, int, &ports_c, 0400); 31module_param_array(ports, short, &ports_c, 0400);
32MODULE_PARM_DESC(ports, "port numbers of tftp servers"); 32MODULE_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
102static struct ip_conntrack_helper tftp[MAX_PORTS]; 102static struct ip_conntrack_helper tftp[MAX_PORTS];
103static char tftp_names[MAX_PORTS][10]; 103static char tftp_names[MAX_PORTS][sizeof("tftp-65535")];
104 104
105static void fini(void) 105static 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. */