aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/bnep/bnep.h2
-rw-r--r--net/bluetooth/bnep/sock.c4
-rw-r--r--net/bluetooth/hci_core.c4
-rw-r--r--net/bluetooth/hci_sock.c4
-rw-r--r--net/ipv4/tcp_output.c12
-rw-r--r--net/netfilter/nf_conntrack_expect.c2
-rw-r--r--net/netfilter/nf_conntrack_extend.c19
-rw-r--r--net/netfilter/nf_queue.c2
-rw-r--r--net/netfilter/nfnetlink_log.c32
-rw-r--r--net/netfilter/nfnetlink_queue.c17
-rw-r--r--net/netfilter/xt_time.c7
-rw-r--r--net/rxrpc/ar-recvmsg.c3
-rw-r--r--net/sctp/bind_addr.c4
-rw-r--r--net/sctp/ipv6.c4
-rw-r--r--net/sctp/protocol.c4
-rw-r--r--net/sctp/sm_make_chunk.c8
-rw-r--r--net/sctp/socket.c73
17 files changed, 126 insertions, 75 deletions
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
index a2992280c3d1..e69244dd8de8 100644
--- a/net/bluetooth/bnep/bnep.h
+++ b/net/bluetooth/bnep/bnep.h
@@ -174,7 +174,7 @@ struct bnep_session {
174 174
175void bnep_net_setup(struct net_device *dev); 175void bnep_net_setup(struct net_device *dev);
176int bnep_sock_init(void); 176int bnep_sock_init(void);
177int bnep_sock_cleanup(void); 177void bnep_sock_cleanup(void);
178 178
179static inline int bnep_mc_hash(__u8 *addr) 179static inline int bnep_mc_hash(__u8 *addr)
180{ 180{
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 81065e548a1f..201e5b1ce473 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -257,12 +257,10 @@ error:
257 return err; 257 return err;
258} 258}
259 259
260int __exit bnep_sock_cleanup(void) 260void __exit bnep_sock_cleanup(void)
261{ 261{
262 if (bt_sock_unregister(BTPROTO_BNEP) < 0) 262 if (bt_sock_unregister(BTPROTO_BNEP) < 0)
263 BT_ERR("Can't unregister BNEP socket"); 263 BT_ERR("Can't unregister BNEP socket");
264 264
265 proto_unregister(&bnep_proto); 265 proto_unregister(&bnep_proto);
266
267 return 0;
268} 266}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 930b58e7149a..aec6929f5c16 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -902,8 +902,6 @@ int hci_unregister_dev(struct hci_dev *hdev)
902 902
903 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 903 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
904 904
905 hci_unregister_sysfs(hdev);
906
907 write_lock_bh(&hci_dev_list_lock); 905 write_lock_bh(&hci_dev_list_lock);
908 list_del(&hdev->list); 906 list_del(&hdev->list);
909 write_unlock_bh(&hci_dev_list_lock); 907 write_unlock_bh(&hci_dev_list_lock);
@@ -915,6 +913,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
915 913
916 hci_notify(hdev, HCI_DEV_UNREG); 914 hci_notify(hdev, HCI_DEV_UNREG);
917 915
916 hci_unregister_sysfs(hdev);
917
918 __hci_dev_put(hdev); 918 __hci_dev_put(hdev);
919 919
920 return 0; 920 return 0;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 14991323c273..b5d4019d3572 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -734,7 +734,7 @@ error:
734 return err; 734 return err;
735} 735}
736 736
737int __exit hci_sock_cleanup(void) 737void __exit hci_sock_cleanup(void)
738{ 738{
739 if (bt_sock_unregister(BTPROTO_HCI) < 0) 739 if (bt_sock_unregister(BTPROTO_HCI) < 0)
740 BT_ERR("HCI socket unregistration failed"); 740 BT_ERR("HCI socket unregistration failed");
@@ -742,6 +742,4 @@ int __exit hci_sock_cleanup(void)
742 hci_unregister_notifier(&hci_sock_nblock); 742 hci_unregister_notifier(&hci_sock_nblock);
743 743
744 proto_unregister(&hci_sk_proto); 744 proto_unregister(&hci_sk_proto);
745
746 return 0;
747} 745}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index ed750f9ceb07..01578f544ad6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1035,6 +1035,13 @@ static void tcp_cwnd_validate(struct sock *sk)
1035 * introducing MSS oddities to segment boundaries. In rare cases where 1035 * introducing MSS oddities to segment boundaries. In rare cases where
1036 * mss_now != mss_cache, we will request caller to create a small skb 1036 * mss_now != mss_cache, we will request caller to create a small skb
1037 * per input skb which could be mostly avoided here (if desired). 1037 * per input skb which could be mostly avoided here (if desired).
1038 *
1039 * We explicitly want to create a request for splitting write queue tail
1040 * to a small skb for Nagle purposes while avoiding unnecessary modulos,
1041 * thus all the complexity (cwnd_len is always MSS multiple which we
1042 * return whenever allowed by the other factors). Basically we need the
1043 * modulo only when the receiver window alone is the limiting factor or
1044 * when we would be allowed to send the split-due-to-Nagle skb fully.
1038 */ 1045 */
1039static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb, 1046static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb,
1040 unsigned int mss_now, unsigned int cwnd) 1047 unsigned int mss_now, unsigned int cwnd)
@@ -1048,10 +1055,11 @@ static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb,
1048 if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk))) 1055 if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
1049 return cwnd_len; 1056 return cwnd_len;
1050 1057
1051 if (skb == tcp_write_queue_tail(sk) && cwnd_len <= skb->len) 1058 needed = min(skb->len, window);
1059
1060 if (skb == tcp_write_queue_tail(sk) && cwnd_len <= needed)
1052 return cwnd_len; 1061 return cwnd_len;
1053 1062
1054 needed = min(skb->len, window);
1055 return needed - needed % mss_now; 1063 return needed - needed % mss_now;
1056} 1064}
1057 1065
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index e06bf0028bb1..684ec9c1ad38 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -381,7 +381,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
381 if (nf_ct_expect_count >= nf_ct_expect_max) { 381 if (nf_ct_expect_count >= nf_ct_expect_max) {
382 if (net_ratelimit()) 382 if (net_ratelimit())
383 printk(KERN_WARNING 383 printk(KERN_WARNING
384 "nf_conntrack: expectation table full"); 384 "nf_conntrack: expectation table full\n");
385 ret = -EMFILE; 385 ret = -EMFILE;
386 goto out; 386 goto out;
387 } 387 }
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
index 8b9be1e978cd..2bd9963b5b3e 100644
--- a/net/netfilter/nf_conntrack_extend.c
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -19,14 +19,6 @@
19static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM]; 19static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM];
20static DEFINE_MUTEX(nf_ct_ext_type_mutex); 20static DEFINE_MUTEX(nf_ct_ext_type_mutex);
21 21
22/* Horrible trick to figure out smallest amount worth kmallocing. */
23#define CACHE(x) (x) + 0 *
24enum {
25 NF_CT_EXT_MIN_SIZE =
26#include <linux/kmalloc_sizes.h>
27 1 };
28#undef CACHE
29
30void __nf_ct_ext_destroy(struct nf_conn *ct) 22void __nf_ct_ext_destroy(struct nf_conn *ct)
31{ 23{
32 unsigned int i; 24 unsigned int i;
@@ -53,7 +45,7 @@ EXPORT_SYMBOL(__nf_ct_ext_destroy);
53static void * 45static void *
54nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) 46nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
55{ 47{
56 unsigned int off, len, real_len; 48 unsigned int off, len;
57 struct nf_ct_ext_type *t; 49 struct nf_ct_ext_type *t;
58 50
59 rcu_read_lock(); 51 rcu_read_lock();
@@ -61,16 +53,14 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
61 BUG_ON(t == NULL); 53 BUG_ON(t == NULL);
62 off = ALIGN(sizeof(struct nf_ct_ext), t->align); 54 off = ALIGN(sizeof(struct nf_ct_ext), t->align);
63 len = off + t->len; 55 len = off + t->len;
64 real_len = t->alloc_size;
65 rcu_read_unlock(); 56 rcu_read_unlock();
66 57
67 *ext = kzalloc(real_len, gfp); 58 *ext = kzalloc(t->alloc_size, gfp);
68 if (!*ext) 59 if (!*ext)
69 return NULL; 60 return NULL;
70 61
71 (*ext)->offset[id] = off; 62 (*ext)->offset[id] = off;
72 (*ext)->len = len; 63 (*ext)->len = len;
73 (*ext)->real_len = real_len;
74 64
75 return (void *)(*ext) + off; 65 return (void *)(*ext) + off;
76} 66}
@@ -95,7 +85,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
95 newlen = newoff + t->len; 85 newlen = newoff + t->len;
96 rcu_read_unlock(); 86 rcu_read_unlock();
97 87
98 if (newlen >= ct->ext->real_len) { 88 if (newlen >= ksize(ct->ext)) {
99 new = kmalloc(newlen, gfp); 89 new = kmalloc(newlen, gfp);
100 if (!new) 90 if (!new)
101 return NULL; 91 return NULL;
@@ -114,7 +104,6 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
114 rcu_read_unlock(); 104 rcu_read_unlock();
115 } 105 }
116 kfree(ct->ext); 106 kfree(ct->ext);
117 new->real_len = newlen;
118 ct->ext = new; 107 ct->ext = new;
119 } 108 }
120 109
@@ -156,8 +145,6 @@ static void update_alloc_size(struct nf_ct_ext_type *type)
156 t1->alloc_size = ALIGN(t1->alloc_size, t2->align) 145 t1->alloc_size = ALIGN(t1->alloc_size, t2->align)
157 + t2->len; 146 + t2->len;
158 } 147 }
159 if (t1->alloc_size < NF_CT_EXT_MIN_SIZE)
160 t1->alloc_size = NF_CT_EXT_MIN_SIZE;
161 } 148 }
162} 149}
163 150
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index bfc2928c1912..ddc80ea114cd 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -51,7 +51,7 @@ int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh)
51 return -EINVAL; 51 return -EINVAL;
52 52
53 mutex_lock(&queue_handler_mutex); 53 mutex_lock(&queue_handler_mutex);
54 if (queue_handler[pf] != qh) { 54 if (queue_handler[pf] && queue_handler[pf] != qh) {
55 mutex_unlock(&queue_handler_mutex); 55 mutex_unlock(&queue_handler_mutex);
56 return -EINVAL; 56 return -EINVAL;
57 } 57 }
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 7efa40d47393..bf3f19b21fe4 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -556,7 +556,7 @@ nfulnl_log_packet(unsigned int pf,
556 /* FIXME: do we want to make the size calculation conditional based on 556 /* FIXME: do we want to make the size calculation conditional based on
557 * what is actually present? way more branches and checks, but more 557 * what is actually present? way more branches and checks, but more
558 * memory efficient... */ 558 * memory efficient... */
559 size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) 559 size = NLMSG_SPACE(sizeof(struct nfgenmsg))
560 + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr)) 560 + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
561 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 561 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
562 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 562 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
@@ -702,20 +702,30 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
702 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 702 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
703 u_int16_t group_num = ntohs(nfmsg->res_id); 703 u_int16_t group_num = ntohs(nfmsg->res_id);
704 struct nfulnl_instance *inst; 704 struct nfulnl_instance *inst;
705 struct nfulnl_msg_config_cmd *cmd = NULL;
705 int ret = 0; 706 int ret = 0;
706 707
708 if (nfula[NFULA_CFG_CMD]) {
709 u_int8_t pf = nfmsg->nfgen_family;
710 cmd = nla_data(nfula[NFULA_CFG_CMD]);
711
712 /* Commands without queue context */
713 switch (cmd->command) {
714 case NFULNL_CFG_CMD_PF_BIND:
715 return nf_log_register(pf, &nfulnl_logger);
716 case NFULNL_CFG_CMD_PF_UNBIND:
717 nf_log_unregister_pf(pf);
718 return 0;
719 }
720 }
721
707 inst = instance_lookup_get(group_num); 722 inst = instance_lookup_get(group_num);
708 if (inst && inst->peer_pid != NETLINK_CB(skb).pid) { 723 if (inst && inst->peer_pid != NETLINK_CB(skb).pid) {
709 ret = -EPERM; 724 ret = -EPERM;
710 goto out_put; 725 goto out_put;
711 } 726 }
712 727
713 if (nfula[NFULA_CFG_CMD]) { 728 if (cmd != NULL) {
714 u_int8_t pf = nfmsg->nfgen_family;
715 struct nfulnl_msg_config_cmd *cmd;
716
717 cmd = nla_data(nfula[NFULA_CFG_CMD]);
718
719 switch (cmd->command) { 729 switch (cmd->command) {
720 case NFULNL_CFG_CMD_BIND: 730 case NFULNL_CFG_CMD_BIND:
721 if (inst) { 731 if (inst) {
@@ -738,14 +748,6 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
738 748
739 instance_destroy(inst); 749 instance_destroy(inst);
740 goto out; 750 goto out;
741 case NFULNL_CFG_CMD_PF_BIND:
742 ret = nf_log_register(pf, &nfulnl_logger);
743 break;
744 case NFULNL_CFG_CMD_PF_UNBIND:
745 /* This is a bug and a feature. We cannot unregister
746 * other handlers, like nfnetlink_inst can */
747 nf_log_unregister_pf(pf);
748 break;
749 default: 751 default:
750 ret = -ENOTSUPP; 752 ret = -ENOTSUPP;
751 break; 753 break;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 0043d3a9f87e..012cb6910820 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -224,7 +224,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
224 struct net_device *indev; 224 struct net_device *indev;
225 struct net_device *outdev; 225 struct net_device *outdev;
226 226
227 size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) 227 size = NLMSG_SPACE(sizeof(struct nfgenmsg))
228 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) 228 + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
229 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 229 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
230 + nla_total_size(sizeof(u_int32_t)) /* ifindex */ 230 + nla_total_size(sizeof(u_int32_t)) /* ifindex */
@@ -703,19 +703,12 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
703 /* Commands without queue context - might sleep */ 703 /* Commands without queue context - might sleep */
704 switch (cmd->command) { 704 switch (cmd->command) {
705 case NFQNL_CFG_CMD_PF_BIND: 705 case NFQNL_CFG_CMD_PF_BIND:
706 ret = nf_register_queue_handler(ntohs(cmd->pf), 706 return nf_register_queue_handler(ntohs(cmd->pf),
707 &nfqh); 707 &nfqh);
708 break;
709 case NFQNL_CFG_CMD_PF_UNBIND: 708 case NFQNL_CFG_CMD_PF_UNBIND:
710 ret = nf_unregister_queue_handler(ntohs(cmd->pf), 709 return nf_unregister_queue_handler(ntohs(cmd->pf),
711 &nfqh); 710 &nfqh);
712 break;
713 default:
714 break;
715 } 711 }
716
717 if (ret < 0)
718 return ret;
719 } 712 }
720 713
721 rcu_read_lock(); 714 rcu_read_lock();
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c
index e9a8794bc3ab..9fa2e0824708 100644
--- a/net/netfilter/xt_time.c
+++ b/net/netfilter/xt_time.c
@@ -95,8 +95,11 @@ static inline void localtime_2(struct xtm *r, time_t time)
95 */ 95 */
96 r->dse = time / 86400; 96 r->dse = time / 86400;
97 97
98 /* 1970-01-01 (w=0) was a Thursday (4). */ 98 /*
99 r->weekday = (4 + r->dse) % 7; 99 * 1970-01-01 (w=0) was a Thursday (4).
100 * -1 and +1 map Sunday properly onto 7.
101 */
102 r->weekday = (4 + r->dse - 1) % 7 + 1;
100} 103}
101 104
102static void localtime_3(struct xtm *r, time_t time) 105static void localtime_3(struct xtm *r, time_t time)
diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c
index f19121d4795b..a39bf97f8830 100644
--- a/net/rxrpc/ar-recvmsg.c
+++ b/net/rxrpc/ar-recvmsg.c
@@ -143,7 +143,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
143 /* copy the peer address and timestamp */ 143 /* copy the peer address and timestamp */
144 if (!continue_call) { 144 if (!continue_call) {
145 if (msg->msg_name && msg->msg_namelen > 0) 145 if (msg->msg_name && msg->msg_namelen > 0)
146 memcpy(&msg->msg_name, &call->conn->trans->peer->srx, 146 memcpy(msg->msg_name,
147 &call->conn->trans->peer->srx,
147 sizeof(call->conn->trans->peer->srx)); 148 sizeof(call->conn->trans->peer->srx));
148 sock_recv_timestamp(msg, &rx->sk, skb); 149 sock_recv_timestamp(msg, &rx->sk, skb);
149 } 150 }
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index a27511ebc4cb..ceefda025e2d 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -209,6 +209,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
209int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) 209int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
210{ 210{
211 struct sctp_sockaddr_entry *addr, *temp; 211 struct sctp_sockaddr_entry *addr, *temp;
212 int found = 0;
212 213
213 /* We hold the socket lock when calling this function, 214 /* We hold the socket lock when calling this function,
214 * and that acts as a writer synchronizing lock. 215 * and that acts as a writer synchronizing lock.
@@ -216,13 +217,14 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
216 list_for_each_entry_safe(addr, temp, &bp->address_list, list) { 217 list_for_each_entry_safe(addr, temp, &bp->address_list, list) {
217 if (sctp_cmp_addr_exact(&addr->a, del_addr)) { 218 if (sctp_cmp_addr_exact(&addr->a, del_addr)) {
218 /* Found the exact match. */ 219 /* Found the exact match. */
220 found = 1;
219 addr->valid = 0; 221 addr->valid = 0;
220 list_del_rcu(&addr->list); 222 list_del_rcu(&addr->list);
221 break; 223 break;
222 } 224 }
223 } 225 }
224 226
225 if (addr && !addr->valid) { 227 if (found) {
226 call_rcu(&addr->rcu, sctp_local_addr_free); 228 call_rcu(&addr->rcu, sctp_local_addr_free);
227 SCTP_DBG_OBJCNT_DEC(addr); 229 SCTP_DBG_OBJCNT_DEC(addr);
228 return 0; 230 return 0;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 87f940587d5f..9aa0733aee87 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -89,6 +89,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
89 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; 89 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
90 struct sctp_sockaddr_entry *addr = NULL; 90 struct sctp_sockaddr_entry *addr = NULL;
91 struct sctp_sockaddr_entry *temp; 91 struct sctp_sockaddr_entry *temp;
92 int found = 0;
92 93
93 switch (ev) { 94 switch (ev) {
94 case NETDEV_UP: 95 case NETDEV_UP:
@@ -111,13 +112,14 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
111 &sctp_local_addr_list, list) { 112 &sctp_local_addr_list, list) {
112 if (ipv6_addr_equal(&addr->a.v6.sin6_addr, 113 if (ipv6_addr_equal(&addr->a.v6.sin6_addr,
113 &ifa->addr)) { 114 &ifa->addr)) {
115 found = 1;
114 addr->valid = 0; 116 addr->valid = 0;
115 list_del_rcu(&addr->list); 117 list_del_rcu(&addr->list);
116 break; 118 break;
117 } 119 }
118 } 120 }
119 spin_unlock_bh(&sctp_local_addr_lock); 121 spin_unlock_bh(&sctp_local_addr_lock);
120 if (addr && !addr->valid) 122 if (found)
121 call_rcu(&addr->rcu, sctp_local_addr_free); 123 call_rcu(&addr->rcu, sctp_local_addr_free);
122 break; 124 break;
123 } 125 }
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 688546dccd82..ad0a4069b95b 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -628,6 +628,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
628 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 628 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
629 struct sctp_sockaddr_entry *addr = NULL; 629 struct sctp_sockaddr_entry *addr = NULL;
630 struct sctp_sockaddr_entry *temp; 630 struct sctp_sockaddr_entry *temp;
631 int found = 0;
631 632
632 switch (ev) { 633 switch (ev) {
633 case NETDEV_UP: 634 case NETDEV_UP:
@@ -647,13 +648,14 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
647 list_for_each_entry_safe(addr, temp, 648 list_for_each_entry_safe(addr, temp,
648 &sctp_local_addr_list, list) { 649 &sctp_local_addr_list, list) {
649 if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { 650 if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) {
651 found = 1;
650 addr->valid = 0; 652 addr->valid = 0;
651 list_del_rcu(&addr->list); 653 list_del_rcu(&addr->list);
652 break; 654 break;
653 } 655 }
654 } 656 }
655 spin_unlock_bh(&sctp_local_addr_lock); 657 spin_unlock_bh(&sctp_local_addr_lock);
656 if (addr && !addr->valid) 658 if (found)
657 call_rcu(&addr->rcu, sctp_local_addr_free); 659 call_rcu(&addr->rcu, sctp_local_addr_free);
658 break; 660 break;
659 } 661 }
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index e45be4e3f80d..578630e8e00d 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2375,6 +2375,14 @@ static int sctp_process_param(struct sctp_association *asoc,
2375 asoc->peer.ipv4_address = 0; 2375 asoc->peer.ipv4_address = 0;
2376 asoc->peer.ipv6_address = 0; 2376 asoc->peer.ipv6_address = 0;
2377 2377
2378 /* Assume that peer supports the address family
2379 * by which it sends a packet.
2380 */
2381 if (peer_addr->sa.sa_family == AF_INET6)
2382 asoc->peer.ipv6_address = 1;
2383 else if (peer_addr->sa.sa_family == AF_INET)
2384 asoc->peer.ipv4_address = 1;
2385
2378 /* Cycle through address types; avoid divide by 0. */ 2386 /* Cycle through address types; avoid divide by 0. */
2379 sat = ntohs(param.p->length) - sizeof(sctp_paramhdr_t); 2387 sat = ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
2380 if (sat) 2388 if (sat)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 939892691a26..d994d822900d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2933,17 +2933,39 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
2933 char __user *optval, 2933 char __user *optval,
2934 int optlen) 2934 int optlen)
2935{ 2935{
2936 struct sctp_assoc_value params;
2937 struct sctp_sock *sp;
2938 struct sctp_association *asoc;
2936 int val; 2939 int val;
2940 int assoc_id = 0;
2937 2941
2938 if (optlen != sizeof(int)) 2942 if (optlen < sizeof(int))
2939 return -EINVAL; 2943 return -EINVAL;
2940 if (get_user(val, (int __user *)optval))
2941 return -EFAULT;
2942 2944
2943 if (val < 0) 2945 if (optlen == sizeof(int)) {
2946 printk(KERN_WARNING
2947 "SCTP: Use of int in max_burst socket option deprecated\n");
2948 printk(KERN_WARNING
2949 "SCTP: Use struct sctp_assoc_value instead\n");
2950 if (copy_from_user(&val, optval, optlen))
2951 return -EFAULT;
2952 } else if (optlen == sizeof(struct sctp_assoc_value)) {
2953 if (copy_from_user(&params, optval, optlen))
2954 return -EFAULT;
2955 val = params.assoc_value;
2956 assoc_id = params.assoc_id;
2957 } else
2944 return -EINVAL; 2958 return -EINVAL;
2945 2959
2946 sctp_sk(sk)->max_burst = val; 2960 sp = sctp_sk(sk);
2961
2962 if (assoc_id != 0) {
2963 asoc = sctp_id2assoc(sk, assoc_id);
2964 if (!asoc)
2965 return -EINVAL;
2966 asoc->max_burst = val;
2967 } else
2968 sp->max_burst = val;
2947 2969
2948 return 0; 2970 return 0;
2949} 2971}
@@ -5005,20 +5027,45 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5005 char __user *optval, 5027 char __user *optval,
5006 int __user *optlen) 5028 int __user *optlen)
5007{ 5029{
5008 int val; 5030 struct sctp_assoc_value params;
5031 struct sctp_sock *sp;
5032 struct sctp_association *asoc;
5009 5033
5010 if (len < sizeof(int)) 5034 if (len < sizeof(int))
5011 return -EINVAL; 5035 return -EINVAL;
5012 5036
5013 len = sizeof(int); 5037 if (len == sizeof(int)) {
5038 printk(KERN_WARNING
5039 "SCTP: Use of int in max_burst socket option deprecated\n");
5040 printk(KERN_WARNING
5041 "SCTP: Use struct sctp_assoc_value instead\n");
5042 params.assoc_id = 0;
5043 } else if (len == sizeof (struct sctp_assoc_value)) {
5044 if (copy_from_user(&params, optval, len))
5045 return -EFAULT;
5046 } else
5047 return -EINVAL;
5014 5048
5015 val = sctp_sk(sk)->max_burst; 5049 sp = sctp_sk(sk);
5016 if (put_user(len, optlen)) 5050
5017 return -EFAULT; 5051 if (params.assoc_id != 0) {
5018 if (copy_to_user(optval, &val, len)) 5052 asoc = sctp_id2assoc(sk, params.assoc_id);
5019 return -EFAULT; 5053 if (!asoc)
5054 return -EINVAL;
5055 params.assoc_value = asoc->max_burst;
5056 } else
5057 params.assoc_value = sp->max_burst;
5058
5059 if (len == sizeof(int)) {
5060 if (copy_to_user(optval, &params.assoc_value, len))
5061 return -EFAULT;
5062 } else {
5063 if (copy_to_user(optval, &params, len))
5064 return -EFAULT;
5065 }
5066
5067 return 0;
5020 5068
5021 return -ENOTSUPP;
5022} 5069}
5023 5070
5024static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, 5071static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,