diff options
Diffstat (limited to 'net')
115 files changed, 636 insertions, 549 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 6567213959c..4add9bd4bc8 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -124,8 +124,8 @@ static void __exit vlan_cleanup_module(void) { int i; - vlan_netlink_fini(); vlan_ioctl_set(NULL); + vlan_netlink_fini(); /* Un-register us from receiving netdevice events */ unregister_netdevice_notifier(&vlan_notifier_block); @@ -776,7 +776,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) case SET_VLAN_NAME_TYPE_CMD: err = -EPERM; if (!capable(CAP_NET_ADMIN)) - return -EPERM; + break; if ((args.u.name_type >= 0) && (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { vlan_name_type = args.u.name_type; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 7a36878241d..4f99bb86af5 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -462,7 +462,8 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ - if (veth->h_vlan_proto != htons(ETH_P_8021Q)) { + if (veth->h_vlan_proto != htons(ETH_P_8021Q) || + VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR) { int orig_headroom = skb_headroom(skb); unsigned short veth_TCI; diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 2086396de17..9c7f712fc7e 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -542,6 +542,13 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev) if (eth->h_proto != htons(ETH_P_IP)) goto non_ip; /* Multi-Protocol Over ATM :-) */ + /* Weed out funny packets (e.g., AF_PACKET or raw). */ + if (skb->len < ETH_HLEN + sizeof(struct iphdr)) + goto non_ip; + skb_set_network_header(skb, ETH_HLEN); + if (skb->len < ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5) + goto non_ip; + while (i < mpc->number_of_mps_macs) { if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN))) if ( send_via_shortcut(skb, mpc) == 0 ) /* try shortcut */ diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c index 3b7d1720c2e..d1be080dcb2 100644 --- a/net/ax25/ax25_in.c +++ b/net/ax25/ax25_in.c @@ -124,7 +124,7 @@ int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb) } skb_pull(skb, 1); /* Remove PID */ - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; skb_reset_network_header(skb); skb->dev = ax25->ax25_dev->dev; skb->pkt_type = PACKET_HOST; diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c index 5fe9b2a6697..d8f21573317 100644 --- a/net/ax25/ax25_subr.c +++ b/net/ax25/ax25_subr.c @@ -279,6 +279,7 @@ void ax25_disconnect(ax25_cb *ax25, int reason) ax25_link_failed(ax25, reason); if (ax25->sk != NULL) { + local_bh_disable(); bh_lock_sock(ax25->sk); ax25->sk->sk_state = TCP_CLOSE; ax25->sk->sk_err = reason; @@ -288,5 +289,6 @@ void ax25_disconnect(ax25_cb *ax25, int reason) sock_set_flag(ax25->sk, SOCK_DEAD); } bh_unlock_sock(ax25->sk); + local_bh_enable(); } } diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 9483320f6da..34d1a3c822b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -259,22 +259,14 @@ int hci_conn_del(struct hci_conn *conn) } tasklet_disable(&hdev->tx_task); - - hci_conn_del_sysfs(conn); - hci_conn_hash_del(hdev, conn); if (hdev->notify) hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); - tasklet_enable(&hdev->tx_task); - skb_queue_purge(&conn->data_q); - + hci_conn_del_sysfs(conn); hci_dev_put(hdev); - /* will free via device release */ - put_device(&conn->dev); - return 0; } diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index cef1e3e1881..cad510309dc 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -320,6 +320,7 @@ static void del_conn(struct work_struct *work) { struct hci_conn *conn = container_of(work, struct hci_conn, work); device_del(&conn->dev); + put_device(&conn->dev); } void hci_conn_del_sysfs(struct hci_conn *conn) diff --git a/net/bridge/br.c b/net/bridge/br.c index 93867bb6cc9..a9018287312 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -39,7 +39,7 @@ static int __init br_init(void) err = br_fdb_init(); if (err) - goto err_out1; + goto err_out; err = br_netfilter_init(); if (err) @@ -65,6 +65,8 @@ err_out3: err_out2: br_netfilter_fini(); err_out1: + br_fdb_fini(); +err_out: llc_sap_put(br_stp_sap); return err; } diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index c07bac5e3e1..bf7787395fe 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -157,8 +157,7 @@ static struct ethtool_ops br_ethtool_ops = { void br_dev_setup(struct net_device *dev) { - memset(dev->dev_addr, 0, ETH_ALEN); - + random_ether_addr(dev->dev_addr); ether_setup(dev); dev->do_ioctl = br_dev_ioctl; diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index eb57502bb26..bc40377136a 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -44,7 +44,7 @@ int __init br_fdb_init(void) return 0; } -void __exit br_fdb_fini(void) +void br_fdb_fini(void) { kmem_cache_destroy(br_fdb_cache); } diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 3cedd4eeeed..0ee79a726d9 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -122,6 +122,7 @@ static inline int is_link_local(const unsigned char *dest) struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) { const unsigned char *dest = eth_hdr(skb)->h_dest; + int (*rhook)(struct sk_buff *skb); if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) goto drop; @@ -147,9 +148,9 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) switch (p->state) { case BR_STATE_FORWARDING: - - if (br_should_route_hook) { - if (br_should_route_hook(skb)) + rhook = rcu_dereference(br_should_route_hook); + if (rhook != NULL) { + if (rhook(skb)) return skb; dest = eth_hdr(skb)->h_dest; } diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c index 392d877040d..6436d30a550 100644 --- a/net/bridge/netfilter/ebt_among.c +++ b/net/bridge/netfilter/ebt_among.c @@ -187,7 +187,7 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask, if (datalen != EBT_ALIGN(expected_length)) { printk(KERN_WARNING - "ebtables: among: wrong size: %d" + "ebtables: among: wrong size: %d " "against expected %d, rounded to %Zd\n", datalen, expected_length, EBT_ALIGN(expected_length)); diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index e44519ebf1d..be6f1868105 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -70,13 +70,13 @@ static int __init ebtable_broute_init(void) if (ret < 0) return ret; /* see br_input.c */ - br_should_route_hook = ebt_broute; + rcu_assign_pointer(br_should_route_hook, ebt_broute); return ret; } static void __exit ebtable_broute_fini(void) { - br_should_route_hook = NULL; + rcu_assign_pointer(br_should_route_hook, NULL); synchronize_net(); ebt_unregister_table(&broute_table); } diff --git a/net/compat.c b/net/compat.c index d74d82155d7..377e560ab5c 100644 --- a/net/compat.c +++ b/net/compat.c @@ -254,6 +254,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr))) return -EFAULT; cmlen = CMSG_COMPAT_SPACE(len); + if (kmsg->msg_controllen < cmlen) + cmlen = kmsg->msg_controllen; kmsg->msg_control += cmlen; kmsg->msg_controllen -= cmlen; return 0; diff --git a/net/core/dev.c b/net/core/dev.c index 86d62611f2f..0879f52115e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2207,8 +2207,12 @@ static void net_rx_action(struct softirq_action *h) * still "owns" the NAPI instance and therefore can * move the instance around on the list at-will. */ - if (unlikely(work == weight)) - list_move_tail(&n->poll_list, list); + if (unlikely(work == weight)) { + if (unlikely(napi_disable_pending(n))) + __napi_complete(n); + else + list_move_tail(&n->poll_list, list); + } netpoll_poll_unlock(have); } @@ -2819,7 +2823,7 @@ void dev_set_allmulti(struct net_device *dev, int inc) /* * Upload unicast and multicast address lists to device and * configure RX filtering. When the device doesn't support unicast - * filtering it is put in promiscous mode while unicast addresses + * filtering it is put in promiscuous mode while unicast addresses * are present. */ void __dev_set_rx_mode(struct net_device *dev) @@ -3972,8 +3976,7 @@ void synchronize_net(void) * @dev: device * * This function shuts down a device interface and removes it - * from the kernel tables. On success 0 is returned, on a failure - * a negative errno code is returned. + * from the kernel tables. * * Callers must hold the rtnl semaphore. You may want * unregister_netdev() instead of this. @@ -3991,8 +3994,7 @@ void unregister_netdevice(struct net_device *dev) * @dev: device * * This function shuts down a device interface and removes it - * from the kernel tables. On success 0 is returned, on a failure - * a negative errno code is returned. + * from the kernel tables. * * This is just a wrapper for unregister_netdevice that takes * the rtnl semaphore. In general you want to use this and not diff --git a/net/core/pktgen.c b/net/core/pktgen.c index de33f36947e..285ec3ed9b3 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2463,8 +2463,6 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev) x->curlft.bytes +=skb->len; x->curlft.packets++; - spin_unlock(&x->lock); - error: spin_unlock(&x->lock); return err; diff --git a/net/core/scm.c b/net/core/scm.c index 100ba6d9d47..10f5c65f6a4 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -196,6 +196,8 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr))) goto out; cmlen = CMSG_SPACE(len); + if (msg->msg_controllen < cmlen) + cmlen = msg->msg_controllen; msg->msg_control += cmlen; msg->msg_controllen -= cmlen; err = 0; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 32d5826b717..b6283779e93 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -275,12 +275,11 @@ static void skb_release_data(struct sk_buff *skb) /* * Free an skbuff by memory without cleaning the state. */ -void kfree_skbmem(struct sk_buff *skb) +static void kfree_skbmem(struct sk_buff *skb) { struct sk_buff *other; atomic_t *fclone_ref; - skb_release_data(skb); switch (skb->fclone) { case SKB_FCLONE_UNAVAILABLE: kmem_cache_free(skbuff_head_cache, skb); @@ -307,16 +306,8 @@ void kfree_skbmem(struct sk_buff *skb) } } -/** - * __kfree_skb - private function - * @skb: buffer - * - * Free an sk_buff. Release anything attached to the buffer. - * Clean the state. This is an internal helper function. Users should - * always call kfree_skb - */ - -void __kfree_skb(struct sk_buff *skb) +/* Free everything but the sk_buff shell. */ +static void skb_release_all(struct sk_buff *skb) { dst_release(skb->dst); #ifdef CONFIG_XFRM @@ -340,7 +331,21 @@ void __kfree_skb(struct sk_buff *skb) skb->tc_verd = 0; #endif #endif + skb_release_data(skb); +} + +/** + * __kfree_skb - private function + * @skb: buffer + * + * Free an sk_buff. Release anything attached to the buffer. + * Clean the state. This is an internal helper function. Users should + * always call kfree_skb + */ +void __kfree_skb(struct sk_buff *skb) +{ + skb_release_all(skb); kfree_skbmem(skb); } @@ -411,16 +416,17 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) C(len); C(data_len); C(mac_len); - n->cloned = 1; n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; + n->cloned = 1; n->nohdr = 0; n->destructor = NULL; - C(truesize); - atomic_set(&n->users, 1); - C(head); - C(data); + C(iif); C(tail); C(end); + C(head); + C(data); + C(truesize); + atomic_set(&n->users, 1); atomic_inc(&(skb_shinfo(skb)->dataref)); skb->cloned = 1; @@ -441,7 +447,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) */ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src) { - skb_release_data(dst); + skb_release_all(dst); return __skb_clone(dst, src); } EXPORT_SYMBOL_GPL(skb_morph); diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 9ef0737043e..9671ecd17e0 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -71,7 +71,7 @@ struct dccp_ackvec { * @dccpavr_ack_ackno - sequence number being acknowledged * @dccpavr_ack_ptr - pointer into dccpav_buf where this record starts * @dccpavr_ack_nonce - dccpav_ack_nonce at the time this record was sent - * @dccpavr_sent_len - lenght of the record in dccpav_buf + * @dccpavr_sent_len - length of the record in dccpav_buf */ struct dccp_ackvec_record { struct list_head dccpavr_node; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 19b33586333..d133416d397 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -239,7 +239,7 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) ccid3_tx_state_name(hctx->ccid3hctx_state), (unsigned)(hctx->ccid3hctx_x >> 6)); /* The value of R is still undefined and so we can not recompute - * the timout value. Keep initial value as per [RFC 4342, 5]. */ + * the timeout value. Keep initial value as per [RFC 4342, 5]. */ t_nfb = TFRC_INITIAL_TIMEOUT; ccid3_update_send_interval(hctx); break; diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c index 40ad428a27f..d26b88dbbb4 100644 --- a/net/dccp/ccids/lib/loss_interval.c +++ b/net/dccp/ccids/lib/loss_interval.c @@ -166,7 +166,7 @@ static u32 dccp_li_calc_first_li(struct sock *sk, } if (unlikely(interval == 0)) { - DCCP_WARN("%s(%p), Could not find a win_count interval > 0." + DCCP_WARN("%s(%p), Could not find a win_count interval > 0. " "Defaulting to 1\n", dccp_role(sk), sk); interval = 1; } diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 66e266fb590..3bc82dc83b3 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -651,16 +651,18 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct dn_dev *dn_db; struct ifaddrmsg *ifm; struct dn_ifaddr *ifa, **ifap; - int err = -EADDRNOTAVAIL; + int err; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy); if (err < 0) goto errout; + err = -ENODEV; ifm = nlmsg_data(nlh); if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL) goto errout; + err = -EADDRNOTAVAIL; for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { if (tb[IFA_LOCAL] && nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c index c6d760d9fbb..208bf35b554 100644 --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -338,7 +338,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos += 8; if (ccmp_replay_check(pn, key->rx_pn)) { - if (net_ratelimit()) { + if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%s " "previous PN %02x%02x%02x%02x%02x%02x " "received PN %02x%02x%02x%02x%02x%02x\n", diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 58b22619ab1..8e146949fc6 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -464,7 +464,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pos += 8; if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { - if (net_ratelimit()) { + if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%s" " previous TSC %08x%04x received TSC " "%08x%04x\n", print_mac(mac, hdr->addr2), @@ -504,7 +504,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) * it needs to be recalculated for the next packet. */ tkey->rx_phase1_done = 0; } - if (net_ratelimit()) { + if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA=" "%s\n", print_mac(mac, hdr->addr2)); } diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index a4c3c51140a..6d06f1385e2 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -144,7 +144,8 @@ static int ieee80211_copy_snap(u8 * data, u16 h_proto) snap->oui[1] = oui[1]; snap->oui[2] = oui[2]; - *(u16 *) (data + SNAP_SIZE) = htons(h_proto); + h_proto = htons(h_proto); + memcpy(data + SNAP_SIZE, &h_proto, sizeof(u16)); return SNAP_SIZE + sizeof(u16); } diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 36d6798947b..08174a2aa87 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -111,12 +111,8 @@ #include <net/tcp.h> #include <net/sock.h> #include <net/arp.h> -#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) #include <net/ax25.h> -#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) #include <net/netrom.h> -#endif -#endif #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) #include <net/atmclip.h> struct neigh_table *clip_tbl_hook; @@ -710,7 +706,7 @@ static int arp_process(struct sk_buff *skb) struct arphdr *arp; unsigned char *arp_ptr; struct rtable *rt; - unsigned char *sha, *tha; + unsigned char *sha; __be32 sip, tip; u16 dev_type = dev->type; int addr_type; @@ -731,20 +727,10 @@ static int arp_process(struct sk_buff *skb) htons(dev_type) != arp->ar_hrd) goto out; break; -#ifdef CONFIG_NET_ETHERNET case ARPHRD_ETHER: -#endif -#ifdef CONFIG_TR case ARPHRD_IEEE802_TR: -#endif -#ifdef CONFIG_FDDI case ARPHRD_FDDI: -#endif -#ifdef CONFIG_NET_FC case ARPHRD_IEEE802: -#endif -#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_TR) || \ - defined(CONFIG_FDDI) || defined(CONFIG_NET_FC) /* * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802 * devices, according to RFC 2625) devices will accept ARP @@ -759,21 +745,16 @@ static int arp_process(struct sk_buff *skb) arp->ar_pro != htons(ETH_P_IP)) goto out; break; -#endif -#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) case ARPHRD_AX25: if (arp->ar_pro != htons(AX25_P_IP) || arp->ar_hrd != htons(ARPHRD_AX25)) goto out; break; -#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE) case ARPHRD_NETROM: if (arp->ar_pro != htons(AX25_P_IP) || arp->ar_hrd != htons(ARPHRD_NETROM)) goto out; break; -#endif -#endif } /* Understand only these message types */ @@ -790,7 +771,6 @@ static int arp_process(struct sk_buff *skb) arp_ptr += dev->addr_len; memcpy(&sip, arp_ptr, 4); arp_ptr += 4; - tha = arp_ptr; arp_ptr += dev->addr_len; memcpy(&tip, arp_ptr, 4); /* @@ -828,7 +808,8 @@ static int arp_process(struct sk_buff *skb) if (arp->ar_op == htons(ARPOP_REQUEST) && inet_addr_type(tip) == RTN_LOCAL && !arp_ignore(in_dev,dev,sip,tip)) - arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr); + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, + dev->dev_addr, sha); goto out; } diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 55d199e4ae2..b42f74617ba 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -516,8 +516,6 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh) goto errout; } - ipv4_devconf_setall(in_dev); - ifa = inet_alloc_ifa(); if (ifa == NULL) { /* @@ -528,6 +526,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh) goto errout; } + ipv4_devconf_setall(in_dev); in_dev_hold(in_dev); if (tb[IFA_ADDRESS] == NULL) @@ -1028,7 +1027,7 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); if (named++ == 0) continue; - dot = strchr(ifa->ifa_label, ':'); + dot = strchr(old, ':'); if (dot == NULL) { sprintf(old, ":%d", named); dot = old; diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index c31bccb9b52..1738113268b 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -9,6 +9,7 @@ #include <linux/pfkeyv2.h> #include <linux/random.h> #include <linux/spinlock.h> +#include <linux/in6.h> #include <net/icmp.h> #include <net/protocol.h> #include <net/udp.h> @@ -224,6 +225,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) /* ... check padding bits here. Silly. :-) */ + /* RFC4303: Drop dummy packets without any error */ + if (nexthdr[1] == IPPROTO_NONE) + goto out; + iph = ip_hdr(skb); ihl = iph->ihl * 4; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 732d8f088b1..97abf934d18 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -804,10 +804,13 @@ static void nl_fib_input(struct sk_buff *skb) nlh = nlmsg_hdr(skb); if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || - nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { - kfree_skb(skb); + nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) return; - } + + skb = skb_clone(skb, GFP_KERNEL); + if (skb == NULL) + return; + nlh = nlmsg_hdr(skb); frn = (struct fib_result_nl *) NLMSG_DATA(nlh); tb = fib_get_table(frn->tb_id_in); diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index b0170732b5e..e468e7a7aac 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -51,6 +51,29 @@ static struct sock *idiagnl; #define INET_DIAG_PUT(skb, attrtype, attrlen) \ RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) +static DEFINE_MUTEX(inet_diag_table_mutex); + +static const struct inet_diag_handler *inet_diag_lock_handler(int type) +{ +#ifdef CONFIG_KMOD + if (!inet_diag_table[type]) + request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, + NETLINK_INET_DIAG, type); +#endif + + mutex_lock(&inet_diag_table_mutex); + if (!inet_diag_table[type]) + return ERR_PTR(-ENOENT); + + return inet_diag_table[type]; +} + +static inline void inet_diag_unlock_handler( + const struct inet_diag_handler *handler) +{ + mutex_unlock(&inet_diag_table_mutex); +} + static int inet_csk_diag_fill(struct sock *sk, struct sk_buff *skb, int ext, u32 pid, u32 seq, u16 nlmsg_flags, @@ -235,9 +258,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, struct inet_hashinfo *hashinfo; const struct inet_diag_handler *handler; - handler = inet_diag_table[nlh->nlmsg_type]; - BUG_ON(handler == NULL); + handler = inet_diag_lock_handler(nlh->nlmsg_type); + if (!handler) + return -ENOENT; + hashinfo = handler->idiag_hashinfo; + err = -EINVAL; if (req->idiag_family == AF_INET) { sk = inet_lookup(hashinfo, req->id.idiag_dst[0], @@ -255,11 +281,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb, } #endif else { - return -EINVAL; + goto unlock; } + err = -ENOENT; if (sk == NULL) - return -ENOENT; + goto unlock; err = -ESTALE; if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE || @@ -296,6 +323,8 @@ out: else sock_put(sk); } +unlock: + inet_diag_unlock_handler(handler); return err; } @@ -678,8 +707,10 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) const struct inet_diag_handler *handler; struct inet_hashinfo *hashinfo; - handler = inet_diag_table[cb->nlh->nlmsg_type]; - BUG_ON(handler == NULL); + handler = inet_diag_lock_handler(cb->nlh->nlmsg_type); + if (!handler) + goto no_handler; + hashinfo = handler->idiag_hashinfo; s_i = cb->args[1]; @@ -743,7 +774,7 @@ skip_listen_ht: } if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV))) - return skb->len; + goto unlock; for (i = s_i; i < hashinfo->ehash_size; i++) { struct inet_ehash_bucket *head = &hashinfo->ehash[i]; @@ -805,6 +836,9 @@ next_dying: done: cb->args[1] = i; cb->args[2] = num; +unlock: + inet_diag_unlock_handler(handler); +no_handler: return skb->len; } @@ -816,15 +850,6 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) nlmsg_len(nlh) < hdrlen) return -EINVAL; -#ifdef CONFIG_KMOD - if (inet_diag_table[nlh->nlmsg_type] == NULL) - request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, - NETLINK_INET_DIAG, nlh->nlmsg_type); -#endif - - if (inet_diag_table[nlh->nlmsg_type] == NULL) - return -ENOENT; - if (nlh->nlmsg_flags & NLM_F_DUMP) { if (nlmsg_attrlen(nlh, hdrlen)) { struct nlattr *attr; @@ -853,8 +878,6 @@ static void inet_diag_rcv(struct sk_buff *skb) mutex_unlock(&inet_diag_mutex); } -static DEFINE_SPINLOCK(inet_diag_register_lock); - int inet_diag_register(const struct inet_diag_handler *h) { const __u16 type = h->idiag_type; @@ -863,13 +886,13 @@ int inet_diag_register(const struct inet_diag_handler *h) if (type >= INET_DIAG_GETSOCK_MAX) goto out; - spin_lock(&inet_diag_register_lock); + mutex_lock(&inet_diag_table_mutex); err = -EEXIST; if (inet_diag_table[type] == NULL) { inet_diag_table[type] = h; err = 0; } - spin_unlock(&inet_diag_register_lock); + mutex_unlock(&inet_diag_table_mutex); out: return err; } @@ -882,11 +905,9 @@ void inet_diag_unregister(const struct inet_diag_handler *h) if (type >= INET_DIAG_GETSOCK_MAX) return; - spin_lock(&inet_diag_register_lock); + mutex_lock(&inet_diag_table_mutex); inet_diag_table[type] = NULL; - spin_unlock(&inet_diag_register_lock); - - synchronize_rcu(); + mutex_unlock(&inet_diag_table_mutex); } EXPORT_SYMBOL_GPL(inet_diag_unregister); diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index ac3b1d3dba2..4a4d49fca1f 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c @@ -310,7 +310,7 @@ static void lro_flush(struct net_lro_mgr *lro_mgr, skb_shinfo(lro_desc->parent)->gso_size = lro_desc->mss; if (lro_desc->vgrp) { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) vlan_hwaccel_receive_skb(lro_desc->parent, lro_desc->vgrp, lro_desc->vlan_tag); @@ -320,7 +320,7 @@ static void lro_flush(struct net_lro_mgr *lro_mgr, lro_desc->vlan_tag); } else { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(lro_desc->parent); else netif_rx(lro_desc->parent); @@ -352,7 +352,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, goto out; if ((skb->protocol == htons(ETH_P_8021Q)) - && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features)) + && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID)) vlan_hdr_len = VLAN_HLEN; if (!lro_desc->active) { /* start new lro session */ @@ -401,10 +401,11 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr, int data_len = len; int hdr_len = min(len, hlen); - skb = netdev_alloc_skb(lro_mgr->dev, hlen); + skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad); if (!skb) return NULL; + skb_reserve(skb, lro_mgr->frag_align_pad); skb->len = len; skb->data_len = len - hdr_len; skb->truesize += true_size; @@ -473,7 +474,7 @@ static struct sk_buff *__lro_proc_segment(struct net_lro_mgr *lro_mgr, goto out; if ((skb->protocol == htons(ETH_P_8021Q)) - && !test_bit(LRO_F_EXTRACT_VLAN_ID, &lro_mgr->features)) + && !(lro_mgr->features & LRO_F_EXTRACT_VLAN_ID)) vlan_hdr_len = VLAN_HLEN; iph = (void *)(skb->data + vlan_hdr_len); @@ -515,7 +516,7 @@ void lro_receive_skb(struct net_lro_mgr *lro_mgr, void *priv) { if (__lro_proc_skb(lro_mgr, skb, NULL, 0, priv)) { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(skb); else netif_rx(skb); @@ -530,7 +531,7 @@ void lro_vlan_hwaccel_receive_skb(struct net_lro_mgr *lro_mgr, void *priv) { if (__lro_proc_skb(lro_mgr, skb, vgrp, vlan_tag, priv)) { - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); else vlan_hwaccel_rx(skb, vgrp, vlan_tag); @@ -549,7 +550,7 @@ void lro_receive_frags(struct net_lro_mgr *lro_mgr, if (!skb) return; - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) netif_receive_skb(skb); else netif_rx(skb); @@ -569,7 +570,7 @@ void lro_vlan_hwaccel_receive_frags(struct net_lro_mgr *lro_mgr, if (!skb) return; - if (test_bit(LRO_F_NAPI, &lro_mgr->features)) + if (lro_mgr->features & LRO_F_NAPI) vlan_hwaccel_receive_skb(skb, vgrp, vlan_tag); else vlan_hwaccel_rx(skb, vgrp, vlan_tag); diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 02b02a8d681..4b93f32de10 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -613,7 +613,7 @@ static int ipgre_rcv(struct sk_buff *skb) offset += 4; } - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; __pskb_pull(skb, offset); skb_reset_network_header(skb); skb_postpull_rcsum(skb, skb_transport_header(skb), offset); diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index c5c107a0182..b8f7763b226 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1396,31 +1396,16 @@ late_initcall(ip_auto_config); /* * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel - * command line parameter. It consists of option fields separated by colons in - * the following order: - * - * <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<PROTO> - * - * Any of the fields can be empty which means to use a default value: - * <client-ip> - address given by BOOTP or RARP - * <server-ip> - address of host returning BOOTP or RARP packet - * <gw-ip> - none, or the address returned by BOOTP - * <netmask> - automatically determined from <client-ip>, or the - * one returned by BOOTP - * <host name> - <client-ip> in ASCII notation, or the name returned - * by BOOTP - * <device> - use all available devices - * <PROTO>: - * off|none - don't do autoconfig at all (DEFAULT) - * on|any - use any configured protocol - * dhcp|bootp|rarp - use only the specified protocol - * both - use both BOOTP and RARP (not DHCP) + * command line parameter. See Documentation/nfsroot.txt. */ static int __init ic_proto_name(char *name) { if (!strcmp(name, "on") || !strcmp(name, "any")) { return 1; } + if (!strcmp(name, "off") || !strcmp(name, "none")) { + return 0; + } #ifdef CONFIG_IP_PNP_DHCP else if (!strcmp(name, "dhcp")) { ic_proto_enabled &= ~IC_RARP; @@ -1454,17 +1439,24 @@ static int __init ip_auto_config_setup(char *addrs) int num = 0; ic_set_manually = 1; + ic_enable = 1; - ic_enable = (*addrs && - (strcmp(addrs, "off") != 0) && - (strcmp(addrs, "none") != 0)); - if (!ic_enable) + /* + * If any dhcp, bootp etc options are set, leave autoconfig on + * and skip the below static IP processing. + */ + if (ic_proto_name(addrs)) return 1; - if (ic_proto_name(addrs)) + /* If no static IP is given, turn off autoconfig and bail. */ + if (*addrs == 0 || + strcmp(addrs, "off") == 0 || + strcmp(addrs, "none") == 0) { + ic_enable = 0; return 1; + } - /* Parse the whole string */ + /* Parse string for static IP assignment. */ ip = addrs; while (ip && *ip) { if ((cp = strchr(ip, ':'))) @@ -1502,7 +1494,10 @@ static int __init ip_auto_config_setup(char *addrs) strlcpy(user_dev_name, ip, sizeof(user_dev_name)); break; case 6: - ic_proto_name(ip); + if (ic_proto_name(ip) == 0 && + ic_myaddr == NONE) { + ic_enable = 0; + } break; } } diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 20c884a5772..8fba20256f5 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c @@ -637,7 +637,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) verdict = NF_DROP; if (IP_VS_FWD_METHOD(cp) != 0) { - IP_VS_ERR("shouldn't reach here, because the box is on the" + IP_VS_ERR("shouldn't reach here, because the box is on the " "half connection in the tun/dr module.\n"); } diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index b64cf45a9ea..693d92490c1 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c @@ -1424,7 +1424,6 @@ proc_do_sync_threshold(ctl_table *table, int write, struct file *filp, static struct ctl_table vs_vars[] = { { - .ctl_name = NET_IPV4_VS_AMEMTHRESH, .procname = "amemthresh", .data = &sysctl_ip_vs_amemthresh, .maxlen = sizeof(int), @@ -1433,7 +1432,6 @@ static struct ctl_table vs_vars[] = { }, #ifdef CONFIG_IP_VS_DEBUG { - .ctl_name = NET_IPV4_VS_DEBUG_LEVEL, .procname = "debug_level", .data = &sysctl_ip_vs_debug_level, .maxlen = sizeof(int), @@ -1442,7 +1440,6 @@ static struct ctl_table vs_vars[] = { }, #endif { - .ctl_name = NET_IPV4_VS_AMDROPRATE, .procname = "am_droprate", .data = &sysctl_ip_vs_am_droprate, .maxlen = sizeof(int), @@ -1450,7 +1447,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_IPV4_VS_DROP_ENTRY, .procname = "drop_entry", .data = &sysctl_ip_vs_drop_entry, .maxlen = sizeof(int), @@ -1458,7 +1454,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_do_defense_mode, }, { - .ctl_name = NET_IPV4_VS_DROP_PACKET, .procname = "drop_packet", .data = &sysctl_ip_vs_drop_packet, .maxlen = sizeof(int), @@ -1466,7 +1461,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_do_defense_mode, }, { - .ctl_name = NET_IPV4_VS_SECURE_TCP, .procname = "secure_tcp", .data = &sysctl_ip_vs_secure_tcp, .maxlen = sizeof(int), @@ -1475,7 +1469,6 @@ static struct ctl_table vs_vars[] = { }, #if 0 { - .ctl_name = NET_IPV4_VS_TO_ES, .procname = "timeout_established", .data = &vs_timeout_table_dos.timeout[IP_VS_S_ESTABLISHED], .maxlen = sizeof(int), @@ -1483,7 +1476,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_SS, .procname = "timeout_synsent", .data = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_SENT], .maxlen = sizeof(int), @@ -1491,7 +1483,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_SR, .procname = "timeout_synrecv", .data = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_RECV], .maxlen = sizeof(int), @@ -1499,7 +1490,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_FW, .procname = "timeout_finwait", .data = &vs_timeout_table_dos.timeout[IP_VS_S_FIN_WAIT], .maxlen = sizeof(int), @@ -1507,7 +1497,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_TW, .procname = "timeout_timewait", .data = &vs_timeout_table_dos.timeout[IP_VS_S_TIME_WAIT], .maxlen = sizeof(int), @@ -1515,7 +1504,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_CL, .procname = "timeout_close", .data = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE], .maxlen = sizeof(int), @@ -1523,7 +1511,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_CW, .procname = "timeout_closewait", .data = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE_WAIT], .maxlen = sizeof(int), @@ -1531,7 +1518,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_LA, .procname = "timeout_lastack", .data = &vs_timeout_table_dos.timeout[IP_VS_S_LAST_ACK], .maxlen = sizeof(int), @@ -1539,7 +1525,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_LI, .procname = "timeout_listen", .data = &vs_timeout_table_dos.timeout[IP_VS_S_LISTEN], .maxlen = sizeof(int), @@ -1547,7 +1532,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_SA, .procname = "timeout_synack", .data = &vs_timeout_table_dos.timeout[IP_VS_S_SYNACK], .maxlen = sizeof(int), @@ -1555,7 +1539,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_UDP, .procname = "timeout_udp", .data = &vs_timeout_table_dos.timeout[IP_VS_S_UDP], .maxlen = sizeof(int), @@ -1563,7 +1546,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec_jiffies, }, { - .ctl_name = NET_IPV4_VS_TO_ICMP, .procname = "timeout_icmp", .data = &vs_timeout_table_dos.timeout[IP_VS_S_ICMP], .maxlen = sizeof(int), @@ -1572,7 +1554,6 @@ static struct ctl_table vs_vars[] = { }, #endif { - .ctl_name = NET_IPV4_VS_CACHE_BYPASS, .procname = "cache_bypass", .data = &sysctl_ip_vs_cache_bypass, .maxlen = sizeof(int), @@ -1580,7 +1561,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_IPV4_VS_EXPIRE_NODEST_CONN, .procname = "expire_nodest_conn", .data = &sysctl_ip_vs_expire_nodest_conn, .maxlen = sizeof(int), @@ -1588,7 +1568,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE, .procname = "expire_quiescent_template", .data = &sysctl_ip_vs_expire_quiescent_template, .maxlen = sizeof(int), @@ -1596,7 +1575,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_IPV4_VS_SYNC_THRESHOLD, .procname = "sync_threshold", .data = &sysctl_ip_vs_sync_threshold, .maxlen = sizeof(sysctl_ip_vs_sync_threshold), @@ -1604,7 +1582,6 @@ static struct ctl_table vs_vars[] = { .proc_handler = &proc_do_sync_threshold, }, { - .ctl_name = NET_IPV4_VS_NAT_ICMP_SEND, .procname = "nat_icmp_send", .data = &sysctl_ip_vs_nat_icmp_send, .maxlen = sizeof(int), @@ -1616,7 +1593,6 @@ static struct ctl_table vs_vars[] = { static ctl_table vs_table[] = { { - .ctl_name = NET_IPV4_VS, .procname = "vs", .mode = 0555, .child = vs_vars diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c index 052f4ed5917..ad89644ef5d 100644 --- a/net/ipv4/ipvs/ip_vs_lblc.c +++ b/net/ipv4/ipvs/ip_vs_lblc.c @@ -114,7 +114,6 @@ struct ip_vs_lblc_table { static ctl_table vs_vars_table[] = { { - .ctl_name = NET_IPV4_VS_LBLC_EXPIRE, .procname = "lblc_expiration", .data = &sysctl_ip_vs_lblc_expiration, .maxlen = sizeof(int), @@ -126,7 +125,6 @@ static ctl_table vs_vars_table[] = { static ctl_table vs_table[] = { { - .ctl_name = NET_IPV4_VS, .procname = "vs", .mode = 0555, .child = vs_vars_table @@ -582,9 +580,14 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler = static int __init ip_vs_lblc_init(void) { + int ret; + INIT_LIST_HEAD(&ip_vs_lblc_scheduler.n_list); sysctl_header = register_sysctl_table(lblc_root_table); - return register_ip_vs_scheduler(&ip_vs_lblc_scheduler); + ret = register_ip_vs_scheduler(&ip_vs_lblc_scheduler); + if (ret) + unregister_sysctl_table(sysctl_header); + return ret; } diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c index 427b593c106..2a5ed85a335 100644 --- a/net/ipv4/ipvs/ip_vs_lblcr.c +++ b/net/ipv4/ipvs/ip_vs_lblcr.c @@ -302,7 +302,6 @@ struct ip_vs_lblcr_table { static ctl_table vs_vars_table[] = { { - .ctl_name = NET_IPV4_VS_LBLCR_EXPIRE, .procname = "lblcr_expiration", .data = &sysctl_ip_vs_lblcr_expiration, .maxlen = sizeof(int), @@ -314,7 +313,6 @@ static ctl_table vs_vars_table[] = { static ctl_table vs_table[] = { { - .ctl_name = NET_IPV4_VS, .procname = "vs", .mode = 0555, .child = vs_vars_table @@ -771,9 +769,14 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler = static int __init ip_vs_lblcr_init(void) { + int ret; + INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list); sysctl_header = register_sysctl_table(lblcr_root_table); - return register_ip_vs_scheduler(&ip_vs_lblcr_scheduler); + ret = register_ip_vs_scheduler(&ip_vs_lblcr_scheduler); + if (ret) + unregister_sysctl_table(sysctl_header); + return ret; } diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c index e844ddb82b9..c0e11ec8f0f 100644 --- a/net/ipv4/ipvs/ip_vs_proto.c +++ b/net/ipv4/ipvs/ip_vs_proto.c @@ -45,7 +45,7 @@ static struct ip_vs_protocol *ip_vs_proto_table[IP_VS_PROTO_TAB_SIZE]; /* * register an ipvs protocol */ -static int register_ip_vs_protocol(struct ip_vs_protocol *pp) +static int __used register_ip_vs_protocol(struct ip_vs_protocol *pp) { unsigned hash = IP_VS_PROTO_HASH(pp->protocol); diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c index 1602304abbf..43223586190 100644 --- a/net/ipv4/ipvs/ip_vs_sched.c +++ b/net/ipv4/ipvs/ip_vs_sched.c @@ -183,19 +183,6 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) /* increase the module use count */ ip_vs_use_count_inc(); - /* - * Make sure that the scheduler with this name doesn't exist - * in the scheduler list. - */ - sched = ip_vs_sched_getbyname(scheduler->name); - if (sched) { - ip_vs_scheduler_put(sched); - ip_vs_use_count_dec(); - IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler " - "already existed in the system\n", scheduler->name); - return -EINVAL; - } - write_lock_bh(&__ip_vs_sched_lock); if (scheduler->n_list.next != &scheduler->n_list) { @@ -207,6 +194,20 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) } /* + * Make sure that the scheduler with this name doesn't exist + * in the scheduler list. + */ + list_for_each_entry(sched, &ip_vs_schedulers, n_list) { + if (strcmp(scheduler->name, sched->name) == 0) { + write_unlock_bh(&__ip_vs_sched_lock); + ip_vs_use_count_dec(); + IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler " + "already existed in the system\n", + scheduler->name); + return -EINVAL; + } + } + /* * Add it into the d-linked scheduler list */ list_add(&scheduler->n_list, &ip_vs_schedulers); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 4b10b98640a..b9b189c2620 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1492,8 +1492,10 @@ static inline int compat_copy_match_to_user(struct ipt_entry_match *m, return xt_compat_match_to_user(m, dstptr, size); } -static int compat_copy_entry_to_user(struct ipt_entry *e, - void __user **dstptr, compat_uint_t *size) +static int +compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, + compat_uint_t *size, struct xt_counters *counters, + unsigned int *i) { struct ipt_entry_target *t; struct compat_ipt_entry __user *ce; @@ -1507,6 +1509,9 @@ static int compat_copy_entry_to_user(struct ipt_entry *e, if (copy_to_user(ce, e, sizeof(struct ipt_entry))) goto out; + if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i]))) + goto out; + *dstptr += sizeof(struct compat_ipt_entry); ret = IPT_MATCH_ITERATE(e, compat_copy_match_to_user, dstptr, size); target_offset = e->target_offset - (origsize - *size); @@ -1522,6 +1527,8 @@ static int compat_copy_entry_to_user(struct ipt_entry *e, goto out; if (put_user(next_offset, &ce->next_offset)) goto out; + + (*i)++; return 0; out: return ret; @@ -1937,14 +1944,13 @@ struct compat_ipt_get_entries static int compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, void __user *userptr) { - unsigned int off, num; - struct compat_ipt_entry e; struct xt_counters *counters; struct xt_table_info *private = table->private; void __user *pos; unsigned int size; int ret = 0; void *loc_cpu_entry; + unsigned int i = 0; counters = alloc_counters(table); if (IS_ERR(counters)) @@ -1958,48 +1964,9 @@ static int compat_copy_entries_to_user(unsigned int total_size, pos = userptr; size = total_size; ret = IPT_ENTRY_ITERATE(loc_cpu_entry, total_size, - compat_copy_entry_to_user, &pos, &size); - if (ret) - goto free_counters; - - /* ... then go back and fix counters and names */ - for (off = 0, num = 0; off < size; off += e.next_offset, num++) { - unsigned int i; - struct ipt_entry_match m; - struct ipt_entry_target t; + compat_copy_entry_to_user, + &pos, &size, counters, &i); - ret = -EFAULT; - if (copy_from_user(&e, userptr + off, - sizeof(struct compat_ipt_entry))) - goto free_counters; - if (copy_to_user(userptr + off + - offsetof(struct compat_ipt_entry, counters), - &counters[num], sizeof(counters[num]))) - goto free_counters; - - for (i = sizeof(struct compat_ipt_entry); - i < e.target_offset; i += m.u.match_size) { - if (copy_from_user(&m, userptr + off + i, - sizeof(struct ipt_entry_match))) - goto free_counters; - if (copy_to_user(userptr + off + i + - offsetof(struct ipt_entry_match, u.user.name), - m.u.kernel.match->name, - strlen(m.u.kernel.match->name) + 1)) - goto free_counters; - } - - if (copy_from_user(&t, userptr + off + e.target_offset, - sizeof(struct ipt_entry_target))) - goto free_counters; - if (copy_to_user(userptr + off + e.target_offset + - offsetof(struct ipt_entry_target, u.user.name), - t.u.kernel.target->name, - strlen(t.u.kernel.target->name) + 1)) - goto free_counters; - } - ret = 0; -free_counters: vfree(counters); return ret; } diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 5de6e57ac55..f8678651250 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -66,7 +66,7 @@ ipt_local_hook(unsigned int hook, if (skb->len < sizeof(struct iphdr) || ip_hdrlen(skb) < sizeof(struct iphdr)) { if (net_ratelimit()) - printk("iptable_raw: ignoring short SOCK_RAW" + printk("iptable_raw: ignoring short SOCK_RAW " "packet.\n"); return NF_ACCEPT; } diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 831e9b29806..910dae732a0 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -419,6 +419,9 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = { .me = THIS_MODULE, }; +module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, + &nf_conntrack_htable_size, 0600); + MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); MODULE_ALIAS("ip_conntrack"); MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 70e7997ea28..86b465b176b 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -607,13 +607,10 @@ static void nf_nat_move_storage(struct nf_conn *conntrack, void *old) struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT); struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old; struct nf_conn *ct = old_nat->ct; - unsigned int srchash; - if (!(ct->status & IPS_NAT_DONE_MASK)) + if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) return; - srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); - write_lock_bh(&nf_nat_lock); hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource); new_nat->ct = ct; diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 3ca98971a1e..8996ccb757d 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c @@ -165,7 +165,7 @@ static int mangle_content_len(struct sk_buff *skb, dataoff = ip_hdrlen(skb) + sizeof(struct udphdr); - /* Get actual SDP lenght */ + /* Get actual SDP length */ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff, &matchlen, POS_SDP_HEADER) > 0) { diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 66b42f547bf..e7050f8eabe 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -271,6 +271,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, int hh_len; struct iphdr *iph; struct sk_buff *skb; + unsigned int iphlen; int err; if (length > rt->u.dst.dev->mtu) { @@ -304,7 +305,8 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, goto error_fault; /* We don't modify invalid header */ - if (length >= sizeof(*iph) && iph->ihl * 4U <= length) { + iphlen = iph->ihl * 4; + if (iphlen >= sizeof(*iph) && iphlen <= length) { if (!iph->saddr) iph->saddr = rt->rt_src; iph->check = 0; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1bff9ed349f..d3377069ce0 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1161,7 +1161,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, rt->fl.oif); #if RT_CACHE_DEBUG >= 1 - printk(KERN_DEBUG "ip_rt_advice: redirect to " + printk(KERN_DEBUG "ipv4_negative_advice: redirect to " "%u.%u.%u.%u/%02x dropped\n", NIPQUAD(rt->rt_dst), rt->fl.fl4_tos); #endif @@ -1252,6 +1252,7 @@ static int ip_error(struct sk_buff *skb) break; case ENETUNREACH: code = ICMP_NET_UNREACH; + IP_INC_STATS_BH(IPSTATS_MIB_INNOROUTES); break; case EACCES: code = ICMP_PKT_FILTERED; @@ -1881,6 +1882,8 @@ no_route: RT_CACHE_STAT_INC(in_no_route); spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); res.type = RTN_UNREACHABLE; + if (err == -ESRCH) + err = -ENETUNREACH; goto local_input; /* @@ -2623,11 +2626,10 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) int idx, s_idx; s_h = cb->args[0]; + if (s_h < 0) + s_h = 0; s_idx = idx = cb->args[1]; - for (h = 0; h <= rt_hash_mask; h++) { - if (h < s_h) continue; - if (h > s_h) - s_idx = 0; + for (h = s_h; h <= rt_hash_mask; h++) { rcu_read_lock_bh(); for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt; rt = rcu_dereference(rt->u.dst.rt_next), idx++) { @@ -2644,6 +2646,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) dst_release(xchg(&skb->dst, NULL)); } rcu_read_unlock_bh(); + s_idx = 0; } done: @@ -2888,18 +2891,14 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset, offset /= sizeof(u32); if (length > 0) { - u32 *src = ((u32 *) IP_RT_ACCT_CPU(0)) + offset; u32 *dst = (u32 *) buffer; - /* Copy first cpu. */ *start = buffer; - memcpy(dst, src, length); + memset(dst, 0, length); - /* Add the other cpus in, one int at a time */ for_each_possible_cpu(i) { unsigned int j; - - src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; + u32 *src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; for (j = 0; j < length/4; j++) dst[j] += src[j]; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index ffddd2b4535..bec6fe88065 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -191,7 +191,7 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, tcp_get_default_congestion_control(val); ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen); - if (ret == 0 && newval && newlen) + if (ret == 1 && newval && newlen) ret = tcp_set_default_congestion_control(val); return ret; } diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 64f1cbaf96e..5aa5f5496d6 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c @@ -298,7 +298,7 @@ static u32 tcp_illinois_ssthresh(struct sock *sk) struct illinois *ca = inet_csk_ca(sk); /* Multiplicative decrease */ - return max((tp->snd_cwnd * ca->beta) >> BETA_SHIFT, 2U); + return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->beta) >> BETA_SHIFT), 2U); } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 0f0c1c9829a..b39f0d86e44 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -923,7 +923,7 @@ static void tcp_init_metrics(struct sock *sk) } if (dst_metric(dst, RTAX_RTTVAR) > tp->mdev) { tp->mdev = dst_metric(dst, RTAX_RTTVAR); - tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN); + tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk)); } tcp_set_rto(sk); tcp_bound_rto(sk); @@ -2651,6 +2651,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, u32 cnt = 0; u32 reord = tp->packets_out; s32 seq_rtt = -1; + s32 ca_seq_rtt = -1; ktime_t last_ackt = net_invalid_timestamp(); while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) { @@ -2659,6 +2660,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, u32 packets_acked; u8 sacked = scb->sacked; + /* Determine how many packets and what bytes were acked, tso and else */ if (after(scb->end_seq, tp->snd_una)) { if (tcp_skb_pcount(skb) == 1 || !after(tp->snd_una, scb->seq)) @@ -2686,15 +2688,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, if (sacked & TCPCB_SACKED_RETRANS) tp->retrans_out -= packets_acked; flag |= FLAG_RETRANS_DATA_ACKED; + ca_seq_rtt = -1; seq_rtt = -1; if ((flag & FLAG_DATA_ACKED) || (packets_acked > 1)) flag |= FLAG_NONHEAD_RETRANS_ACKED; } else { + ca_seq_rtt = now - scb->when; + last_ackt = skb->tstamp; if (seq_rtt < 0) { - seq_rtt = now - scb->when; - if (fully_acked) - last_ackt = skb->tstamp; + seq_rtt = ca_seq_rtt; } if (!(sacked & TCPCB_SACKED_ACKED)) reord = min(cnt, reord); @@ -2709,10 +2712,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, !before(end_seq, tp->snd_up)) tp->urg_mode = 0; } else { + ca_seq_rtt = now - scb->when; + last_ackt = skb->tstamp; if (seq_rtt < 0) { - seq_rtt = now - scb->when; - if (fully_acked) - last_ackt = skb->tstamp; + seq_rtt = ca_seq_rtt; } reord = min(cnt, reord); } @@ -2772,8 +2775,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, net_invalid_timestamp())) rtt_us = ktime_us_delta(ktime_get_real(), last_ackt); - else if (seq_rtt > 0) - rtt_us = jiffies_to_usecs(seq_rtt); + else if (ca_seq_rtt > 0) + rtt_us = jiffies_to_usecs(ca_seq_rtt); } ca_ops->pkts_acked(sk, pkts_acked, rtt_us); @@ -3003,17 +3006,13 @@ static int tcp_process_frto(struct sock *sk, int flag) } if (tp->frto_counter == 1) { - /* Sending of the next skb must be allowed or no F-RTO */ - if (!tcp_send_head(sk) || - after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, - tp->snd_una + tp->snd_wnd)) { - tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3), - flag); - return 1; - } - + /* tcp_may_send_now needs to see updated state */ tp->snd_cwnd = tcp_packets_in_flight(tp) + 2; tp->frto_counter = 2; + + if (!tcp_may_send_now(sk)) + tcp_enter_frto_loss(sk, 2, flag); + return 1; } else { switch (sysctl_tcp_frto_response) { @@ -3069,6 +3068,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) } prior_fackets = tp->fackets_out; + prior_in_flight = tcp_packets_in_flight(tp); if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { /* Window is constant, pure forward advance. @@ -3108,8 +3108,6 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) if (!prior_packets) goto no_queue; - prior_in_flight = tcp_packets_in_flight(tp); - /* See if we can take anything off of the retransmit queue. */ flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e566f3c6767..652c32368cc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -900,8 +900,7 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, sizeof(*keys) * md5sig->entries4); /* Free old key list, and reference new one */ - if (md5sig->keys4) - kfree(md5sig->keys4); + kfree(md5sig->keys4); md5sig->keys4 = keys; md5sig->alloced4++; } @@ -939,10 +938,10 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr) tp->md5sig_info->alloced4 = 0; } else if (tp->md5sig_info->entries4 != i) { /* Need to do some manipulation */ - memcpy(&tp->md5sig_info->keys4[i], - &tp->md5sig_info->keys4[i+1], - (tp->md5sig_info->entries4 - i) * - sizeof(struct tcp4_md5sig_key)); + memmove(&tp->md5sig_info->keys4[i], + &tp->md5sig_info->keys4[i+1], + (tp->md5sig_info->entries4 - i) * + sizeof(struct tcp4_md5sig_key)); } tcp_free_md5sig_pool(); return 0; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 324b4207254..f4c1eef89af 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1162,8 +1162,7 @@ int tcp_may_send_now(struct sock *sk) return (skb && tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), (tcp_skb_is_last(sk, skb) ? - TCP_NAGLE_PUSH : - tp->nonagle))); + tp->nonagle : TCP_NAGLE_PUSH))); } /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet @@ -1295,6 +1294,7 @@ static int tcp_mtu_probe(struct sock *sk) struct sk_buff *skb, *nskb, *next; int len; int probe_size; + int size_needed; unsigned int pif; int copy; int mss_now; @@ -1313,27 +1313,20 @@ static int tcp_mtu_probe(struct sock *sk) /* Very simple search strategy: just double the MSS. */ mss_now = tcp_current_mss(sk, 0); probe_size = 2*tp->mss_cache; + size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache; if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) { /* TODO: set timer for probe_converge_event */ return -1; } /* Have enough data in the send queue to probe? */ - len = 0; - if ((skb = tcp_send_head(sk)) == NULL) - return -1; - while ((len += skb->len) < probe_size && !tcp_skb_is_last(sk, skb)) - skb = tcp_write_queue_next(sk, skb); - if (len < probe_size) + if (tp->write_seq - tp->snd_nxt < size_needed) return -1; - /* Receive window check. */ - if (after(TCP_SKB_CB(skb)->seq + probe_size, tp->snd_una + tp->snd_wnd)) { - if (tp->snd_wnd < probe_size) - return -1; - else - return 0; - } + if (tp->snd_wnd < size_needed) + return -1; + if (after(tp->snd_nxt + size_needed, tp->snd_una + tp->snd_wnd)) + return 0; /* Do we need to wait to drain cwnd? */ pif = tcp_packets_in_flight(tp); @@ -1352,7 +1345,6 @@ static int tcp_mtu_probe(struct sock *sk) skb = tcp_send_head(sk); tcp_insert_write_queue_before(nskb, skb, sk); - tcp_advance_send_head(sk, skb); TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq; TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1bd8d818f8e..e8c347579da 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -967,7 +967,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, if (unlikely(score.addr_type == IPV6_ADDR_ANY || score.addr_type & IPV6_ADDR_MULTICAST)) { LIMIT_NETDEBUG(KERN_DEBUG - "ADDRCONF: unspecified / multicast address" + "ADDRCONF: unspecified / multicast address " "assigned as unicast address on %s", dev->name); continue; @@ -2293,6 +2293,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, break; } + if (!idev && dev->mtu >= IPV6_MIN_MTU) + idev = ipv6_add_dev(dev); + if (idev) idev->if_flags |= IF_READY; } else { @@ -2357,12 +2360,18 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, break; case NETDEV_CHANGEMTU: - if ( idev && dev->mtu >= IPV6_MIN_MTU) { + if (idev && dev->mtu >= IPV6_MIN_MTU) { rt6_mtu_change(dev, dev->mtu); idev->cnf.mtu6 = dev->mtu; break; } + if (!idev && dev->mtu >= IPV6_MIN_MTU) { + idev = ipv6_add_dev(dev); + if (idev) + break; + } + /* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */ case NETDEV_DOWN: diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 2ed689ac449..5d4245ab418 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -123,11 +123,11 @@ ipv4_connected: goto out; } sk->sk_bound_dev_if = usin->sin6_scope_id; - if (!sk->sk_bound_dev_if && - (addr_type & IPV6_ADDR_MULTICAST)) - fl.oif = np->mcast_oif; } + if (!sk->sk_bound_dev_if && (addr_type & IPV6_ADDR_MULTICAST)) + sk->sk_bound_dev_if = np->mcast_oif; + /* Connect to link-local address requires an interface */ if (!sk->sk_bound_dev_if) { err = -EINVAL; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 7db66f10e00..44405325467 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -230,6 +230,12 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) } /* ... check padding bits here. Silly. :-) */ + /* RFC4303: Drop dummy packets without any error */ + if (nexthdr[1] == IPPROTO_NONE) { + ret = -EINVAL; + goto out; + } + pskb_trim(skb, skb->len - alen - padlen - 2); ret = nexthdr[1]; } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 86e1835ce4e..6338a9c1aa1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -933,6 +933,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, return 0; out_err_release: + if (err == -ENETUNREACH) + IP6_INC_STATS_BH(NULL, IPSTATS_MIB_OUTNOROUTES); dst_release(*dst); *dst = NULL; return err; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1334fc174bc..8c5f80fd03a 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -1046,7 +1046,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; default: - return -EINVAL; + return -ENOPROTOOPT; } len = min_t(unsigned int, sizeof(int), len); if(put_user(len, optlen)) @@ -1069,9 +1069,8 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER - /* we need to exclude all possible EINVALs except default case */ - if (err == -EINVAL && optname != IPV6_ADDRFORM && - optname != MCAST_MSFILTER) { + /* we need to exclude all possible ENOPROTOOPTs except default case */ + if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { int len; if (get_user(len, optlen)) @@ -1108,9 +1107,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER - /* we need to exclude all possible EINVALs except default case */ - if (err == -EINVAL && optname != IPV6_ADDRFORM && - optname != MCAST_MSFILTER) { + /* we need to exclude all possible ENOPROTOOPTs except default case */ + if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { int len; if (get_user(len, optlen)) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 67997a74ddc..777ed733b2d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -612,7 +612,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, * optimistic addresses, but we may send the solicitation * if we don't include the sllao. So here we check * if our address is optimistic, and if so, we - * supress the inclusion of the sllao. + * suppress the inclusion of the sllao. */ if (send_sllao) { struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3aad861975a..93980c3b83e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -581,7 +581,10 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer, } sk->sk_route_caps &= ~NETIF_F_GSO_MASK; } - tcp_alloc_md5sig_pool(); + if (tcp_alloc_md5sig_pool() == NULL) { + kfree(newkey); + return -ENOMEM; + } if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) { keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) * (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC); @@ -634,10 +637,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer) kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; tp->md5sig_info->alloced6 = 0; - - tcp_free_md5sig_pool(); - - return 0; } else { /* shrink the database */ if (tp->md5sig_info->entries6 != i) @@ -646,6 +645,8 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer) (tp->md5sig_info->entries6 - i) * sizeof (tp->md5sig_info->keys6[0])); } + tcp_free_md5sig_pool(); + return 0; } } return -ENOENT; diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 82e27b80d07..b8e9eb445d7 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -233,7 +233,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output; /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ - x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); + x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTF_ANYCAST|RTF_LOCAL); x->u.rt6.rt6i_metric = rt0->rt6i_metric; x->u.rt6.rt6i_node = rt0->rt6i_node; x->u.rt6.rt6i_gateway = rt0->rt6i_gateway; diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 48ce59a6e02..d5e4dd75200 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1118,8 +1118,6 @@ static int irda_create(struct net *net, struct socket *sock, int protocol) self->max_sdu_size_rx = TTP_SAR_UNBOUND; break; default: - IRDA_ERROR("%s: protocol not supported!\n", - __FUNCTION__); return -ESOCKTNOSUPPORT; } break; diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index e5e4792a031..598dcbe4a50 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -496,7 +496,7 @@ static int ircomm_param_poll(void *instance, irda_param_t *param, int get) IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); - /* Poll parameters are always of lenght 0 (just a signal) */ + /* Poll parameters are always of length 0 (just a signal) */ if (!get) { /* Respond with DTE line settings */ ircomm_param_request(self, IRCOMM_DTE, TRUE); diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 1120b150e21..be627e1f04d 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -1245,6 +1245,7 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, self->flow = cmd; } +#ifdef CONFIG_PROC_FS static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf) { int ret=0; @@ -1354,7 +1355,6 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf) * * */ -#ifdef CONFIG_PROC_FS static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused) { diff --git a/net/irda/iriap.c b/net/irda/iriap.c index dc5e34a0162..a86a5d83786 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -928,7 +928,7 @@ void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb) opcode = fp[0]; if (~opcode & 0x80) { - IRDA_WARNING("%s: IrIAS multiframe commands or results" + IRDA_WARNING("%s: IrIAS multiframe commands or results " "is not implemented yet!\n", __FUNCTION__); return; } diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index 7f9c8542e5f..1ab91f787cc 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -296,6 +296,7 @@ void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) */ void irlan_eth_send_gratuitous_arp(struct net_device *dev) { +#ifdef CONFIG_INET struct in_device *in_dev; /* @@ -303,7 +304,6 @@ void irlan_eth_send_gratuitous_arp(struct net_device *dev) * is useful if we have changed access points on the same * subnet. */ -#ifdef CONFIG_INET IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n"); rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); @@ -342,7 +342,7 @@ static void irlan_eth_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ - IRDA_WARNING("Promiscous mode not implemented by IrLAN!\n"); + IRDA_WARNING("Promiscuous mode not implemented by IrLAN!\n"); } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) { /* Disable promiscuous mode, use normal mode. */ diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 4f3764546b2..7c132d6342a 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -144,7 +144,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) frame->control = SNRM_CMD | PF_BIT; /* - * If we are establishing a connection then insert QoS paramerters + * If we are establishing a connection then insert QoS parameters */ if (qos) { skb_put(tx_skb, 9); /* 25 left */ diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index cedff8068fb..f24cb755908 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -353,6 +353,7 @@ void irlmp_unregister_link(__u32 saddr) /* Final cleanup */ del_timer(&link->idle_timer); link->magic = 0; + hashbin_delete(link->lsaps, (FREE_FUNC) __irlmp_close_lsap); kfree(link); } } diff --git a/net/irda/parameters.c b/net/irda/parameters.c index 2627dad7cd8..722bbe044d9 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -133,7 +133,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, int err; p.pi = pi; /* In case handler needs to know */ - p.pl = type & PV_MASK; /* The integer type codes the lenght as well */ + p.pl = type & PV_MASK; /* The integer type codes the length as well */ p.pv.i = 0; /* Clear value */ /* Call handler for this parameter */ @@ -142,7 +142,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, return err; /* - * If parameter lenght is still 0, then (1) this is an any length + * If parameter length is still 0, then (1) this is an any length * integer, and (2) the handler function does not care which length * we choose to use, so we pick the one the gives the fewest bytes. */ @@ -206,11 +206,11 @@ static int irda_extract_integer(void *self, __u8 *buf, int len, __u8 pi, { irda_param_t p; int n = 0; - int extract_len; /* Real lenght we extract */ + int extract_len; /* Real length we extract */ int err; p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ p.pv.i = 0; /* Clear value */ extract_len = p.pl; /* Default : extract all */ @@ -297,7 +297,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, IRDA_DEBUG(2, "%s()\n", __FUNCTION__); p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __FUNCTION__, p.pi, p.pl); @@ -339,7 +339,7 @@ static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi, irda_param_t p; p.pi = pi; /* In case handler needs to know */ - p.pl = buf[1]; /* Extract lenght of value */ + p.pl = buf[1]; /* Extract length of value */ /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { @@ -463,7 +463,7 @@ int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, int n = 0; IRDA_ASSERT(buf != NULL, return ret;); - IRDA_ASSERT(info != 0, return ret;); + IRDA_ASSERT(info != NULL, return ret;); pi_minor = pi & info->pi_mask; pi_major = pi >> info->pi_major_offset; @@ -517,7 +517,7 @@ static int irda_param_extract(void *self, __u8 *buf, int len, int n = 0; IRDA_ASSERT(buf != NULL, return ret;); - IRDA_ASSERT(info != 0, return ret;); + IRDA_ASSERT(info != NULL, return ret;); pi_minor = buf[n] & info->pi_mask; pi_major = buf[n] >> info->pi_major_offset; @@ -570,7 +570,7 @@ int irda_param_extract_all(void *self, __u8 *buf, int len, int n = 0; IRDA_ASSERT(buf != NULL, return ret;); - IRDA_ASSERT(info != 0, return ret;); + IRDA_ASSERT(info != NULL, return ret;); /* * Parse all parameters. Each parameter must be at least two bytes diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c index e71286768a4..c246983308b 100644 --- a/net/irda/wrapper.c +++ b/net/irda/wrapper.c @@ -238,7 +238,7 @@ async_bump(struct net_device *dev, skb_reserve(newskb, 1); if(docopy) { - /* Copy data without CRC (lenght already checked) */ + /* Copy data without CRC (length already checked) */ skb_copy_to_linear_data(newskb, rx_buff->data, rx_buff->len - 2); /* Deliver this skb */ diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index a2f5a6ea389..7698f6c459d 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -97,7 +97,7 @@ struct iucv_irq_list { struct iucv_irq_data data; }; -static struct iucv_irq_data *iucv_irq_data; +static struct iucv_irq_data *iucv_irq_data[NR_CPUS]; static cpumask_t iucv_buffer_cpumask = CPU_MASK_NONE; static cpumask_t iucv_irq_cpumask = CPU_MASK_NONE; @@ -277,7 +277,7 @@ union iucv_param { /* * Anchor for per-cpu IUCV command parameter block. */ -static union iucv_param *iucv_param; +static union iucv_param *iucv_param[NR_CPUS]; /** * iucv_call_b2f0 @@ -356,7 +356,7 @@ static void iucv_allow_cpu(void *data) * 0x10 - Flag to allow priority message completion interrupts * 0x08 - Flag to allow IUCV control interrupts */ - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[cpu]; memset(parm, 0, sizeof(union iucv_param)); parm->set_mask.ipmask = 0xf8; iucv_call_b2f0(IUCV_SETMASK, parm); @@ -377,7 +377,7 @@ static void iucv_block_cpu(void *data) union iucv_param *parm; /* Disable all iucv interrupts. */ - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[cpu]; memset(parm, 0, sizeof(union iucv_param)); iucv_call_b2f0(IUCV_SETMASK, parm); @@ -401,9 +401,9 @@ static void iucv_declare_cpu(void *data) return; /* Declare interrupt buffer. */ - parm = percpu_ptr(iucv_param, cpu); + parm = iucv_param[cpu]; memset(parm, 0, sizeof(union iucv_param)); - parm->db.ipbfadr1 = virt_to_phys(percpu_ptr(iucv_irq_data, cpu)); + parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]); rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm); if (rc) { char *err = "Unknown"; @@ -458,7 +458,7 @@ static void iucv_retrieve_cpu(void *data) iucv_block_cpu(NULL); /* Retrieve interrupt buffer. */ - parm = percpu_ptr(iucv_param, cpu); + parm = iucv_param[cpu]; iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm); /* Clear indication that an iucv buffer exists for this cpu. */ @@ -558,22 +558,23 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, switch (action) { case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: - if (!percpu_populate(iucv_irq_data, - sizeof(struct iucv_irq_data), - GFP_KERNEL|GFP_DMA, cpu)) + iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data), + GFP_KERNEL|GFP_DMA, cpu_to_node(cpu)); + if (!iucv_irq_data[cpu]) return NOTIFY_BAD; - if (!percpu_populate(iucv_param, sizeof(union iucv_param), - GFP_KERNEL|GFP_DMA, cpu)) { - percpu_depopulate(iucv_irq_data, cpu); + iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param), + GFP_KERNEL|GFP_DMA, cpu_to_node(cpu)); + if (!iucv_param[cpu]) return NOTIFY_BAD; - } break; case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: - percpu_depopulate(iucv_param, cpu); - percpu_depopulate(iucv_irq_data, cpu); + kfree(iucv_param[cpu]); + iucv_param[cpu] = NULL; + kfree(iucv_irq_data[cpu]); + iucv_irq_data[cpu] = NULL; break; case CPU_ONLINE: case CPU_ONLINE_FROZEN: @@ -612,7 +613,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16]) { union iucv_param *parm; - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (userdata) memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); @@ -755,7 +756,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler, local_bh_disable(); /* Prepare parameter block. */ - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); parm->ctrl.ippathid = path->pathid; parm->ctrl.ipmsglim = path->msglim; @@ -799,7 +800,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler, BUG_ON(in_atomic()); spin_lock_bh(&iucv_table_lock); iucv_cleanup_queue(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); parm->ctrl.ipmsglim = path->msglim; parm->ctrl.ipflags1 = path->flags; @@ -854,7 +855,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]) int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (userdata) memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); @@ -881,7 +882,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16]) int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (userdata) memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); @@ -936,7 +937,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); parm->purge.ippathid = path->pathid; parm->purge.ipmsgid = msg->id; @@ -1003,7 +1004,7 @@ int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg, } local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); parm->db.ipbfadr1 = (u32)(addr_t) buffer; parm->db.ipbfln1f = (u32) size; @@ -1040,7 +1041,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg) int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); parm->db.ippathid = path->pathid; parm->db.ipmsgid = msg->id; @@ -1074,7 +1075,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (flags & IUCV_IPRMDATA) { parm->dpl.ippathid = path->pathid; @@ -1118,7 +1119,7 @@ int iucv_message_send(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (flags & IUCV_IPRMDATA) { /* Message of 8 bytes can be placed into the parameter list. */ @@ -1172,7 +1173,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg, int rc; local_bh_disable(); - parm = percpu_ptr(iucv_param, smp_processor_id()); + parm = iucv_param[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (flags & IUCV_IPRMDATA) { parm->dpl.ippathid = path->pathid; @@ -1559,7 +1560,7 @@ static void iucv_external_interrupt(u16 code) struct iucv_irq_data *p; struct iucv_irq_list *work; - p = percpu_ptr(iucv_irq_data, smp_processor_id()); + p = iucv_irq_data[smp_processor_id()]; if (p->ippathid >= iucv_max_pathid) { printk(KERN_WARNING "iucv_do_int: Got interrupt with " "pathid %d > max_connections (%ld)\n", @@ -1598,6 +1599,7 @@ static void iucv_external_interrupt(u16 code) static int __init iucv_init(void) { int rc; + int cpu; if (!MACHINE_IS_VM) { rc = -EPROTONOSUPPORT; @@ -1617,19 +1619,23 @@ static int __init iucv_init(void) rc = PTR_ERR(iucv_root); goto out_bus; } - /* Note: GFP_DMA used to get memory below 2G */ - iucv_irq_data = percpu_alloc(sizeof(struct iucv_irq_data), - GFP_KERNEL|GFP_DMA); - if (!iucv_irq_data) { - rc = -ENOMEM; - goto out_root; - } - /* Allocate parameter blocks. */ - iucv_param = percpu_alloc(sizeof(union iucv_param), - GFP_KERNEL|GFP_DMA); - if (!iucv_param) { - rc = -ENOMEM; - goto out_extint; + + for_each_online_cpu(cpu) { + /* Note: GFP_DMA used to get memory below 2G */ + iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data), + GFP_KERNEL|GFP_DMA, cpu_to_node(cpu)); + if (!iucv_irq_data[cpu]) { + rc = -ENOMEM; + goto out_free; + } + + /* Allocate parameter blocks. */ + iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param), + GFP_KERNEL|GFP_DMA, cpu_to_node(cpu)); + if (!iucv_param[cpu]) { + rc = -ENOMEM; + goto out_free; + } } register_hotcpu_notifier(&iucv_cpu_notifier); ASCEBC(iucv_error_no_listener, 16); @@ -1638,9 +1644,13 @@ static int __init iucv_init(void) iucv_available = 1; return 0; -out_extint: - percpu_free(iucv_irq_data); -out_root: +out_free: + for_each_possible_cpu(cpu) { + kfree(iucv_param[cpu]); + iucv_param[cpu] = NULL; + kfree(iucv_irq_data[cpu]); + iucv_irq_data[cpu] = NULL; + } s390_root_dev_unregister(iucv_root); out_bus: bus_unregister(&iucv_bus); @@ -1658,6 +1668,7 @@ out: static void __exit iucv_exit(void) { struct iucv_irq_list *p, *n; + int cpu; spin_lock_irq(&iucv_queue_lock); list_for_each_entry_safe(p, n, &iucv_task_queue, list) @@ -1666,8 +1677,12 @@ static void __exit iucv_exit(void) kfree(p); spin_unlock_irq(&iucv_queue_lock); unregister_hotcpu_notifier(&iucv_cpu_notifier); - percpu_free(iucv_param); - percpu_free(iucv_irq_data); + for_each_possible_cpu(cpu) { + kfree(iucv_param[cpu]); + iucv_param[cpu] = NULL; + kfree(iucv_irq_data[cpu]); + iucv_irq_data[cpu] = NULL; + } s390_root_dev_unregister(iucv_root); bus_unregister(&iucv_bus); unregister_external_interrupt(0x4000, iucv_external_interrupt); diff --git a/net/key/af_key.c b/net/key/af_key.c index 10c89d47f68..26d5e63c4cc 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -1015,9 +1015,7 @@ static inline struct sk_buff *pfkey_xfrm_state2msg(struct xfrm_state *x) { struct sk_buff *skb; - spin_lock_bh(&x->lock); skb = __pfkey_xfrm_state2msg(x, 1, 3); - spin_unlock_bh(&x->lock); return skb; } @@ -1552,7 +1550,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, out_hdr = (struct sadb_msg *) out_skb->data; out_hdr->sadb_msg_version = hdr->sadb_msg_version; - out_hdr->sadb_msg_type = SADB_DUMP; + out_hdr->sadb_msg_type = SADB_GET; out_hdr->sadb_msg_satype = pfkey_proto2satype(proto); out_hdr->sadb_msg_errno = 0; out_hdr->sadb_msg_reserved = 0; @@ -2786,12 +2784,22 @@ static struct sadb_msg *pfkey_get_base_msg(struct sk_buff *skb, int *errp) static inline int aalg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d) { - return t->aalgos & (1 << d->desc.sadb_alg_id); + unsigned int id = d->desc.sadb_alg_id; + + if (id >= sizeof(t->aalgos) * 8) + return 0; + + return (t->aalgos >> id) & 1; } static inline int ealg_tmpl_set(struct xfrm_tmpl *t, struct xfrm_algo_desc *d) { - return t->ealgos & (1 << d->desc.sadb_alg_id); + unsigned int id = d->desc.sadb_alg_id; + + if (id >= sizeof(t->ealgos) * 8) + return 0; + + return (t->ealgos >> id) & 1; } static int count_ah_combs(struct xfrm_tmpl *t) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index e0ee65a969b..6378850d858 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -216,6 +216,7 @@ static int ieee80211_open(struct net_device *dev) res = local->ops->start(local_to_hw(local)); if (res) return res; + ieee80211_hw_config(local); } switch (sdata->type) { @@ -232,7 +233,6 @@ static int ieee80211_open(struct net_device *dev) netif_tx_unlock_bh(local->mdev); local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; - ieee80211_hw_config(local); } break; case IEEE80211_IF_TYPE_STA: @@ -267,6 +267,17 @@ static int ieee80211_open(struct net_device *dev) tasklet_enable(&local->tasklet); } + /* + * set_multicast_list will be invoked by the networking core + * which will check whether any increments here were done in + * error and sync them down to the hardware as filter flags. + */ + if (sdata->flags & IEEE80211_SDATA_ALLMULTI) + atomic_inc(&local->iff_allmultis); + + if (sdata->flags & IEEE80211_SDATA_PROMISC) + atomic_inc(&local->iff_promiscs); + local->open_count++; netif_start_queue(dev); @@ -284,6 +295,18 @@ static int ieee80211_stop(struct net_device *dev) netif_stop_queue(dev); + /* + * Don't count this interface for promisc/allmulti while it + * is down. dev_mc_unsync() will invoke set_multicast_list + * on the master interface which will sync these down to the + * hardware as filter flags. + */ + if (sdata->flags & IEEE80211_SDATA_ALLMULTI) + atomic_dec(&local->iff_allmultis); + + if (sdata->flags & IEEE80211_SDATA_PROMISC) + atomic_dec(&local->iff_promiscs); + dev_mc_unsync(local->mdev, dev); /* down all dependent devices, that is VLANs */ @@ -311,8 +334,7 @@ static int ieee80211_stop(struct net_device *dev) ieee80211_configure_filter(local); netif_tx_unlock_bh(local->mdev); - local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; - ieee80211_hw_config(local); + local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; } break; case IEEE80211_IF_TYPE_STA: @@ -334,6 +356,11 @@ static int ieee80211_stop(struct net_device *dev) cancel_delayed_work(&local->scan_work); } flush_workqueue(local->hw.workqueue); + + sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; + kfree(sdata->u.sta.extra_ie); + sdata->u.sta.extra_ie = NULL; + sdata->u.sta.extra_ie_len = 0; /* fall through */ default: conf.if_id = dev->ifindex; @@ -366,8 +393,8 @@ static void ieee80211_set_multicast_list(struct net_device *dev) allmulti = !!(dev->flags & IFF_ALLMULTI); promisc = !!(dev->flags & IFF_PROMISC); - sdata_allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI; - sdata_promisc = sdata->flags & IEEE80211_SDATA_PROMISC; + sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI); + sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC); if (allmulti != sdata_allmulti) { if (dev->flags & IFF_ALLMULTI) @@ -400,7 +427,6 @@ static const struct header_ops ieee80211_header_ops = { void ieee80211_if_setup(struct net_device *dev) { ether_setup(dev); - dev->header_ops = &ieee80211_header_ops; dev->hard_start_xmit = ieee80211_subif_start_xmit; dev->wireless_handlers = &ieee80211_iw_handler_def; dev->set_multicast_list = ieee80211_set_multicast_list; diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 7027eed4d4a..308bbe4a133 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -591,7 +591,7 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, sdata->bss->force_unicast_rateidx = -1; if (rate->value < 0) return 0; - for (i=0; i< mode->num_rates; i++) { + for (i=0; i < mode->num_rates; i++) { struct ieee80211_rate *rates = &mode->rates[i]; int this_rate = rates->rate; @@ -599,10 +599,10 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, sdata->bss->max_ratectrl_rateidx = i; if (rate->fixed) sdata->bss->force_unicast_rateidx = i; - break; + return 0; } } - return 0; + return -EINVAL; } static int ieee80211_ioctl_giwrate(struct net_device *dev, diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index 7254bd60983..c3f27839374 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c @@ -33,6 +33,7 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops) if (!strcmp(alg->ops->name, ops->name)) { /* don't register an algorithm twice */ WARN_ON(1); + mutex_unlock(&rate_ctrl_mutex); return -EALREADY; } } @@ -59,11 +60,11 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops) list_for_each_entry(alg, &rate_ctrl_algs, list) { if (alg->ops == ops) { list_del(&alg->list); + kfree(alg); break; } } mutex_unlock(&rate_ctrl_mutex); - kfree(alg); } EXPORT_SYMBOL(ieee80211_rate_control_unregister); diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 015b3f879aa..bee8080f224 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -808,12 +808,8 @@ static void ieee80211_associated(struct net_device *dev, sta_info_put(sta); } if (disassoc) { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - mod_timer(&ifsta->timer, jiffies + - IEEE80211_MONITORING_INTERVAL + 30 * HZ); + ifsta->state = IEEE80211_DISABLED; + ieee80211_set_associated(dev, ifsta, 0); } else { mod_timer(&ifsta->timer, jiffies + IEEE80211_MONITORING_INTERVAL); @@ -2647,7 +2643,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) local->sta_scanning = 0; if (ieee80211_hw_config(local)) - printk(KERN_DEBUG "%s: failed to restore operational" + printk(KERN_DEBUG "%s: failed to restore operational " "channel after scan\n", dev->name); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 428a9fcf57d..a7263fc476b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -997,7 +997,7 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) && (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC && - rx->sdata->drop_unencrypted && + (rx->key || rx->sdata->drop_unencrypted) && (rx->sdata->eapol == 0 || !ieee80211_is_eapol(rx->skb)))) { if (net_ratelimit()) printk(KERN_DEBUG "%s: RX non-WEP frame, but expected " @@ -1443,6 +1443,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sub_if_data *prev = NULL; struct sk_buff *skb_new; u8 *bssid; + int hdrlen; /* * key references and virtual interfaces are protected using RCU @@ -1472,6 +1473,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, rx.fc = le16_to_cpu(hdr->frame_control); type = rx.fc & IEEE80211_FCTL_FTYPE; + /* + * Drivers are required to align the payload data to a four-byte + * boundary, so the last two bits of the address where it starts + * may not be set. The header is required to be directly before + * the payload data, padding like atheros hardware adds which is + * inbetween the 802.11 header and the payload is not supported, + * the driver is required to move the 802.11 header further back + * in that case. + */ + hdrlen = ieee80211_get_hdrlen(rx.fc); + WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3); + if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) local->dot11ReceivedFragmentCount++; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index e8491554a5d..cfd8ee9adad 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/skbuff.h> #include <linux/if_arp.h> +#include <linux/timer.h> #include <net/mac80211.h> #include "ieee80211_i.h" @@ -306,7 +307,8 @@ static void sta_info_cleanup(unsigned long data) } read_unlock_bh(&local->sta_lock); - local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL; + local->sta_cleanup.expires = + round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); add_timer(&local->sta_cleanup); } @@ -345,7 +347,8 @@ void sta_info_init(struct ieee80211_local *local) INIT_LIST_HEAD(&local->sta_list); init_timer(&local->sta_cleanup); - local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL; + local->sta_cleanup.expires = + round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL); local->sta_cleanup.data = (unsigned long) local; local->sta_cleanup.function = sta_info_cleanup; diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9bf0e1cc530..b5f3413403b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -265,7 +265,8 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, skb->data + hdrlen + WEP_IV_LEN, len)) { - printk(KERN_DEBUG "WEP decrypt failed (ICV)\n"); + if (net_ratelimit()) + printk(KERN_DEBUG "WEP decrypt failed (ICV)\n"); ret = -1; } diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 000c2fb462d..a4d5cdeb011 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1016,7 +1016,7 @@ struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced) } EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable); -int set_hashsize(const char *val, struct kernel_param *kp) +int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) { int i, bucket, hashsize, vmalloced; int old_vmalloced, old_size; @@ -1063,8 +1063,9 @@ int set_hashsize(const char *val, struct kernel_param *kp) nf_ct_free_hashtable(old_hash, old_vmalloced, old_size); return 0; } +EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); -module_param_call(hashsize, set_hashsize, param_get_uint, +module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, &nf_conntrack_htable_size, 0600); int __init nf_conntrack_init(void) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9be1826e6cd..7d231243754 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1024,8 +1024,10 @@ ctnetlink_create_conntrack(struct nlattr *cda[], } /* setup master conntrack: this is a confirmed expectation */ - if (master_ct) + if (master_ct) { + __set_bit(IPS_EXPECTED_BIT, &ct->status); ct->master = master_ct; + } add_timer(&ct->timeout); nf_conntrack_hash_insert(ct); diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 8f8b5a48df3..515abffc4a0 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -187,7 +187,7 @@ static const struct sip_header_nfo ct_sip_hdrs[] = { } }; -/* get line lenght until first CR or LF seen. */ +/* get line length until first CR or LF seen. */ int ct_sip_lnlen(const char *line, const char *limit) { const char *k = line; @@ -236,7 +236,7 @@ static int digits_len(struct nf_conn *ct, const char *dptr, return len; } -/* get digits lenght, skiping blank spaces. */ +/* get digits length, skipping blank spaces. */ static int skp_digits_len(struct nf_conn *ct, const char *dptr, const char *limit, int *shift) { diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index d9a3bded0d0..b6160e41eb1 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -377,7 +377,9 @@ int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr, u_int16_t msize = m->u.user.match_size - off; if (copy_to_user(cm, m, sizeof(*cm)) || - put_user(msize, &cm->u.user.match_size)) + put_user(msize, &cm->u.user.match_size) || + copy_to_user(cm->u.user.name, m->u.kernel.match->name, + strlen(m->u.kernel.match->name) + 1)) return -EFAULT; if (match->compat_to_user) { @@ -468,7 +470,9 @@ int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr, u_int16_t tsize = t->u.user.target_size - off; if (copy_to_user(ct, t, sizeof(*ct)) || - put_user(tsize, &ct->u.user.target_size)) + put_user(tsize, &ct->u.user.target_size) || + copy_to_user(ct->u.user.name, t->u.kernel.target->name, + strlen(t->u.kernel.target->name) + 1)) return -EFAULT; if (target->compat_to_user) { diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index 856793e8db7..0621ca7de3b 100644 --- a/net/netfilter/xt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c @@ -86,11 +86,6 @@ checkentry(const char *tablename, { const struct xt_connmark_target_info *matchinfo = targinfo; - if (nf_ct_l3proto_try_module_get(target->family) < 0) { - printk(KERN_WARNING "can't load conntrack support for " - "proto=%d\n", target->family); - return false; - } if (matchinfo->mode == XT_CONNMARK_RESTORE) { if (strcmp(tablename, "mangle") != 0) { printk(KERN_WARNING "CONNMARK: restore can only be " @@ -103,6 +98,11 @@ checkentry(const char *tablename, printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); return false; } + if (nf_ct_l3proto_try_module_get(target->family) < 0) { + printk(KERN_WARNING "can't load conntrack support for " + "proto=%d\n", target->family); + return false; + } return true; } diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 021b5c8d20e..d8feba9bdb4 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c @@ -90,11 +90,6 @@ static bool checkentry(const char *tablename, const void *entry, { const struct xt_connsecmark_target_info *info = targinfo; - if (nf_ct_l3proto_try_module_get(target->family) < 0) { - printk(KERN_WARNING "can't load conntrack support for " - "proto=%d\n", target->family); - return false; - } switch (info->mode) { case CONNSECMARK_SAVE: case CONNSECMARK_RESTORE: @@ -105,6 +100,11 @@ static bool checkentry(const char *tablename, const void *entry, return false; } + if (nf_ct_l3proto_try_module_get(target->family) < 0) { + printk(KERN_WARNING "can't load conntrack support for " + "proto=%d\n", target->family); + return false; + } return true; } diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 07435a602b1..8e76d1f52fb 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c @@ -174,10 +174,8 @@ xt_tcpmss_target6(struct sk_buff *skb, nexthdr = ipv6h->nexthdr; tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr); - if (tcphoff < 0) { - WARN_ON(1); + if (tcphoff < 0) return NF_DROP; - } ret = tcpmss_mangle_packet(skb, targinfo, tcphoff, sizeof(*ipv6h) + sizeof(struct tcphdr)); if (ret < 0) diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 19103678bf2..2ef44d8560c 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -240,7 +240,7 @@ static bool select_all(const struct xt_hashlimit_htable *ht, static bool select_gc(const struct xt_hashlimit_htable *ht, const struct dsthash_ent *he) { - return jiffies >= he->expires; + return time_after_eq(jiffies, he->expires); } static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 56483377997..9c41464d58d 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -71,7 +71,7 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { }; /* - * NetLabel Misc Managment Functions + * NetLabel Misc Management Functions */ /** diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index 8c68da5ef0a..6caf459665f 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c @@ -56,7 +56,7 @@ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev) /* Spoof incoming device */ skb->dev = dev; - skb_reset_mac_header(skb); + skb->mac_header = skb->network_header; skb_reset_network_header(skb); skb->pkt_type = PACKET_HOST; diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 73d60a30712..4469a7be006 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -60,11 +60,7 @@ static void rfkill_led_trigger(struct rfkill *rfkill, static int rfkill_toggle_radio(struct rfkill *rfkill, enum rfkill_state state) { - int retval; - - retval = mutex_lock_interruptible(&rfkill->mutex); - if (retval) - return retval; + int retval = 0; if (state != rfkill->state) { retval = rfkill->toggle_radio(rfkill->data, state); @@ -74,7 +70,6 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, } } - mutex_unlock(&rfkill->mutex); return retval; } @@ -158,12 +153,13 @@ static ssize_t rfkill_state_store(struct device *dev, if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (mutex_lock_interruptible(&rfkill->mutex)) + return -ERESTARTSYS; error = rfkill_toggle_radio(rfkill, state ? RFKILL_STATE_ON : RFKILL_STATE_OFF); - if (error) - return error; + mutex_unlock(&rfkill->mutex); - return count; + return error ? error : count; } static ssize_t rfkill_claim_show(struct device *dev, diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index 1b6741f1d74..12cfcf09556 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c @@ -55,13 +55,13 @@ static int rose_header(struct sk_buff *skb, struct net_device *dev, static int rose_rebuild_header(struct sk_buff *skb) { +#ifdef CONFIG_INET struct net_device *dev = skb->dev; struct net_device_stats *stats = netdev_priv(dev); unsigned char *bp = (unsigned char *)skb->data; struct sk_buff *skbn; unsigned int len; -#ifdef CONFIG_INET if (arp_find(bp + 7, skb)) { return 1; } diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig index e662f1d0766..0d3103c4f11 100644 --- a/net/rxrpc/Kconfig +++ b/net/rxrpc/Kconfig @@ -5,6 +5,7 @@ config AF_RXRPC tristate "RxRPC session sockets" depends on INET && EXPERIMENTAL + select CRYPTO select KEYS help Say Y or M here to include support for RxRPC session sockets (just diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index e09a95aa68f..8e69d699383 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -1021,6 +1021,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn, abort_code = RXKADINCONSISTENCY; if (version != RXKAD_VERSION) + goto protocol_error; abort_code = RXKADTICKETLEN; if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN) diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 55e7e4530f4..a6ad491e434 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -160,7 +160,7 @@ struct hfsc_class u64 cl_vtoff; /* inter-period cumulative vt offset */ u64 cl_cvtmax; /* max child's vt in the last period */ u64 cl_cvtoff; /* cumulative cvtmax of all periods */ - u64 cl_pcvtoff; /* parent's cvtoff at initalization + u64 cl_pcvtoff; /* parent's cvtoff at initialization time */ struct internal_sc cl_rsc; /* internal real-time service curve */ diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig index 8210f549c49..5390bc79215 100644 --- a/net/sctp/Kconfig +++ b/net/sctp/Kconfig @@ -6,9 +6,9 @@ menuconfig IP_SCTP tristate "The SCTP Protocol (EXPERIMENTAL)" depends on INET && EXPERIMENTAL depends on IPV6 || IPV6=n - select CRYPTO if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5 - select CRYPTO_HMAC if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5 - select CRYPTO_SHA1 if SCTP_HMAC_SHA1 + select CRYPTO + select CRYPTO_HMAC + select CRYPTO_SHA1 select CRYPTO_MD5 if SCTP_HMAC_MD5 ---help--- Stream Control Transmission Protocol diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 6d5fa6bb371..97e6ebd1450 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -54,11 +54,13 @@ static struct sctp_hmac sctp_hmac_list[SCTP_AUTH_NUM_HMACS] = { /* id 2 is reserved as well */ .hmac_id = SCTP_AUTH_HMAC_ID_RESERVED_2, }, +#if defined (CONFIG_CRYPTO_SHA256) || defined (CONFIG_CRYPTO_SHA256_MODULE) { .hmac_id = SCTP_AUTH_HMAC_ID_SHA256, .hmac_name="hmac(sha256)", .hmac_len = SCTP_SHA256_SIG_SIZE, } +#endif }; @@ -631,7 +633,7 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param) int found = 0; int i; - if (!param) + if (!param || param->param_hdr.length == 0) return 0; len = ntohs(param->param_hdr.length) - sizeof(sctp_paramhdr_t); diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index cae95af9a8c..6a7d01091f0 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -105,6 +105,32 @@ out: return error; } +/* Exactly duplicate the address lists. This is necessary when doing + * peer-offs and accepts. We don't want to put all the current system + * addresses into the endpoint. That's useless. But we do want duplicat + * the list of bound addresses that the older endpoint used. + */ +int sctp_bind_addr_dup(struct sctp_bind_addr *dest, + const struct sctp_bind_addr *src, + gfp_t gfp) +{ + struct sctp_sockaddr_entry *addr; + struct list_head *pos; + int error = 0; + + /* All addresses share the same port. */ + dest->port = src->port; + + list_for_each(pos, &src->address_list) { + addr = list_entry(pos, struct sctp_sockaddr_entry, list); + error = sctp_add_bind_addr(dest, &addr->a, 1, gfp); + if (error < 0) + break; + } + + return error; +} + /* Initialize the SCTP_bind_addr structure for either an endpoint or * an association. */ diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5a9783c38de..3cc629d3c9f 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -77,6 +77,8 @@ static int sctp_process_param(struct sctp_association *asoc, union sctp_params param, const union sctp_addr *peer_addr, gfp_t gfp); +static void *sctp_addto_param(struct sctp_chunk *chunk, int len, + const void *data); /* What was the inbound interface for this chunk? */ int sctp_chunk_iif(const struct sctp_chunk *chunk) @@ -207,11 +209,10 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); chunksize += sizeof(ecap_param); - if (sctp_prsctp_enable) { + + if (sctp_prsctp_enable) chunksize += sizeof(prsctp_param); - extensions[num_ext] = SCTP_CID_FWD_TSN; - num_ext += 1; - } + /* ADDIP: Section 4.2.7: * An implementation supporting this extension [ADDIP] MUST list * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and @@ -243,7 +244,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, if (auth_chunks->length) chunksize += ntohs(auth_chunks->length); else - auth_hmacs = NULL; + auth_chunks = NULL; extensions[num_ext] = SCTP_CID_AUTH; num_ext += 1; @@ -288,7 +289,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); - /* Add the supported extensions paramter. Be nice and add this + /* Add the supported extensions parameter. Be nice and add this * fist before addiding the parameters for the extensions themselves */ if (num_ext) { @@ -297,7 +298,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, htons(sizeof(sctp_supported_ext_param_t) + num_ext); sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), &ext_param); - sctp_addto_chunk(retval, num_ext, extensions); + sctp_addto_param(retval, num_ext, extensions); } if (sctp_prsctp_enable) @@ -371,12 +372,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, if (asoc->peer.ecn_capable) chunksize += sizeof(ecap_param); - /* Tell peer that we'll do PR-SCTP only if peer advertised. */ - if (asoc->peer.prsctp_capable) { + if (sctp_prsctp_enable) chunksize += sizeof(prsctp_param); - extensions[num_ext] = SCTP_CID_FWD_TSN; - num_ext += 1; - } if (sctp_addip_enable) { extensions[num_ext] = SCTP_CID_ASCONF; @@ -384,7 +381,6 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, num_ext += 2; } - chunksize += sizeof(ext_param) + num_ext; chunksize += sizeof(aiparam); if (asoc->peer.auth_capable) { @@ -407,6 +403,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, num_ext += 1; } + if (num_ext) + chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; + /* Now allocate and fill out the chunk. */ retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); if (!retval) @@ -428,7 +427,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, htons(sizeof(sctp_supported_ext_param_t) + num_ext); sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t), &ext_param); - sctp_addto_chunk(retval, num_ext, extensions); + sctp_addto_param(retval, num_ext, extensions); } if (asoc->peer.prsctp_capable) sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); @@ -2866,7 +2865,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, chunk_len -= length; /* Skip the address parameter and store a pointer to the first - * asconf paramter. + * asconf parameter. */ length = ntohs(addr_param->v4.param_hdr.length); asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); @@ -2875,7 +2874,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, /* create an ASCONF_ACK chunk. * Based on the definitions of parameters, we know that the size of * ASCONF_ACK parameters are less than or equal to the twice of ASCONF - * paramters. + * parameters. */ asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 2); if (!asconf_ack) @@ -3069,7 +3068,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, asconf_len -= length; /* Skip the address parameter in the last asconf sent and store a - * pointer to the first asconf paramter. + * pointer to the first asconf parameter. */ length = ntohs(addr_param->v4.param_hdr.length); asconf_param = (sctp_addip_param_t *)((void *)addr_param + length); diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5ebbe808d80..d247ed4ee42 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -959,7 +959,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep, { struct sctp_transport *transport = (struct sctp_transport *) arg; - if (asoc->overall_error_count >= asoc->max_retrans) { + if (asoc->overall_error_count > asoc->max_retrans) { sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ETIMEDOUT)); /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ @@ -1146,7 +1146,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, /* Check if the timestamp looks valid. */ if (time_after(hbinfo->sent_at, jiffies) || time_after(jiffies, hbinfo->sent_at + max_interval)) { - SCTP_DEBUG_PRINTK("%s: HEARTBEAT ACK with invalid timestamp" + SCTP_DEBUG_PRINTK("%s: HEARTBEAT ACK with invalid timestamp " "received for transport: %p\n", __FUNCTION__, link); return SCTP_DISPOSITION_DISCARD; @@ -1309,26 +1309,6 @@ static void sctp_tietags_populate(struct sctp_association *new_asoc, new_asoc->c.initial_tsn = asoc->c.initial_tsn; } -static void sctp_auth_params_populate(struct sctp_association *new_asoc, - const struct sctp_association *asoc) -{ - /* Only perform this if AUTH extension is enabled */ - if (!sctp_auth_enable) - return; - - /* We need to provide the same parameter information as - * was in the original INIT. This means that we need to copy - * the HMACS, CHUNKS, and RANDOM parameter from the original - * assocaition. - */ - memcpy(new_asoc->c.auth_random, asoc->c.auth_random, - sizeof(asoc->c.auth_random)); - memcpy(new_asoc->c.auth_hmacs, asoc->c.auth_hmacs, - sizeof(asoc->c.auth_hmacs)); - memcpy(new_asoc->c.auth_chunks, asoc->c.auth_chunks, - sizeof(asoc->c.auth_chunks)); -} - /* * Compare vtag/tietag values to determine unexpected COOKIE-ECHO * handling action. @@ -1486,8 +1466,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( sctp_tietags_populate(new_asoc, asoc); - sctp_auth_params_populate(new_asoc, asoc); - /* B) "Z" shall respond immediately with an INIT ACK chunk. */ /* If there are errors need to be reported for unknown parameters, diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ff8bc95670e..ea9649ca0b2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -6325,7 +6325,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, struct sctp_endpoint *newep = newsp->ep; struct sk_buff *skb, *tmp; struct sctp_ulpevent *event; - int flags = 0; + struct sctp_bind_hashbucket *head; /* Migrate socket buffer sizes and all the socket level options to the * new socket. @@ -6342,23 +6342,21 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, newsp->hmac = NULL; /* Hook this new socket in to the bind_hash list. */ + head = &sctp_port_hashtable[sctp_phashfn(inet_sk(oldsk)->num)]; + sctp_local_bh_disable(); + sctp_spin_lock(&head->lock); pp = sctp_sk(oldsk)->bind_hash; sk_add_bind_node(newsk, &pp->owner); sctp_sk(newsk)->bind_hash = pp; inet_sk(newsk)->num = inet_sk(oldsk)->num; + sctp_spin_unlock(&head->lock); + sctp_local_bh_enable(); /* Copy the bind_addr list from the original endpoint to the new * endpoint so that we can handle restarts properly */ - if (PF_INET6 == assoc->base.sk->sk_family) - flags = SCTP_ADDR6_ALLOWED; - if (assoc->peer.ipv4_address) - flags |= SCTP_ADDR4_PEERSUPP; - if (assoc->peer.ipv6_address) - flags |= SCTP_ADDR6_PEERSUPP; - sctp_bind_addr_copy(&newsp->ep->base.bind_addr, - &oldsp->ep->base.bind_addr, - SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags); + sctp_bind_addr_dup(&newsp->ep->base.bind_addr, + &oldsp->ep->base.bind_addr, GFP_KERNEL); /* Move any messages in the old socket's receive queue that are for the * peeled off association to the new socket's receive queue. diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 2c17c7efad4..307314356e1 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -830,7 +830,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey( ak = (struct sctp_authkey_event *) skb_put(skb, sizeof(struct sctp_authkey_event)); - ak->auth_type = SCTP_AUTHENTICATION_EVENT; + ak->auth_type = SCTP_AUTHENTICATION_INDICATION; ak->auth_flags = 0; ak->auth_length = sizeof(struct sctp_authkey_event); diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 4908041ffb3..1733fa29a50 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -53,6 +53,7 @@ static struct sctp_ulpevent * sctp_ulpq_reasm(struct sctp_ulpq *ulpq, struct sctp_ulpevent *); static struct sctp_ulpevent * sctp_ulpq_order(struct sctp_ulpq *, struct sctp_ulpevent *); +static void sctp_ulpq_reasm_drain(struct sctp_ulpq *ulpq); /* 1st Level Abstractions */ @@ -190,6 +191,7 @@ static void sctp_ulpq_set_pd(struct sctp_ulpq *ulpq) static int sctp_ulpq_clear_pd(struct sctp_ulpq *ulpq) { ulpq->pd_mode = 0; + sctp_ulpq_reasm_drain(ulpq); return sctp_clear_pd(ulpq->asoc->base.sk, ulpq->asoc); } @@ -699,6 +701,37 @@ void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *ulpq, __u32 fwd_tsn) } } +/* + * Drain the reassembly queue. If we just cleared parted delivery, it + * is possible that the reassembly queue will contain already reassembled + * messages. Retrieve any such messages and give them to the user. + */ +static void sctp_ulpq_reasm_drain(struct sctp_ulpq *ulpq) +{ + struct sctp_ulpevent *event = NULL; + struct sk_buff_head temp; + + if (skb_queue_empty(&ulpq->reasm)) + return; + + while ((event = sctp_ulpq_retrieve_reassembled(ulpq)) != NULL) { + /* Do ordering if needed. */ + if ((event) && (event->msg_flags & MSG_EOR)){ + skb_queue_head_init(&temp); + __skb_queue_tail(&temp, sctp_event2skb(event)); + + event = sctp_ulpq_order(ulpq, event); + } + + /* Send event to the ULP. 'event' is the + * sctp_ulpevent for very first SKB on the temp' list. + */ + if (event) + sctp_ulpq_tail_event(ulpq, event); + } +} + + /* Helper function to gather skbs that have possibly become * ordered by an an incoming chunk. */ diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 53995af9ca4..1f2d85e869c 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -540,7 +540,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); if (IS_ERR(p)) { err = PTR_ERR(p); - gss_msg->msg.errno = (err == -EACCES) ? -EACCES : -EAGAIN; + gss_msg->msg.errno = (err == -EAGAIN) ? -EAGAIN : -EACCES; goto err_release_msg; } gss_msg->ctx = gss_get_ctx(ctx); @@ -625,7 +625,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) err = -EINVAL; gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); if (!gss_auth->mech) { - printk(KERN_WARNING "%s: Pseudoflavor %d not found!", + printk(KERN_WARNING "%s: Pseudoflavor %d not found!\n", __FUNCTION__, flavor); goto err_free; } @@ -967,7 +967,7 @@ gss_validate(struct rpc_task *task, __be32 *p) if (maj_stat == GSS_S_CONTEXT_EXPIRED) clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); if (maj_stat) { - dprintk("RPC: %5u gss_validate: gss_verify_mic returned" + dprintk("RPC: %5u gss_validate: gss_verify_mic returned " "error 0x%08x\n", task->tk_pid, maj_stat); goto out_bad; } diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 9843eacef11..60c3dba545d 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -147,13 +147,17 @@ gss_import_sec_context_kerberos(const void *p, p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); if (IS_ERR(p)) goto out_err_free_ctx; - if (tmp != SGN_ALG_DES_MAC_MD5) + if (tmp != SGN_ALG_DES_MAC_MD5) { + p = ERR_PTR(-ENOSYS); goto out_err_free_ctx; + } p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); if (IS_ERR(p)) goto out_err_free_ctx; - if (tmp != SEAL_ALG_DES) + if (tmp != SEAL_ALG_DES) { + p = ERR_PTR(-ENOSYS); goto out_err_free_ctx; + } p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); if (IS_ERR(p)) goto out_err_free_ctx; diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index 1c6eda5077c..dedcbd6108f 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -83,6 +83,7 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text, u32 seq_send; dprintk("RPC: gss_krb5_seal\n"); + BUG_ON(ctx == NULL); now = get_seconds(); diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 18f0a8dcc09..c59f3ca2b41 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -280,7 +280,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait) mask = POLLOUT | POLLWRNORM; if (rpci->ops == NULL) mask |= POLLERR | POLLHUP; - if (!list_empty(&rpci->pipe)) + if (filp->private_data || !list_empty(&rpci->pipe)) mask |= POLLIN | POLLRDNORM; return mask; } diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 282a9a2ec90..cd641c8634f 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -62,7 +62,7 @@ static inline void do_xprt_reserve(struct rpc_task *); static void xprt_connect_status(struct rpc_task *task); static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); -static spinlock_t xprt_list_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(xprt_list_lock); static LIST_HEAD(xprt_list); /* diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 9e11ce71595..ee8de7af2a5 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -92,7 +92,6 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, seg[n].mr_page = NULL; seg[n].mr_offset = xdrbuf->head[0].iov_base; seg[n].mr_len = xdrbuf->head[0].iov_len; - pos += xdrbuf->head[0].iov_len; ++n; } @@ -104,7 +103,6 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, seg[n].mr_len = min_t(u32, PAGE_SIZE - xdrbuf->page_base, xdrbuf->page_len); len = xdrbuf->page_len - seg[n].mr_len; - pos += len; ++n; p = 1; while (len > 0) { @@ -119,20 +117,15 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos, } } - if (pos < xdrbuf->len && xdrbuf->tail[0].iov_len) { + if (xdrbuf->tail[0].iov_len) { if (n == nsegs) return 0; seg[n].mr_page = NULL; seg[n].mr_offset = xdrbuf->tail[0].iov_base; seg[n].mr_len = xdrbuf->tail[0].iov_len; - pos += xdrbuf->tail[0].iov_len; ++n; } - if (pos < xdrbuf->len) - dprintk("RPC: %s: marshaled only %d of %d\n", - __func__, pos, xdrbuf->len); - return n; } diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 1afeb3eb8e4..6f2112dd9f7 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -89,7 +89,7 @@ static struct ctl_table_header *sunrpc_table_header; static ctl_table xr_tunables_table[] = { { - .ctl_name = CTL_SLOTTABLE_RDMA, + .ctl_name = CTL_UNNUMBERED, .procname = "rdma_slot_table_entries", .data = &xprt_rdma_slot_table_entries, .maxlen = sizeof(unsigned int), @@ -100,7 +100,7 @@ static ctl_table xr_tunables_table[] = { .extra2 = &max_slot_table_size }, { - .ctl_name = CTL_RDMA_MAXINLINEREAD, + .ctl_name = CTL_UNNUMBERED, .procname = "rdma_max_inline_read", .data = &xprt_rdma_max_inline_read, .maxlen = sizeof(unsigned int), @@ -109,7 +109,7 @@ static ctl_table xr_tunables_table[] = { .strategy = &sysctl_intvec, }, { - .ctl_name = CTL_RDMA_MAXINLINEWRITE, + .ctl_name = CTL_UNNUMBERED, .procname = "rdma_max_inline_write", .data = &xprt_rdma_max_inline_write, .maxlen = sizeof(unsigned int), @@ -118,7 +118,7 @@ static ctl_table xr_tunables_table[] = { .strategy = &sysctl_intvec, }, { - .ctl_name = CTL_RDMA_WRITEPADDING, + .ctl_name = CTL_UNNUMBERED, .procname = "rdma_inline_write_padding", .data = &xprt_rdma_inline_write_padding, .maxlen = sizeof(unsigned int), @@ -129,7 +129,7 @@ static ctl_table xr_tunables_table[] = { .extra2 = &max_padding, }, { - .ctl_name = CTL_RDMA_MEMREG, + .ctl_name = CTL_UNNUMBERED, .procname = "rdma_memreg_strategy", .data = &xprt_rdma_memreg_strategy, .maxlen = sizeof(unsigned int), diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 02298f529da..2f630a512ab 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1828,7 +1828,7 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, * @args: rpc transport creation arguments * */ -struct rpc_xprt *xs_setup_udp(struct xprt_create *args) +static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) { struct sockaddr *addr = args->dstaddr; struct rpc_xprt *xprt; @@ -1894,7 +1894,7 @@ struct rpc_xprt *xs_setup_udp(struct xprt_create *args) * @args: rpc transport creation arguments * */ -struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) +static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) { struct sockaddr *addr = args->dstaddr; struct rpc_xprt *xprt; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 6b792265dc0..24ddfd2ca38 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -253,7 +253,7 @@ static int release(struct socket *sock) dbg("sock_delete: %x\n",tsock); if (!tsock) return 0; - down_interruptible(&tsock->sem); + down(&tsock->sem); if (!sock->sk) { up(&tsock->sem); return 0; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e835da8fc09..060bba4567d 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1637,8 +1637,15 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, mutex_lock(&u->readlock); skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) + if (!skb) { + unix_state_lock(sk); + /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ + if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && + (sk->sk_shutdown & RCV_SHUTDOWN)) + err = 0; + unix_state_unlock(sk); goto out_unlock; + } wake_up_interruptible_sync(&u->peer_wait); diff --git a/net/wireless/wext.c b/net/wireless/wext.c index 85e5f9dd0d8..47e80cc2077 100644 --- a/net/wireless/wext.c +++ b/net/wireless/wext.c @@ -1094,7 +1094,7 @@ int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, rtnl_lock(); ret = wireless_process_ioctl(net, ifr, cmd); rtnl_unlock(); - if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct ifreq))) + if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct iwreq))) return -EFAULT; return ret; } diff --git a/net/x25/x25_forward.c b/net/x25/x25_forward.c index 8738ec7ce69..34478035e05 100644 --- a/net/x25/x25_forward.c +++ b/net/x25/x25_forward.c @@ -118,13 +118,14 @@ int x25_forward_data(int lci, struct x25_neigh *from, struct sk_buff *skb) { goto out; if ( (skbn = pskb_copy(skb, GFP_ATOMIC)) == NULL){ - goto out; + goto output; } x25_transmit_link(skbn, nb); - x25_neigh_put(nb); rc = 1; +output: + x25_neigh_put(nb); out: return rc; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b702bd8a389..26b846e11bf 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1318,8 +1318,9 @@ restart: if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); + err = PTR_ERR(policy); if (IS_ERR(policy)) - return PTR_ERR(policy); + goto dropdst; } if (!policy) { @@ -1330,8 +1331,9 @@ restart: policy = flow_cache_lookup(fl, dst_orig->ops->family, dir, xfrm_policy_lookup); + err = PTR_ERR(policy); if (IS_ERR(policy)) - return PTR_ERR(policy); + goto dropdst; } if (!policy) @@ -1344,6 +1346,7 @@ restart: xfrm_nr += pols[0]->xfrm_nr; switch (policy->action) { + default: case XFRM_POLICY_BLOCK: /* Prohibit the flow */ err = -EPERM; @@ -1500,8 +1503,9 @@ restart: return 0; error: - dst_release(dst_orig); xfrm_pols_put(pols, npols); +dropdst: + dst_release(dst_orig); *dst_p = NULL; return err; } @@ -2158,7 +2162,7 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SPD-add res=%u", result); @@ -2175,7 +2179,7 @@ xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid) if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SPD-delete res=%u", result); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 224b44e31a0..f26aaaca1fa 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -552,7 +552,7 @@ int __xfrm_state_delete(struct xfrm_state *x) * The xfrm_state_alloc call gives a reference, and that * is what we are dropping here. */ - __xfrm_state_put(x); + xfrm_state_put(x); err = 0; } @@ -1749,6 +1749,7 @@ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid) } EXPORT_SYMBOL(km_policy_expired); +#ifdef CONFIG_XFRM_MIGRATE int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_migrate) { @@ -1768,6 +1769,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, return err; } EXPORT_SYMBOL(km_migrate); +#endif int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr) { @@ -2028,17 +2030,18 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid) { struct audit_buffer *audit_buf; + u32 spi; extern int audit_enabled; if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SAD-add res=%u",result); xfrm_audit_common_stateinfo(x, audit_buf); - audit_log_format(audit_buf, " spi=%lu(0x%lx)", - (unsigned long)x->id.spi, (unsigned long)x->id.spi); + spi = ntohl(x->id.spi); + audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_state_add); @@ -2047,17 +2050,18 @@ void xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid) { struct audit_buffer *audit_buf; + u32 spi; extern int audit_enabled; if (audit_enabled == 0) return; - audit_buf = xfrm_audit_start(sid, auid); + audit_buf = xfrm_audit_start(auid, sid); if (audit_buf == NULL) return; audit_log_format(audit_buf, " op=SAD-delete res=%u",result); xfrm_audit_common_stateinfo(x, audit_buf); - audit_log_format(audit_buf, " spi=%lu(0x%lx)", - (unsigned long)x->id.spi, (unsigned long)x->id.spi); + spi = ntohl(x->id.spi); + audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d41588d101d..c4f6419b176 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -31,11 +31,6 @@ #include <linux/in6.h> #endif -static inline int alg_len(struct xfrm_algo *alg) -{ - return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); -} - static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) { struct nlattr *rt = attrs[type]; @@ -45,7 +40,7 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) return 0; algp = nla_data(rt); - if (nla_len(rt) < alg_len(algp)) + if (nla_len(rt) < xfrm_alg_len(algp)) return -EINVAL; switch (type) { @@ -204,7 +199,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, return -ENOSYS; *props = algo->desc.sadb_alg_id; - p = kmemdup(ualg, alg_len(ualg), GFP_KERNEL); + p = kmemdup(ualg, xfrm_alg_len(ualg), GFP_KERNEL); if (!p) return -ENOMEM; @@ -507,7 +502,6 @@ static int copy_to_user_state_extra(struct xfrm_state *x, struct xfrm_usersa_info *p, struct sk_buff *skb) { - spin_lock_bh(&x->lock); copy_to_user_state(x, p); if (x->coaddr) @@ -515,12 +509,11 @@ static int copy_to_user_state_extra(struct xfrm_state *x, if (x->lastused) NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused); - spin_unlock_bh(&x->lock); if (x->aalg) - NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg); + NLA_PUT(skb, XFRMA_ALG_AUTH, xfrm_alg_len(x->aalg), x->aalg); if (x->ealg) - NLA_PUT(skb, XFRMA_ALG_CRYPT, alg_len(x->ealg), x->ealg); + NLA_PUT(skb, XFRMA_ALG_CRYPT, xfrm_alg_len(x->ealg), x->ealg); if (x->calg) NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); @@ -1980,9 +1973,9 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x) { size_t l = 0; if (x->aalg) - l += nla_total_size(alg_len(x->aalg)); + l += nla_total_size(xfrm_alg_len(x->aalg)); if (x->ealg) - l += nla_total_size(alg_len(x->ealg)); + l += nla_total_size(xfrm_alg_len(x->ealg)); if (x->calg) l += nla_total_size(sizeof(*x->calg)); if (x->encap) |