Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Wed, 21 Jul 2010 01:25:24 +0000 (18:25 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 21 Jul 2010 01:25:24 +0000 (18:25 -0700)
Conflicts:
drivers/vhost/net.c
net/bridge/br_device.c

Fix merge conflict in drivers/vhost/net.c with guidance from
Stephen Rothwell.

Revert the effects of net-2.6 commit 573201f36fd9c7c6d5218cdcd9948cee700b277d
since net-next-2.6 has fixes that make bridge netpoll work properly thus
we don't need it disabled.

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
drivers/net/r8169.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/vhost/net.c
include/net/sock.h
net/core/dev.c
net/ipv4/ipmr.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/sched/act_nat.c
net/xfrm/xfrm_policy.c

diff --combined drivers/net/r8169.c
index 239d7efdd4504921794a92b20a8bde8071e8c507,cdc6a5c2e70d81955efec9d3c633a593ef943b16..35540411990d5867f1ed9d44164fc8b7e47a8a11
@@@ -88,7 -88,7 +88,7 @@@ static const int multicast_filter_limi
  #define RTL_W32(reg, val32)   writel ((val32), ioaddr + (reg))
  #define RTL_R8(reg)           readb (ioaddr + (reg))
  #define RTL_R16(reg)          readw (ioaddr + (reg))
 -#define RTL_R32(reg)          ((unsigned long) readl (ioaddr + (reg)))
 +#define RTL_R32(reg)          readl (ioaddr + (reg))
  
  enum mac_version {
        RTL_GIGA_MAC_NONE   = 0x00,
@@@ -1316,7 -1316,7 +1316,7 @@@ static void rtl8169_get_mac_version(str
                { 0x7c800000, 0x28000000,       RTL_GIGA_MAC_VER_26 },
  
                /* 8168C family. */
-               { 0x7cf00000, 0x3ca00000,       RTL_GIGA_MAC_VER_24 },
+               { 0x7cf00000, 0x3cb00000,       RTL_GIGA_MAC_VER_24 },
                { 0x7cf00000, 0x3c900000,       RTL_GIGA_MAC_VER_23 },
                { 0x7cf00000, 0x3c800000,       RTL_GIGA_MAC_VER_18 },
                { 0x7c800000, 0x3c800000,       RTL_GIGA_MAC_VER_24 },
index f59b9f7226a836ad0af19d98c1c1fd503a942204,f20d3eeeea7fe0ee4001bf3597255bab1ad9856e..585e8166f22a635f628a5524d040d0f1807b3805
@@@ -69,11 -69,6 +69,11 @@@ int rt2x00lib_enable_radio(struct rt2x0
         */
        rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
  
 +      /*
 +       * Start watchdog monitoring.
 +       */
 +      rt2x00link_start_watchdog(rt2x00dev);
 +
        /*
         * Start the TX queues.
         */
@@@ -93,11 -88,6 +93,11 @@@ void rt2x00lib_disable_radio(struct rt2
        ieee80211_stop_queues(rt2x00dev->hw);
        rt2x00queue_stop_queues(rt2x00dev);
  
 +      /*
 +       * Stop watchdog monitoring.
 +       */
 +      rt2x00link_stop_watchdog(rt2x00dev);
 +
        /*
         * Disable RX.
         */
@@@ -178,32 -168,10 +178,32 @@@ static void rt2x00lib_intf_scheduled(st
  /*
   * Interrupt context handlers.
   */
 -static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
 -                                    struct ieee80211_vif *vif)
 +static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
 +                                   struct ieee80211_vif *vif)
  {
 -      struct rt2x00_intf *intf = vif_to_intf(vif);
 +      struct rt2x00_dev *rt2x00dev = data;
 +      struct sk_buff *skb;
 +
 +      /*
 +       * Only AP mode interfaces do broad- and multicast buffering
 +       */
 +      if (vif->type != NL80211_IFTYPE_AP)
 +              return;
 +
 +      /*
 +       * Send out buffered broad- and multicast frames
 +       */
 +      skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
 +      while (skb) {
 +              rt2x00mac_tx(rt2x00dev->hw, skb);
 +              skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
 +      }
 +}
 +
 +static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
 +                                      struct ieee80211_vif *vif)
 +{
 +      struct rt2x00_dev *rt2x00dev = data;
  
        if (vif->type != NL80211_IFTYPE_AP &&
            vif->type != NL80211_IFTYPE_ADHOC &&
            vif->type != NL80211_IFTYPE_WDS)
                return;
  
 -      spin_lock(&intf->lock);
 -      intf->delayed_flags |= DELAYED_UPDATE_BEACON;
 -      spin_unlock(&intf->lock);
 +      rt2x00queue_update_beacon(rt2x00dev, vif, true);
  }
  
  void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
        if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                return;
  
 -      ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
 -                                                 rt2x00lib_beacondone_iter,
 -                                                 rt2x00dev);
 +      /* send buffered bc/mc frames out for every bssid */
 +      ieee80211_iterate_active_interfaces(rt2x00dev->hw,
 +                                          rt2x00lib_bc_buffer_iter,
 +                                          rt2x00dev);
 +      /*
 +       * Devices with pre tbtt interrupt don't need to update the beacon
 +       * here as they will fetch the next beacon directly prior to
 +       * transmission.
 +       */
 +      if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags))
 +              return;
  
 -      ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
 +      /* fetch next beacon */
 +      ieee80211_iterate_active_interfaces(rt2x00dev->hw,
 +                                          rt2x00lib_beaconupdate_iter,
 +                                          rt2x00dev);
  }
  EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
  
 +void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
 +{
 +      if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
 +              return;
 +
 +      /* fetch next beacon */
 +      ieee80211_iterate_active_interfaces(rt2x00dev->hw,
 +                                          rt2x00lib_beaconupdate_iter,
 +                                          rt2x00dev);
 +}
 +EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt);
 +
  void rt2x00lib_txdone(struct queue_entry *entry,
                      struct txdone_entry_desc *txdesc)
  {
         */
        rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
  
 +      /*
 +       * Remove the extra tx headroom from the skb.
 +       */
 +      skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom);
 +
 +      /*
 +       * Signal that the TX descriptor is no longer in the skb.
 +       */
 +      skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
 +
        /*
         * Remove L2 padding which was added during
         */
        /*
         * If the IV/EIV data was stripped from the frame before it was
         * passed to the hardware, we should now reinsert it again because
 -       * mac80211 will expect the the same data to be present it the
 +       * mac80211 will expect the same data to be present it the
         * frame as it was passed to us.
         */
        if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
         */
        success =
            test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
 -          test_bit(TXDONE_UNKNOWN, &txdesc->flags) ||
 -          test_bit(TXDONE_FALLBACK, &txdesc->flags);
 +          test_bit(TXDONE_UNKNOWN, &txdesc->flags);
  
        /*
         * Update TX statistics.
        /*
         * Frame was send with retries, hardware tried
         * different rates to send out the frame, at each
 -       * retry it lowered the rate 1 step.
 +       * retry it lowered the rate 1 step except when the
 +       * lowest rate was used.
         */
        for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
                tx_info->status.rates[i].idx = rate_idx - i;
                tx_info->status.rates[i].flags = rate_flags;
 +
 +              if (rate_idx - i == 0) {
 +                      /*
 +                       * The lowest rate (index 0) was used until the
 +                       * number of max retries was reached.
 +                       */
 +                      tx_info->status.rates[i].count = retry_rates - i;
 +                      i++;
 +                      break;
 +              }
                tx_info->status.rates[i].count = 1;
        }
        if (i < (IEEE80211_TX_MAX_RATES - 1))
                        rt2x00dev->low_level_stats.dot11ACKFailureCount++;
        }
  
 +      /*
 +       * Every single frame has it's own tx status, hence report
 +       * every frame as ampdu of size 1.
 +       *
 +       * TODO: if we can find out how many frames were aggregated
 +       * by the hw we could provide the real ampdu_len to mac80211
 +       * which would allow the rc algorithm to better decide on
 +       * which rates are suitable.
 +       */
 +      if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 +              tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
 +              tx_info->status.ampdu_len = 1;
 +              tx_info->status.ampdu_ack_len = success ? 1 : 0;
 +      }
 +
        if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                if (success)
                        rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
         * send the status report back.
         */
        if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
 -              ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
 +              /*
 +               * Only PCI and SOC devices process the tx status in process
 +               * context. Hence use ieee80211_tx_status for PCI and SOC
 +               * devices and stick to ieee80211_tx_status_irqsafe for USB.
 +               */
 +              if (rt2x00_is_usb(rt2x00dev))
 +                      ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
 +              else
 +                      ieee80211_tx_status(rt2x00dev->hw, entry->skb);
        else
 -              dev_kfree_skb_irq(entry->skb);
 +              dev_kfree_skb_any(entry->skb);
  
        /*
         * Make this entry available for reuse.
@@@ -540,16 -444,7 +540,16 @@@ void rt2x00lib_rxdone(struct rt2x00_de
         */
        rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
        memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
 -      ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
 +
 +      /*
 +       * Currently only PCI and SOC devices handle rx interrupts in process
 +       * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni
 +       * for PCI and SOC devices.
 +       */
 +      if (rt2x00_is_usb(rt2x00dev))
 +              ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
 +      else
 +              ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
  
        /*
         * Replace the skb with the freshly allocated one.
@@@ -958,6 -853,11 +958,11 @@@ int rt2x00lib_probe_dev(struct rt2x00_d
                    BIT(NL80211_IFTYPE_MESH_POINT) |
                    BIT(NL80211_IFTYPE_WDS);
  
+       /*
+        * Initialize configuration work.
+        */
+       INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
        /*
         * Let the driver probe the device to detect the capabilities.
         */
                goto exit;
        }
  
-       /*
-        * Initialize configuration work.
-        */
-       INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
        /*
         * Allocate queue array.
         */
diff --combined drivers/vhost/net.c
index 107af9e61dc1f237e2fb84fe8074f3a55917e033,2f6185c845e03618ca679513aecd55bfb96c76d5..7a104e2de3fa77d189bf9ae010cda3f0ee0dd706
@@@ -177,8 -177,8 +177,8 @@@ static void handle_tx(struct vhost_net 
                        break;
                }
                if (err != len)
-                       pr_err("Truncated TX packet: "
-                              " len %d != %zd\n", err, len);
+                       pr_debug("Truncated TX packet: "
+                                " len %d != %zd\n", err, len);
                vhost_add_used_and_signal(&net->dev, vq, head, 0);
                total_len += len;
                if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
@@@ -275,8 -275,8 +275,8 @@@ static void handle_rx(struct vhost_net 
                }
                /* TODO: Should check and handle checksum. */
                if (err > len) {
-                       pr_err("Discarded truncated rx packet: "
-                              " len %d > %zd\n", err, len);
+                       pr_debug("Discarded truncated rx packet: "
+                                " len %d > %zd\n", err, len);
                        vhost_discard_vq_desc(vq);
                        continue;
                }
@@@ -527,17 -527,23 +527,23 @@@ static long vhost_net_set_backend(struc
  
        /* start polling new socket */
        oldsock = vq->private_data;
-       if (sock != oldsock){
 -      if (sock == oldsock)
 -              goto done;
++      if (sock != oldsock) {
 +                vhost_net_disable_vq(n, vq);
 +                rcu_assign_pointer(vq->private_data, sock);
 +                vhost_net_enable_vq(n, vq);
 +      }
  
 -      vhost_net_disable_vq(n, vq);
 -      rcu_assign_pointer(vq->private_data, sock);
 -      vhost_net_enable_vq(n, vq);
+ done:
+       mutex_unlock(&vq->mutex);
        if (oldsock) {
                vhost_net_flush_vq(n, index);
                fput(oldsock->file);
        }
  
+       mutex_unlock(&n->dev.mutex);
+       return 0;
  err_vq:
        mutex_unlock(&vq->mutex);
  err:
@@@ -633,7 -639,7 +639,7 @@@ static long vhost_net_compat_ioctl(stru
  }
  #endif
  
 -const static struct file_operations vhost_net_fops = {
 +static const struct file_operations vhost_net_fops = {
        .owner          = THIS_MODULE,
        .release        = vhost_net_release,
        .unlocked_ioctl = vhost_net_ioctl,
diff --combined include/net/sock.h
index 3100e71f0c3d637183e436dfdc3bd8b6889abff0,0a691ea7654aefb403e25039f08641691d3de74c..a441c9cdd62540cd7100189c5fa7aea2f6b0b22b
@@@ -295,8 -295,7 +295,8 @@@ struct sock 
        unsigned short          sk_ack_backlog;
        unsigned short          sk_max_ack_backlog;
        __u32                   sk_priority;
 -      struct ucred            sk_peercred;
 +      struct pid              *sk_peer_pid;
 +      const struct cred       *sk_peer_cred;
        long                    sk_rcvtimeo;
        long                    sk_sndtimeo;
        struct sk_filter        *sk_filter;
@@@ -772,7 -771,6 +772,7 @@@ struct proto 
        int                     *sysctl_wmem;
        int                     *sysctl_rmem;
        int                     max_header;
 +      bool                    no_autobind;
  
        struct kmem_cache       *slab;
        unsigned int            obj_size;
@@@ -1226,12 -1224,7 +1226,7 @@@ static inline void sk_tx_queue_clear(st
  
  static inline int sk_tx_queue_get(const struct sock *sk)
  {
-       return sk->sk_tx_queue_mapping;
- }
- static inline bool sk_tx_queue_recorded(const struct sock *sk)
- {
-       return (sk && sk->sk_tx_queue_mapping >= 0);
+       return sk ? sk->sk_tx_queue_mapping : -1;
  }
  
  static inline void sk_set_socket(struct sock *sk, struct socket *sock)
@@@ -1713,13 -1706,19 +1708,13 @@@ static inline void sk_eat_skb(struct so
  static inline
  struct net *sock_net(const struct sock *sk)
  {
 -#ifdef CONFIG_NET_NS
 -      return sk->sk_net;
 -#else
 -      return &init_net;
 -#endif
 +      return read_pnet(&sk->sk_net);
  }
  
  static inline
  void sock_net_set(struct sock *sk, struct net *net)
  {
 -#ifdef CONFIG_NET_NS
 -      sk->sk_net = net;
 -#endif
 +      write_pnet(&sk->sk_net, net);
  }
  
  /*
diff --combined net/core/dev.c
index 9de75cdade563b6bc5652e108633baaf5500eb63,0ea10f849be862fff3219bc69ed4c5db0cbd9253..6e1b4370781cc433570a467822c6d7da66863aa2
@@@ -803,31 -803,35 +803,31 @@@ struct net_device *dev_getfirstbyhwtype
  EXPORT_SYMBOL(dev_getfirstbyhwtype);
  
  /**
 - *    dev_get_by_flags - find any device with given flags
 + *    dev_get_by_flags_rcu - find any device with given flags
   *    @net: the applicable net namespace
   *    @if_flags: IFF_* values
   *    @mask: bitmask of bits in if_flags to check
   *
   *    Search for any interface with the given flags. Returns NULL if a device
 - *    is not found or a pointer to the device. The device returned has
 - *    had a reference added and the pointer is safe until the user calls
 - *    dev_put to indicate they have finished with it.
 + *    is not found or a pointer to the device. Must be called inside
 + *    rcu_read_lock(), and result refcount is unchanged.
   */
  
 -struct net_device *dev_get_by_flags(struct net *net, unsigned short if_flags,
 +struct net_device *dev_get_by_flags_rcu(struct net *net, unsigned short if_flags,
                                    unsigned short mask)
  {
        struct net_device *dev, *ret;
  
        ret = NULL;
 -      rcu_read_lock();
        for_each_netdev_rcu(net, dev) {
                if (((dev->flags ^ if_flags) & mask) == 0) {
 -                      dev_hold(dev);
                        ret = dev;
                        break;
                }
        }
 -      rcu_read_unlock();
        return ret;
  }
 -EXPORT_SYMBOL(dev_get_by_flags);
 +EXPORT_SYMBOL(dev_get_by_flags_rcu);
  
  /**
   *    dev_valid_name - check if name is okay for network device
@@@ -1537,8 -1541,7 +1537,8 @@@ static void dev_queue_xmit_nit(struct s
                                if (net_ratelimit())
                                        printk(KERN_CRIT "protocol %04x is "
                                               "buggy, dev %s\n",
 -                                             skb2->protocol, dev->name);
 +                                             ntohs(skb2->protocol),
 +                                             dev->name);
                                skb_reset_network_header(skb2);
                        }
  
@@@ -1592,9 -1595,7 +1592,9 @@@ EXPORT_SYMBOL(__netif_schedule)
  
  void dev_kfree_skb_irq(struct sk_buff *skb)
  {
 -      if (atomic_dec_and_test(&skb->users)) {
 +      if (!skb->destructor)
 +              dev_kfree_skb(skb);
 +      else if (atomic_dec_and_test(&skb->users)) {
                struct softnet_data *sd;
                unsigned long flags;
  
@@@ -1910,26 -1911,18 +1910,34 @@@ static int dev_gso_segment(struct sk_bu
   */
  static inline void skb_orphan_try(struct sk_buff *skb)
  {
-       if (!skb_tx(skb)->flags)
+       struct sock *sk = skb->sk;
+       if (sk && !skb_tx(skb)->flags) {
+               /* skb_tx_hash() wont be able to get sk.
+                * We copy sk_hash into skb->rxhash
+                */
+               if (!skb->rxhash)
+                       skb->rxhash = sk->sk_hash;
                skb_orphan(skb);
+       }
  }
  
 +/*
 + * Returns true if either:
 + *    1. skb has frag_list and the device doesn't support FRAGLIST, or
 + *    2. skb is fragmented and the device does not support SG, or if
 + *       at least one of fragments is in highmem and device does not
 + *       support DMA from it.
 + */
 +static inline int skb_needs_linearize(struct sk_buff *skb,
 +                                    struct net_device *dev)
 +{
 +      return skb_is_nonlinear(skb) &&
 +             ((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
 +              (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
 +                                            illegal_highdma(dev, skb))));
 +}
 +
  int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        struct netdev_queue *txq)
  {
                                goto out_kfree_skb;
                        if (skb->next)
                                goto gso;
 +              } else {
 +                      if (skb_needs_linearize(skb, dev) &&
 +                          __skb_linearize(skb))
 +                              goto out_kfree_skb;
 +
 +                      /* If packet is not checksummed and device does not
 +                       * support checksumming for this protocol, complete
 +                       * checksumming here.
 +                       */
 +                      if (skb->ip_summed == CHECKSUM_PARTIAL) {
 +                              skb_set_transport_header(skb, skb->csum_start -
 +                                            skb_headroom(skb));
 +                              if (!dev_can_checksum(dev, skb) &&
 +                                   skb_checksum_help(skb))
 +                                      goto out_kfree_skb;
 +                      }
                }
  
                rc = ops->ndo_start_xmit(skb, dev);
@@@ -2029,8 -2006,7 +2037,7 @@@ u16 skb_tx_hash(const struct net_devic
        if (skb->sk && skb->sk->sk_hash)
                hash = skb->sk->sk_hash;
        else
-               hash = (__force u16) skb->protocol;
+               hash = (__force u16) skb->protocol ^ skb->rxhash;
        hash = jhash_1word(hash, hashrnd);
  
        return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
@@@ -2053,12 -2029,11 +2060,11 @@@ static inline u16 dev_cap_txqueue(struc
  static struct netdev_queue *dev_pick_tx(struct net_device *dev,
                                        struct sk_buff *skb)
  {
-       u16 queue_index;
+       int queue_index;
        struct sock *sk = skb->sk;
  
-       if (sk_tx_queue_recorded(sk)) {
-               queue_index = sk_tx_queue_get(sk);
-       } else {
+       queue_index = sk_tx_queue_get(sk);
+       if (queue_index < 0) {
                const struct net_device_ops *ops = dev->netdev_ops;
  
                if (ops->ndo_select_queue) {
@@@ -2087,24 -2062,14 +2093,24 @@@ static inline int __dev_xmit_skb(struc
                                 struct netdev_queue *txq)
  {
        spinlock_t *root_lock = qdisc_lock(q);
 +      bool contended = qdisc_is_running(q);
        int rc;
  
 +      /*
 +       * Heuristic to force contended enqueues to serialize on a
 +       * separate lock before trying to get qdisc main lock.
 +       * This permits __QDISC_STATE_RUNNING owner to get the lock more often
 +       * and dequeue packets faster.
 +       */
 +      if (unlikely(contended))
 +              spin_lock(&q->busylock);
 +
        spin_lock(root_lock);
        if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
                kfree_skb(skb);
                rc = NET_XMIT_DROP;
        } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
 -                 !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) {
 +                 qdisc_run_begin(q)) {
                /*
                 * This is a work-conserving queue; there are no old skbs
                 * waiting to be sent out; and the qdisc is not running -
                if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE))
                        skb_dst_force(skb);
                __qdisc_update_bstats(q, skb->len);
 -              if (sch_direct_xmit(skb, q, dev, txq, root_lock))
 +              if (sch_direct_xmit(skb, q, dev, txq, root_lock)) {
 +                      if (unlikely(contended)) {
 +                              spin_unlock(&q->busylock);
 +                              contended = false;
 +                      }
                        __qdisc_run(q);
 -              else
 -                      clear_bit(__QDISC_STATE_RUNNING, &q->state);
 +              else
 +                      qdisc_run_end(q);
  
                rc = NET_XMIT_SUCCESS;
        } else {
                skb_dst_force(skb);
                rc = qdisc_enqueue_root(skb, q);
 -              qdisc_run(q);
 +              if (qdisc_run_begin(q)) {
 +                      if (unlikely(contended)) {
 +                              spin_unlock(&q->busylock);
 +                              contended = false;
 +                      }
 +                      __qdisc_run(q);
 +              }
        }
        spin_unlock(root_lock);
 -
 +      if (unlikely(contended))
 +              spin_unlock(&q->busylock);
        return rc;
  }
  
 -/*
 - * Returns true if either:
 - *    1. skb has frag_list and the device doesn't support FRAGLIST, or
 - *    2. skb is fragmented and the device does not support SG, or if
 - *       at least one of fragments is in highmem and device does not
 - *       support DMA from it.
 - */
 -static inline int skb_needs_linearize(struct sk_buff *skb,
 -                                    struct net_device *dev)
 -{
 -      return (skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
 -             (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
 -                                            illegal_highdma(dev, skb)));
 -}
 -
  /**
   *    dev_queue_xmit - transmit a buffer
   *    @skb: buffer to transmit
@@@ -2172,6 -2141,25 +2178,6 @@@ int dev_queue_xmit(struct sk_buff *skb
        struct Qdisc *q;
        int rc = -ENOMEM;
  
 -      /* GSO will handle the following emulations directly. */
 -      if (netif_needs_gso(dev, skb))
 -              goto gso;
 -
 -      /* Convert a paged skb to linear, if required */
 -      if (skb_needs_linearize(skb, dev) && __skb_linearize(skb))
 -              goto out_kfree_skb;
 -
 -      /* If packet is not checksummed and device does not support
 -       * checksumming for this protocol, complete checksumming here.
 -       */
 -      if (skb->ip_summed == CHECKSUM_PARTIAL) {
 -              skb_set_transport_header(skb, skb->csum_start -
 -                                            skb_headroom(skb));
 -              if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb))
 -                      goto out_kfree_skb;
 -      }
 -
 -gso:
        /* Disable soft irqs for various locks below. Also
         * stops preemption for RCU.
         */
        rc = -ENETDOWN;
        rcu_read_unlock_bh();
  
 -out_kfree_skb:
        kfree_skb(skb);
        return rc;
  out:
@@@ -2614,14 -2603,70 +2620,14 @@@ static inline int deliver_skb(struct sk
        return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
  }
  
 -#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
 -
 -#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
 +#if (defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)) && \
 +    (defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE))
  /* This hook is defined here for ATM LANE */
  int (*br_fdb_test_addr_hook)(struct net_device *dev,
                             unsigned char *addr) __read_mostly;
  EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
  #endif
  
 -/*
 - * If bridge module is loaded call bridging hook.
 - *  returns NULL if packet was consumed.
 - */
 -struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
 -                                      struct sk_buff *skb) __read_mostly;
 -EXPORT_SYMBOL_GPL(br_handle_frame_hook);
 -
 -static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
 -                                          struct packet_type **pt_prev, int *ret,
 -                                          struct net_device *orig_dev)
 -{
 -      struct net_bridge_port *port;
 -
 -      if (skb->pkt_type == PACKET_LOOPBACK ||
 -          (port = rcu_dereference(skb->dev->br_port)) == NULL)
 -              return skb;
 -
 -      if (*pt_prev) {
 -              *ret = deliver_skb(skb, *pt_prev, orig_dev);
 -              *pt_prev = NULL;
 -      }
 -
 -      return br_handle_frame_hook(port, skb);
 -}
 -#else
 -#define handle_bridge(skb, pt_prev, ret, orig_dev)    (skb)
 -#endif
 -
 -#if defined(CONFIG_MACVLAN) || defined(CONFIG_MACVLAN_MODULE)
 -struct sk_buff *(*macvlan_handle_frame_hook)(struct macvlan_port *p,
 -                                           struct sk_buff *skb) __read_mostly;
 -EXPORT_SYMBOL_GPL(macvlan_handle_frame_hook);
 -
 -static inline struct sk_buff *handle_macvlan(struct sk_buff *skb,
 -                                           struct packet_type **pt_prev,
 -                                           int *ret,
 -                                           struct net_device *orig_dev)
 -{
 -      struct macvlan_port *port;
 -
 -      port = rcu_dereference(skb->dev->macvlan_port);
 -      if (!port)
 -              return skb;
 -
 -      if (*pt_prev) {
 -              *ret = deliver_skb(skb, *pt_prev, orig_dev);
 -              *pt_prev = NULL;
 -      }
 -      return macvlan_handle_frame_hook(port, skb);
 -}
 -#else
 -#define handle_macvlan(skb, pt_prev, ret, orig_dev)   (skb)
 -#endif
 -
  #ifdef CONFIG_NET_CLS_ACT
  /* TODO: Maybe we should just force sch_ingress to be compiled in
   * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions
@@@ -2672,6 -2717,9 +2678,6 @@@ static inline struct sk_buff *handle_in
        if (*pt_prev) {
                *ret = deliver_skb(skb, *pt_prev, orig_dev);
                *pt_prev = NULL;
 -      } else {
 -              /* Huh? Why does turning on AF_PACKET affect this? */
 -              skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
        }
  
        switch (ing_filter(skb)) {
@@@ -2714,51 -2762,6 +2720,51 @@@ void netif_nit_deliver(struct sk_buff *
        rcu_read_unlock();
  }
  
 +/**
 + *    netdev_rx_handler_register - register receive handler
 + *    @dev: device to register a handler for
 + *    @rx_handler: receive handler to register
 + *    @rx_handler_data: data pointer that is used by rx handler
 + *
 + *    Register a receive hander for a device. This handler will then be
 + *    called from __netif_receive_skb. A negative errno code is returned
 + *    on a failure.
 + *
 + *    The caller must hold the rtnl_mutex.
 + */
 +int netdev_rx_handler_register(struct net_device *dev,
 +                             rx_handler_func_t *rx_handler,
 +                             void *rx_handler_data)
 +{
 +      ASSERT_RTNL();
 +
 +      if (dev->rx_handler)
 +              return -EBUSY;
 +
 +      rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
 +      rcu_assign_pointer(dev->rx_handler, rx_handler);
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(netdev_rx_handler_register);
 +
 +/**
 + *    netdev_rx_handler_unregister - unregister receive handler
 + *    @dev: device to unregister a handler from
 + *
 + *    Unregister a receive hander from a device.
 + *
 + *    The caller must hold the rtnl_mutex.
 + */
 +void netdev_rx_handler_unregister(struct net_device *dev)
 +{
 +
 +      ASSERT_RTNL();
 +      rcu_assign_pointer(dev->rx_handler, NULL);
 +      rcu_assign_pointer(dev->rx_handler_data, NULL);
 +}
 +EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
 +
  static inline void skb_bond_set_mac_by_master(struct sk_buff *skb,
                                              struct net_device *master)
  {
@@@ -2780,8 -2783,7 +2786,8 @@@ int __skb_bond_should_drop(struct sk_bu
        if (master->priv_flags & IFF_MASTER_ARPMON)
                dev->last_rx = jiffies;
  
 -      if ((master->priv_flags & IFF_MASTER_ALB) && master->br_port) {
 +      if ((master->priv_flags & IFF_MASTER_ALB) &&
 +          (master->priv_flags & IFF_BRIDGE_PORT)) {
                /* Do address unmangle. The local destination address
                 * will be always the one master has. Provides the right
                 * functionality in a bridge.
@@@ -2812,7 -2814,6 +2818,7 @@@ EXPORT_SYMBOL(__skb_bond_should_drop)
  static int __netif_receive_skb(struct sk_buff *skb)
  {
        struct packet_type *ptype, *pt_prev;
 +      rx_handler_func_t *rx_handler;
        struct net_device *orig_dev;
        struct net_device *master;
        struct net_device *null_or_orig;
                        skb->dev = master;
        }
  
 -      __get_cpu_var(softnet_data).processed++;
 -
 +      __this_cpu_inc(softnet_data.processed);
        skb_reset_network_header(skb);
        skb_reset_transport_header(skb);
        skb->mac_len = skb->network_header - skb->mac_header;
  ncls:
  #endif
  
 -      skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
 -      if (!skb)
 -              goto out;
 -      skb = handle_macvlan(skb, &pt_prev, &ret, orig_dev);
 -      if (!skb)
 -              goto out;
 +      /* Handle special case of bridge or macvlan */
 +      rx_handler = rcu_dereference(skb->dev->rx_handler);
 +      if (rx_handler) {
 +              if (pt_prev) {
 +                      ret = deliver_skb(skb, pt_prev, orig_dev);
 +                      pt_prev = NULL;
 +              }
 +              skb = rx_handler(skb);
 +              if (!skb)
 +                      goto out;
 +      }
  
        /*
         * Make sure frames received on VLAN interfaces stacked on
@@@ -2957,9 -2954,6 +2963,9 @@@ int netif_receive_skb(struct sk_buff *s
        if (netdev_tstamp_prequeue)
                net_timestamp_check(skb);
  
 +      if (skb_defer_rx_timestamp(skb))
 +              return NET_RX_SUCCESS;
 +
  #ifdef CONFIG_RPS
        {
                struct rps_dev_flow voidflow, *rflow = &voidflow;
@@@ -3724,11 -3718,10 +3730,11 @@@ void dev_seq_stop(struct seq_file *seq
  
  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
  {
 -      const struct net_device_stats *stats = dev_get_stats(dev);
 +      struct rtnl_link_stats64 temp;
 +      const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
  
 -      seq_printf(seq, "%6s: %7lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
 -                 "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
 +      seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
 +                 "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
                   dev->name, stats->rx_bytes, stats->rx_packets,
                   stats->rx_errors,
                   stats->rx_dropped + stats->rx_missed_errors,
@@@ -5277,22 -5270,20 +5283,22 @@@ void netdev_run_todo(void
  /**
   *    dev_txq_stats_fold - fold tx_queues stats
   *    @dev: device to get statistics from
 - *    @stats: struct net_device_stats to hold results
 + *    @stats: struct rtnl_link_stats64 to hold results
   */
  void dev_txq_stats_fold(const struct net_device *dev,
 -                      struct net_device_stats *stats)
 +                      struct rtnl_link_stats64 *stats)
  {
 -      unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0;
 +      u64 tx_bytes = 0, tx_packets = 0, tx_dropped = 0;
        unsigned int i;
        struct netdev_queue *txq;
  
        for (i = 0; i < dev->num_tx_queues; i++) {
                txq = netdev_get_tx_queue(dev, i);
 +              spin_lock_bh(&txq->_xmit_lock);
                tx_bytes   += txq->tx_bytes;
                tx_packets += txq->tx_packets;
                tx_dropped += txq->tx_dropped;
 +              spin_unlock_bh(&txq->_xmit_lock);
        }
        if (tx_bytes || tx_packets || tx_dropped) {
                stats->tx_bytes   = tx_bytes;
  }
  EXPORT_SYMBOL(dev_txq_stats_fold);
  
 +/* Convert net_device_stats to rtnl_link_stats64.  They have the same
 + * fields in the same order, with only the type differing.
 + */
 +static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
 +                                  const struct net_device_stats *netdev_stats)
 +{
 +#if BITS_PER_LONG == 64
 +        BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats));
 +        memcpy(stats64, netdev_stats, sizeof(*stats64));
 +#else
 +      size_t i, n = sizeof(*stats64) / sizeof(u64);
 +      const unsigned long *src = (const unsigned long *)netdev_stats;
 +      u64 *dst = (u64 *)stats64;
 +
 +      BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) !=
 +                   sizeof(*stats64) / sizeof(u64));
 +      for (i = 0; i < n; i++)
 +              dst[i] = src[i];
 +#endif
 +}
 +
  /**
   *    dev_get_stats   - get network device statistics
   *    @dev: device to get statistics from
 + *    @storage: place to store stats
   *
 - *    Get network statistics from device. The device driver may provide
 - *    its own method by setting dev->netdev_ops->get_stats; otherwise
 - *    the internal statistics structure is used.
 + *    Get network statistics from device. Return @storage.
 + *    The device driver may provide its own method by setting
 + *    dev->netdev_ops->get_stats64 or dev->netdev_ops->get_stats;
 + *    otherwise the internal statistics structure is used.
   */
 -const struct net_device_stats *dev_get_stats(struct net_device *dev)
 +struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
 +                                      struct rtnl_link_stats64 *storage)
  {
        const struct net_device_ops *ops = dev->netdev_ops;
  
 -      if (ops->ndo_get_stats)
 -              return ops->ndo_get_stats(dev);
 -
 -      dev_txq_stats_fold(dev, &dev->stats);
 -      return &dev->stats;
 +      if (ops->ndo_get_stats64) {
 +              memset(storage, 0, sizeof(*storage));
 +              return ops->ndo_get_stats64(dev, storage);
 +      }
 +      if (ops->ndo_get_stats) {
 +              netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev));
 +              return storage;
 +      }
 +      netdev_stats_to_stats64(storage, &dev->stats);
 +      dev_txq_stats_fold(dev, storage);
 +      return storage;
  }
  EXPORT_SYMBOL(dev_get_stats);
  
@@@ -5853,68 -5814,6 +5859,68 @@@ char *netdev_drivername(const struct ne
        return buffer;
  }
  
 +static int __netdev_printk(const char *level, const struct net_device *dev,
 +                         struct va_format *vaf)
 +{
 +      int r;
 +
 +      if (dev && dev->dev.parent)
 +              r = dev_printk(level, dev->dev.parent, "%s: %pV",
 +                             netdev_name(dev), vaf);
 +      else if (dev)
 +              r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
 +      else
 +              r = printk("%s(NULL net_device): %pV", level, vaf);
 +
 +      return r;
 +}
 +
 +int netdev_printk(const char *level, const struct net_device *dev,
 +                const char *format, ...)
 +{
 +      struct va_format vaf;
 +      va_list args;
 +      int r;
 +
 +      va_start(args, format);
 +
 +      vaf.fmt = format;
 +      vaf.va = &args;
 +
 +      r = __netdev_printk(level, dev, &vaf);
 +      va_end(args);
 +
 +      return r;
 +}
 +EXPORT_SYMBOL(netdev_printk);
 +
 +#define define_netdev_printk_level(func, level)                       \
 +int func(const struct net_device *dev, const char *fmt, ...)  \
 +{                                                             \
 +      int r;                                                  \
 +      struct va_format vaf;                                   \
 +      va_list args;                                           \
 +                                                              \
 +      va_start(args, fmt);                                    \
 +                                                              \
 +      vaf.fmt = fmt;                                          \
 +      vaf.va = &args;                                         \
 +                                                              \
 +      r = __netdev_printk(level, dev, &vaf);                  \
 +      va_end(args);                                           \
 +                                                              \
 +      return r;                                               \
 +}                                                             \
 +EXPORT_SYMBOL(func);
 +
 +define_netdev_printk_level(netdev_emerg, KERN_EMERG);
 +define_netdev_printk_level(netdev_alert, KERN_ALERT);
 +define_netdev_printk_level(netdev_crit, KERN_CRIT);
 +define_netdev_printk_level(netdev_err, KERN_ERR);
 +define_netdev_printk_level(netdev_warn, KERN_WARNING);
 +define_netdev_printk_level(netdev_notice, KERN_NOTICE);
 +define_netdev_printk_level(netdev_info, KERN_INFO);
 +
  static void __net_exit netdev_exit(struct net *net)
  {
        kfree(net->dev_name_head);
diff --combined net/ipv4/ipmr.c
index 539592294f45ac557f0f996b3276f1afb3d9eba7,7f6273506eea46522a17ff85b9a451cb18fdc7d3..179fcab866fc5f550d580f3ca06b5abd24f0f58a
@@@ -442,8 -442,10 +442,10 @@@ static netdev_tx_t reg_vif_xmit(struct 
        int err;
  
        err = ipmr_fib_lookup(net, &fl, &mrt);
-       if (err < 0)
+       if (err < 0) {
+               kfree_skb(skb);
                return err;
+       }
  
        read_lock(&mrt_lock);
        dev->stats.tx_bytes += skb->len;
@@@ -1553,9 -1555,9 +1555,9 @@@ static void ipmr_queue_xmit(struct net 
                        goto out_free;
        }
  
 -      dev = rt->u.dst.dev;
 +      dev = rt->dst.dev;
  
 -      if (skb->len+encap > dst_mtu(&rt->u.dst) && (ntohs(iph->frag_off) & IP_DF)) {
 +      if (skb->len+encap > dst_mtu(&rt->dst) && (ntohs(iph->frag_off) & IP_DF)) {
                /* Do not fragment multicasts. Alas, IPv4 does not
                   allow to send ICMP, so that packets will disappear
                   to blackhole.
                goto out_free;
        }
  
 -      encap += LL_RESERVED_SPACE(dev) + rt->u.dst.header_len;
 +      encap += LL_RESERVED_SPACE(dev) + rt->dst.header_len;
  
        if (skb_cow(skb, encap)) {
                ip_rt_put(rt);
        vif->bytes_out += skb->len;
  
        skb_dst_drop(skb);
 -      skb_dst_set(skb, &rt->u.dst);
 +      skb_dst_set(skb, &rt->dst);
        ip_decrease_ttl(ip_hdr(skb));
  
        /* FIXME: forward and output firewalls used to be called here.
@@@ -1728,8 -1730,10 +1730,10 @@@ int ip_mr_input(struct sk_buff *skb
                goto dont_forward;
  
        err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt);
-       if (err < 0)
+       if (err < 0) {
+               kfree_skb(skb);
                return err;
+       }
  
        if (!local) {
                    if (IPCB(skb)->opt.router_alert) {
diff --combined net/ipv4/tcp.c
index 9fce8a8a13aabd35f420d073be735a7ab5f2c520,65afeaec15b7ebb85610650353e881aacb3e90aa..86b9f67abede2cbaa262865585d752fc9303013c
@@@ -315,6 -315,7 +315,6 @@@ struct tcp_splice_state 
   * is strict, actions are advisory and have some latency.
   */
  int tcp_memory_pressure __read_mostly;
 -
  EXPORT_SYMBOL(tcp_memory_pressure);
  
  void tcp_enter_memory_pressure(struct sock *sk)
                tcp_memory_pressure = 1;
        }
  }
 -
  EXPORT_SYMBOL(tcp_enter_memory_pressure);
  
  /* Convert seconds to retransmits based on initial and max timeout */
@@@ -458,7 -460,6 +458,7 @@@ unsigned int tcp_poll(struct file *file
        }
        return mask;
  }
 +EXPORT_SYMBOL(tcp_poll);
  
  int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
  {
  
        return put_user(answ, (int __user *)arg);
  }
 +EXPORT_SYMBOL(tcp_ioctl);
  
  static inline void tcp_mark_push(struct tcp_sock *tp, struct sk_buff *skb)
  {
 -      TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 +      TCP_SKB_CB(skb)->flags |= TCPHDR_PSH;
        tp->pushed_seq = tp->write_seq;
  }
  
@@@ -527,7 -527,7 +527,7 @@@ static inline void skb_entail(struct so
  
        skb->csum    = 0;
        tcb->seq     = tcb->end_seq = tp->write_seq;
 -      tcb->flags   = TCPCB_FLAG_ACK;
 +      tcb->flags   = TCPHDR_ACK;
        tcb->sacked  = 0;
        skb_header_release(skb);
        tcp_add_write_queue_tail(sk, skb);
@@@ -608,6 -608,7 +608,7 @@@ ssize_t tcp_splice_read(struct socket *
        ssize_t spliced;
        int ret;
  
+       sock_rps_record_flow(sk);
        /*
         * We can't seek on a socket input
         */
  
        return ret;
  }
 +EXPORT_SYMBOL(tcp_splice_read);
  
  struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
  {
@@@ -816,7 -816,7 +817,7 @@@ new_segment
                skb_shinfo(skb)->gso_segs = 0;
  
                if (!copied)
 -                      TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
 +                      TCP_SKB_CB(skb)->flags &= ~TCPHDR_PSH;
  
                copied += copy;
                poffset += copy;
@@@ -857,15 -857,15 +858,15 @@@ out_err
        return sk_stream_error(sk, flags, err);
  }
  
 -ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset,
 -                   size_t size, int flags)
 +int tcp_sendpage(struct sock *sk, struct page *page, int offset,
 +               size_t size, int flags)
  {
        ssize_t res;
 -      struct sock *sk = sock->sk;
  
        if (!(sk->sk_route_caps & NETIF_F_SG) ||
            !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
 -              return sock_no_sendpage(sock, page, offset, size, flags);
 +              return sock_no_sendpage(sk->sk_socket, page, offset, size,
 +                                      flags);
  
        lock_sock(sk);
        TCP_CHECK_TIMER(sk);
        release_sock(sk);
        return res;
  }
 +EXPORT_SYMBOL(tcp_sendpage);
  
  #define TCP_PAGE(sk)  (sk->sk_sndmsg_page)
  #define TCP_OFF(sk)   (sk->sk_sndmsg_off)
@@@ -899,9 -898,10 +900,9 @@@ static inline int select_size(struct so
        return tmp;
  }
  
 -int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 +int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                size_t size)
  {
 -      struct sock *sk = sock->sk;
        struct iovec *iov;
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
@@@ -1062,7 -1062,7 +1063,7 @@@ new_segment
                        }
  
                        if (!copied)
 -                              TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
 +                              TCP_SKB_CB(skb)->flags &= ~TCPHDR_PSH;
  
                        tp->write_seq += copy;
                        TCP_SKB_CB(skb)->end_seq += copy;
@@@ -1122,7 -1122,6 +1123,7 @@@ out_err
        release_sock(sk);
        return err;
  }
 +EXPORT_SYMBOL(tcp_sendmsg);
  
  /*
   *    Handle reading urgent data. BSD has very simple semantics for
@@@ -1382,7 -1381,6 +1383,7 @@@ int tcp_read_sock(struct sock *sk, read
                tcp_cleanup_rbuf(sk, copied);
        return copied;
  }
 +EXPORT_SYMBOL(tcp_read_sock);
  
  /*
   *    This routine copies from a sock struct into the user buffer.
@@@ -1777,7 -1775,6 +1778,7 @@@ recv_urg
        err = tcp_recv_urg(sk, msg, len, flags);
        goto out;
  }
 +EXPORT_SYMBOL(tcp_recvmsg);
  
  void tcp_set_state(struct sock *sk, int state)
  {
@@@ -1870,7 -1867,6 +1871,7 @@@ void tcp_shutdown(struct sock *sk, int 
                        tcp_send_fin(sk);
        }
  }
 +EXPORT_SYMBOL(tcp_shutdown);
  
  void tcp_close(struct sock *sk, long timeout)
  {
  
        sk_mem_reclaim(sk);
  
 +      /* If socket has been already reset (e.g. in tcp_reset()) - kill it. */
 +      if (sk->sk_state == TCP_CLOSE)
 +              goto adjudge_to_death;
 +
        /* As outlined in RFC 2525, section 2.17, we send a RST here because
         * data was lost. To witness the awful effects of the old behavior of
         * always doing a FIN, run an older 2.1.x kernel or 2.0.x, start a bulk
@@@ -2034,7 -2026,6 +2035,7 @@@ out
        local_bh_enable();
        sock_put(sk);
  }
 +EXPORT_SYMBOL(tcp_close);
  
  /* These states need RST on ABORT according to RFC793 */
  
@@@ -2108,7 -2099,6 +2109,7 @@@ int tcp_disconnect(struct sock *sk, in
        sk->sk_error_report(sk);
        return err;
  }
 +EXPORT_SYMBOL(tcp_disconnect);
  
  /*
   *    Socket option code for TCP.
@@@ -2407,7 -2397,6 +2408,7 @@@ int tcp_setsockopt(struct sock *sk, in
                                                     optval, optlen);
        return do_tcp_setsockopt(sk, level, optname, optval, optlen);
  }
 +EXPORT_SYMBOL(tcp_setsockopt);
  
  #ifdef CONFIG_COMPAT
  int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
                                                  optval, optlen);
        return do_tcp_setsockopt(sk, level, optname, optval, optlen);
  }
 -
  EXPORT_SYMBOL(compat_tcp_setsockopt);
  #endif
  
@@@ -2483,6 -2473,7 +2484,6 @@@ void tcp_get_info(struct sock *sk, stru
  
        info->tcpi_total_retrans = tp->total_retrans;
  }
 -
  EXPORT_SYMBOL_GPL(tcp_get_info);
  
  static int do_tcp_getsockopt(struct sock *sk, int level,
@@@ -2621,7 -2612,6 +2622,7 @@@ int tcp_getsockopt(struct sock *sk, in
                                                     optval, optlen);
        return do_tcp_getsockopt(sk, level, optname, optval, optlen);
  }
 +EXPORT_SYMBOL(tcp_getsockopt);
  
  #ifdef CONFIG_COMPAT
  int compat_tcp_getsockopt(struct sock *sk, int level, int optname,
                                                  optval, optlen);
        return do_tcp_getsockopt(sk, level, optname, optval, optlen);
  }
 -
  EXPORT_SYMBOL(compat_tcp_getsockopt);
  #endif
  
@@@ -2868,6 -2859,7 +2869,6 @@@ void tcp_free_md5sig_pool(void
        if (pool)
                __tcp_free_md5sig_pool(pool);
  }
 -
  EXPORT_SYMBOL(tcp_free_md5sig_pool);
  
  static struct tcp_md5sig_pool * __percpu *
@@@ -2943,6 -2935,7 +2944,6 @@@ retry
        }
        return pool;
  }
 -
  EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
  
  
@@@ -2966,7 -2959,7 +2967,7 @@@ struct tcp_md5sig_pool *tcp_get_md5sig_
        spin_unlock(&tcp_md5sig_pool_lock);
  
        if (p)
 -              return *per_cpu_ptr(p, smp_processor_id());
 +              return *this_cpu_ptr(p);
  
        local_bh_enable();
        return NULL;
@@@ -2994,6 -2987,7 +2995,6 @@@ int tcp_md5_hash_header(struct tcp_md5s
        th->check = old_checksum;
        return err;
  }
 -
  EXPORT_SYMBOL(tcp_md5_hash_header);
  
  int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
        const unsigned head_data_len = skb_headlen(skb) > header_len ?
                                       skb_headlen(skb) - header_len : 0;
        const struct skb_shared_info *shi = skb_shinfo(skb);
 +      struct sk_buff *frag_iter;
  
        sg_init_table(&sg, 1);
  
                        return 1;
        }
  
 +      skb_walk_frags(skb, frag_iter)
 +              if (tcp_md5_hash_skb_data(hp, frag_iter, 0))
 +                      return 1;
 +
        return 0;
  }
 -
  EXPORT_SYMBOL(tcp_md5_hash_skb_data);
  
  int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, struct tcp_md5sig_key *key)
        sg_init_one(&sg, key->key, key->keylen);
        return crypto_hash_update(&hp->md5_desc, &sg, key->keylen);
  }
 -
  EXPORT_SYMBOL(tcp_md5_hash_key);
  
  #endif
@@@ -3307,3 -3298,16 +3308,3 @@@ void __init tcp_init(void
        tcp_secret_retiring = &tcp_secret_two;
        tcp_secret_secondary = &tcp_secret_two;
  }
 -
 -EXPORT_SYMBOL(tcp_close);
 -EXPORT_SYMBOL(tcp_disconnect);
 -EXPORT_SYMBOL(tcp_getsockopt);
 -EXPORT_SYMBOL(tcp_ioctl);
 -EXPORT_SYMBOL(tcp_poll);
 -EXPORT_SYMBOL(tcp_read_sock);
 -EXPORT_SYMBOL(tcp_recvmsg);
 -EXPORT_SYMBOL(tcp_sendmsg);
 -EXPORT_SYMBOL(tcp_splice_read);
 -EXPORT_SYMBOL(tcp_sendpage);
 -EXPORT_SYMBOL(tcp_setsockopt);
 -EXPORT_SYMBOL(tcp_shutdown);
diff --combined net/ipv4/tcp_output.c
index b3f6f099b1a3151e6cd860d710acf7d55b8549d9,7ed9dc1042d1930a7eb2107def30642cb367fa92..de3bd84585881f99f8a23eb28fa9f380516d087c
@@@ -247,7 -247,6 +247,7 @@@ void tcp_select_initial_window(int __sp
        /* Set the clamp no higher than max representable value */
        (*window_clamp) = min(65535U << (*rcv_wscale), *window_clamp);
  }
 +EXPORT_SYMBOL(tcp_select_initial_window);
  
  /* Chose a new window to advertise, update state in tcp_sock for the
   * socket, and return result with RFC1323 scaling applied.  The return
@@@ -295,9 -294,9 +295,9 @@@ static u16 tcp_select_window(struct soc
  /* Packet ECN state for a SYN-ACK */
  static inline void TCP_ECN_send_synack(struct tcp_sock *tp, struct sk_buff *skb)
  {
 -      TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR;
 +      TCP_SKB_CB(skb)->flags &= ~TCPHDR_CWR;
        if (!(tp->ecn_flags & TCP_ECN_OK))
 -              TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE;
 +              TCP_SKB_CB(skb)->flags &= ~TCPHDR_ECE;
  }
  
  /* Packet ECN state for a SYN.  */
@@@ -307,7 -306,7 +307,7 @@@ static inline void TCP_ECN_send_syn(str
  
        tp->ecn_flags = 0;
        if (sysctl_tcp_ecn == 1) {
 -              TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE | TCPCB_FLAG_CWR;
 +              TCP_SKB_CB(skb)->flags |= TCPHDR_ECE | TCPHDR_CWR;
                tp->ecn_flags = TCP_ECN_OK;
        }
  }
@@@ -362,7 -361,7 +362,7 @@@ static void tcp_init_nondata_skb(struc
        skb_shinfo(skb)->gso_type = 0;
  
        TCP_SKB_CB(skb)->seq = seq;
 -      if (flags & (TCPCB_FLAG_SYN | TCPCB_FLAG_FIN))
 +      if (flags & (TCPHDR_SYN | TCPHDR_FIN))
                seq++;
        TCP_SKB_CB(skb)->end_seq = seq;
  }
@@@ -821,7 -820,7 +821,7 @@@ static int tcp_transmit_skb(struct soc
        tcb = TCP_SKB_CB(skb);
        memset(&opts, 0, sizeof(opts));
  
 -      if (unlikely(tcb->flags & TCPCB_FLAG_SYN))
 +      if (unlikely(tcb->flags & TCPHDR_SYN))
                tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5);
        else
                tcp_options_size = tcp_established_options(sk, skb, &opts,
        *(((__be16 *)th) + 6)   = htons(((tcp_header_size >> 2) << 12) |
                                        tcb->flags);
  
 -      if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
 +      if (unlikely(tcb->flags & TCPHDR_SYN)) {
                /* RFC1323: The window in SYN & SYN/ACK segments
                 * is never scaled.
                 */
        }
  
        tcp_options_write((__be32 *)(th + 1), tp, &opts);
 -      if (likely((tcb->flags & TCPCB_FLAG_SYN) == 0))
 +      if (likely((tcb->flags & TCPHDR_SYN) == 0))
                TCP_ECN_send(sk, skb, tcp_header_size);
  
  #ifdef CONFIG_TCP_MD5SIG
  
        icsk->icsk_af_ops->send_check(sk, skb);
  
 -      if (likely(tcb->flags & TCPCB_FLAG_ACK))
 +      if (likely(tcb->flags & TCPHDR_ACK))
                tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
  
        if (skb->len != tcp_header_size)
@@@ -1024,7 -1023,7 +1024,7 @@@ int tcp_fragment(struct sock *sk, struc
  
        /* PSH and FIN should only be set in the second packet. */
        flags = TCP_SKB_CB(skb)->flags;
 -      TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN | TCPCB_FLAG_PSH);
 +      TCP_SKB_CB(skb)->flags = flags & ~(TCPHDR_FIN | TCPHDR_PSH);
        TCP_SKB_CB(buff)->flags = flags;
        TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked;
  
@@@ -1190,7 -1189,6 +1190,7 @@@ void tcp_mtup_init(struct sock *sk
        icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, sysctl_tcp_base_mss);
        icsk->icsk_mtup.probe_size = 0;
  }
 +EXPORT_SYMBOL(tcp_mtup_init);
  
  /* This function synchronize snd mss to current pmtu/exthdr set.
  
@@@ -1234,7 -1232,6 +1234,7 @@@ unsigned int tcp_sync_mss(struct sock *
  
        return mss_now;
  }
 +EXPORT_SYMBOL(tcp_sync_mss);
  
  /* Compute the current effective MSS, taking SACKs and IP options,
   * and even PMTU discovery events into account.
@@@ -1331,7 -1328,8 +1331,7 @@@ static inline unsigned int tcp_cwnd_tes
        u32 in_flight, cwnd;
  
        /* Don't be strict about the congestion window for the final FIN.  */
 -      if ((TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
 -          tcp_skb_pcount(skb) == 1)
 +      if ((TCP_SKB_CB(skb)->flags & TCPHDR_FIN) && tcp_skb_pcount(skb) == 1)
                return 1;
  
        in_flight = tcp_packets_in_flight(tp);
@@@ -1400,7 -1398,7 +1400,7 @@@ static inline int tcp_nagle_test(struc
         * Nagle can be ignored during F-RTO too (see RFC4138).
         */
        if (tcp_urg_mode(tp) || (tp->frto_counter == 2) ||
 -          (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN))
 +          (TCP_SKB_CB(skb)->flags & TCPHDR_FIN))
                return 1;
  
        if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
@@@ -1463,7 -1461,7 +1463,7 @@@ int tcp_may_send_now(struct sock *sk
   * packet has never been sent out before (and thus is not cloned).
   */
  static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
 -                      unsigned int mss_now)
 +                      unsigned int mss_now, gfp_t gfp)
  {
        struct sk_buff *buff;
        int nlen = skb->len - len;
        if (skb->len != skb->data_len)
                return tcp_fragment(sk, skb, len, mss_now);
  
 -      buff = sk_stream_alloc_skb(sk, 0, GFP_ATOMIC);
 +      buff = sk_stream_alloc_skb(sk, 0, gfp);
        if (unlikely(buff == NULL))
                return -ENOMEM;
  
  
        /* PSH and FIN should only be set in the second packet. */
        flags = TCP_SKB_CB(skb)->flags;
 -      TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN | TCPCB_FLAG_PSH);
 +      TCP_SKB_CB(skb)->flags = flags & ~(TCPHDR_FIN | TCPHDR_PSH);
        TCP_SKB_CB(buff)->flags = flags;
  
        /* This packet was never sent out yet, so no SACK bits. */
@@@ -1520,7 -1518,7 +1520,7 @@@ static int tcp_tso_should_defer(struct 
        const struct inet_connection_sock *icsk = inet_csk(sk);
        u32 send_win, cong_win, limit, in_flight;
  
 -      if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)
 +      if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
                goto send_now;
  
        if (icsk->icsk_ca_state != TCP_CA_Open)
@@@ -1646,7 -1644,7 +1646,7 @@@ static int tcp_mtu_probe(struct sock *s
  
        TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq;
        TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size;
 -      TCP_SKB_CB(nskb)->flags = TCPCB_FLAG_ACK;
 +      TCP_SKB_CB(nskb)->flags = TCPHDR_ACK;
        TCP_SKB_CB(nskb)->sacked = 0;
        nskb->csum = 0;
        nskb->ip_summed = skb->ip_summed;
                        sk_wmem_free_skb(sk, skb);
                } else {
                        TCP_SKB_CB(nskb)->flags |= TCP_SKB_CB(skb)->flags &
 -                                                 ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
 +                                                 ~(TCPHDR_FIN|TCPHDR_PSH);
                        if (!skb_shinfo(skb)->nr_frags) {
                                skb_pull(skb, copy);
                                if (skb->ip_summed != CHECKSUM_PARTIAL)
@@@ -1771,7 -1769,7 +1771,7 @@@ static int tcp_write_xmit(struct sock *
                                                    cwnd_quota);
  
                if (skb->len > limit &&
 -                  unlikely(tso_fragment(sk, skb, limit, mss_now)))
 +                  unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))
                        break;
  
                TCP_SKB_CB(skb)->when = tcp_time_stamp;
@@@ -2022,7 -2020,7 +2022,7 @@@ static void tcp_retrans_try_collapse(st
  
        if (!sysctl_tcp_retrans_collapse)
                return;
 -      if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN)
 +      if (TCP_SKB_CB(skb)->flags & TCPHDR_SYN)
                return;
  
        tcp_for_write_queue_from_safe(skb, tmp, sk) {
@@@ -2114,7 -2112,7 +2114,7 @@@ int tcp_retransmit_skb(struct sock *sk
         * since it is cheap to do so and saves bytes on the network.
         */
        if (skb->len > 0 &&
 -          (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
 +          (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) &&
            tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
                if (!pskb_trim(skb, 0)) {
                        /* Reuse, even though it does some unnecessary work */
@@@ -2210,6 -2208,9 +2210,9 @@@ void tcp_xmit_retransmit_queue(struct s
        int mib_idx;
        int fwd_rexmitting = 0;
  
+       if (!tp->packets_out)
+               return;
        if (!tp->lost_out)
                tp->retransmit_high = tp->snd_una;
  
@@@ -2303,7 -2304,7 +2306,7 @@@ void tcp_send_fin(struct sock *sk
        mss_now = tcp_current_mss(sk);
  
        if (tcp_send_head(sk) != NULL) {
 -              TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
 +              TCP_SKB_CB(skb)->flags |= TCPHDR_FIN;
                TCP_SKB_CB(skb)->end_seq++;
                tp->write_seq++;
        } else {
                skb_reserve(skb, MAX_TCP_HEADER);
                /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
                tcp_init_nondata_skb(skb, tp->write_seq,
 -                                   TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
 +                                   TCPHDR_ACK | TCPHDR_FIN);
                tcp_queue_skb(sk, skb);
        }
        __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF);
@@@ -2345,7 -2346,7 +2348,7 @@@ void tcp_send_active_reset(struct sock 
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(skb, MAX_TCP_HEADER);
        tcp_init_nondata_skb(skb, tcp_acceptable_seq(sk),
 -                           TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
 +                           TCPHDR_ACK | TCPHDR_RST);
        /* Send it off. */
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
        if (tcp_transmit_skb(sk, skb, 0, priority))
@@@ -2365,11 -2366,11 +2368,11 @@@ int tcp_send_synack(struct sock *sk
        struct sk_buff *skb;
  
        skb = tcp_write_queue_head(sk);
 -      if (skb == NULL || !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN)) {
 +      if (skb == NULL || !(TCP_SKB_CB(skb)->flags & TCPHDR_SYN)) {
                printk(KERN_DEBUG "tcp_send_synack: wrong queue state\n");
                return -EFAULT;
        }
 -      if (!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_ACK)) {
 +      if (!(TCP_SKB_CB(skb)->flags & TCPHDR_ACK)) {
                if (skb_cloned(skb)) {
                        struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
                        if (nskb == NULL)
                        skb = nskb;
                }
  
 -              TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ACK;
 +              TCP_SKB_CB(skb)->flags |= TCPHDR_ACK;
                TCP_ECN_send_synack(tcp_sk(sk), skb);
        }
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
@@@ -2462,7 -2463,7 +2465,7 @@@ struct sk_buff *tcp_make_synack(struct 
         * not even correctly set)
         */
        tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn,
 -                           TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
 +                           TCPHDR_SYN | TCPHDR_ACK);
  
        if (OPTION_COOKIE_EXTENSION & opts.options) {
                if (s_data_desired) {
  
        return skb;
  }
 +EXPORT_SYMBOL(tcp_make_synack);
  
  /* Do all connect socket setups that can be done AF independent. */
  static void tcp_connect_init(struct sock *sk)
@@@ -2595,7 -2595,7 +2598,7 @@@ int tcp_connect(struct sock *sk
        skb_reserve(buff, MAX_TCP_HEADER);
  
        tp->snd_nxt = tp->write_seq;
 -      tcp_init_nondata_skb(buff, tp->write_seq++, TCPCB_FLAG_SYN);
 +      tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN);
        TCP_ECN_send_syn(sk, buff);
  
        /* Send it off. */
                                  inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
        return 0;
  }
 +EXPORT_SYMBOL(tcp_connect);
  
  /* Send out a delayed ack, the caller does the policy checking
   * to see if we should even be here.  See tcp_input.c:tcp_ack_snd_check()
@@@ -2702,7 -2701,7 +2705,7 @@@ void tcp_send_ack(struct sock *sk
  
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(buff, MAX_TCP_HEADER);
 -      tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPCB_FLAG_ACK);
 +      tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPHDR_ACK);
  
        /* Send it off, this clears delayed acks for us. */
        TCP_SKB_CB(buff)->when = tcp_time_stamp;
@@@ -2736,7 -2735,7 +2739,7 @@@ static int tcp_xmit_probe_skb(struct so
         * end to send an ack.  Don't queue or clone SKB, just
         * send it.
         */
 -      tcp_init_nondata_skb(skb, tp->snd_una - !urgent, TCPCB_FLAG_ACK);
 +      tcp_init_nondata_skb(skb, tp->snd_una - !urgent, TCPHDR_ACK);
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
        return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC);
  }
@@@ -2766,13 -2765,13 +2769,13 @@@ int tcp_write_wakeup(struct sock *sk
                if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq ||
                    skb->len > mss) {
                        seg_size = min(seg_size, mss);
 -                      TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 +                      TCP_SKB_CB(skb)->flags |= TCPHDR_PSH;
                        if (tcp_fragment(sk, skb, seg_size, mss))
                                return -1;
                } else if (!tcp_skb_pcount(skb))
                        tcp_set_skb_tso_segs(sk, skb, mss);
  
 -              TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 +              TCP_SKB_CB(skb)->flags |= TCPHDR_PSH;
                TCP_SKB_CB(skb)->when = tcp_time_stamp;
                err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
                if (!err)
@@@ -2825,3 -2824,10 +2828,3 @@@ void tcp_send_probe0(struct sock *sk
                                          TCP_RTO_MAX);
        }
  }
 -
 -EXPORT_SYMBOL(tcp_select_initial_window);
 -EXPORT_SYMBOL(tcp_connect);
 -EXPORT_SYMBOL(tcp_make_synack);
 -EXPORT_SYMBOL(tcp_simple_retransmit);
 -EXPORT_SYMBOL(tcp_sync_mss);
 -EXPORT_SYMBOL(tcp_mtup_init);
diff --combined net/sched/act_nat.c
index 0be49a4b4d8c271558db306c049339f62f4d22fc,724553e8ed7bc9d8ecd668c71ab9373936a3d2d3..24e614c495f26091d5acdc8af3a8f951d8d984c2
@@@ -205,7 -205,7 +205,7 @@@ static int tcf_nat(struct sk_buff *skb
        {
                struct icmphdr *icmph;
  
-               if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph)))
+               if (!pskb_may_pull(skb, ihl + sizeof(*icmph)))
                        goto drop;
  
                icmph = (void *)(skb_network_header(skb) + ihl);
                    (icmph->type != ICMP_PARAMETERPROB))
                        break;
  
+               if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph)))
+                       goto drop;
                iph = (void *)(icmph + 1);
                if (egress)
                        addr = iph->daddr;
@@@ -265,29 -268,40 +268,29 @@@ static int tcf_nat_dump(struct sk_buff 
  {
        unsigned char *b = skb_tail_pointer(skb);
        struct tcf_nat *p = a->priv;
 -      struct tc_nat *opt;
 +      struct tc_nat opt;
        struct tcf_t t;
 -      int s;
  
 -      s = sizeof(*opt);
 +      opt.old_addr = p->old_addr;
 +      opt.new_addr = p->new_addr;
 +      opt.mask = p->mask;
 +      opt.flags = p->flags;
  
 -      /* netlink spinlocks held above us - must use ATOMIC */
 -      opt = kzalloc(s, GFP_ATOMIC);
 -      if (unlikely(!opt))
 -              return -ENOBUFS;
 +      opt.index = p->tcf_index;
 +      opt.action = p->tcf_action;
 +      opt.refcnt = p->tcf_refcnt - ref;
 +      opt.bindcnt = p->tcf_bindcnt - bind;
  
 -      opt->old_addr = p->old_addr;
 -      opt->new_addr = p->new_addr;
 -      opt->mask = p->mask;
 -      opt->flags = p->flags;
 -
 -      opt->index = p->tcf_index;
 -      opt->action = p->tcf_action;
 -      opt->refcnt = p->tcf_refcnt - ref;
 -      opt->bindcnt = p->tcf_bindcnt - bind;
 -
 -      NLA_PUT(skb, TCA_NAT_PARMS, s, opt);
 +      NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
        t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
        t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
        NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
  
 -      kfree(opt);
 -
        return skb->len;
  
  nla_put_failure:
        nlmsg_trim(skb, b);
 -      kfree(opt);
        return -1;
  }
  
diff --combined net/xfrm/xfrm_policy.c
index 037d956353e536b8611c0b9150df95aa9a2f90e6,a7ec5a8a2380e6277fa4a3755e01fb0aa58076fb..2b3ed7ad49338f3ec2d64caf1dd589c2aefc4264
@@@ -1594,8 -1594,8 +1594,8 @@@ xfrm_resolve_and_create_bundle(struct x
  
        /* Try to instantiate a bundle */
        err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
-       if (err < 0) {
-               if (err != -EAGAIN)
+       if (err <= 0) {
+               if (err != 0 && err != -EAGAIN)
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
                return ERR_PTR(err);
        }
@@@ -1678,6 -1678,13 +1678,13 @@@ xfrm_bundle_lookup(struct net *net, str
                        goto make_dummy_bundle;
                dst_hold(&xdst->u.dst);
                return oldflo;
+       } else if (new_xdst == NULL) {
+               num_xfrms = 0;
+               if (oldflo == NULL)
+                       goto make_dummy_bundle;
+               xdst->num_xfrms = 0;
+               dst_hold(&xdst->u.dst);
+               return oldflo;
        }
  
        /* Kill the previous bundle */
@@@ -1760,6 -1767,10 +1767,10 @@@ restart
                                xfrm_pols_put(pols, num_pols);
                                err = PTR_ERR(xdst);
                                goto dropdst;
+                       } else if (xdst == NULL) {
+                               num_xfrms = 0;
+                               drop_pols = num_pols;
+                               goto no_transform;
                        }
  
                        spin_lock_bh(&xfrm_policy_sk_bundle_lock);
@@@ -2481,8 -2492,7 +2492,8 @@@ static int __net_init xfrm_statistics_i
        int rv;
  
        if (snmp_mib_init((void __percpu **)net->mib.xfrm_statistics,
 -                        sizeof(struct linux_xfrm_mib)) < 0)
 +                        sizeof(struct linux_xfrm_mib),
 +                        __alignof__(struct linux_xfrm_mib)) < 0)
                return -ENOMEM;
        rv = xfrm_proc_init(net);
        if (rv < 0)
This page took 0.07953 seconds and 5 git commands to generate.