diff options
Diffstat (limited to 'net')
43 files changed, 279 insertions, 275 deletions
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index be04e9fb11f..ab166b48ce8 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -196,6 +196,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s switch (CAPIMSG_SUBCOMMAND(skb->data)) { case CAPI_CONF: + if (skb->len < CAPI_MSG_BASELEN + 10) + break; + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); @@ -226,6 +229,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_FUNCTION_GET_PROFILE: + if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile)) + break; + controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); msgnum = CAPIMSG_MSGID(skb->data); @@ -246,17 +252,26 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_FUNCTION_GET_MANUFACTURER: + if (skb->len < CAPI_MSG_BASELEN + 15) + break; + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); if (!info && ctrl) { + int len = min_t(uint, CAPI_MANUFACTURER_LEN, + skb->data[CAPI_MSG_BASELEN + 14]); + + memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN); strncpy(ctrl->manu, - skb->data + CAPI_MSG_BASELEN + 15, - skb->data[CAPI_MSG_BASELEN + 14]); + skb->data + CAPI_MSG_BASELEN + 15, len); } break; case CAPI_FUNCTION_GET_VERSION: + if (skb->len < CAPI_MSG_BASELEN + 32) + break; + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); if (!info && ctrl) { @@ -269,13 +284,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_FUNCTION_GET_SERIAL_NUMBER: + if (skb->len < CAPI_MSG_BASELEN + 17) + break; + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); if (!info && ctrl) { + int len = min_t(uint, CAPI_SERIAL_LEN, + skb->data[CAPI_MSG_BASELEN + 16]); + memset(ctrl->serial, 0, CAPI_SERIAL_LEN); strncpy(ctrl->serial, - skb->data + CAPI_MSG_BASELEN + 17, - skb->data[CAPI_MSG_BASELEN + 16]); + skb->data + CAPI_MSG_BASELEN + 17, len); } break; @@ -284,14 +304,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s break; case CAPI_IND: + if (skb->len < CAPI_MSG_BASELEN + 6) + break; + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); if (func == CAPI_FUNCTION_LOOPBACK) { + int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6, + skb->data[CAPI_MSG_BASELEN + 5]); appl = CAPIMSG_APPID(skb->data); msgnum = CAPIMSG_MSGID(skb->data); cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, - skb->data + CAPI_MSG_BASELEN + 6, - skb->data[CAPI_MSG_BASELEN + 5]); + skb->data + CAPI_MSG_BASELEN + 6, len); } break; @@ -309,6 +333,9 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) BT_DBG("session %p skb %p len %d", session, skb, skb->len); + if (skb->len < CAPI_MSG_BASELEN) + return; + if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { cmtp_recv_interopmsg(session, skb); return; diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index d4c935692cc..801d687ea4e 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -242,7 +242,7 @@ static void add_conn(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, work); int i; - if (device_register(&conn->dev) < 0) { + if (device_add(&conn->dev) < 0) { BT_ERR("Failed to register connection device"); return; } @@ -272,6 +272,8 @@ void hci_conn_add_sysfs(struct hci_conn *conn) dev_set_drvdata(&conn->dev, conn); + device_initialize(&conn->dev); + INIT_WORK(&conn->work, add_conn); schedule_work(&conn->work); @@ -287,6 +289,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn) { BT_DBG("conn %p", conn); + if (!device_is_registered(&conn->dev)) + return; + INIT_WORK(&conn->work, del_conn); schedule_work(&conn->work); diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 29a8fa4d372..f8c25d50015 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -585,6 +585,12 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_ goto done; } + if (la->l2_psm > 0 && btohs(la->l2_psm) < 0x1001 && + !capable(CAP_NET_BIND_SERVICE)) { + err = -EACCES; + goto done; + } + write_lock_bh(&l2cap_sk_list.lock); if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) { @@ -2150,8 +2156,8 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu, - pi->omtu, pi->link_mode); + sk->sk_state, btohs(pi->psm), pi->scid, pi->dcid, + pi->imtu, pi->omtu, pi->link_mode); } read_unlock_bh(&l2cap_sk_list.lock); diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 544d65b7baa..cb7e855f082 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -557,7 +557,6 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; struct sk_buff *skb; - int err; int sent = 0; if (msg->msg_flags & MSG_OOB) @@ -572,6 +571,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, while (len) { size_t size = min_t(size_t, len, d->mtu); + int err; skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, msg->msg_flags & MSG_DONTWAIT, &err); @@ -582,13 +582,16 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); if (err) { kfree_skb(skb); - sent = err; + if (sent == 0) + sent = err; break; } err = rfcomm_dlc_send(d, skb); if (err < 0) { kfree_skb(skb); + if (sent == 0) + sent = err; break; } @@ -598,7 +601,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, release_sock(sk); - return sent ? sent : err; + return sent; } static long rfcomm_sock_data_wait(struct sock *sk, long timeo) diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index e0e0d09023b..eb2b52484c7 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -697,9 +697,13 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) BT_DBG("tty %p", tty); + if (!dev || !dev->dlc) + return 0; + room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc); if (room < 0) room = 0; + return room; } @@ -915,12 +919,14 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - struct rfcomm_dlc *dlc = dev->dlc; BT_DBG("tty %p dev %p", tty, dev); - if (!skb_queue_empty(&dlc->tx_queue)) - return dlc->mtu; + if (!dev || !dev->dlc) + return 0; + + if (!skb_queue_empty(&dev->dlc->tx_queue)) + return dev->dlc->mtu; return 0; } @@ -928,11 +934,12 @@ static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) static void rfcomm_tty_flush_buffer(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - if (!dev) - return; BT_DBG("tty %p dev %p", tty, dev); + if (!dev || !dev->dlc) + return; + skb_queue_purge(&dev->dlc->tx_queue); if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup) @@ -952,11 +959,12 @@ static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) static void rfcomm_tty_hangup(struct tty_struct *tty) { struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; - if (!dev) - return; BT_DBG("tty %p dev %p", tty, dev); + if (!dev) + return; + rfcomm_tty_flush_buffer(tty); if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bee558a4180..6c84ccb8c9d 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -610,7 +610,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, struct ebt_entry_target *t; struct ebt_target *target; unsigned int i, j, hook = 0, hookmask = 0; - size_t gap = e->next_offset - e->target_offset; + size_t gap; int ret; /* don't mess with the struct ebt_entries */ @@ -660,6 +660,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, if (ret != 0) goto cleanup_watchers; t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); + gap = e->next_offset - e->target_offset; target = find_target_lock(t->u.name, &ret, &ebt_mutex); if (!target) goto cleanup_watchers; diff --git a/net/core/flow.c b/net/core/flow.c index d137f971f97..5d25697920b 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -231,22 +231,16 @@ nocache: err = resolver(key, family, dir, &obj, &obj_ref); - if (fle) { - if (err) { - /* Force security policy check on next lookup */ - *head = fle->next; - flow_entry_kill(cpu, fle); - } else { - fle->genid = atomic_read(&flow_cache_genid); - - if (fle->object) - atomic_dec(fle->object_ref); - - fle->object = obj; - fle->object_ref = obj_ref; - if (obj) - atomic_inc(fle->object_ref); - } + if (fle && !err) { + fle->genid = atomic_read(&flow_cache_genid); + + if (fle->object) + atomic_dec(fle->object_ref); + + fle->object = obj; + fle->object_ref = obj_ref; + if (obj) + atomic_inc(fle->object_ref); } local_bh_enable(); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 1897a3a385d..04d4b93c68e 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -148,6 +148,7 @@ #include <linux/seq_file.h> #include <linux/wait.h> #include <linux/etherdevice.h> +#include <linux/kthread.h> #include <net/checksum.h> #include <net/ipv6.h> #include <net/addrconf.h> @@ -360,8 +361,7 @@ struct pktgen_thread { spinlock_t if_lock; struct list_head if_list; /* All device here */ struct list_head th_list; - int removed; - char name[32]; + struct task_struct *tsk; char result[512]; u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ @@ -1689,7 +1689,7 @@ static int pktgen_thread_show(struct seq_file *seq, void *v) BUG_ON(!t); seq_printf(seq, "Name: %s max_before_softirq: %d\n", - t->name, t->max_before_softirq); + t->tsk->comm, t->max_before_softirq); seq_printf(seq, "Running: "); @@ -3112,7 +3112,7 @@ static void pktgen_rem_thread(struct pktgen_thread *t) { /* Remove from the thread list */ - remove_proc_entry(t->name, pg_proc_dir); + remove_proc_entry(t->tsk->comm, pg_proc_dir); mutex_lock(&pktgen_thread_lock); @@ -3260,58 +3260,40 @@ out:; * Main loop of the thread goes here */ -static void pktgen_thread_worker(struct pktgen_thread *t) +static int pktgen_thread_worker(void *arg) { DEFINE_WAIT(wait); + struct pktgen_thread *t = arg; struct pktgen_dev *pkt_dev = NULL; int cpu = t->cpu; - sigset_t tmpsig; u32 max_before_softirq; u32 tx_since_softirq = 0; - daemonize("pktgen/%d", cpu); - - /* Block all signals except SIGKILL, SIGSTOP and SIGTERM */ - - spin_lock_irq(¤t->sighand->siglock); - tmpsig = current->blocked; - siginitsetinv(¤t->blocked, - sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGTERM)); - - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - /* Migrate to the right CPU */ - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (smp_processor_id() != cpu) - BUG(); + BUG_ON(smp_processor_id() != cpu); init_waitqueue_head(&t->queue); - t->control &= ~(T_TERMINATE); - t->control &= ~(T_RUN); - t->control &= ~(T_STOP); - t->control &= ~(T_REMDEVALL); - t->control &= ~(T_REMDEV); - t->pid = current->pid; PG_DEBUG(printk("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid)); max_before_softirq = t->max_before_softirq; - __set_current_state(TASK_INTERRUPTIBLE); - mb(); + set_current_state(TASK_INTERRUPTIBLE); - while (1) { - - __set_current_state(TASK_RUNNING); + while (!kthread_should_stop()) { + pkt_dev = next_to_run(t); - /* - * Get next dev to xmit -- if any. - */ + if (!pkt_dev && + (t->control & (T_STOP | T_RUN | T_REMDEVALL | T_REMDEV)) + == 0) { + prepare_to_wait(&(t->queue), &wait, + TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + finish_wait(&(t->queue), &wait); + } - pkt_dev = next_to_run(t); + __set_current_state(TASK_RUNNING); if (pkt_dev) { @@ -3329,21 +3311,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t) do_softirq(); tx_since_softirq = 0; } - } else { - prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 10); - finish_wait(&(t->queue), &wait); } - /* - * Back from sleep, either due to the timeout or signal. - * We check if we have any "posted" work for us. - */ - - if (t->control & T_TERMINATE || signal_pending(current)) - /* we received a request to terminate ourself */ - break; - if (t->control & T_STOP) { pktgen_stop(t); t->control &= ~(T_STOP); @@ -3364,20 +3333,19 @@ static void pktgen_thread_worker(struct pktgen_thread *t) t->control &= ~(T_REMDEV); } - if (need_resched()) - schedule(); + set_current_state(TASK_INTERRUPTIBLE); } - PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name)); + PG_DEBUG(printk("pktgen: %s stopping all device\n", t->tsk->comm)); pktgen_stop(t); - PG_DEBUG(printk("pktgen: %s removing all device\n", t->name)); + PG_DEBUG(printk("pktgen: %s removing all device\n", t->tsk->comm)); pktgen_rem_all_ifs(t); - PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); + PG_DEBUG(printk("pktgen: %s removing thread.\n", t->tsk->comm)); pktgen_rem_thread(t); - t->removed = 1; + return 0; } static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, @@ -3495,37 +3463,11 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) return add_dev_to_thread(t, pkt_dev); } -static struct pktgen_thread *__init pktgen_find_thread(const char *name) +static int __init pktgen_create_thread(int cpu) { struct pktgen_thread *t; - - mutex_lock(&pktgen_thread_lock); - - list_for_each_entry(t, &pktgen_threads, th_list) - if (strcmp(t->name, name) == 0) { - mutex_unlock(&pktgen_thread_lock); - return t; - } - - mutex_unlock(&pktgen_thread_lock); - return NULL; -} - -static int __init pktgen_create_thread(const char *name, int cpu) -{ - int err; - struct pktgen_thread *t = NULL; struct proc_dir_entry *pe; - - if (strlen(name) > 31) { - printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n"); - return -EINVAL; - } - - if (pktgen_find_thread(name)) { - printk("pktgen: ERROR: thread: %s already exists\n", name); - return -EINVAL; - } + struct task_struct *p; t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL); if (!t) { @@ -3533,14 +3475,29 @@ static int __init pktgen_create_thread(const char *name, int cpu) return -ENOMEM; } - strcpy(t->name, name); spin_lock_init(&t->if_lock); t->cpu = cpu; - pe = create_proc_entry(t->name, 0600, pg_proc_dir); + INIT_LIST_HEAD(&t->if_list); + + list_add_tail(&t->th_list, &pktgen_threads); + + p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); + if (IS_ERR(p)) { + printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); + list_del(&t->th_list); + kfree(t); + return PTR_ERR(p); + } + kthread_bind(p, cpu); + t->tsk = p; + + pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir); if (!pe) { printk("pktgen: cannot create %s/%s procfs entry.\n", - PG_PROC_DIR, t->name); + PG_PROC_DIR, t->tsk->comm); + kthread_stop(p); + list_del(&t->th_list); kfree(t); return -EINVAL; } @@ -3548,21 +3505,7 @@ static int __init pktgen_create_thread(const char *name, int cpu) pe->proc_fops = &pktgen_thread_fops; pe->data = t; - INIT_LIST_HEAD(&t->if_list); - - list_add_tail(&t->th_list, &pktgen_threads); - - t->removed = 0; - - err = kernel_thread((void *)pktgen_thread_worker, (void *)t, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - if (err < 0) { - printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); - remove_proc_entry(t->name, pg_proc_dir); - list_del(&t->th_list); - kfree(t); - return err; - } + wake_up_process(p); return 0; } @@ -3643,10 +3586,8 @@ static int __init pg_init(void) for_each_online_cpu(cpu) { int err; - char buf[30]; - sprintf(buf, "kpktgend_%i", cpu); - err = pktgen_create_thread(buf, cpu); + err = pktgen_create_thread(cpu); if (err) printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n", cpu, err); @@ -3674,9 +3615,8 @@ static void __exit pg_cleanup(void) list_for_each_safe(q, n, &pktgen_threads) { t = list_entry(q, struct pktgen_thread, th_list); - t->control |= (T_TERMINATE); - - wait_event_interruptible_timeout(queue, (t->removed == 1), HZ); + kthread_stop(t->tsk); + kfree(t); } /* Un-register us from receiving netdevice events */ diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index e3f37fdda65..a824852909e 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -167,7 +167,7 @@ static void ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context) { struct ieee80211softmac_device *mac = ieee80211_priv(dev); - ieee80211softmac_assoc_work((void*)mac); + ieee80211softmac_assoc_work(&mac->associnfo.work.work); } static void @@ -177,7 +177,7 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void switch (event_type) { case IEEE80211SOFTMAC_EVENT_AUTHENTICATED: - ieee80211softmac_assoc_work((void*)mac); + ieee80211softmac_assoc_work(&mac->associnfo.work.work); break; case IEEE80211SOFTMAC_EVENT_AUTH_FAILED: case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT: diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 480d72c7a42..fa2f7da606a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -463,7 +463,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev, err = -E2BIG; } spin_unlock_irqrestore(&mac->lock, flags); - mutex_lock(&mac->associnfo.mutex); + mutex_unlock(&mac->associnfo.mutex); return err; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 1144900d37f..86400964367 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -305,7 +305,7 @@ lookup_protocol: sk->sk_reuse = 1; inet = inet_sk(sk); - inet->is_icsk = INET_PROTOSW_ICSK & answer_flags; + inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; if (SOCK_RAW == sock->type) { inet->num = protocol; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 84bed40273a..480ace9819f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -165,9 +165,8 @@ struct in_device *inetdev_init(struct net_device *dev) NET_IPV4_NEIGH, "ipv4", NULL, NULL); #endif - /* Account for reference dev->ip_ptr */ + /* Account for reference dev->ip_ptr (below) */ in_dev_hold(in_dev); - rcu_assign_pointer(dev->ip_ptr, in_dev); #ifdef CONFIG_SYSCTL devinet_sysctl_register(in_dev, &in_dev->cnf); @@ -175,6 +174,9 @@ struct in_device *inetdev_init(struct net_device *dev) ip_mc_init_dev(in_dev); if (dev->flags & IFF_UP) ip_mc_up(in_dev); + + /* we can receive as soon as ip_ptr is set -- do this last */ + rcu_assign_pointer(dev->ip_ptr, in_dev); out: return in_dev; out_kfree: diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index a68966059b5..c47ce7076bd 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -15,16 +15,19 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type) struct flowi fl = {}; struct dst_entry *odst; unsigned int hh_len; + unsigned int type; + type = inet_addr_type(iph->saddr); if (addr_type == RTN_UNSPEC) - addr_type = inet_addr_type(iph->saddr); + addr_type = type; /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook. */ if (addr_type == RTN_LOCAL) { fl.nl_u.ip4_u.daddr = iph->daddr; - fl.nl_u.ip4_u.saddr = iph->saddr; + if (type == RTN_LOCAL) + fl.nl_u.ip4_u.saddr = iph->saddr; fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0; fl.mark = (*pskb)->mark; diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index f6026d4ac42..47bd3ad18b7 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -6,8 +6,8 @@ menu "IP: Netfilter Configuration" depends on INET && NETFILTER config NF_CONNTRACK_IPV4 - tristate "IPv4 connection tracking support (required for NAT) (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + tristate "IPv4 connection tracking support (required for NAT)" + depends on NF_CONNTRACK ---help--- Connection tracking keeps a record of what packets have passed through your machine, in order to figure out how they are related diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 5fcf91d617c..6f31fad9be1 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c @@ -959,7 +959,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], if (cda[CTA_PROTOINFO-1]) { err = ctnetlink_change_protoinfo(ct, cda); if (err < 0) - return err; + goto err; } #if defined(CONFIG_IP_NF_CONNTRACK_MARK) diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 09696f16aa9..fc1f153c86b 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -919,13 +919,13 @@ copy_entries_to_user(unsigned int total_size, #ifdef CONFIG_COMPAT struct compat_delta { struct compat_delta *next; - u_int16_t offset; + unsigned int offset; short delta; }; static struct compat_delta *compat_offsets = NULL; -static int compat_add_offset(u_int16_t offset, short delta) +static int compat_add_offset(unsigned int offset, short delta) { struct compat_delta *tmp; @@ -957,7 +957,7 @@ static void compat_flush_offsets(void) } } -static short compat_calc_jump(u_int16_t offset) +static short compat_calc_jump(unsigned int offset) { struct compat_delta *tmp; short delta; @@ -997,7 +997,7 @@ static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info, void *base, struct xt_table_info *newinfo) { struct ipt_entry_target *t; - u_int16_t entry_offset; + unsigned int entry_offset; int off, i, ret; off = 0; @@ -1467,7 +1467,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, { struct ipt_entry_target *t; struct ipt_target *target; - u_int16_t entry_offset; + unsigned int entry_offset; int ret, off, h, j; duprintf("check_compat_entry_size_and_hooks %p\n", e); diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 28b9233956b..d669685afd0 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -127,10 +127,13 @@ masquerade_target(struct sk_buff **pskb, static inline int device_cmp(struct ip_conntrack *i, void *ifindex) { + int ret; #ifdef CONFIG_NF_NAT_NEEDED struct nf_conn_nat *nat = nfct_nat(i); + + if (!nat) + return 0; #endif - int ret; read_lock_bh(&masq_lock); #ifdef CONFIG_NF_NAT_NEEDED diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index 730a7a44c88..00d6dea9f7f 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c @@ -123,7 +123,7 @@ nf_nat_fn(unsigned int hooknum, nat = nfct_nat(ct); if (!nat) - return NF_DROP; + return NF_ACCEPT; switch (ctinfo) { case IP_CT_RELATED: diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c701f6abbfc..5c16e24a606 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4420,9 +4420,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * But, this leaves one open to an easy denial of * service attack, and SYN cookies can't defend * against this problem. So, we drop the data - * in the interest of security over speed. + * in the interest of security over speed unless + * it's still in use. */ - goto discard; + kfree_skb(skb); + return 0; } goto discard; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index bf7a22412bc..12de90a5047 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -648,7 +648,7 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, TCPOLEN_TIMESTAMP); rep.opt[1] = htonl(tcp_time_stamp); rep.opt[2] = htonl(ts); - arg.iov[0].iov_len = TCPOLEN_TSTAMP_ALIGNED; + arg.iov[0].iov_len += TCPOLEN_TSTAMP_ALIGNED; } /* Swap the send and the receive. */ diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 32c1a972fa3..23e32c80691 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1650,7 +1650,8 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size); - skb->ip_summed = next_skb->ip_summed; + if (next_skb->ip_summed == CHECKSUM_PARTIAL) + skb->ip_summed = CHECKSUM_PARTIAL; if (skb->ip_summed != CHECKSUM_PARTIAL) skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size); diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index f230eeecf09..41c15784818 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c @@ -30,7 +30,7 @@ #include <net/tcp.h> -MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); +MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); MODULE_DESCRIPTION("TCP cwnd snooper"); MODULE_LICENSE("GPL"); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9b0a9064315..2a7e4618f52 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -341,6 +341,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) static struct inet6_dev * ipv6_add_dev(struct net_device *dev) { struct inet6_dev *ndev; + struct in6_addr maddr; ASSERT_RTNL(); @@ -413,8 +414,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) if (netif_carrier_ok(dev)) ndev->if_flags |= IF_READY; - /* protected by rtnl_lock */ - rcu_assign_pointer(dev->ip6_ptr, ndev); ipv6_mc_init_dev(ndev); ndev->tstamp = jiffies; @@ -425,6 +424,13 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) NULL); addrconf_sysctl_register(ndev, &ndev->cnf); #endif + /* protected by rtnl_lock */ + rcu_assign_pointer(dev->ip6_ptr, ndev); + + /* Join all-node multicast group */ + ipv6_addr_all_nodes(&maddr); + ipv6_dev_mc_inc(dev, &maddr); + return ndev; } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e5cd83b2205..0e0e4262f4d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -171,7 +171,7 @@ lookup_protocol: sk->sk_reuse = 1; inet = inet_sk(sk); - inet->is_icsk = INET_PROTOSW_ICSK & answer_flags; + inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; if (SOCK_RAW == sock->type) { inet->num = protocol; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index a1c231a04ac..882cde4b404 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2258,8 +2258,6 @@ void ipv6_mc_up(struct inet6_dev *idev) void ipv6_mc_init_dev(struct inet6_dev *idev) { - struct in6_addr maddr; - write_lock_bh(&idev->lock); rwlock_init(&idev->mc_lock); idev->mc_gq_running = 0; @@ -2275,10 +2273,6 @@ void ipv6_mc_init_dev(struct inet6_dev *idev) idev->mc_maxdelay = IGMP6_UNSOLICITED_IVAL; idev->mc_v1_seen = 0; write_unlock_bh(&idev->lock); - - /* Add all-nodes address. */ - ipv6_addr_all_nodes(&maddr); - ipv6_dev_mc_inc(idev->dev, &maddr); } /* diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 37e5fca923a..d9c15402ba6 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -835,6 +835,8 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, s->nfct_reasm = skb; s2 = s->next; + s->next = NULL; + NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1); s = s2; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8c3d56871b5..5f0043c30b7 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2017,6 +2017,7 @@ static inline size_t rt6_nlmsg_size(void) + nla_total_size(4) /* RTA_IIF */ + nla_total_size(4) /* RTA_OIF */ + nla_total_size(4) /* RTA_PRIORITY */ + + RTAX_MAX * nla_total_size(4) /* RTA_METRICS */ + nla_total_size(sizeof(struct rta_cacheinfo)); } diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 1b853c34d30..cd10e44db01 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -44,8 +44,7 @@ choice depends on NF_CONNTRACK_ENABLED config NF_CONNTRACK_SUPPORT - bool "Layer 3 Independent Connection tracking (EXPERIMENTAL)" - depends on EXPERIMENTAL + bool "Layer 3 Independent Connection tracking" help Layer 3 independent connection tracking is experimental scheme which generalize ip_conntrack to support other layer 3 protocols. @@ -122,7 +121,7 @@ config NF_CONNTRACK_EVENTS config NF_CT_PROTO_GRE tristate - depends on EXPERIMENTAL && NF_CONNTRACK + depends on NF_CONNTRACK config NF_CT_PROTO_SCTP tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' @@ -136,8 +135,8 @@ config NF_CT_PROTO_SCTP Documentation/modules.txt. If unsure, say `N'. config NF_CONNTRACK_AMANDA - tristate "Amanda backup protocol support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + tristate "Amanda backup protocol support" + depends on NF_CONNTRACK select TEXTSEARCH select TEXTSEARCH_KMP help @@ -151,8 +150,8 @@ config NF_CONNTRACK_AMANDA To compile it as a module, choose M here. If unsure, say N. config NF_CONNTRACK_FTP - tristate "FTP protocol support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + tristate "FTP protocol support" + depends on NF_CONNTRACK help Tracking FTP connections is problematic: special helpers are required for tracking them, and doing masquerading and other forms @@ -184,8 +183,8 @@ config NF_CONNTRACK_H323 To compile it as a module, choose M here. If unsure, say N. config NF_CONNTRACK_IRC - tristate "IRC protocol support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + tristate "IRC protocol support" + depends on NF_CONNTRACK help There is a commonly-used extension to IRC called Direct Client-to-Client Protocol (DCC). This enables users to send @@ -218,8 +217,8 @@ config NF_CONNTRACK_NETBIOS_NS To compile it as a module, choose M here. If unsure, say N. config NF_CONNTRACK_PPTP - tristate "PPtP protocol support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + tristate "PPtP protocol support" + depends on NF_CONNTRACK select NF_CT_PROTO_GRE help This module adds support for PPTP (Point to Point Tunnelling @@ -249,8 +248,8 @@ config NF_CONNTRACK_SIP To compile it as a module, choose M here. If unsure, say N. config NF_CONNTRACK_TFTP - tristate "TFTP protocol support (EXPERIMENTAL)" - depends on EXPERIMENTAL && NF_CONNTRACK + tristate "TFTP protocol support" + depends on NF_CONNTRACK help TFTP connection tracking helper, this is required depending on how restrictive your ruleset is. diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c index a5b234e444d..2a48efdf0d6 100644 --- a/net/netfilter/nf_conntrack_netbios_ns.c +++ b/net/netfilter/nf_conntrack_netbios_ns.c @@ -89,6 +89,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff, exp->expectfn = NULL; exp->flags = NF_CT_EXPECT_PERMANENT; + exp->helper = NULL; nf_conntrack_expect_related(exp); nf_conntrack_expect_put(exp); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index bd1d2de75e4..811e3e782f0 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -981,7 +981,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], if (cda[CTA_PROTOINFO-1]) { err = ctnetlink_change_protoinfo(ct, cda); if (err < 0) - return err; + goto err; } #if defined(CONFIG_NF_CONNTRACK_MARK) diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index a5a6e192ac2..f28bf69d3d4 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -745,7 +745,7 @@ static int __init xt_hashlimit_init(void) } hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net); if (!hashlimit_procdir6) { - printk(KERN_ERR "xt_hashlimit: tnable to create proc dir " + printk(KERN_ERR "xt_hashlimit: unable to create proc dir " "entry\n"); goto err4; } diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 4afc75f9e37..73e0ff469bf 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -130,12 +130,12 @@ static int netlbl_cipsov4_add_common(struct genl_info *info, nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem) if (nla->nla_type == NLBL_CIPSOV4_A_TAG) { - if (iter > CIPSO_V4_TAG_MAXCNT) + if (iter >= CIPSO_V4_TAG_MAXCNT) return -EINVAL; doi_def->tags[iter++] = nla_get_u8(nla); } - if (iter < CIPSO_V4_TAG_MAXCNT) - doi_def->tags[iter] = CIPSO_V4_TAG_INVALID; + while (iter < CIPSO_V4_TAG_MAXCNT) + doi_def->tags[iter++] = CIPSO_V4_TAG_INVALID; return 0; } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 276131fe56d..383dd4e82ee 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -472,8 +472,7 @@ static int netlink_release(struct socket *sock) NETLINK_URELEASE, &n); } - if (nlk->module) - module_put(nlk->module); + module_put(nlk->module); netlink_table_grab(); if (nlk->flags & NETLINK_KERNEL_SOCKET) { diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index f0bbe36799c..0b1ddb1005a 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -124,8 +124,8 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, padlen = len % 4; err.length = htons(len); len += padlen; - sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); - chunk->subh.err_hdr = sctp_addto_chunk(chunk, paylen, payload); + chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); + sctp_addto_chunk(chunk, paylen, payload); } /* 3.3.2 Initiation (INIT) (1) @@ -1562,7 +1562,7 @@ static int sctp_process_missing_param(const struct sctp_association *asoc, if (*errp) { report.num_missing = htonl(1); report.type = paramtype; - sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, + sctp_init_cause(*errp, SCTP_ERROR_MISS_PARAM, &report, sizeof(report)); } @@ -1775,7 +1775,9 @@ int sctp_verify_init(const struct sctp_association *asoc, /* Verify stream values are non-zero. */ if ((0 == peer_init->init_hdr.num_outbound_streams) || - (0 == peer_init->init_hdr.num_inbound_streams)) { + (0 == peer_init->init_hdr.num_inbound_streams) || + (0 == peer_init->init_hdr.init_tag) || + (SCTP_DEFAULT_MINWINDOW > ntohl(peer_init->init_hdr.a_rwnd))) { sctp_process_inv_mandatory(asoc, chunk, errp); return 0; diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 7bbc6156e45..8bd30976cde 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -217,7 +217,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, asoc->peer.sack_needed = 0; - error = sctp_outq_tail(&asoc->outqueue, sack); + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(sack)); /* Stop the SACK timer. */ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index aa51d190bfb..fbbc9e6a3b7 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -440,7 +440,6 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, { struct sctp_chunk *chunk = arg; sctp_init_chunk_t *initchunk; - __u32 init_tag; struct sctp_chunk *err_chunk; struct sctp_packet *packet; sctp_error_t error; @@ -462,24 +461,6 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, /* Grab the INIT header. */ chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; - init_tag = ntohl(chunk->subh.init_hdr->init_tag); - - /* Verification Tag: 3.3.3 - * If the value of the Initiate Tag in a received INIT ACK - * chunk is found to be 0, the receiver MUST treat it as an - * error and close the association by transmitting an ABORT. - */ - if (!init_tag) { - struct sctp_chunk *reply = sctp_make_abort(asoc, chunk, 0); - if (!reply) - goto nomem; - - sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply)); - return sctp_stop_t1_and_abort(commands, SCTP_ERROR_INV_PARAM, - ECONNREFUSED, asoc, - chunk->transport); - } - /* Verify the INIT chunk before processing it. */ err_chunk = NULL; if (!sctp_verify_init(asoc, chunk->chunk_hdr->type, @@ -550,9 +531,6 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep, SCTP_CHUNK(err_chunk)); return SCTP_DISPOSITION_CONSUME; - -nomem: - return SCTP_DISPOSITION_NOMEM; } /* @@ -1553,6 +1531,28 @@ sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep, } +/* + * Unexpected INIT-ACK handler. + * + * Section 5.2.3 + * If an INIT ACK received by an endpoint in any state other than the + * COOKIE-WAIT state, the endpoint should discard the INIT ACK chunk. + * An unexpected INIT ACK usually indicates the processing of an old or + * duplicated INIT chunk. +*/ +sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + const sctp_subtype_t type, + void *arg, sctp_cmd_seq_t *commands) +{ + /* Per the above section, we'll discard the chunk if we have an + * endpoint. If this is an OOTB INIT-ACK, treat it as such. + */ + if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) + return sctp_sf_ootb(ep, asoc, type, arg, commands); + else + return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); +} /* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A') * diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 733dd87b3a7..5f6cc7aa661 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c @@ -152,7 +152,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_EMPTY */ \ TYPE_SCTP_FUNC(sctp_sf_ootb), \ /* SCTP_STATE_CLOSED */ \ - TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ + TYPE_SCTP_FUNC(sctp_sf_do_5_2_3_initack), \ /* SCTP_STATE_COOKIE_WAIT */ \ TYPE_SCTP_FUNC(sctp_sf_do_5_1C_ack), \ /* SCTP_STATE_COOKIE_ECHOED */ \ diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 52a2726d327..b5c80b18990 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -484,8 +484,6 @@ out: return sk; } -void x25_init_timers(struct sock *sk); - static int x25_create(struct socket *sock, int protocol) { struct sock *sk; diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index 47b68a30167..328d80f000a 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -56,6 +56,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) sk_add_backlog(sk, skb); } bh_unlock_sock(sk); + sock_put(sk); return queued; } diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 9f42b9c9de3..27f5cc7966f 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -254,7 +254,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, * They want reverse charging, we won't accept it. */ if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) { - SOCK_DEBUG(sk, "X.25: rejecting reverse charging request"); + SOCK_DEBUG(sk, "X.25: rejecting reverse charging request\n"); return -1; } @@ -262,29 +262,29 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, if (theirs.throughput) { if (theirs.throughput < ours->throughput) { - SOCK_DEBUG(sk, "X.25: throughput negotiated down"); + SOCK_DEBUG(sk, "X.25: throughput negotiated down\n"); new->throughput = theirs.throughput; } } if (theirs.pacsize_in && theirs.pacsize_out) { if (theirs.pacsize_in < ours->pacsize_in) { - SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down"); + SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down\n"); new->pacsize_in = theirs.pacsize_in; } if (theirs.pacsize_out < ours->pacsize_out) { - SOCK_DEBUG(sk, "X.25: packet size outwards negotiated down"); + SOCK_DEBUG(sk, "X.25: packet size outwards negotiated down\n"); new->pacsize_out = theirs.pacsize_out; } } if (theirs.winsize_in && theirs.winsize_out) { if (theirs.winsize_in < ours->winsize_in) { - SOCK_DEBUG(sk, "X.25: window size inwards negotiated down"); + SOCK_DEBUG(sk, "X.25: window size inwards negotiated down\n"); new->winsize_in = theirs.winsize_in; } if (theirs.winsize_out < ours->winsize_out) { - SOCK_DEBUG(sk, "X.25: window size outwards negotiated down"); + SOCK_DEBUG(sk, "X.25: window size outwards negotiated down\n"); new->winsize_out = theirs.winsize_out; } } diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 6b381fc0383..f1cf3402e75 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c @@ -399,7 +399,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list, if (!probe) break; - status = crypto_has_alg(name, type, mask | CRYPTO_ALG_ASYNC); + status = crypto_has_alg(list[i].name, type, + mask | CRYPTO_ALG_ASYNC); if (!status) break; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index bebd40e5a62..b7e537fe2d7 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -650,19 +650,18 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) struct xfrm_policy *pol; struct xfrm_policy *delpol; struct hlist_head *chain; - struct hlist_node *entry, *newpos, *last; + struct hlist_node *entry, *newpos; struct dst_entry *gc_list; write_lock_bh(&xfrm_policy_lock); chain = policy_hash_bysel(&policy->selector, policy->family, dir); delpol = NULL; newpos = NULL; - last = NULL; hlist_for_each_entry(pol, entry, chain, bydst) { - if (!delpol && - pol->type == policy->type && + if (pol->type == policy->type && !selector_cmp(&pol->selector, &policy->selector) && - xfrm_sec_ctx_match(pol->security, policy->security)) { + xfrm_sec_ctx_match(pol->security, policy->security) && + !WARN_ON(delpol)) { if (excl) { write_unlock_bh(&xfrm_policy_lock); return -EEXIST; @@ -671,17 +670,12 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) if (policy->priority > pol->priority) continue; } else if (policy->priority >= pol->priority) { - last = &pol->bydst; + newpos = &pol->bydst; continue; } - if (!newpos) - newpos = &pol->bydst; if (delpol) break; - last = &pol->bydst; } - if (!newpos) - newpos = last; if (newpos) hlist_add_after(newpos, &policy->bydst); else diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e5372b11fc8..82f36d396fc 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -434,18 +434,19 @@ error_no_put: return NULL; } -static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_usersa_info *p = NLMSG_DATA(nlh); struct xfrm_state *x; int err; struct km_event c; - err = verify_newsa_info(p, (struct rtattr **)xfrma); + err = verify_newsa_info(p, xfrma); if (err) return err; - x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err); + x = xfrm_state_construct(p, xfrma, &err); if (!x) return err; @@ -507,14 +508,15 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p, return x; } -static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_state *x; int err = -ESRCH; struct km_event c; struct xfrm_usersa_id *p = NLMSG_DATA(nlh); - x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err); + x = xfrm_user_state_lookup(p, xfrma, &err); if (x == NULL) return err; @@ -672,14 +674,15 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, return skb; } -static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_usersa_id *p = NLMSG_DATA(nlh); struct xfrm_state *x; struct sk_buff *resp_skb; int err = -ESRCH; - x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err); + x = xfrm_user_state_lookup(p, xfrma, &err); if (x == NULL) goto out_noput; @@ -718,7 +721,8 @@ static int verify_userspi_info(struct xfrm_userspi_info *p) return 0; } -static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_state *x; struct xfrm_userspi_info *p; @@ -1013,7 +1017,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, return NULL; } -static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh); struct xfrm_policy *xp; @@ -1024,11 +1029,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr err = verify_newpolicy_info(p); if (err) return err; - err = verify_sec_ctx_len((struct rtattr **)xfrma); + err = verify_sec_ctx_len(xfrma); if (err) return err; - xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err); + xp = xfrm_policy_construct(p, xfrma, &err); if (!xp) return err; @@ -1227,7 +1232,8 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, return skb; } -static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_policy *xp; struct xfrm_userpolicy_id *p; @@ -1239,7 +1245,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr p = NLMSG_DATA(nlh); delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; - err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); + err = copy_from_user_policy_type(&type, xfrma); if (err) return err; @@ -1250,11 +1256,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr if (p->index) xp = xfrm_policy_byid(type, p->dir, p->index, delete); else { - struct rtattr **rtattrs = (struct rtattr **)xfrma; - struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; + struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; struct xfrm_policy tmp; - err = verify_sec_ctx_len(rtattrs); + err = verify_sec_ctx_len(xfrma); if (err) return err; @@ -1302,7 +1307,8 @@ out: return err; } -static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct km_event c; struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); @@ -1367,7 +1373,8 @@ nlmsg_failure: return -1; } -static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_state *x; struct sk_buff *r_skb; @@ -1415,7 +1422,8 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) return err; } -static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_state *x; struct km_event c; @@ -1439,7 +1447,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) goto out; spin_lock_bh(&x->lock); - err = xfrm_update_ae_params(x,(struct rtattr **)xfrma); + err = xfrm_update_ae_params(x, xfrma); spin_unlock_bh(&x->lock); if (err < 0) goto out; @@ -1455,14 +1463,15 @@ out: return err; } -static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct km_event c; u8 type = XFRM_POLICY_TYPE_MAIN; int err; struct xfrm_audit audit_info; - err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); + err = copy_from_user_policy_type(&type, xfrma); if (err) return err; @@ -1477,7 +1486,8 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x return 0; } -static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_policy *xp; struct xfrm_user_polexpire *up = NLMSG_DATA(nlh); @@ -1485,18 +1495,17 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void * u8 type = XFRM_POLICY_TYPE_MAIN; int err = -ENOENT; - err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); + err = copy_from_user_policy_type(&type, xfrma); if (err) return err; if (p->index) xp = xfrm_policy_byid(type, p->dir, p->index, 0); else { - struct rtattr **rtattrs = (struct rtattr **)xfrma; - struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; + struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; struct xfrm_policy tmp; - err = verify_sec_ctx_len(rtattrs); + err = verify_sec_ctx_len(xfrma); if (err) return err; @@ -1537,7 +1546,8 @@ out: return err; } -static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_state *x; int err; @@ -1568,7 +1578,8 @@ out: return err; } -static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) +static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, + struct rtattr **xfrma) { struct xfrm_policy *xp; struct xfrm_user_tmpl *ut; @@ -1647,7 +1658,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { #undef XMSGSIZE static struct xfrm_link { - int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); + int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **); int (*dump)(struct sk_buff *, struct netlink_callback *); } xfrm_dispatch[XFRM_NR_MSGTYPES] = { [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, @@ -1735,7 +1746,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err if (link->doit == NULL) goto err_einval; - *errp = link->doit(skb, nlh, (void **) &xfrma); + *errp = link->doit(skb, nlh, xfrma); return *errp; |