diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-12-01 09:58:15 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-12-01 09:58:15 -0500 |
commit | b00615d163cd24fa98d155acfc1f9d81d6fe1103 (patch) | |
tree | dde815788aaea3e336aaaf24763311ce63a22e1b /net | |
parent | 75639e7ee1401b3876c7a00ffe96ea8027668690 (diff) | |
parent | d6797322231af98b9bb4afb175dd614cf511e5f7 (diff) |
Merge branch 'topic/pcm-dma-fix' into topic/core-change
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan.c | 7 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 1 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 13 | ||||
-rw-r--r-- | net/bridge/br_if.c | 6 | ||||
-rw-r--r-- | net/can/bcm.c | 19 | ||||
-rw-r--r-- | net/core/dev.c | 11 | ||||
-rw-r--r-- | net/core/skbuff.c | 3 | ||||
-rw-r--r-- | net/decnet/sysctl_net_decnet.c | 7 | ||||
-rw-r--r-- | net/ipv4/ipip.c | 32 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_core.c | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_helper.c | 34 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 19 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 8 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 64 | ||||
-rw-r--r-- | net/netfilter/xt_connlimit.c | 10 | ||||
-rw-r--r-- | net/rose/rose_route.c | 16 | ||||
-rw-r--r-- | net/sctp/associola.c | 4 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 15 | ||||
-rw-r--r-- | net/sctp/socket.c | 40 | ||||
-rw-r--r-- | net/sctp/transport.c | 3 | ||||
-rw-r--r-- | net/sunrpc/addr.c | 18 |
22 files changed, 190 insertions, 147 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 8836575f9d79..a29c5ab5815c 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -281,8 +281,11 @@ out_uninit_applicant: | |||
281 | if (ngrp) | 281 | if (ngrp) |
282 | vlan_gvrp_uninit_applicant(real_dev); | 282 | vlan_gvrp_uninit_applicant(real_dev); |
283 | out_free_group: | 283 | out_free_group: |
284 | if (ngrp) | 284 | if (ngrp) { |
285 | vlan_group_free(ngrp); | 285 | hlist_del_rcu(&ngrp->hlist); |
286 | /* Free the group, after all cpu's are done. */ | ||
287 | call_rcu(&ngrp->rcu, vlan_rcu_free); | ||
288 | } | ||
286 | return err; | 289 | return err; |
287 | } | 290 | } |
288 | 291 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index a9750984f772..b7c4224f4e7d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -211,6 +211,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
211 | conn->type = type; | 211 | conn->type = type; |
212 | conn->mode = HCI_CM_ACTIVE; | 212 | conn->mode = HCI_CM_ACTIVE; |
213 | conn->state = BT_OPEN; | 213 | conn->state = BT_OPEN; |
214 | conn->auth_type = HCI_AT_GENERAL_BONDING; | ||
214 | 215 | ||
215 | conn->power_save = 1; | 216 | conn->power_save = 1; |
216 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 217 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 77e9fb130adb..947f8bbb4bb3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -2205,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
2205 | { | 2205 | { |
2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
2207 | struct l2cap_conf_req *req = data; | 2207 | struct l2cap_conf_req *req = data; |
2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM }; | 2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
2209 | void *ptr = req->data; | 2209 | void *ptr = req->data; |
2210 | 2210 | ||
2211 | BT_DBG("sk %p", sk); | 2211 | BT_DBG("sk %p", sk); |
@@ -2394,6 +2394,10 @@ done: | |||
2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; | 2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; |
2395 | 2395 | ||
2396 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 2396 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
2397 | |||
2398 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2399 | sizeof(rfc), (unsigned long) &rfc); | ||
2400 | |||
2397 | break; | 2401 | break; |
2398 | 2402 | ||
2399 | case L2CAP_MODE_STREAMING: | 2403 | case L2CAP_MODE_STREAMING: |
@@ -2401,6 +2405,10 @@ done: | |||
2401 | pi->max_pdu_size = rfc.max_pdu_size; | 2405 | pi->max_pdu_size = rfc.max_pdu_size; |
2402 | 2406 | ||
2403 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 2407 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
2408 | |||
2409 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2410 | sizeof(rfc), (unsigned long) &rfc); | ||
2411 | |||
2404 | break; | 2412 | break; |
2405 | 2413 | ||
2406 | default: | 2414 | default: |
@@ -2410,9 +2418,6 @@ done: | |||
2410 | rfc.mode = pi->mode; | 2418 | rfc.mode = pi->mode; |
2411 | } | 2419 | } |
2412 | 2420 | ||
2413 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2414 | sizeof(rfc), (unsigned long) &rfc); | ||
2415 | |||
2416 | if (result == L2CAP_CONF_SUCCESS) | 2421 | if (result == L2CAP_CONF_SUCCESS) |
2417 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 2422 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; |
2418 | } | 2423 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b1b3b0fbf41c..4a9f52732655 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -377,12 +377,16 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
377 | struct net_bridge_port *p; | 377 | struct net_bridge_port *p; |
378 | int err = 0; | 378 | int err = 0; |
379 | 379 | ||
380 | if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) | 380 | /* Don't allow bridging non-ethernet like devices */ |
381 | if ((dev->flags & IFF_LOOPBACK) || | ||
382 | dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN) | ||
381 | return -EINVAL; | 383 | return -EINVAL; |
382 | 384 | ||
385 | /* No bridging of bridges */ | ||
383 | if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) | 386 | if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) |
384 | return -ELOOP; | 387 | return -ELOOP; |
385 | 388 | ||
389 | /* Device is already being bridged */ | ||
386 | if (dev->br_port != NULL) | 390 | if (dev->br_port != NULL) |
387 | return -EBUSY; | 391 | return -EBUSY; |
388 | 392 | ||
diff --git a/net/can/bcm.c b/net/can/bcm.c index 597da4f8f888..e8d58f33fe09 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -132,23 +132,27 @@ static inline struct bcm_sock *bcm_sk(const struct sock *sk) | |||
132 | /* | 132 | /* |
133 | * procfs functions | 133 | * procfs functions |
134 | */ | 134 | */ |
135 | static char *bcm_proc_getifname(int ifindex) | 135 | static char *bcm_proc_getifname(char *result, int ifindex) |
136 | { | 136 | { |
137 | struct net_device *dev; | 137 | struct net_device *dev; |
138 | 138 | ||
139 | if (!ifindex) | 139 | if (!ifindex) |
140 | return "any"; | 140 | return "any"; |
141 | 141 | ||
142 | /* no usage counting */ | 142 | read_lock(&dev_base_lock); |
143 | dev = __dev_get_by_index(&init_net, ifindex); | 143 | dev = __dev_get_by_index(&init_net, ifindex); |
144 | if (dev) | 144 | if (dev) |
145 | return dev->name; | 145 | strcpy(result, dev->name); |
146 | else | ||
147 | strcpy(result, "???"); | ||
148 | read_unlock(&dev_base_lock); | ||
146 | 149 | ||
147 | return "???"; | 150 | return result; |
148 | } | 151 | } |
149 | 152 | ||
150 | static int bcm_proc_show(struct seq_file *m, void *v) | 153 | static int bcm_proc_show(struct seq_file *m, void *v) |
151 | { | 154 | { |
155 | char ifname[IFNAMSIZ]; | ||
152 | struct sock *sk = (struct sock *)m->private; | 156 | struct sock *sk = (struct sock *)m->private; |
153 | struct bcm_sock *bo = bcm_sk(sk); | 157 | struct bcm_sock *bo = bcm_sk(sk); |
154 | struct bcm_op *op; | 158 | struct bcm_op *op; |
@@ -157,7 +161,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) | |||
157 | seq_printf(m, " / sk %p", sk); | 161 | seq_printf(m, " / sk %p", sk); |
158 | seq_printf(m, " / bo %p", bo); | 162 | seq_printf(m, " / bo %p", bo); |
159 | seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs); | 163 | seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs); |
160 | seq_printf(m, " / bound %s", bcm_proc_getifname(bo->ifindex)); | 164 | seq_printf(m, " / bound %s", bcm_proc_getifname(ifname, bo->ifindex)); |
161 | seq_printf(m, " <<<\n"); | 165 | seq_printf(m, " <<<\n"); |
162 | 166 | ||
163 | list_for_each_entry(op, &bo->rx_ops, list) { | 167 | list_for_each_entry(op, &bo->rx_ops, list) { |
@@ -169,7 +173,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) | |||
169 | continue; | 173 | continue; |
170 | 174 | ||
171 | seq_printf(m, "rx_op: %03X %-5s ", | 175 | seq_printf(m, "rx_op: %03X %-5s ", |
172 | op->can_id, bcm_proc_getifname(op->ifindex)); | 176 | op->can_id, bcm_proc_getifname(ifname, op->ifindex)); |
173 | seq_printf(m, "[%d]%c ", op->nframes, | 177 | seq_printf(m, "[%d]%c ", op->nframes, |
174 | (op->flags & RX_CHECK_DLC)?'d':' '); | 178 | (op->flags & RX_CHECK_DLC)?'d':' '); |
175 | if (op->kt_ival1.tv64) | 179 | if (op->kt_ival1.tv64) |
@@ -194,7 +198,8 @@ static int bcm_proc_show(struct seq_file *m, void *v) | |||
194 | list_for_each_entry(op, &bo->tx_ops, list) { | 198 | list_for_each_entry(op, &bo->tx_ops, list) { |
195 | 199 | ||
196 | seq_printf(m, "tx_op: %03X %s [%d] ", | 200 | seq_printf(m, "tx_op: %03X %s [%d] ", |
197 | op->can_id, bcm_proc_getifname(op->ifindex), | 201 | op->can_id, |
202 | bcm_proc_getifname(ifname, op->ifindex), | ||
198 | op->nframes); | 203 | op->nframes); |
199 | 204 | ||
200 | if (op->kt_ival1.tv64) | 205 | if (op->kt_ival1.tv64) |
diff --git a/net/core/dev.c b/net/core/dev.c index b8f74cfb1bfd..fe10551d3671 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -942,14 +942,15 @@ rollback: | |||
942 | ret = notifier_to_errno(ret); | 942 | ret = notifier_to_errno(ret); |
943 | 943 | ||
944 | if (ret) { | 944 | if (ret) { |
945 | if (err) { | 945 | /* err >= 0 after dev_alloc_name() or stores the first errno */ |
946 | printk(KERN_ERR | 946 | if (err >= 0) { |
947 | "%s: name change rollback failed: %d.\n", | ||
948 | dev->name, ret); | ||
949 | } else { | ||
950 | err = ret; | 947 | err = ret; |
951 | memcpy(dev->name, oldname, IFNAMSIZ); | 948 | memcpy(dev->name, oldname, IFNAMSIZ); |
952 | goto rollback; | 949 | goto rollback; |
950 | } else { | ||
951 | printk(KERN_ERR | ||
952 | "%s: name change rollback failed: %d.\n", | ||
953 | dev->name, ret); | ||
953 | } | 954 | } |
954 | } | 955 | } |
955 | 956 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 80a96166df39..ec85681a7dd8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2701 | 2701 | ||
2702 | NAPI_GRO_CB(skb)->free = 1; | 2702 | NAPI_GRO_CB(skb)->free = 1; |
2703 | goto done; | 2703 | goto done; |
2704 | } | 2704 | } else if (skb_gro_len(p) != pinfo->gso_size) |
2705 | return -E2BIG; | ||
2705 | 2706 | ||
2706 | headroom = skb_headroom(p); | 2707 | headroom = skb_headroom(p); |
2707 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | 2708 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); |
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 26b0ab1e9f56..2036568beea9 100644 --- a/net/decnet/sysctl_net_decnet.c +++ b/net/decnet/sysctl_net_decnet.c | |||
@@ -263,11 +263,10 @@ static int dn_def_dev_strategy(ctl_table *table, | |||
263 | return -ENODEV; | 263 | return -ENODEV; |
264 | 264 | ||
265 | rv = -ENODEV; | 265 | rv = -ENODEV; |
266 | if (dev->dn_ptr != NULL) { | 266 | if (dev->dn_ptr != NULL) |
267 | rv = dn_dev_set_default(dev, 1); | 267 | rv = dn_dev_set_default(dev, 1); |
268 | if (rv) | 268 | if (rv) |
269 | dev_put(dev); | 269 | dev_put(dev); |
270 | } | ||
271 | } | 270 | } |
272 | 271 | ||
273 | return rv; | 272 | return rv; |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 08ccd344de7a..ae40ed1ba560 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -438,25 +438,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
438 | goto tx_error; | 438 | goto tx_error; |
439 | } | 439 | } |
440 | 440 | ||
441 | if (tiph->frag_off) | 441 | df |= old_iph->frag_off & htons(IP_DF); |
442 | |||
443 | if (df) { | ||
442 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 444 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); |
443 | else | ||
444 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | ||
445 | 445 | ||
446 | if (mtu < 68) { | 446 | if (mtu < 68) { |
447 | stats->collisions++; | 447 | stats->collisions++; |
448 | ip_rt_put(rt); | 448 | ip_rt_put(rt); |
449 | goto tx_error; | 449 | goto tx_error; |
450 | } | 450 | } |
451 | if (skb_dst(skb)) | ||
452 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
453 | 451 | ||
454 | df |= (old_iph->frag_off&htons(IP_DF)); | 452 | if (skb_dst(skb)) |
453 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
455 | 454 | ||
456 | if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { | 455 | if ((old_iph->frag_off & htons(IP_DF)) && |
457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); | 456 | mtu < ntohs(old_iph->tot_len)) { |
458 | ip_rt_put(rt); | 457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
459 | goto tx_error; | 458 | htonl(mtu)); |
459 | ip_rt_put(rt); | ||
460 | goto tx_error; | ||
461 | } | ||
460 | } | 462 | } |
461 | 463 | ||
462 | if (tunnel->err_count > 0) { | 464 | if (tunnel->err_count > 0) { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 630a56df7b47..99508d66a642 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
483 | return -EINVAL; | 483 | return -EINVAL; |
484 | } | 484 | } |
485 | 485 | ||
486 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 486 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) { |
487 | dev_put(dev); | ||
487 | return -EADDRNOTAVAIL; | 488 | return -EADDRNOTAVAIL; |
489 | } | ||
488 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; | 490 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
489 | ip_rt_multicast_event(in_dev); | 491 | ip_rt_multicast_event(in_dev); |
490 | 492 | ||
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 68afc6ecd343..fe1a64479dd0 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -750,6 +750,8 @@ static int __init nf_nat_init(void) | |||
750 | BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); | 750 | BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); |
751 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, | 751 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, |
752 | nfnetlink_parse_nat_setup); | 752 | nfnetlink_parse_nat_setup); |
753 | BUG_ON(nf_ct_nat_offset != NULL); | ||
754 | rcu_assign_pointer(nf_ct_nat_offset, nf_nat_get_offset); | ||
753 | return 0; | 755 | return 0; |
754 | 756 | ||
755 | cleanup_extend: | 757 | cleanup_extend: |
@@ -764,6 +766,7 @@ static void __exit nf_nat_cleanup(void) | |||
764 | nf_ct_extend_unregister(&nat_extend); | 766 | nf_ct_extend_unregister(&nat_extend); |
765 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); | 767 | rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); |
766 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL); | 768 | rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL); |
769 | rcu_assign_pointer(nf_ct_nat_offset, NULL); | ||
767 | synchronize_net(); | 770 | synchronize_net(); |
768 | } | 771 | } |
769 | 772 | ||
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 09172a65d9b6..f9520fa3aba9 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -73,6 +73,28 @@ adjust_tcp_sequence(u32 seq, | |||
73 | DUMP_OFFSET(this_way); | 73 | DUMP_OFFSET(this_way); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* Get the offset value, for conntrack */ | ||
77 | s16 nf_nat_get_offset(const struct nf_conn *ct, | ||
78 | enum ip_conntrack_dir dir, | ||
79 | u32 seq) | ||
80 | { | ||
81 | struct nf_conn_nat *nat = nfct_nat(ct); | ||
82 | struct nf_nat_seq *this_way; | ||
83 | s16 offset; | ||
84 | |||
85 | if (!nat) | ||
86 | return 0; | ||
87 | |||
88 | this_way = &nat->seq[dir]; | ||
89 | spin_lock_bh(&nf_nat_seqofs_lock); | ||
90 | offset = after(seq, this_way->correction_pos) | ||
91 | ? this_way->offset_after : this_way->offset_before; | ||
92 | spin_unlock_bh(&nf_nat_seqofs_lock); | ||
93 | |||
94 | return offset; | ||
95 | } | ||
96 | EXPORT_SYMBOL_GPL(nf_nat_get_offset); | ||
97 | |||
76 | /* Frobs data inside this packet, which is linear. */ | 98 | /* Frobs data inside this packet, which is linear. */ |
77 | static void mangle_contents(struct sk_buff *skb, | 99 | static void mangle_contents(struct sk_buff *skb, |
78 | unsigned int dataoff, | 100 | unsigned int dataoff, |
@@ -189,11 +211,6 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
189 | adjust_tcp_sequence(ntohl(tcph->seq), | 211 | adjust_tcp_sequence(ntohl(tcph->seq), |
190 | (int)rep_len - (int)match_len, | 212 | (int)rep_len - (int)match_len, |
191 | ct, ctinfo); | 213 | ct, ctinfo); |
192 | /* Tell TCP window tracking about seq change */ | ||
193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), | ||
194 | ct, CTINFO2DIR(ctinfo), | ||
195 | (int)rep_len - (int)match_len); | ||
196 | |||
197 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); | 214 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); |
198 | } | 215 | } |
199 | return 1; | 216 | return 1; |
@@ -415,12 +432,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, | |||
415 | tcph->seq = newseq; | 432 | tcph->seq = newseq; |
416 | tcph->ack_seq = newack; | 433 | tcph->ack_seq = newack; |
417 | 434 | ||
418 | if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) | 435 | return nf_nat_sack_adjust(skb, tcph, ct, ctinfo); |
419 | return 0; | ||
420 | |||
421 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff); | ||
422 | |||
423 | return 1; | ||
424 | } | 436 | } |
425 | 437 | ||
426 | /* Setup NAT on this expected conntrack so it follows master. */ | 438 | /* Setup NAT on this expected conntrack so it follows master. */ |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 98440ad82558..f1813bc71088 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1183,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) | |||
1183 | #if TCP_DEBUG | 1183 | #if TCP_DEBUG |
1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); | 1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); |
1185 | 1185 | ||
1186 | WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); | 1186 | WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq), |
1187 | KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", | ||
1188 | tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt); | ||
1187 | #endif | 1189 | #endif |
1188 | 1190 | ||
1189 | if (inet_csk_ack_scheduled(sk)) { | 1191 | if (inet_csk_ack_scheduled(sk)) { |
@@ -1430,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1430 | /* Now that we have two receive queues this | 1432 | /* Now that we have two receive queues this |
1431 | * shouldn't happen. | 1433 | * shouldn't happen. |
1432 | */ | 1434 | */ |
1433 | if (before(*seq, TCP_SKB_CB(skb)->seq)) { | 1435 | if (WARN(before(*seq, TCP_SKB_CB(skb)->seq), |
1434 | printk(KERN_INFO "recvmsg bug: copied %X " | 1436 | KERN_INFO "recvmsg bug: copied %X " |
1435 | "seq %X\n", *seq, TCP_SKB_CB(skb)->seq); | 1437 | "seq %X rcvnxt %X fl %X\n", *seq, |
1438 | TCP_SKB_CB(skb)->seq, tp->rcv_nxt, | ||
1439 | flags)) | ||
1436 | break; | 1440 | break; |
1437 | } | 1441 | |
1438 | offset = *seq - TCP_SKB_CB(skb)->seq; | 1442 | offset = *seq - TCP_SKB_CB(skb)->seq; |
1439 | if (tcp_hdr(skb)->syn) | 1443 | if (tcp_hdr(skb)->syn) |
1440 | offset--; | 1444 | offset--; |
@@ -1443,8 +1447,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1443 | if (tcp_hdr(skb)->fin) | 1447 | if (tcp_hdr(skb)->fin) |
1444 | goto found_fin_ok; | 1448 | goto found_fin_ok; |
1445 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " | 1449 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " |
1446 | "copied %X seq %X\n", *seq, | 1450 | "copied %X seq %X rcvnxt %X fl %X\n", |
1447 | TCP_SKB_CB(skb)->seq); | 1451 | *seq, TCP_SKB_CB(skb)->seq, |
1452 | tp->rcv_nxt, flags); | ||
1448 | } | 1453 | } |
1449 | 1454 | ||
1450 | /* Well, if we have backlog, try to process it now yet. */ | 1455 | /* Well, if we have backlog, try to process it now yet. */ |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ca6e68dcd8a8..b9168c1864ca 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1351,6 +1351,11 @@ err_stat: | |||
1351 | return ret; | 1351 | return ret; |
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | s16 (*nf_ct_nat_offset)(const struct nf_conn *ct, | ||
1355 | enum ip_conntrack_dir dir, | ||
1356 | u32 seq); | ||
1357 | EXPORT_SYMBOL_GPL(nf_ct_nat_offset); | ||
1358 | |||
1354 | int nf_conntrack_init(struct net *net) | 1359 | int nf_conntrack_init(struct net *net) |
1355 | { | 1360 | { |
1356 | int ret; | 1361 | int ret; |
@@ -1368,6 +1373,9 @@ int nf_conntrack_init(struct net *net) | |||
1368 | /* For use by REJECT target */ | 1373 | /* For use by REJECT target */ |
1369 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); | 1374 | rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); |
1370 | rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); | 1375 | rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); |
1376 | |||
1377 | /* Howto get NAT offsets */ | ||
1378 | rcu_assign_pointer(nf_ct_nat_offset, NULL); | ||
1371 | } | 1379 | } |
1372 | return 0; | 1380 | return 0; |
1373 | 1381 | ||
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 97a82ba75376..ba2b76937283 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -492,6 +492,21 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff, | |||
492 | } | 492 | } |
493 | } | 493 | } |
494 | 494 | ||
495 | #ifdef CONFIG_NF_NAT_NEEDED | ||
496 | static inline s16 nat_offset(const struct nf_conn *ct, | ||
497 | enum ip_conntrack_dir dir, | ||
498 | u32 seq) | ||
499 | { | ||
500 | typeof(nf_ct_nat_offset) get_offset = rcu_dereference(nf_ct_nat_offset); | ||
501 | |||
502 | return get_offset != NULL ? get_offset(ct, dir, seq) : 0; | ||
503 | } | ||
504 | #define NAT_OFFSET(pf, ct, dir, seq) \ | ||
505 | (pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0) | ||
506 | #else | ||
507 | #define NAT_OFFSET(pf, ct, dir, seq) 0 | ||
508 | #endif | ||
509 | |||
495 | static bool tcp_in_window(const struct nf_conn *ct, | 510 | static bool tcp_in_window(const struct nf_conn *ct, |
496 | struct ip_ct_tcp *state, | 511 | struct ip_ct_tcp *state, |
497 | enum ip_conntrack_dir dir, | 512 | enum ip_conntrack_dir dir, |
@@ -506,6 +521,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
506 | struct ip_ct_tcp_state *receiver = &state->seen[!dir]; | 521 | struct ip_ct_tcp_state *receiver = &state->seen[!dir]; |
507 | const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; | 522 | const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; |
508 | __u32 seq, ack, sack, end, win, swin; | 523 | __u32 seq, ack, sack, end, win, swin; |
524 | s16 receiver_offset; | ||
509 | bool res; | 525 | bool res; |
510 | 526 | ||
511 | /* | 527 | /* |
@@ -519,11 +535,16 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
519 | if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) | 535 | if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) |
520 | tcp_sack(skb, dataoff, tcph, &sack); | 536 | tcp_sack(skb, dataoff, tcph, &sack); |
521 | 537 | ||
538 | /* Take into account NAT sequence number mangling */ | ||
539 | receiver_offset = NAT_OFFSET(pf, ct, !dir, ack - 1); | ||
540 | ack -= receiver_offset; | ||
541 | sack -= receiver_offset; | ||
542 | |||
522 | pr_debug("tcp_in_window: START\n"); | 543 | pr_debug("tcp_in_window: START\n"); |
523 | pr_debug("tcp_in_window: "); | 544 | pr_debug("tcp_in_window: "); |
524 | nf_ct_dump_tuple(tuple); | 545 | nf_ct_dump_tuple(tuple); |
525 | pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n", | 546 | pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", |
526 | seq, ack, sack, win, end); | 547 | seq, ack, receiver_offset, sack, receiver_offset, win, end); |
527 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " | 548 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " |
528 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", | 549 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", |
529 | sender->td_end, sender->td_maxend, sender->td_maxwin, | 550 | sender->td_end, sender->td_maxend, sender->td_maxwin, |
@@ -613,8 +634,8 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
613 | 634 | ||
614 | pr_debug("tcp_in_window: "); | 635 | pr_debug("tcp_in_window: "); |
615 | nf_ct_dump_tuple(tuple); | 636 | nf_ct_dump_tuple(tuple); |
616 | pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n", | 637 | pr_debug("seq=%u ack=%u+(%d) sack=%u+(%d) win=%u end=%u\n", |
617 | seq, ack, sack, win, end); | 638 | seq, ack, receiver_offset, sack, receiver_offset, win, end); |
618 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " | 639 | pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " |
619 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", | 640 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", |
620 | sender->td_end, sender->td_maxend, sender->td_maxwin, | 641 | sender->td_end, sender->td_maxend, sender->td_maxwin, |
@@ -700,7 +721,7 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
700 | before(seq, sender->td_maxend + 1) ? | 721 | before(seq, sender->td_maxend + 1) ? |
701 | after(end, sender->td_end - receiver->td_maxwin - 1) ? | 722 | after(end, sender->td_end - receiver->td_maxwin - 1) ? |
702 | before(sack, receiver->td_end + 1) ? | 723 | before(sack, receiver->td_end + 1) ? |
703 | after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG" | 724 | after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG" |
704 | : "ACK is under the lower bound (possible overly delayed ACK)" | 725 | : "ACK is under the lower bound (possible overly delayed ACK)" |
705 | : "ACK is over the upper bound (ACKed data not seen yet)" | 726 | : "ACK is over the upper bound (ACKed data not seen yet)" |
706 | : "SEQ is under the lower bound (already ACKed data retransmitted)" | 727 | : "SEQ is under the lower bound (already ACKed data retransmitted)" |
@@ -715,39 +736,6 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
715 | return res; | 736 | return res; |
716 | } | 737 | } |
717 | 738 | ||
718 | #ifdef CONFIG_NF_NAT_NEEDED | ||
719 | /* Update sender->td_end after NAT successfully mangled the packet */ | ||
720 | /* Caller must linearize skb at tcp header. */ | ||
721 | void nf_conntrack_tcp_update(const struct sk_buff *skb, | ||
722 | unsigned int dataoff, | ||
723 | struct nf_conn *ct, int dir, | ||
724 | s16 offset) | ||
725 | { | ||
726 | const struct tcphdr *tcph = (const void *)skb->data + dataoff; | ||
727 | const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir]; | ||
728 | const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir]; | ||
729 | __u32 end; | ||
730 | |||
731 | end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph); | ||
732 | |||
733 | spin_lock_bh(&ct->lock); | ||
734 | /* | ||
735 | * We have to worry for the ack in the reply packet only... | ||
736 | */ | ||
737 | if (ct->proto.tcp.seen[dir].td_end + offset == end) | ||
738 | ct->proto.tcp.seen[dir].td_end = end; | ||
739 | ct->proto.tcp.last_end = end; | ||
740 | spin_unlock_bh(&ct->lock); | ||
741 | pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i " | ||
742 | "receiver end=%u maxend=%u maxwin=%u scale=%i\n", | ||
743 | sender->td_end, sender->td_maxend, sender->td_maxwin, | ||
744 | sender->td_scale, | ||
745 | receiver->td_end, receiver->td_maxend, receiver->td_maxwin, | ||
746 | receiver->td_scale); | ||
747 | } | ||
748 | EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update); | ||
749 | #endif | ||
750 | |||
751 | #define TH_FIN 0x01 | 739 | #define TH_FIN 0x01 |
752 | #define TH_SYN 0x02 | 740 | #define TH_SYN 0x02 |
753 | #define TH_RST 0x04 | 741 | #define TH_RST 0x04 |
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 680980954395..38f03f75a636 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c | |||
@@ -103,7 +103,7 @@ static int count_them(struct xt_connlimit_data *data, | |||
103 | const struct nf_conntrack_tuple *tuple, | 103 | const struct nf_conntrack_tuple *tuple, |
104 | const union nf_inet_addr *addr, | 104 | const union nf_inet_addr *addr, |
105 | const union nf_inet_addr *mask, | 105 | const union nf_inet_addr *mask, |
106 | const struct xt_match *match) | 106 | u_int8_t family) |
107 | { | 107 | { |
108 | const struct nf_conntrack_tuple_hash *found; | 108 | const struct nf_conntrack_tuple_hash *found; |
109 | struct xt_connlimit_conn *conn; | 109 | struct xt_connlimit_conn *conn; |
@@ -113,8 +113,7 @@ static int count_them(struct xt_connlimit_data *data, | |||
113 | bool addit = true; | 113 | bool addit = true; |
114 | int matches = 0; | 114 | int matches = 0; |
115 | 115 | ||
116 | 116 | if (family == NFPROTO_IPV6) | |
117 | if (match->family == NFPROTO_IPV6) | ||
118 | hash = &data->iphash[connlimit_iphash6(addr, mask)]; | 117 | hash = &data->iphash[connlimit_iphash6(addr, mask)]; |
119 | else | 118 | else |
120 | hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; | 119 | hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; |
@@ -157,8 +156,7 @@ static int count_them(struct xt_connlimit_data *data, | |||
157 | continue; | 156 | continue; |
158 | } | 157 | } |
159 | 158 | ||
160 | if (same_source_net(addr, mask, &conn->tuple.src.u3, | 159 | if (same_source_net(addr, mask, &conn->tuple.src.u3, family)) |
161 | match->family)) | ||
162 | /* same source network -> be counted! */ | 160 | /* same source network -> be counted! */ |
163 | ++matches; | 161 | ++matches; |
164 | nf_ct_put(found_ct); | 162 | nf_ct_put(found_ct); |
@@ -207,7 +205,7 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
207 | 205 | ||
208 | spin_lock_bh(&info->data->lock); | 206 | spin_lock_bh(&info->data->lock); |
209 | connections = count_them(info->data, tuple_ptr, &addr, | 207 | connections = count_them(info->data, tuple_ptr, &addr, |
210 | &info->mask, par->match); | 208 | &info->mask, par->family); |
211 | spin_unlock_bh(&info->data->lock); | 209 | spin_unlock_bh(&info->data->lock); |
212 | 210 | ||
213 | if (connections < 0) { | 211 | if (connections < 0) { |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 9478d9b3d977..f3e21989b88c 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
@@ -578,18 +578,18 @@ static int rose_clear_routes(void) | |||
578 | 578 | ||
579 | /* | 579 | /* |
580 | * Check that the device given is a valid AX.25 interface that is "up". | 580 | * Check that the device given is a valid AX.25 interface that is "up". |
581 | * called whith RTNL | ||
581 | */ | 582 | */ |
582 | static struct net_device *rose_ax25_dev_get(char *devname) | 583 | static struct net_device *rose_ax25_dev_find(char *devname) |
583 | { | 584 | { |
584 | struct net_device *dev; | 585 | struct net_device *dev; |
585 | 586 | ||
586 | if ((dev = dev_get_by_name(&init_net, devname)) == NULL) | 587 | if ((dev = __dev_get_by_name(&init_net, devname)) == NULL) |
587 | return NULL; | 588 | return NULL; |
588 | 589 | ||
589 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) | 590 | if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) |
590 | return dev; | 591 | return dev; |
591 | 592 | ||
592 | dev_put(dev); | ||
593 | return NULL; | 593 | return NULL; |
594 | } | 594 | } |
595 | 595 | ||
@@ -720,27 +720,23 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg) | |||
720 | case SIOCADDRT: | 720 | case SIOCADDRT: |
721 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) | 721 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) |
722 | return -EFAULT; | 722 | return -EFAULT; |
723 | if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) | 723 | if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL) |
724 | return -EINVAL; | 724 | return -EINVAL; |
725 | if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */ | 725 | if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */ |
726 | dev_put(dev); | ||
727 | return -EINVAL; | 726 | return -EINVAL; |
728 | } | ||
729 | if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ | 727 | if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ |
730 | return -EINVAL; | 728 | return -EINVAL; |
731 | if (rose_route.ndigis > AX25_MAX_DIGIS) | 729 | if (rose_route.ndigis > AX25_MAX_DIGIS) |
732 | return -EINVAL; | 730 | return -EINVAL; |
733 | err = rose_add_node(&rose_route, dev); | 731 | err = rose_add_node(&rose_route, dev); |
734 | dev_put(dev); | ||
735 | return err; | 732 | return err; |
736 | 733 | ||
737 | case SIOCDELRT: | 734 | case SIOCDELRT: |
738 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) | 735 | if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) |
739 | return -EFAULT; | 736 | return -EFAULT; |
740 | if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) | 737 | if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL) |
741 | return -EINVAL; | 738 | return -EINVAL; |
742 | err = rose_del_node(&rose_route, dev); | 739 | err = rose_del_node(&rose_route, dev); |
743 | dev_put(dev); | ||
744 | return err; | 740 | return err; |
745 | 741 | ||
746 | case SIOCRSCLRRT: | 742 | case SIOCRSCLRRT: |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 8450960df24f..7eed77a39d0d 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -1485,15 +1485,13 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) | |||
1485 | * local endpoint and the remote peer. | 1485 | * local endpoint and the remote peer. |
1486 | */ | 1486 | */ |
1487 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, | 1487 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, |
1488 | gfp_t gfp) | 1488 | sctp_scope_t scope, gfp_t gfp) |
1489 | { | 1489 | { |
1490 | sctp_scope_t scope; | ||
1491 | int flags; | 1490 | int flags; |
1492 | 1491 | ||
1493 | /* Use scoping rules to determine the subset of addresses from | 1492 | /* Use scoping rules to determine the subset of addresses from |
1494 | * the endpoint. | 1493 | * the endpoint. |
1495 | */ | 1494 | */ |
1496 | scope = sctp_scope(&asoc->peer.active_path->ipaddr); | ||
1497 | flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; | 1495 | flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; |
1498 | if (asoc->peer.ipv4_address) | 1496 | if (asoc->peer.ipv4_address) |
1499 | flags |= SCTP_ADDR4_PEERSUPP; | 1497 | flags |= SCTP_ADDR4_PEERSUPP; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c8fae1983dd1..d4df45022ffa 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
384 | if (!new_asoc) | 384 | if (!new_asoc) |
385 | goto nomem; | 385 | goto nomem; |
386 | 386 | ||
387 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, | ||
388 | sctp_scope(sctp_source(chunk)), | ||
389 | GFP_ATOMIC) < 0) | ||
390 | goto nomem_init; | ||
391 | |||
387 | /* The call, sctp_process_init(), can fail on memory allocation. */ | 392 | /* The call, sctp_process_init(), can fail on memory allocation. */ |
388 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 393 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, |
389 | sctp_source(chunk), | 394 | sctp_source(chunk), |
@@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
401 | len = ntohs(err_chunk->chunk_hdr->length) - | 406 | len = ntohs(err_chunk->chunk_hdr->length) - |
402 | sizeof(sctp_chunkhdr_t); | 407 | sizeof(sctp_chunkhdr_t); |
403 | 408 | ||
404 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | ||
405 | goto nomem_init; | ||
406 | |||
407 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 409 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
408 | if (!repl) | 410 | if (!repl) |
409 | goto nomem_init; | 411 | goto nomem_init; |
@@ -1452,6 +1454,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1452 | if (!new_asoc) | 1454 | if (!new_asoc) |
1453 | goto nomem; | 1455 | goto nomem; |
1454 | 1456 | ||
1457 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, | ||
1458 | sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0) | ||
1459 | goto nomem; | ||
1460 | |||
1455 | /* In the outbound INIT ACK the endpoint MUST copy its current | 1461 | /* In the outbound INIT ACK the endpoint MUST copy its current |
1456 | * Verification Tag and Peers Verification tag into a reserved | 1462 | * Verification Tag and Peers Verification tag into a reserved |
1457 | * place (local tie-tag and per tie-tag) within the state cookie. | 1463 | * place (local tie-tag and per tie-tag) within the state cookie. |
@@ -1488,9 +1494,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1488 | sizeof(sctp_chunkhdr_t); | 1494 | sizeof(sctp_chunkhdr_t); |
1489 | } | 1495 | } |
1490 | 1496 | ||
1491 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | ||
1492 | goto nomem; | ||
1493 | |||
1494 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 1497 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
1495 | if (!repl) | 1498 | if (!repl) |
1496 | goto nomem; | 1499 | goto nomem; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c8d05758661d..3a95fcb17a9e 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1080,6 +1080,13 @@ static int __sctp_connect(struct sock* sk, | |||
1080 | err = -ENOMEM; | 1080 | err = -ENOMEM; |
1081 | goto out_free; | 1081 | goto out_free; |
1082 | } | 1082 | } |
1083 | |||
1084 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, | ||
1085 | GFP_KERNEL); | ||
1086 | if (err < 0) { | ||
1087 | goto out_free; | ||
1088 | } | ||
1089 | |||
1083 | } | 1090 | } |
1084 | 1091 | ||
1085 | /* Prime the peer's transport structures. */ | 1092 | /* Prime the peer's transport structures. */ |
@@ -1095,11 +1102,6 @@ static int __sctp_connect(struct sock* sk, | |||
1095 | walk_size += af->sockaddr_len; | 1102 | walk_size += af->sockaddr_len; |
1096 | } | 1103 | } |
1097 | 1104 | ||
1098 | err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); | ||
1099 | if (err < 0) { | ||
1100 | goto out_free; | ||
1101 | } | ||
1102 | |||
1103 | /* In case the user of sctp_connectx() wants an association | 1105 | /* In case the user of sctp_connectx() wants an association |
1104 | * id back, assign one now. | 1106 | * id back, assign one now. |
1105 | */ | 1107 | */ |
@@ -1274,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, | |||
1274 | } | 1276 | } |
1275 | 1277 | ||
1276 | /* | 1278 | /* |
1277 | * New (hopefully final) interface for the API. The option buffer is used | 1279 | * New (hopefully final) interface for the API. |
1278 | * both for the returned association id and the addresses. | 1280 | * We use the sctp_getaddrs_old structure so that use-space library |
1281 | * can avoid any unnecessary allocations. The only defferent part | ||
1282 | * is that we store the actual length of the address buffer into the | ||
1283 | * addrs_num structure member. That way we can re-use the existing | ||
1284 | * code. | ||
1279 | */ | 1285 | */ |
1280 | SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, | 1286 | SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, |
1281 | char __user *optval, | 1287 | char __user *optval, |
1282 | int __user *optlen) | 1288 | int __user *optlen) |
1283 | { | 1289 | { |
1290 | struct sctp_getaddrs_old param; | ||
1284 | sctp_assoc_t assoc_id = 0; | 1291 | sctp_assoc_t assoc_id = 0; |
1285 | int err = 0; | 1292 | int err = 0; |
1286 | 1293 | ||
1287 | if (len < sizeof(assoc_id)) | 1294 | if (len < sizeof(param)) |
1288 | return -EINVAL; | 1295 | return -EINVAL; |
1289 | 1296 | ||
1297 | if (copy_from_user(¶m, optval, sizeof(param))) | ||
1298 | return -EFAULT; | ||
1299 | |||
1290 | err = __sctp_setsockopt_connectx(sk, | 1300 | err = __sctp_setsockopt_connectx(sk, |
1291 | (struct sockaddr __user *)(optval + sizeof(assoc_id)), | 1301 | (struct sockaddr __user *)param.addrs, |
1292 | len - sizeof(assoc_id), &assoc_id); | 1302 | param.addr_num, &assoc_id); |
1293 | 1303 | ||
1294 | if (err == 0 || err == -EINPROGRESS) { | 1304 | if (err == 0 || err == -EINPROGRESS) { |
1295 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) | 1305 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) |
@@ -1689,6 +1699,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1689 | goto out_unlock; | 1699 | goto out_unlock; |
1690 | } | 1700 | } |
1691 | asoc = new_asoc; | 1701 | asoc = new_asoc; |
1702 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL); | ||
1703 | if (err < 0) { | ||
1704 | err = -ENOMEM; | ||
1705 | goto out_free; | ||
1706 | } | ||
1692 | 1707 | ||
1693 | /* If the SCTP_INIT ancillary data is specified, set all | 1708 | /* If the SCTP_INIT ancillary data is specified, set all |
1694 | * the association init values accordingly. | 1709 | * the association init values accordingly. |
@@ -1718,11 +1733,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1718 | err = -ENOMEM; | 1733 | err = -ENOMEM; |
1719 | goto out_free; | 1734 | goto out_free; |
1720 | } | 1735 | } |
1721 | err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); | ||
1722 | if (err < 0) { | ||
1723 | err = -ENOMEM; | ||
1724 | goto out_free; | ||
1725 | } | ||
1726 | } | 1736 | } |
1727 | 1737 | ||
1728 | /* ASSERT: we have a valid association at this point. */ | 1738 | /* ASSERT: we have a valid association at this point. */ |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index c256e4839316..3b141bb32faf 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
308 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 308 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
309 | * association's active path for getsockname(). | 309 | * association's active path for getsockname(). |
310 | */ | 310 | */ |
311 | if (asoc && (transport == asoc->peer.active_path)) | 311 | if (asoc && (!asoc->peer.primary_path || |
312 | (transport == asoc->peer.active_path))) | ||
312 | opt->pf->af->to_sk_saddr(&transport->saddr, | 313 | opt->pf->af->to_sk_saddr(&transport->saddr, |
313 | asoc->base.sk); | 314 | asoc->base.sk); |
314 | } else | 315 | } else |
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 22e8fd89477f..c7450c8f0a7c 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c | |||
@@ -306,24 +306,25 @@ EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr); | |||
306 | * @sap: buffer into which to plant socket address | 306 | * @sap: buffer into which to plant socket address |
307 | * @salen: size of buffer | 307 | * @salen: size of buffer |
308 | * | 308 | * |
309 | * @uaddr does not have to be '\0'-terminated, but strict_strtoul() and | ||
310 | * rpc_pton() require proper string termination to be successful. | ||
311 | * | ||
309 | * Returns the size of the socket address if successful; otherwise | 312 | * Returns the size of the socket address if successful; otherwise |
310 | * zero is returned. | 313 | * zero is returned. |
311 | */ | 314 | */ |
312 | size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | 315 | size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, |
313 | struct sockaddr *sap, const size_t salen) | 316 | struct sockaddr *sap, const size_t salen) |
314 | { | 317 | { |
315 | char *c, buf[RPCBIND_MAXUADDRLEN]; | 318 | char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')]; |
316 | unsigned long portlo, porthi; | 319 | unsigned long portlo, porthi; |
317 | unsigned short port; | 320 | unsigned short port; |
318 | 321 | ||
319 | if (uaddr_len > sizeof(buf)) | 322 | if (uaddr_len > RPCBIND_MAXUADDRLEN) |
320 | return 0; | 323 | return 0; |
321 | 324 | ||
322 | memcpy(buf, uaddr, uaddr_len); | 325 | memcpy(buf, uaddr, uaddr_len); |
323 | 326 | ||
324 | buf[uaddr_len] = '\n'; | 327 | buf[uaddr_len] = '\0'; |
325 | buf[uaddr_len + 1] = '\0'; | ||
326 | |||
327 | c = strrchr(buf, '.'); | 328 | c = strrchr(buf, '.'); |
328 | if (unlikely(c == NULL)) | 329 | if (unlikely(c == NULL)) |
329 | return 0; | 330 | return 0; |
@@ -332,9 +333,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | |||
332 | if (unlikely(portlo > 255)) | 333 | if (unlikely(portlo > 255)) |
333 | return 0; | 334 | return 0; |
334 | 335 | ||
335 | c[0] = '\n'; | 336 | *c = '\0'; |
336 | c[1] = '\0'; | ||
337 | |||
338 | c = strrchr(buf, '.'); | 337 | c = strrchr(buf, '.'); |
339 | if (unlikely(c == NULL)) | 338 | if (unlikely(c == NULL)) |
340 | return 0; | 339 | return 0; |
@@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | |||
345 | 344 | ||
346 | port = (unsigned short)((porthi << 8) | portlo); | 345 | port = (unsigned short)((porthi << 8) | portlo); |
347 | 346 | ||
348 | c[0] = '\0'; | 347 | *c = '\0'; |
349 | |||
350 | if (rpc_pton(buf, strlen(buf), sap, salen) == 0) | 348 | if (rpc_pton(buf, strlen(buf), sap, salen) == 0) |
351 | return 0; | 349 | return 0; |
352 | 350 | ||