diff options
Diffstat (limited to 'net')
27 files changed, 156 insertions, 70 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 65f094845719..bb94e6da223c 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -57,6 +57,7 @@ | |||
57 | static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) | 57 | static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) |
58 | { | 58 | { |
59 | __u8 status; | 59 | __u8 status; |
60 | struct hci_conn *pend; | ||
60 | 61 | ||
61 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); | 62 | BT_DBG("%s ocf 0x%x", hdev->name, ocf); |
62 | 63 | ||
@@ -71,6 +72,15 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb | |||
71 | clear_bit(HCI_INQUIRY, &hdev->flags); | 72 | clear_bit(HCI_INQUIRY, &hdev->flags); |
72 | hci_req_complete(hdev, status); | 73 | hci_req_complete(hdev, status); |
73 | } | 74 | } |
75 | |||
76 | hci_dev_lock(hdev); | ||
77 | |||
78 | pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
79 | if (pend) | ||
80 | hci_acl_connect(pend); | ||
81 | |||
82 | hci_dev_unlock(hdev); | ||
83 | |||
74 | break; | 84 | break; |
75 | 85 | ||
76 | default: | 86 | default: |
@@ -565,11 +575,20 @@ static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status) | |||
565 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 575 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
566 | { | 576 | { |
567 | __u8 status = *((__u8 *) skb->data); | 577 | __u8 status = *((__u8 *) skb->data); |
578 | struct hci_conn *pend; | ||
568 | 579 | ||
569 | BT_DBG("%s status %d", hdev->name, status); | 580 | BT_DBG("%s status %d", hdev->name, status); |
570 | 581 | ||
571 | clear_bit(HCI_INQUIRY, &hdev->flags); | 582 | clear_bit(HCI_INQUIRY, &hdev->flags); |
572 | hci_req_complete(hdev, status); | 583 | hci_req_complete(hdev, status); |
584 | |||
585 | hci_dev_lock(hdev); | ||
586 | |||
587 | pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2); | ||
588 | if (pend) | ||
589 | hci_acl_connect(pend); | ||
590 | |||
591 | hci_dev_unlock(hdev); | ||
573 | } | 592 | } |
574 | 593 | ||
575 | /* Inquiry Result */ | 594 | /* Inquiry Result */ |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index f26a9eb49945..711a085eca5b 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -120,10 +120,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
120 | if (!hci_test_bit(evt, &flt->event_mask)) | 120 | if (!hci_test_bit(evt, &flt->event_mask)) |
121 | continue; | 121 | continue; |
122 | 122 | ||
123 | if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE && | 123 | if (flt->opcode && |
124 | flt->opcode != *(__u16 *)(skb->data + 3)) || | 124 | ((evt == HCI_EV_CMD_COMPLETE && |
125 | (evt == HCI_EV_CMD_STATUS && | 125 | flt->opcode != |
126 | flt->opcode != *(__u16 *)(skb->data + 4)))) | 126 | get_unaligned((__u16 *)(skb->data + 3))) || |
127 | (evt == HCI_EV_CMD_STATUS && | ||
128 | flt->opcode != | ||
129 | get_unaligned((__u16 *)(skb->data + 4))))) | ||
127 | continue; | 130 | continue; |
128 | } | 131 | } |
129 | 132 | ||
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 954eb74eb370..3eeeb7a86e75 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -259,7 +259,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn) | |||
259 | 259 | ||
260 | BT_DBG("conn %p", conn); | 260 | BT_DBG("conn %p", conn); |
261 | 261 | ||
262 | conn->dev.parent = &hdev->dev; | 262 | conn->dev.bus = &bt_bus; |
263 | conn->dev.parent = &hdev->dev; | ||
264 | |||
263 | conn->dev.release = bt_release; | 265 | conn->dev.release = bt_release; |
264 | 266 | ||
265 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, | 267 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 2b3dcb8f90fa..bbf78e6a7bc3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1353,12 +1353,12 @@ static inline int l2cap_conf_output(struct sock *sk, void **ptr) | |||
1353 | 1353 | ||
1354 | /* Configure output options and let the other side know | 1354 | /* Configure output options and let the other side know |
1355 | * which ones we don't like. */ | 1355 | * which ones we don't like. */ |
1356 | if (pi->conf_mtu < pi->omtu) { | 1356 | if (pi->conf_mtu < pi->omtu) |
1357 | l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); | ||
1358 | result = L2CAP_CONF_UNACCEPT; | 1357 | result = L2CAP_CONF_UNACCEPT; |
1359 | } else { | 1358 | else |
1360 | pi->omtu = pi->conf_mtu; | 1359 | pi->omtu = pi->conf_mtu; |
1361 | } | 1360 | |
1361 | l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu); | ||
1362 | 1362 | ||
1363 | BT_DBG("sk %p result %d", sk, result); | 1363 | BT_DBG("sk %p result %d", sk, result); |
1364 | return result; | 1364 | return result; |
@@ -1533,6 +1533,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
1533 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) | 1533 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) |
1534 | return -ENOENT; | 1534 | return -ENOENT; |
1535 | 1535 | ||
1536 | if (sk->sk_state == BT_DISCONN) | ||
1537 | goto unlock; | ||
1538 | |||
1536 | l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); | 1539 | l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); |
1537 | 1540 | ||
1538 | if (flags & 0x0001) { | 1541 | if (flags & 0x0001) { |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index b8e3a5f1c8a8..1fb5d42f37ae 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -765,7 +765,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old) | |||
765 | 765 | ||
766 | BT_DBG("tty %p termios %p", tty, old); | 766 | BT_DBG("tty %p termios %p", tty, old); |
767 | 767 | ||
768 | if (!dev) | 768 | if (!dev || !dev->dlc || !dev->dlc->session) |
769 | return; | 769 | return; |
770 | 770 | ||
771 | /* Handle turning off CRTSCTS */ | 771 | /* Handle turning off CRTSCTS */ |
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 4e4119a12139..4c61a7e0a86e 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c | |||
@@ -58,12 +58,13 @@ static int get_fdb_entries(struct net_bridge *br, void __user *userbuf, | |||
58 | { | 58 | { |
59 | int num; | 59 | int num; |
60 | void *buf; | 60 | void *buf; |
61 | size_t size = maxnum * sizeof(struct __fdb_entry); | 61 | size_t size; |
62 | 62 | ||
63 | if (size > PAGE_SIZE) { | 63 | /* Clamp size to PAGE_SIZE, test maxnum to avoid overflow */ |
64 | size = PAGE_SIZE; | 64 | if (maxnum > PAGE_SIZE/sizeof(struct __fdb_entry)) |
65 | maxnum = PAGE_SIZE/sizeof(struct __fdb_entry); | 65 | maxnum = PAGE_SIZE/sizeof(struct __fdb_entry); |
66 | } | 66 | |
67 | size = maxnum * sizeof(struct __fdb_entry); | ||
67 | 68 | ||
68 | buf = kmalloc(size, GFP_USER); | 69 | buf = kmalloc(size, GFP_USER); |
69 | if (!buf) | 70 | if (!buf) |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index eb0ff7ab05ed..fc4242c0767c 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -277,7 +277,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
277 | __u64 seq; | 277 | __u64 seq; |
278 | 278 | ||
279 | sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, | 279 | sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, |
280 | &hdr->saddr, dh->dccph_sport, skb->dev->ifindex); | 280 | &hdr->saddr, dh->dccph_sport, inet6_iif(skb)); |
281 | 281 | ||
282 | if (sk == NULL) { | 282 | if (sk == NULL) { |
283 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); | 283 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); |
diff --git a/net/dccp/probe.c b/net/dccp/probe.c index 146496fce2e2..fded1493c1dc 100644 --- a/net/dccp/probe.c +++ b/net/dccp/probe.c | |||
@@ -160,6 +160,8 @@ static __init int dccpprobe_init(void) | |||
160 | init_waitqueue_head(&dccpw.wait); | 160 | init_waitqueue_head(&dccpw.wait); |
161 | spin_lock_init(&dccpw.lock); | 161 | spin_lock_init(&dccpw.lock); |
162 | dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock); | 162 | dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock); |
163 | if (IS_ERR(dccpw.fifo)) | ||
164 | return PTR_ERR(dccpw.fifo); | ||
163 | 165 | ||
164 | if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops)) | 166 | if (!proc_net_fops_create(procname, S_IRUSR, &dccpprobe_fops)) |
165 | goto err0; | 167 | goto err0; |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 143c4668538b..8b848aa77bfc 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -225,10 +225,8 @@ __ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple) | |||
225 | struct ip_conntrack_expect *i; | 225 | struct ip_conntrack_expect *i; |
226 | 226 | ||
227 | list_for_each_entry(i, &ip_conntrack_expect_list, list) { | 227 | list_for_each_entry(i, &ip_conntrack_expect_list, list) { |
228 | if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { | 228 | if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) |
229 | atomic_inc(&i->use); | ||
230 | return i; | 229 | return i; |
231 | } | ||
232 | } | 230 | } |
233 | return NULL; | 231 | return NULL; |
234 | } | 232 | } |
@@ -241,6 +239,8 @@ ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple) | |||
241 | 239 | ||
242 | read_lock_bh(&ip_conntrack_lock); | 240 | read_lock_bh(&ip_conntrack_lock); |
243 | i = __ip_conntrack_expect_find(tuple); | 241 | i = __ip_conntrack_expect_find(tuple); |
242 | if (i) | ||
243 | atomic_inc(&i->use); | ||
244 | read_unlock_bh(&ip_conntrack_lock); | 244 | read_unlock_bh(&ip_conntrack_lock); |
245 | 245 | ||
246 | return i; | 246 | return i; |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 7b7441202bfd..6cb9070cd0bc 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | |||
@@ -1417,7 +1417,7 @@ static int process_rcf(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
1417 | DEBUGP | 1417 | DEBUGP |
1418 | ("ip_ct_ras: set RAS connection timeout to %u seconds\n", | 1418 | ("ip_ct_ras: set RAS connection timeout to %u seconds\n", |
1419 | info->timeout); | 1419 | info->timeout); |
1420 | ip_ct_refresh_acct(ct, ctinfo, NULL, info->timeout * HZ); | 1420 | ip_ct_refresh(ct, *pskb, info->timeout * HZ); |
1421 | 1421 | ||
1422 | /* Set expect timeout */ | 1422 | /* Set expect timeout */ |
1423 | read_lock_bh(&ip_conntrack_lock); | 1423 | read_lock_bh(&ip_conntrack_lock); |
@@ -1465,7 +1465,7 @@ static int process_urq(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
1465 | info->sig_port[!dir] = 0; | 1465 | info->sig_port[!dir] = 0; |
1466 | 1466 | ||
1467 | /* Give it 30 seconds for UCF or URJ */ | 1467 | /* Give it 30 seconds for UCF or URJ */ |
1468 | ip_ct_refresh_acct(ct, ctinfo, NULL, 30 * HZ); | 1468 | ip_ct_refresh(ct, *pskb, 30 * HZ); |
1469 | 1469 | ||
1470 | return 0; | 1470 | return 0; |
1471 | } | 1471 | } |
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 262d0d44ec1b..55f0ae641081 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
@@ -153,6 +153,7 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct ip_conntrack *ct) | |||
153 | return ret; | 153 | return ret; |
154 | 154 | ||
155 | nfattr_failure: | 155 | nfattr_failure: |
156 | ip_conntrack_proto_put(proto); | ||
156 | return -1; | 157 | return -1; |
157 | } | 158 | } |
158 | 159 | ||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 7edad790478a..97556cc2e4e0 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -351,9 +351,10 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
351 | if (v->data_len < sizeof(*user_iph)) | 351 | if (v->data_len < sizeof(*user_iph)) |
352 | return 0; | 352 | return 0; |
353 | diff = v->data_len - e->skb->len; | 353 | diff = v->data_len - e->skb->len; |
354 | if (diff < 0) | 354 | if (diff < 0) { |
355 | skb_trim(e->skb, v->data_len); | 355 | if (pskb_trim(e->skb, v->data_len)) |
356 | else if (diff > 0) { | 356 | return -ENOMEM; |
357 | } else if (diff > 0) { | ||
357 | if (v->data_len > 0xFFFF) | 358 | if (v->data_len > 0xFFFF) |
358 | return -EINVAL; | 359 | return -EINVAL; |
359 | if (diff > skb_tailroom(e->skb)) { | 360 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index ad0312d0e4fd..264763adc39b 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -114,6 +114,14 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
114 | tcph->window = 0; | 114 | tcph->window = 0; |
115 | tcph->urg_ptr = 0; | 115 | tcph->urg_ptr = 0; |
116 | 116 | ||
117 | /* Adjust TCP checksum */ | ||
118 | tcph->check = 0; | ||
119 | tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), | ||
120 | nskb->nh.iph->saddr, | ||
121 | nskb->nh.iph->daddr, | ||
122 | csum_partial((char *)tcph, | ||
123 | sizeof(struct tcphdr), 0)); | ||
124 | |||
117 | /* Set DF, id = 0 */ | 125 | /* Set DF, id = 0 */ |
118 | nskb->nh.iph->frag_off = htons(IP_DF); | 126 | nskb->nh.iph->frag_off = htons(IP_DF); |
119 | nskb->nh.iph->id = 0; | 127 | nskb->nh.iph->id = 0; |
@@ -129,14 +137,8 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
129 | if (ip_route_me_harder(&nskb, addr_type)) | 137 | if (ip_route_me_harder(&nskb, addr_type)) |
130 | goto free_nskb; | 138 | goto free_nskb; |
131 | 139 | ||
132 | /* Adjust TCP checksum */ | ||
133 | nskb->ip_summed = CHECKSUM_NONE; | 140 | nskb->ip_summed = CHECKSUM_NONE; |
134 | tcph->check = 0; | 141 | |
135 | tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr), | ||
136 | nskb->nh.iph->saddr, | ||
137 | nskb->nh.iph->daddr, | ||
138 | csum_partial((char *)tcph, | ||
139 | sizeof(struct tcphdr), 0)); | ||
140 | /* Adjust IP TTL */ | 142 | /* Adjust IP TTL */ |
141 | nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); | 143 | nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); |
142 | 144 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4322318ab332..c05e8edaf544 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2316,9 +2316,10 @@ void __init tcp_init(void) | |||
2316 | sysctl_max_syn_backlog = 128; | 2316 | sysctl_max_syn_backlog = 128; |
2317 | } | 2317 | } |
2318 | 2318 | ||
2319 | sysctl_tcp_mem[0] = 768 << order; | 2319 | /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */ |
2320 | sysctl_tcp_mem[1] = 1024 << order; | 2320 | sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order; |
2321 | sysctl_tcp_mem[2] = 1536 << order; | 2321 | sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3; |
2322 | sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; | ||
2322 | 2323 | ||
2323 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); | 2324 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); |
2324 | max_share = min(4UL*1024*1024, limit); | 2325 | max_share = min(4UL*1024*1024, limit); |
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 4be336f17883..f230eeecf092 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
@@ -156,6 +156,8 @@ static __init int tcpprobe_init(void) | |||
156 | init_waitqueue_head(&tcpw.wait); | 156 | init_waitqueue_head(&tcpw.wait); |
157 | spin_lock_init(&tcpw.lock); | 157 | spin_lock_init(&tcpw.lock); |
158 | tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock); | 158 | tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock); |
159 | if (IS_ERR(tcpw.fifo)) | ||
160 | return PTR_ERR(tcpw.fifo); | ||
159 | 161 | ||
160 | if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops)) | 162 | if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops)) |
161 | goto err0; | 163 | goto err0; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 865d75214a9a..9e1bd374875e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -928,23 +928,32 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) | |||
928 | return 1; | 928 | return 1; |
929 | #else | 929 | #else |
930 | struct udp_sock *up = udp_sk(sk); | 930 | struct udp_sock *up = udp_sk(sk); |
931 | struct udphdr *uh = skb->h.uh; | 931 | struct udphdr *uh; |
932 | struct iphdr *iph; | 932 | struct iphdr *iph; |
933 | int iphlen, len; | 933 | int iphlen, len; |
934 | 934 | ||
935 | __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr); | 935 | __u8 *udpdata; |
936 | __be32 *udpdata32 = (__be32 *)udpdata; | 936 | __be32 *udpdata32; |
937 | __u16 encap_type = up->encap_type; | 937 | __u16 encap_type = up->encap_type; |
938 | 938 | ||
939 | /* if we're overly short, let UDP handle it */ | 939 | /* if we're overly short, let UDP handle it */ |
940 | if (udpdata > skb->tail) | 940 | len = skb->len - sizeof(struct udphdr); |
941 | if (len <= 0) | ||
941 | return 1; | 942 | return 1; |
942 | 943 | ||
943 | /* if this is not encapsulated socket, then just return now */ | 944 | /* if this is not encapsulated socket, then just return now */ |
944 | if (!encap_type) | 945 | if (!encap_type) |
945 | return 1; | 946 | return 1; |
946 | 947 | ||
947 | len = skb->tail - udpdata; | 948 | /* If this is a paged skb, make sure we pull up |
949 | * whatever data we need to look at. */ | ||
950 | if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8))) | ||
951 | return 1; | ||
952 | |||
953 | /* Now we can get the pointers */ | ||
954 | uh = skb->h.uh; | ||
955 | udpdata = (__u8 *)uh + sizeof(struct udphdr); | ||
956 | udpdata32 = (__be32 *)udpdata; | ||
948 | 957 | ||
949 | switch (encap_type) { | 958 | switch (encap_type) { |
950 | default: | 959 | default: |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 84d7ebdb9d21..b9f40290d12a 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -542,6 +542,7 @@ ip6ip6_rcv(struct sk_buff *skb) | |||
542 | skb->dev = t->dev; | 542 | skb->dev = t->dev; |
543 | dst_release(skb->dst); | 543 | dst_release(skb->dst); |
544 | skb->dst = NULL; | 544 | skb->dst = NULL; |
545 | nf_reset(skb); | ||
545 | if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) | 546 | if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) |
546 | ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); | 547 | ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); |
547 | ip6ip6_ecn_decapsulate(ipv6h, skb); | 548 | ip6ip6_ecn_decapsulate(ipv6h, skb); |
@@ -1149,6 +1150,20 @@ fail: | |||
1149 | return err; | 1150 | return err; |
1150 | } | 1151 | } |
1151 | 1152 | ||
1153 | static void __exit ip6ip6_destroy_tunnels(void) | ||
1154 | { | ||
1155 | int h; | ||
1156 | struct ip6_tnl *t; | ||
1157 | |||
1158 | for (h = 0; h < HASH_SIZE; h++) { | ||
1159 | while ((t = tnls_r_l[h]) != NULL) | ||
1160 | unregister_netdevice(t->dev); | ||
1161 | } | ||
1162 | |||
1163 | t = tnls_wc[0]; | ||
1164 | unregister_netdevice(t->dev); | ||
1165 | } | ||
1166 | |||
1152 | /** | 1167 | /** |
1153 | * ip6_tunnel_cleanup - free resources and unregister protocol | 1168 | * ip6_tunnel_cleanup - free resources and unregister protocol |
1154 | **/ | 1169 | **/ |
@@ -1158,7 +1173,9 @@ static void __exit ip6_tunnel_cleanup(void) | |||
1158 | if (xfrm6_tunnel_deregister(&ip6ip6_handler)) | 1173 | if (xfrm6_tunnel_deregister(&ip6ip6_handler)) |
1159 | printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); | 1174 | printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); |
1160 | 1175 | ||
1161 | unregister_netdev(ip6ip6_fb_tnl_dev); | 1176 | rtnl_lock(); |
1177 | ip6ip6_destroy_tunnels(); | ||
1178 | rtnl_unlock(); | ||
1162 | } | 1179 | } |
1163 | 1180 | ||
1164 | module_init(ip6_tunnel_init); | 1181 | module_init(ip6_tunnel_init); |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 9510c24ca8d2..9fec832ee08b 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -349,9 +349,10 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
349 | if (v->data_len < sizeof(*user_iph)) | 349 | if (v->data_len < sizeof(*user_iph)) |
350 | return 0; | 350 | return 0; |
351 | diff = v->data_len - e->skb->len; | 351 | diff = v->data_len - e->skb->len; |
352 | if (diff < 0) | 352 | if (diff < 0) { |
353 | skb_trim(e->skb, v->data_len); | 353 | if (pskb_trim(e->skb, v->data_len)) |
354 | else if (diff > 0) { | 354 | return -ENOMEM; |
355 | } else if (diff > 0) { | ||
355 | if (v->data_len > 0xFFFF) | 356 | if (v->data_len > 0xFFFF) |
356 | return -EINVAL; | 357 | return -EINVAL; |
357 | if (diff > skb_tailroom(e->skb)) { | 358 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 167c2ea88f6b..204e02162d49 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -1494,7 +1494,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
1494 | if (_frag_off) { | 1494 | if (_frag_off) { |
1495 | if (target < 0 && | 1495 | if (target < 0 && |
1496 | ((!ipv6_ext_hdr(hp->nexthdr)) || | 1496 | ((!ipv6_ext_hdr(hp->nexthdr)) || |
1497 | nexthdr == NEXTHDR_NONE)) { | 1497 | hp->nexthdr == NEXTHDR_NONE)) { |
1498 | if (fragoff) | 1498 | if (fragoff) |
1499 | *fragoff = _frag_off; | 1499 | *fragoff = _frag_off; |
1500 | return hp->nexthdr; | 1500 | return hp->nexthdr; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c953466b7afd..b39ae99122d5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -330,6 +330,8 @@ static int inline rt6_check_neigh(struct rt6_info *rt) | |||
330 | read_lock_bh(&neigh->lock); | 330 | read_lock_bh(&neigh->lock); |
331 | if (neigh->nud_state & NUD_VALID) | 331 | if (neigh->nud_state & NUD_VALID) |
332 | m = 2; | 332 | m = 2; |
333 | else if (!(neigh->nud_state & NUD_FAILED)) | ||
334 | m = 1; | ||
333 | read_unlock_bh(&neigh->lock); | 335 | read_unlock_bh(&neigh->lock); |
334 | } | 336 | } |
335 | return m; | 337 | return m; |
@@ -347,9 +349,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif, | |||
347 | m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; | 349 | m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; |
348 | #endif | 350 | #endif |
349 | n = rt6_check_neigh(rt); | 351 | n = rt6_check_neigh(rt); |
350 | if (n > 1) | 352 | if (!n && (strict & RT6_LOOKUP_F_REACHABLE)) |
351 | m |= 16; | ||
352 | else if (!n && strict & RT6_LOOKUP_F_REACHABLE) | ||
353 | return -1; | 353 | return -1; |
354 | return m; | 354 | return m; |
355 | } | 355 | } |
@@ -380,10 +380,11 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, | |||
380 | continue; | 380 | continue; |
381 | 381 | ||
382 | if (m > mpri) { | 382 | if (m > mpri) { |
383 | rt6_probe(match); | 383 | if (strict & RT6_LOOKUP_F_REACHABLE) |
384 | rt6_probe(match); | ||
384 | match = rt; | 385 | match = rt; |
385 | mpri = m; | 386 | mpri = m; |
386 | } else { | 387 | } else if (strict & RT6_LOOKUP_F_REACHABLE) { |
387 | rt6_probe(rt); | 388 | rt6_probe(rt); |
388 | } | 389 | } |
389 | } | 390 | } |
@@ -636,7 +637,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, | |||
636 | int strict = 0; | 637 | int strict = 0; |
637 | int attempts = 3; | 638 | int attempts = 3; |
638 | int err; | 639 | int err; |
639 | int reachable = RT6_LOOKUP_F_REACHABLE; | 640 | int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; |
640 | 641 | ||
641 | strict |= flags & RT6_LOOKUP_F_IFACE; | 642 | strict |= flags & RT6_LOOKUP_F_IFACE; |
642 | 643 | ||
@@ -733,7 +734,7 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, | |||
733 | int strict = 0; | 734 | int strict = 0; |
734 | int attempts = 3; | 735 | int attempts = 3; |
735 | int err; | 736 | int err; |
736 | int reachable = RT6_LOOKUP_F_REACHABLE; | 737 | int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE; |
737 | 738 | ||
738 | strict |= flags & RT6_LOOKUP_F_IFACE; | 739 | strict |= flags & RT6_LOOKUP_F_IFACE; |
739 | 740 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e0c3934a7e4b..c83f23e51c46 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -242,14 +242,13 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
242 | { | 242 | { |
243 | struct ipv6_pinfo *np; | 243 | struct ipv6_pinfo *np; |
244 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; | 244 | struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; |
245 | struct net_device *dev = skb->dev; | ||
246 | struct in6_addr *saddr = &hdr->saddr; | 245 | struct in6_addr *saddr = &hdr->saddr; |
247 | struct in6_addr *daddr = &hdr->daddr; | 246 | struct in6_addr *daddr = &hdr->daddr; |
248 | struct udphdr *uh = (struct udphdr*)(skb->data+offset); | 247 | struct udphdr *uh = (struct udphdr*)(skb->data+offset); |
249 | struct sock *sk; | 248 | struct sock *sk; |
250 | int err; | 249 | int err; |
251 | 250 | ||
252 | sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex); | 251 | sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb)); |
253 | 252 | ||
254 | if (sk == NULL) | 253 | if (sk == NULL) |
255 | return; | 254 | return; |
@@ -348,7 +347,7 @@ static void udpv6_mcast_deliver(struct udphdr *uh, | |||
348 | 347 | ||
349 | read_lock(&udp_hash_lock); | 348 | read_lock(&udp_hash_lock); |
350 | sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | 349 | sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); |
351 | dif = skb->dev->ifindex; | 350 | dif = inet6_iif(skb); |
352 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 351 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
353 | if (!sk) { | 352 | if (!sk) { |
354 | kfree_skb(skb); | 353 | kfree_skb(skb); |
@@ -429,7 +428,7 @@ static int udpv6_rcv(struct sk_buff **pskb) | |||
429 | * check socket cache ... must talk to Alan about his plans | 428 | * check socket cache ... must talk to Alan about his plans |
430 | * for sock caches... i'll skip this for now. | 429 | * for sock caches... i'll skip this for now. |
431 | */ | 430 | */ |
432 | sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex); | 431 | sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb)); |
433 | 432 | ||
434 | if (sk == NULL) { | 433 | if (sk == NULL) { |
435 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | 434 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 5073261b9d0c..fede83763095 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c | |||
@@ -1678,7 +1678,8 @@ static int irlmp_slsap_inuse(__u8 slsap_sel) | |||
1678 | * every IrLAP connection and check every LSAP associated with each | 1678 | * every IrLAP connection and check every LSAP associated with each |
1679 | * the connection. | 1679 | * the connection. |
1680 | */ | 1680 | */ |
1681 | spin_lock_irqsave(&irlmp->links->hb_spinlock, flags); | 1681 | spin_lock_irqsave_nested(&irlmp->links->hb_spinlock, flags, |
1682 | SINGLE_DEPTH_NESTING); | ||
1682 | lap = (struct lap_cb *) hashbin_get_first(irlmp->links); | 1683 | lap = (struct lap_cb *) hashbin_get_first(irlmp->links); |
1683 | while (lap != NULL) { | 1684 | while (lap != NULL) { |
1684 | IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); | 1685 | IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 836541e509fe..de0567b1f422 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -469,10 +469,8 @@ __nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) | |||
469 | struct nf_conntrack_expect *i; | 469 | struct nf_conntrack_expect *i; |
470 | 470 | ||
471 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { | 471 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { |
472 | if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { | 472 | if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) |
473 | atomic_inc(&i->use); | ||
474 | return i; | 473 | return i; |
475 | } | ||
476 | } | 474 | } |
477 | return NULL; | 475 | return NULL; |
478 | } | 476 | } |
@@ -485,6 +483,8 @@ nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) | |||
485 | 483 | ||
486 | read_lock_bh(&nf_conntrack_lock); | 484 | read_lock_bh(&nf_conntrack_lock); |
487 | i = __nf_conntrack_expect_find(tuple); | 485 | i = __nf_conntrack_expect_find(tuple); |
486 | if (i) | ||
487 | atomic_inc(&i->use); | ||
488 | read_unlock_bh(&nf_conntrack_lock); | 488 | read_unlock_bh(&nf_conntrack_lock); |
489 | 489 | ||
490 | return i; | 490 | return i; |
@@ -893,12 +893,6 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, | |||
893 | 893 | ||
894 | memset(conntrack, 0, nf_ct_cache[features].size); | 894 | memset(conntrack, 0, nf_ct_cache[features].size); |
895 | conntrack->features = features; | 895 | conntrack->features = features; |
896 | if (helper) { | ||
897 | struct nf_conn_help *help = nfct_help(conntrack); | ||
898 | NF_CT_ASSERT(help); | ||
899 | help->helper = helper; | ||
900 | } | ||
901 | |||
902 | atomic_set(&conntrack->ct_general.use, 1); | 896 | atomic_set(&conntrack->ct_general.use, 1); |
903 | conntrack->ct_general.destroy = destroy_conntrack; | 897 | conntrack->ct_general.destroy = destroy_conntrack; |
904 | conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; | 898 | conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; |
@@ -982,8 +976,13 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
982 | #endif | 976 | #endif |
983 | nf_conntrack_get(&conntrack->master->ct_general); | 977 | nf_conntrack_get(&conntrack->master->ct_general); |
984 | NF_CT_STAT_INC(expect_new); | 978 | NF_CT_STAT_INC(expect_new); |
985 | } else | 979 | } else { |
980 | struct nf_conn_help *help = nfct_help(conntrack); | ||
981 | |||
982 | if (help) | ||
983 | help->helper = __nf_ct_helper_find(&repl_tuple); | ||
986 | NF_CT_STAT_INC(new); | 984 | NF_CT_STAT_INC(new); |
985 | } | ||
987 | 986 | ||
988 | /* Overload tuple linked list to put us in unconfirmed list. */ | 987 | /* Overload tuple linked list to put us in unconfirmed list. */ |
989 | list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); | 988 | list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index bd0156a28ecd..ab67c2be2b5d 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -161,6 +161,7 @@ ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
161 | return ret; | 161 | return ret; |
162 | 162 | ||
163 | nfattr_failure: | 163 | nfattr_failure: |
164 | nf_ct_proto_put(proto); | ||
164 | return -1; | 165 | return -1; |
165 | } | 166 | } |
166 | 167 | ||
@@ -949,6 +950,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
949 | { | 950 | { |
950 | struct nf_conn *ct; | 951 | struct nf_conn *ct; |
951 | int err = -EINVAL; | 952 | int err = -EINVAL; |
953 | struct nf_conn_help *help; | ||
952 | 954 | ||
953 | ct = nf_conntrack_alloc(otuple, rtuple); | 955 | ct = nf_conntrack_alloc(otuple, rtuple); |
954 | if (ct == NULL || IS_ERR(ct)) | 956 | if (ct == NULL || IS_ERR(ct)) |
@@ -976,9 +978,16 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
976 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); | 978 | ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); |
977 | #endif | 979 | #endif |
978 | 980 | ||
981 | help = nfct_help(ct); | ||
982 | if (help) | ||
983 | help->helper = nf_ct_helper_find_get(rtuple); | ||
984 | |||
979 | add_timer(&ct->timeout); | 985 | add_timer(&ct->timeout); |
980 | nf_conntrack_hash_insert(ct); | 986 | nf_conntrack_hash_insert(ct); |
981 | 987 | ||
988 | if (help && help->helper) | ||
989 | nf_ct_helper_put(help->helper); | ||
990 | |||
982 | return 0; | 991 | return 0; |
983 | 992 | ||
984 | err: | 993 | err: |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index b2bf8f2e01da..1e5207b80fe5 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -544,7 +544,7 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
544 | } | 544 | } |
545 | /* global sequence number */ | 545 | /* global sequence number */ |
546 | if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) { | 546 | if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) { |
547 | tmp_uint = atomic_inc_return(&global_seq); | 547 | tmp_uint = htonl(atomic_inc_return(&global_seq)); |
548 | NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); | 548 | NFA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint); |
549 | } | 549 | } |
550 | 550 | ||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 6e4ada3c1844..e815a9aa6e95 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -622,9 +622,10 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) | |||
622 | int diff; | 622 | int diff; |
623 | 623 | ||
624 | diff = data_len - e->skb->len; | 624 | diff = data_len - e->skb->len; |
625 | if (diff < 0) | 625 | if (diff < 0) { |
626 | skb_trim(e->skb, data_len); | 626 | if (pskb_trim(e->skb, data_len)) |
627 | else if (diff > 0) { | 627 | return -ENOMEM; |
628 | } else if (diff > 0) { | ||
628 | if (data_len > 0xFFFF) | 629 | if (data_len > 0xFFFF) |
629 | return -EINVAL; | 630 | return -EINVAL; |
630 | if (diff > skb_tailroom(e->skb)) { | 631 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b43e7647e125..2ee14f8a1908 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -495,6 +495,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, | |||
495 | goto out; | 495 | goto out; |
496 | } | 496 | } |
497 | 497 | ||
498 | err = -ESRCH; | ||
498 | x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto, | 499 | x = xfrm_state_lookup_byaddr(&p->daddr, saddr, p->proto, |
499 | p->family); | 500 | p->family); |
500 | } | 501 | } |
@@ -1927,6 +1928,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
1927 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 1928 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
1928 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); | 1929 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); |
1929 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | 1930 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); |
1931 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
1932 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
1933 | #endif | ||
1930 | skb = alloc_skb(len, GFP_ATOMIC); | 1934 | skb = alloc_skb(len, GFP_ATOMIC); |
1931 | if (skb == NULL) | 1935 | if (skb == NULL) |
1932 | return -ENOMEM; | 1936 | return -ENOMEM; |
@@ -2034,6 +2038,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve | |||
2034 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 2038 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
2035 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); | 2039 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); |
2036 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | 2040 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); |
2041 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
2042 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
2043 | #endif | ||
2037 | skb = alloc_skb(len, GFP_ATOMIC); | 2044 | skb = alloc_skb(len, GFP_ATOMIC); |
2038 | if (skb == NULL) | 2045 | if (skb == NULL) |
2039 | return -ENOMEM; | 2046 | return -ENOMEM; |
@@ -2060,6 +2067,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * | |||
2060 | len += RTA_SPACE(headlen); | 2067 | len += RTA_SPACE(headlen); |
2061 | headlen = sizeof(*id); | 2068 | headlen = sizeof(*id); |
2062 | } | 2069 | } |
2070 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
2071 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
2072 | #endif | ||
2063 | len += NLMSG_SPACE(headlen); | 2073 | len += NLMSG_SPACE(headlen); |
2064 | 2074 | ||
2065 | skb = alloc_skb(len, GFP_ATOMIC); | 2075 | skb = alloc_skb(len, GFP_ATOMIC); |
@@ -2106,10 +2116,12 @@ static int xfrm_notify_policy_flush(struct km_event *c) | |||
2106 | struct nlmsghdr *nlh; | 2116 | struct nlmsghdr *nlh; |
2107 | struct sk_buff *skb; | 2117 | struct sk_buff *skb; |
2108 | unsigned char *b; | 2118 | unsigned char *b; |
2119 | int len = 0; | ||
2109 | #ifdef CONFIG_XFRM_SUB_POLICY | 2120 | #ifdef CONFIG_XFRM_SUB_POLICY |
2110 | struct xfrm_userpolicy_type upt; | 2121 | struct xfrm_userpolicy_type upt; |
2122 | len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); | ||
2111 | #endif | 2123 | #endif |
2112 | int len = NLMSG_LENGTH(0); | 2124 | len += NLMSG_LENGTH(0); |
2113 | 2125 | ||
2114 | skb = alloc_skb(len, GFP_ATOMIC); | 2126 | skb = alloc_skb(len, GFP_ATOMIC); |
2115 | if (skb == NULL) | 2127 | if (skb == NULL) |