]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Jun 2010 14:32:21 +0000 (07:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Jun 2010 14:32:21 +0000 (07:32 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (30 commits)
  X25: remove duplicated #include
  tcp: use correct net ns in cookie_v4_check()
  rps: tcp: fix rps_sock_flow_table table updates
  ppp_generic: fix multilink fragment sizes
  syncookies: remove Kconfig text line about disabled-by-default
  ixgbe: only check pfc bits in hang logic if pfc is enabled
  net: check for refcount if pop a stacked dst_entry
  ixgbe: return IXGBE_ERR_RAR_INDEX when out of range
  act_pedit: access skb->data safely
  sfc: Store port number in net_device::dev_id
  epic100: Test __BIG_ENDIAN instead of (non-existent) CONFIG_BIG_ENDIAN
  tehuti: return -EFAULT on copy_to_user errors
  isdn/kcapi: return -EFAULT on copy_from_user errors
  e1000e: change logical negate to bitwise
  sfc: Get port number from CS_PORT_NUM, not PCI function number
  cls_u32: use skb_header_pointer() to dereference data safely
  TCP: tcp_hybla: Fix integer overflow in slow start increment
  act_nat: fix the wrong checksum when addr isn't in old_addr/mask
  net/fec: fix pm to survive to suspend/resume
  korina: count RX DMA OVR as rx_fifo_error
  ...

31 files changed:
drivers/isdn/capi/kcapi.c
drivers/net/bnx2.c
drivers/net/e1000e/netdev.c
drivers/net/enic/enic.h
drivers/net/enic/enic_main.c
drivers/net/epic100.c
drivers/net/fec.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/korina.c
drivers/net/ppp_generic.c
drivers/net/sfc/net_driver.h
drivers/net/sfc/siena.c
drivers/net/tehuti.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/ath/ath5k/base.c
include/net/dst.h
net/8021q/vlan_dev.c
net/core/dev.c
net/ipv4/Kconfig
net/ipv4/syncookies.c
net/ipv4/tcp_hybla.c
net/ipv4/tcp_ipv4.c
net/mac80211/agg-tx.c
net/mac80211/rx.c
net/sched/act_nat.c
net/sched/act_pedit.c
net/sched/cls_u32.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c

index bde3c88b8b270e0ca527849b0f58c9647bfb67ad..b054494df846958d99fdc45c4075dc57339981bd 100644 (file)
@@ -1020,12 +1020,12 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
                if (cmd == AVMB1_ADDCARD) {
                   if ((retval = copy_from_user(&cdef, data,
                                            sizeof(avmb1_carddef))))
-                          return retval;
+                          return -EFAULT;
                   cdef.cardtype = AVM_CARDTYPE_B1;
                } else {
                   if ((retval = copy_from_user(&cdef, data,
                                            sizeof(avmb1_extcarddef))))
-                          return retval;
+                          return -EFAULT;
                }
                cparams.port = cdef.port;
                cparams.irq = cdef.irq;
@@ -1218,7 +1218,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
                kcapi_carddef cdef;
 
                if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
-                       return retval;
+                       return -EFAULT;
 
                cparams.port = cdef.port;
                cparams.irq = cdef.irq;
index 188e356c30a30e005a69eaf05997ea57fdae880e..949d7a9dcf9269b4ccef78703ffb7e1701767237 100644 (file)
@@ -247,6 +247,7 @@ static const struct flash_spec flash_5709 = {
 MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
 
 static void bnx2_init_napi(struct bnx2 *bp);
+static void bnx2_del_napi(struct bnx2 *bp);
 
 static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
 {
@@ -6270,6 +6271,7 @@ open_err:
        bnx2_free_skbs(bp);
        bnx2_free_irq(bp);
        bnx2_free_mem(bp);
+       bnx2_del_napi(bp);
        return rc;
 }
 
@@ -6537,6 +6539,7 @@ bnx2_close(struct net_device *dev)
        bnx2_free_irq(bp);
        bnx2_free_skbs(bp);
        bnx2_free_mem(bp);
+       bnx2_del_napi(bp);
        bp->link_up = 0;
        netif_carrier_off(bp->dev);
        bnx2_set_power_state(bp, PCI_D3hot);
@@ -8227,7 +8230,16 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
        return str;
 }
 
-static void __devinit
+static void
+bnx2_del_napi(struct bnx2 *bp)
+{
+       int i;
+
+       for (i = 0; i < bp->irq_nvecs; i++)
+               netif_napi_del(&bp->bnx2_napi[i].napi);
+}
+
+static void
 bnx2_init_napi(struct bnx2 *bp)
 {
        int i;
index 24507f3b8b1708755e0631d9c28be2fe08f67493..57a7e41da69e91e64d547362d04c7495d907f567 100644 (file)
@@ -2554,7 +2554,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
                        mdef = er32(MDEF(i));
 
                        /* Ignore filters with anything other than IPMI ports */
-                       if (mdef & !(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
+                       if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
                                continue;
 
                        /* Enable this decision filter in MANC2H */
index 85f2a2e7030aa2e1962385f9c8e92a04e1aaa29d..45e86d1e5b1b29545371a7a1129fbb99f94cfb40 100644 (file)
@@ -74,7 +74,14 @@ struct enic_msix_entry {
        void *devid;
 };
 
+#define ENIC_SET_APPLIED               (1 << 0)
+#define ENIC_SET_REQUEST               (1 << 1)
+#define ENIC_SET_NAME                  (1 << 2)
+#define ENIC_SET_INSTANCE              (1 << 3)
+#define ENIC_SET_HOST                  (1 << 4)
+
 struct enic_port_profile {
+       u32 set;
        u8 request;
        char name[PORT_PROFILE_MAX];
        u8 instance_uuid[PORT_UUID_MAX];
index 6586b5c7e4b617066bea1d652f175b51b5f9d6f4..bc7d6b96de3dec39ca96b369a6656ec22ab04a12 100644 (file)
@@ -1029,8 +1029,7 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error)
        return err;
 }
 
-static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac,
-       char *name, u8 *instance_uuid, u8 *host_uuid)
+static int enic_set_port_profile(struct enic *enic, u8 *mac)
 {
        struct vic_provinfo *vp;
        u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
@@ -1040,97 +1039,112 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac,
                "%02X%02X-%02X%02X%02X%02X%0X%02X";
        int err;
 
-       if (!name)
-               return -EINVAL;
+       err = enic_vnic_dev_deinit(enic);
+       if (err)
+               return err;
 
-       if (!is_valid_ether_addr(mac))
-               return -EADDRNOTAVAIL;
+       switch (enic->pp.request) {
 
-       vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE);
-       if (!vp)
-               return -ENOMEM;
+       case PORT_REQUEST_ASSOCIATE:
 
-       vic_provinfo_add_tlv(vp,
-               VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
-               strlen(name) + 1, name);
-
-       vic_provinfo_add_tlv(vp,
-               VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
-               ETH_ALEN, mac);
-
-       if (instance_uuid) {
-               uuid = instance_uuid;
-               sprintf(uuid_str, uuid_fmt,
-                       uuid[0],  uuid[1],  uuid[2],  uuid[3],
-                       uuid[4],  uuid[5],  uuid[6],  uuid[7],
-                       uuid[8],  uuid[9],  uuid[10], uuid[11],
-                       uuid[12], uuid[13], uuid[14], uuid[15]);
-               vic_provinfo_add_tlv(vp,
-                       VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
-                       sizeof(uuid_str), uuid_str);
-       }
+               if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
+                       return -EINVAL;
 
-       if (host_uuid) {
-               uuid = host_uuid;
-               sprintf(uuid_str, uuid_fmt,
-                       uuid[0],  uuid[1],  uuid[2],  uuid[3],
-                       uuid[4],  uuid[5],  uuid[6],  uuid[7],
-                       uuid[8],  uuid[9],  uuid[10], uuid[11],
-                       uuid[12], uuid[13], uuid[14], uuid[15]);
-               vic_provinfo_add_tlv(vp,
-                       VIC_LINUX_PROV_TLV_HOST_UUID_STR,
-                       sizeof(uuid_str), uuid_str);
-       }
+               if (!is_valid_ether_addr(mac))
+                       return -EADDRNOTAVAIL;
 
-       err = enic_vnic_dev_deinit(enic);
-       if (err)
-               goto err_out;
+               vp = vic_provinfo_alloc(GFP_KERNEL, oui,
+                       VIC_PROVINFO_LINUX_TYPE);
+               if (!vp)
+                       return -ENOMEM;
 
-       memset(&enic->pp, 0, sizeof(enic->pp));
+               vic_provinfo_add_tlv(vp,
+                       VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR,
+                       strlen(enic->pp.name) + 1, enic->pp.name);
 
-       err = enic_dev_init_prov(enic, vp);
-       if (err)
-               goto err_out;
+               vic_provinfo_add_tlv(vp,
+                       VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR,
+                       ETH_ALEN, mac);
+
+               if (enic->pp.set & ENIC_SET_INSTANCE) {
+                       uuid = enic->pp.instance_uuid;
+                       sprintf(uuid_str, uuid_fmt,
+                               uuid[0],  uuid[1],  uuid[2],  uuid[3],
+                               uuid[4],  uuid[5],  uuid[6],  uuid[7],
+                               uuid[8],  uuid[9],  uuid[10], uuid[11],
+                               uuid[12], uuid[13], uuid[14], uuid[15]);
+                       vic_provinfo_add_tlv(vp,
+                               VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
+                               sizeof(uuid_str), uuid_str);
+               }
 
-       enic->pp.request = request;
-       memcpy(enic->pp.name, name, PORT_PROFILE_MAX);
-       if (instance_uuid)
-               memcpy(enic->pp.instance_uuid,
-                       instance_uuid, PORT_UUID_MAX);
-       if (host_uuid)
-               memcpy(enic->pp.host_uuid,
-                       host_uuid, PORT_UUID_MAX);
+               if (enic->pp.set & ENIC_SET_HOST) {
+                       uuid = enic->pp.host_uuid;
+                       sprintf(uuid_str, uuid_fmt,
+                               uuid[0],  uuid[1],  uuid[2],  uuid[3],
+                               uuid[4],  uuid[5],  uuid[6],  uuid[7],
+                               uuid[8],  uuid[9],  uuid[10], uuid[11],
+                               uuid[12], uuid[13], uuid[14], uuid[15]);
+                       vic_provinfo_add_tlv(vp,
+                               VIC_LINUX_PROV_TLV_HOST_UUID_STR,
+                               sizeof(uuid_str), uuid_str);
+               }
 
-err_out:
-       vic_provinfo_free(vp);
+               err = enic_dev_init_prov(enic, vp);
+               vic_provinfo_free(vp);
+               if (err)
+                       return err;
+               break;
 
-       return err;
-}
+       case PORT_REQUEST_DISASSOCIATE:
+               break;
 
-static int enic_unset_port_profile(struct enic *enic)
-{
-       memset(&enic->pp, 0, sizeof(enic->pp));
-       return enic_vnic_dev_deinit(enic);
+       default:
+               return -EINVAL;
+       }
+
+       enic->pp.set |= ENIC_SET_APPLIED;
+       return 0;
 }
 
 static int enic_set_vf_port(struct net_device *netdev, int vf,
        struct nlattr *port[])
 {
        struct enic *enic = netdev_priv(netdev);
-       char *name = NULL;
-       u8 *instance_uuid = NULL;
-       u8 *host_uuid = NULL;
-       u8 request = PORT_REQUEST_DISASSOCIATE;
+
+       memset(&enic->pp, 0, sizeof(enic->pp));
+
+       if (port[IFLA_PORT_REQUEST]) {
+               enic->pp.set |= ENIC_SET_REQUEST;
+               enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
+       }
+
+       if (port[IFLA_PORT_PROFILE]) {
+               enic->pp.set |= ENIC_SET_NAME;
+               memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+                       PORT_PROFILE_MAX);
+       }
+
+       if (port[IFLA_PORT_INSTANCE_UUID]) {
+               enic->pp.set |= ENIC_SET_INSTANCE;
+               memcpy(enic->pp.instance_uuid,
+                       nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
+       }
+
+       if (port[IFLA_PORT_HOST_UUID]) {
+               enic->pp.set |= ENIC_SET_HOST;
+               memcpy(enic->pp.host_uuid,
+                       nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
+       }
 
        /* don't support VFs, yet */
        if (vf != PORT_SELF_VF)
                return -EOPNOTSUPP;
 
-       if (port[IFLA_PORT_REQUEST])
-               request = nla_get_u8(port[IFLA_PORT_REQUEST]);
+       if (!(enic->pp.set & ENIC_SET_REQUEST))
+               return -EOPNOTSUPP;
 
-       switch (request) {
-       case PORT_REQUEST_ASSOCIATE:
+       if (enic->pp.request == PORT_REQUEST_ASSOCIATE) {
 
                /* If the interface mac addr hasn't been assigned,
                 * assign a random mac addr before setting port-
@@ -1139,30 +1153,9 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 
                if (is_zero_ether_addr(netdev->dev_addr))
                        random_ether_addr(netdev->dev_addr);
-
-               if (port[IFLA_PORT_PROFILE])
-                       name = nla_data(port[IFLA_PORT_PROFILE]);
-
-               if (port[IFLA_PORT_INSTANCE_UUID])
-                       instance_uuid =
-                               nla_data(port[IFLA_PORT_INSTANCE_UUID]);
-
-               if (port[IFLA_PORT_HOST_UUID])
-                       host_uuid = nla_data(port[IFLA_PORT_HOST_UUID]);
-
-               return enic_set_port_profile(enic, request,
-                       netdev->dev_addr, name,
-                       instance_uuid, host_uuid);
-
-       case PORT_REQUEST_DISASSOCIATE:
-
-               return enic_unset_port_profile(enic);
-
-       default:
-               break;
        }
 
-       return -EOPNOTSUPP;
+       return enic_set_port_profile(enic, netdev->dev_addr);
 }
 
 static int enic_get_vf_port(struct net_device *netdev, int vf,
@@ -1172,14 +1165,12 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
        int err, error, done;
        u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
 
-       /* don't support VFs, yet */
-       if (vf != PORT_SELF_VF)
-               return -EOPNOTSUPP;
+       if (!(enic->pp.set & ENIC_SET_APPLIED))
+               return -ENODATA;
 
        err = enic_dev_init_done(enic, &done, &error);
-
        if (err)
-               return err;
+               error = err;
 
        switch (error) {
        case ERR_SUCCESS:
@@ -1202,12 +1193,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf,
 
        NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
        NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
-       NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
-               enic->pp.name);
-       NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
-               enic->pp.instance_uuid);
-       NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
-               enic->pp.host_uuid);
+       if (enic->pp.set & ENIC_SET_NAME)
+               NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
+                       enic->pp.name);
+       if (enic->pp.set & ENIC_SET_INSTANCE)
+               NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
+                       enic->pp.instance_uuid);
+       if (enic->pp.set & ENIC_SET_HOST)
+               NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
+                       enic->pp.host_uuid);
 
        return 0;
 
index 6838dfc9ef23a4549c69144c7d87db589e1c7928..4c274657283c36ad2157d5874447e3c434483869 100644 (file)
@@ -87,6 +87,7 @@ static int rx_copybreak;
 #include <linux/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
@@ -230,7 +231,7 @@ static const u16 media2miictl[16] = {
  * The EPIC100 Rx and Tx buffer descriptors.  Note that these
  * really ARE host-endian; it's not a misannotation.  We tell
  * the card to byteswap them internally on big-endian hosts -
- * look for #ifdef CONFIG_BIG_ENDIAN in epic_open().
+ * look for #ifdef __BIG_ENDIAN in epic_open().
  */
 
 struct epic_tx_desc {
@@ -690,7 +691,7 @@ static int epic_open(struct net_device *dev)
                outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
 
        /* Tell the chip to byteswap descriptors on big-endian hosts */
-#ifdef CONFIG_BIG_ENDIAN
+#ifdef __BIG_ENDIAN
        outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
        inl(ioaddr + GENCTL);
        outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
@@ -806,7 +807,7 @@ static void epic_restart(struct net_device *dev)
        for (i = 16; i > 0; i--)
                outl(0x0008, ioaddr + TEST1);
 
-#ifdef CONFIG_BIG_ENDIAN
+#ifdef __BIG_ENDIAN
        outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
 #else
        outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
index ddf7a86cd4661f0cdfa438d7a2a9dae6db68acec..edfff92a6d8ebd8c141b9697b216efccfbbec226 100644 (file)
@@ -1373,10 +1373,9 @@ fec_suspend(struct platform_device *dev, pm_message_t state)
 
        if (ndev) {
                fep = netdev_priv(ndev);
-               if (netif_running(ndev)) {
-                       netif_device_detach(ndev);
-                       fec_stop(ndev);
-               }
+               if (netif_running(ndev))
+                       fec_enet_close(ndev);
+               clk_disable(fep->clk);
        }
        return 0;
 }
@@ -1385,12 +1384,13 @@ static int
 fec_resume(struct platform_device *dev)
 {
        struct net_device *ndev = platform_get_drvdata(dev);
+       struct fec_enet_private *fep;
 
        if (ndev) {
-               if (netif_running(ndev)) {
-                       fec_enet_init(ndev, 0);
-                       netif_device_attach(ndev);
-               }
+               fep = netdev_priv(ndev);
+               clk_enable(fep->clk);
+               if (netif_running(ndev))
+                       fec_enet_open(ndev);
        }
        return 0;
 }
index 1159d9138f0577c84643ba3db8b263d995cd683a..9595b1bfb8dd54edab12c60fcf0bace4a19d1d1f 100644 (file)
@@ -1188,6 +1188,7 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
                IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
        } else {
                hw_dbg(hw, "RAR index %d is out of range.\n", index);
+               return IXGBE_ERR_RAR_INDEX;
        }
 
        return 0;
@@ -1219,6 +1220,7 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
                IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
        } else {
                hw_dbg(hw, "RAR index %d is out of range.\n", index);
+               return IXGBE_ERR_RAR_INDEX;
        }
 
        /* clear VMDq pool/queue selection for this RAR */
index d571d101de08fb4c183af77cb9b64d10904d10a7..b2af2f67f604c2d24018a2e9af8307e5e33d5828 100644 (file)
@@ -642,7 +642,7 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter,
        u32 txoff = IXGBE_TFCS_TXOFF;
 
 #ifdef CONFIG_IXGBE_DCB
-       if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+       if (adapter->dcb_cfg.pfc_mode_enable) {
                int tc;
                int reg_idx = tx_ring->reg_idx;
                int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
index 2eb6e151016cac10ca15eadfd9311283361e09b9..cdd1998f18c705348a618098f8e098edda8d7e98 100644 (file)
@@ -2609,6 +2609,7 @@ struct ixgbe_info {
 #define IXGBE_ERR_EEPROM_VERSION                -24
 #define IXGBE_ERR_NO_SPACE                      -25
 #define IXGBE_ERR_OVERTEMP                      -26
+#define IXGBE_ERR_RAR_INDEX                     -27
 #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF
 
 #endif /* _IXGBE_TYPE_H_ */
index 26bf1b76b9977a1510bf3407c34322bed46512ba..c7a9bef4dfb0890001c5243211862def6a4de2a6 100644 (file)
@@ -135,6 +135,7 @@ struct korina_private {
        struct napi_struct napi;
        struct timer_list media_check_timer;
        struct mii_if_info mii_if;
+       struct work_struct restart_task;
        struct net_device *dev;
        int phy_addr;
 };
@@ -375,7 +376,7 @@ static int korina_rx(struct net_device *dev, int limit)
                if (devcs & ETH_RX_LE)
                        dev->stats.rx_length_errors++;
                if (devcs & ETH_RX_OVR)
-                       dev->stats.rx_over_errors++;
+                       dev->stats.rx_fifo_errors++;
                if (devcs & ETH_RX_CV)
                        dev->stats.rx_frame_errors++;
                if (devcs & ETH_RX_CES)
@@ -764,10 +765,9 @@ static int korina_alloc_ring(struct net_device *dev)
 
        /* Initialize the receive descriptors */
        for (i = 0; i < KORINA_NUM_RDS; i++) {
-               skb = dev_alloc_skb(KORINA_RBSIZE + 2);
+               skb = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE);
                if (!skb)
                        return -ENOMEM;
-               skb_reserve(skb, 2);
                lp->rx_skb[i] = skb;
                lp->rd_ring[i].control = DMA_DESC_IOD |
                                DMA_COUNT(KORINA_RBSIZE);
@@ -890,12 +890,12 @@ static int korina_init(struct net_device *dev)
 
 /*
  * Restart the RC32434 ethernet controller.
- * FIXME: check the return status where we call it
  */
-static int korina_restart(struct net_device *dev)
+static void korina_restart_task(struct work_struct *work)
 {
-       struct korina_private *lp = netdev_priv(dev);
-       int ret;
+       struct korina_private *lp = container_of(work,
+                       struct korina_private, restart_task);
+       struct net_device *dev = lp->dev;
 
        /*
         * Disable interrupts
@@ -916,10 +916,9 @@ static int korina_restart(struct net_device *dev)
 
        napi_disable(&lp->napi);
 
-       ret = korina_init(dev);
-       if (ret < 0) {
+       if (korina_init(dev) < 0) {
                printk(KERN_ERR "%s: cannot restart device\n", dev->name);
-               return ret;
+               return;
        }
        korina_multicast_list(dev);
 
@@ -927,8 +926,6 @@ static int korina_restart(struct net_device *dev)
        enable_irq(lp->ovr_irq);
        enable_irq(lp->tx_irq);
        enable_irq(lp->rx_irq);
-
-       return ret;
 }
 
 static void korina_clear_and_restart(struct net_device *dev, u32 value)
@@ -937,7 +934,7 @@ static void korina_clear_and_restart(struct net_device *dev, u32 value)
 
        netif_stop_queue(dev);
        writel(value, &lp->eth_regs->ethintfc);
-       korina_restart(dev);
+       schedule_work(&lp->restart_task);
 }
 
 /* Ethernet Tx Underflow interrupt */
@@ -962,11 +959,8 @@ static irqreturn_t korina_und_interrupt(int irq, void *dev_id)
 static void korina_tx_timeout(struct net_device *dev)
 {
        struct korina_private *lp = netdev_priv(dev);
-       unsigned long flags;
 
-       spin_lock_irqsave(&lp->lock, flags);
-       korina_restart(dev);
-       spin_unlock_irqrestore(&lp->lock, flags);
+       schedule_work(&lp->restart_task);
 }
 
 /* Ethernet Rx Overflow interrupt */
@@ -1086,6 +1080,8 @@ static int korina_close(struct net_device *dev)
 
        napi_disable(&lp->napi);
 
+       cancel_work_sync(&lp->restart_task);
+
        free_irq(lp->rx_irq, dev);
        free_irq(lp->tx_irq, dev);
        free_irq(lp->ovr_irq, dev);
@@ -1198,6 +1194,8 @@ static int korina_probe(struct platform_device *pdev)
        }
        setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev);
 
+       INIT_WORK(&lp->restart_task, korina_restart_task);
+
        printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
                        dev->name);
 out:
index c5f8eb102bf76de12c86d2665b19b1c7fcb8d8b0..1b2c29150202080e75c2e9732b0150c204ed9161 100644 (file)
@@ -1422,7 +1422,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                flen = len;
                if (nfree > 0) {
                        if (pch->speed == 0) {
-                               flen = totlen/nfree;
+                               flen = len/nfree;
                                if (nbigger > 0) {
                                        flen++;
                                        nbigger--;
index 2e6fd89f2a72d722555357bf46595754f6426e38..4762c91cb587f03c19eddd58abef2ea449a2e941 100644 (file)
@@ -830,7 +830,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx)
 
 static inline unsigned int efx_port_num(struct efx_nic *efx)
 {
-       return PCI_FUNC(efx->pci_dev->devfn);
+       return efx->net_dev->dev_id;
 }
 
 /**
index 727b4228e0819bfe336e38ed6504bd8c2d852edc..f2b1e6180753536336921b90f53f62c8675fda72 100644 (file)
@@ -206,6 +206,7 @@ static int siena_probe_nic(struct efx_nic *efx)
 {
        struct siena_nic_data *nic_data;
        bool already_attached = 0;
+       efx_oword_t reg;
        int rc;
 
        /* Allocate storage for hardware specific data */
@@ -220,6 +221,9 @@ static int siena_probe_nic(struct efx_nic *efx)
                goto fail1;
        }
 
+       efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
+       efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
+
        efx_mcdi_init(efx);
 
        /* Recover from a failed assertion before probing */
index 20ab161923253835b7ee760f8fc027bdcc8aa82c..737df6032bbc1d4bd9635b78210a52bcfa7efea2 100644 (file)
@@ -646,7 +646,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
                error = copy_from_user(data, ifr->ifr_data, sizeof(data));
                if (error) {
                        pr_err("cant copy from user\n");
-                       RET(error);
+                       RET(-EFAULT);
                }
                DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
        }
@@ -665,7 +665,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
                    data[2]);
                error = copy_to_user(ifr->ifr_data, data, sizeof(data));
                if (error)
-                       RET(error);
+                       RET(-EFAULT);
                break;
 
        case BDX_OP_WRITE:
index 166e77dfffda9f9ec1b00c764d09b5b41b763506..e47f5a986b1c213c7f14e43b38dda541504c8b7d 100644 (file)
@@ -37,8 +37,6 @@
 #include <net/x25device.h>
 #include "x25_asy.h"
 
-#include <net/x25device.h>
-
 static struct net_device **x25_asy_devs;
 static int x25_asy_maxdev = SL_NRUNIT;
 
index cc6d41dec332091eeef2c9a0b7905f2e26c95cfe..2978359c4366f18860c247bed40a33fd08217574 100644 (file)
@@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
                struct ath5k_txq *txq);
 static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
-static int ath5k_reset_wake(struct ath5k_softc *sc);
 static int ath5k_start(struct ieee80211_hw *hw);
 static void ath5k_stop(struct ieee80211_hw *hw);
 static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data)
 {
        struct ath5k_softc *sc = (void *)data;
 
-       ath5k_reset_wake(sc);
+       ath5k_reset(sc, sc->curchan);
 }
 
 /*
@@ -2941,23 +2940,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
        ath5k_beacon_config(sc);
        /* intrs are enabled by ath5k_beacon_config */
 
+       ieee80211_wake_queues(sc->hw);
+
        return 0;
 err:
        return ret;
 }
 
-static int
-ath5k_reset_wake(struct ath5k_softc *sc)
-{
-       int ret;
-
-       ret = ath5k_reset(sc, sc->curchan);
-       if (!ret)
-               ieee80211_wake_queues(sc->hw);
-
-       return ret;
-}
-
 static int ath5k_start(struct ieee80211_hw *hw)
 {
        return ath5k_init(hw->priv);
index 612069beda733676b1e106ce8f24ee19e66b8910..81d1413a87010967684febe7344169baa7d828ef 100644 (file)
@@ -250,11 +250,11 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
  * Linux networking.  Thus, destinations are stackable.
  */
 
-static inline struct dst_entry *dst_pop(struct dst_entry *dst)
+static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
 {
-       struct dst_entry *child = dst_clone(dst->child);
+       struct dst_entry *child = skb_dst(skb)->child;
 
-       dst_release(dst);
+       skb_dst_drop(skb);
        return child;
 }
 
index 55be90826f5fd1317f961b9fbabb3f3b989f380e..52984267781782cd78aa0bd7bc3d38280745c1b1 100644 (file)
@@ -708,7 +708,8 @@ static int vlan_dev_init(struct net_device *dev)
        netif_carrier_off(dev);
 
        /* IFF_BROADCAST|IFF_MULTICAST; ??? */
-       dev->flags  = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI);
+       dev->flags  = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
+                                         IFF_MASTER | IFF_SLAVE);
        dev->iflink = real_dev->ifindex;
        dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
                                          (1<<__LINK_STATE_DORMANT))) |
index 1845b08c624e1fa4c9dd398f4b61c2963dbfc1f2..d03470f5260ae530f9945b50a6a1722466d07d60 100644 (file)
@@ -2795,7 +2795,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
        struct net_device *orig_dev;
        struct net_device *master;
        struct net_device *null_or_orig;
-       struct net_device *null_or_bond;
+       struct net_device *orig_or_bond;
        int ret = NET_RX_DROP;
        __be16 type;
 
@@ -2868,10 +2868,10 @@ ncls:
         * device that may have registered for a specific ptype.  The
         * handler may have to adjust skb->dev and orig_dev.
         */
-       null_or_bond = NULL;
+       orig_or_bond = orig_dev;
        if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) &&
            (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) {
-               null_or_bond = vlan_dev_real_dev(skb->dev);
+               orig_or_bond = vlan_dev_real_dev(skb->dev);
        }
 
        type = skb->protocol;
@@ -2879,7 +2879,7 @@ ncls:
                        &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
                if (ptype->type == type && (ptype->dev == null_or_orig ||
                     ptype->dev == skb->dev || ptype->dev == orig_dev ||
-                    ptype->dev == null_or_bond)) {
+                    ptype->dev == orig_or_bond)) {
                        if (pt_prev)
                                ret = deliver_skb(skb, pt_prev, orig_dev);
                        pt_prev = ptype;
index 8e3a1fd938ab3c2f18a8f9884598858b2020cd88..7c3a7d19124995fd89034a4db2254566aab4cdfd 100644 (file)
@@ -303,7 +303,7 @@ config ARPD
          If unsure, say N.
 
 config SYN_COOKIES
-       bool "IP: TCP syncookie support (disabled per default)"
+       bool "IP: TCP syncookie support"
        ---help---
          Normal TCP/IP networking is open to an attack known as "SYN
          flooding". This denial-of-service attack prevents legitimate remote
@@ -328,13 +328,13 @@ config SYN_COOKIES
          server is really overloaded. If this happens frequently better turn
          them off.
 
-         If you say Y here, note that SYN cookies aren't enabled by default;
-         you can enable them by saying Y to "/proc file system support" and
+         If you say Y here, you can disable SYN cookies at run time by
+         saying Y to "/proc file system support" and
          "Sysctl support" below and executing the command
 
-         echo 1 >/proc/sys/net/ipv4/tcp_syncookies
+         echo 0 > /proc/sys/net/ipv4/tcp_syncookies
 
-         at boot time after the /proc file system has been mounted.
+         after the /proc file system has been mounted.
 
          If unsure, say N.
 
index 5c24db4a3c91a54d7d6b3b86e8d4d906999d7d76..9f6b22206c527263fea9c56727967afd92b773bb 100644 (file)
@@ -347,7 +347,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
                                               { .sport = th->dest,
                                                 .dport = th->source } } };
                security_req_classify_flow(req, &fl);
-               if (ip_route_output_key(&init_net, &rt, &fl)) {
+               if (ip_route_output_key(sock_net(sk), &rt, &fl)) {
                        reqsk_free(req);
                        goto out;
                }
index c209e054a634ed5b07f9b6d8374006887a2c2085..377bc93493712f3037ae1cb2e12eb6e421366a4e 100644 (file)
@@ -126,8 +126,8 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
                 * calculate 2^fract in a <<7 value.
                 */
                is_slowstart = 1;
-               increment = ((1 << ca->rho) * hybla_fraction(rho_fractions))
-                       - 128;
+               increment = ((1 << min(ca->rho, 16U)) *
+                       hybla_fraction(rho_fractions)) - 128;
        } else {
                /*
                 * congestion avoidance
index 202cf09c4cd4be9f8a556d2740a51ca4bba96e56..fe193e53af447f49fe05a8cba7b495c38f421be2 100644 (file)
@@ -1555,6 +1555,7 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
 #endif
 
        if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
+               sock_rps_save_rxhash(sk, skb->rxhash);
                TCP_CHECK_TIMER(sk);
                if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) {
                        rsk = sk;
@@ -1579,7 +1580,9 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
                        }
                        return 0;
                }
-       }
+       } else
+               sock_rps_save_rxhash(sk, skb->rxhash);
+
 
        TCP_CHECK_TIMER(sk);
        if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) {
@@ -1672,8 +1675,6 @@ process:
 
        skb->dev = NULL;
 
-       sock_rps_save_rxhash(sk, skb->rxhash);
-
        bh_lock_sock_nested(sk);
        ret = 0;
        if (!sock_owned_by_user(sk)) {
index c163d0a149f49be05b07fa879562f2d821004beb..98258b7341e356111bef3674f56b3a6adeee5961 100644 (file)
@@ -332,14 +332,16 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
                IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
 
        spin_unlock(&local->ampdu_lock);
-       spin_unlock_bh(&sta->lock);
 
-       /* send an addBA request */
+       /* prepare tid data */
        sta->ampdu_mlme.dialog_token_allocator++;
        sta->ampdu_mlme.tid_tx[tid]->dialog_token =
                        sta->ampdu_mlme.dialog_token_allocator;
        sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
 
+       spin_unlock_bh(&sta->lock);
+
+       /* send AddBA request */
        ieee80211_send_addba_request(sdata, pubsta->addr, tid,
                         sta->ampdu_mlme.tid_tx[tid]->dialog_token,
                         sta->ampdu_mlme.tid_tx[tid]->ssn,
index 6e2a7bcd8cb888ce24be03cc56cb2516ca95fade..5e0b65406c44a6787c6fbc5f5720d3c0337ad5b6 100644 (file)
@@ -1818,17 +1818,26 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
                return RX_CONTINUE;
 
        if (ieee80211_is_back_req(bar->frame_control)) {
+               struct {
+                       __le16 control, start_seq_num;
+               } __packed bar_data;
+
                if (!rx->sta)
                        return RX_DROP_MONITOR;
+
+               if (skb_copy_bits(skb, offsetof(struct ieee80211_bar, control),
+                                 &bar_data, sizeof(bar_data)))
+                       return RX_DROP_MONITOR;
+
                spin_lock(&rx->sta->lock);
-               tid = le16_to_cpu(bar->control) >> 12;
+               tid = le16_to_cpu(bar_data.control) >> 12;
                if (!rx->sta->ampdu_mlme.tid_active_rx[tid]) {
                        spin_unlock(&rx->sta->lock);
                        return RX_DROP_MONITOR;
                }
                tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
 
-               start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
+               start_seq_num = le16_to_cpu(bar_data.start_seq_num) >> 4;
 
                /* reset session timer */
                if (tid_agg_rx->timeout)
index d885ba311564d9a766fce6eac37edbaf0ed82b71..570949417f388735e93bf887294326a8f24aa534 100644 (file)
@@ -159,6 +159,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
                        iph->daddr = new_addr;
 
                csum_replace4(&iph->check, addr, new_addr);
+       } else if ((iph->frag_off & htons(IP_OFFSET)) ||
+                  iph->protocol != IPPROTO_ICMP) {
+               goto out;
        }
 
        ihl = iph->ihl * 4;
@@ -247,6 +250,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
                break;
        }
 
+out:
        return action;
 
 drop:
index fdbd0b7bd840715c41626abfa74831ddcd9ef2fb..50e3d945e1f48a12b8a499aeb07d50f3d286017a 100644 (file)
@@ -125,7 +125,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
 {
        struct tcf_pedit *p = a->priv;
        int i, munged = 0;
-       u8 *pptr;
+       unsigned int off;
 
        if (!(skb->tc_verd & TC_OK2MUNGE)) {
                /* should we set skb->cloned? */
@@ -134,7 +134,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
                }
        }
 
-       pptr = skb_network_header(skb);
+       off = skb_network_offset(skb);
 
        spin_lock(&p->tcf_lock);
 
@@ -144,17 +144,17 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
                struct tc_pedit_key *tkey = p->tcfp_keys;
 
                for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
-                       u32 *ptr;
+                       u32 *ptr, _data;
                        int offset = tkey->off;
 
                        if (tkey->offmask) {
-                               if (skb->len > tkey->at) {
-                                        char *j = pptr + tkey->at;
-                                        offset += ((*j & tkey->offmask) >>
-                                                  tkey->shift);
-                               } else {
+                               char *d, _d;
+
+                               d = skb_header_pointer(skb, off + tkey->at, 1,
+                                                      &_d);
+                               if (!d)
                                        goto bad;
-                               }
+                               offset += (*d & tkey->offmask) >> tkey->shift;
                        }
 
                        if (offset % 4) {
@@ -169,9 +169,13 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
                                goto bad;
                        }
 
-                       ptr = (u32 *)(pptr+offset);
+                       ptr = skb_header_pointer(skb, off + offset, 4, &_data);
+                       if (!ptr)
+                               goto bad;
                        /* just do it, baby */
                        *ptr = ((*ptr & tkey->mask) ^ tkey->val);
+                       if (ptr == &_data)
+                               skb_store_bits(skb, off + offset, ptr, 4);
                        munged++;
                }
 
index 96275422c619e9d2a4e5eecd4fa8b433a526c8ab..4f522143811e467fe70e7e4b13db47f979b11b8a 100644 (file)
@@ -98,11 +98,11 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
 {
        struct {
                struct tc_u_knode *knode;
-               u8                *ptr;
+               unsigned int      off;
        } stack[TC_U32_MAXDEPTH];
 
        struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root;
-       u8 *ptr = skb_network_header(skb);
+       unsigned int off = skb_network_offset(skb);
        struct tc_u_knode *n;
        int sdepth = 0;
        int off2 = 0;
@@ -134,8 +134,14 @@ next_knode:
 #endif
 
                for (i = n->sel.nkeys; i>0; i--, key++) {
-
-                       if ((*(__be32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) {
+                       unsigned int toff;
+                       __be32 *data, _data;
+
+                       toff = off + key->off + (off2 & key->offmask);
+                       data = skb_header_pointer(skb, toff, 4, &_data);
+                       if (!data)
+                               goto out;
+                       if ((*data ^ key->val) & key->mask) {
                                n = n->next;
                                goto next_knode;
                        }
@@ -174,29 +180,45 @@ check_terminal:
                if (sdepth >= TC_U32_MAXDEPTH)
                        goto deadloop;
                stack[sdepth].knode = n;
-               stack[sdepth].ptr = ptr;
+               stack[sdepth].off = off;
                sdepth++;
 
                ht = n->ht_down;
                sel = 0;
-               if (ht->divisor)
-                       sel = ht->divisor&u32_hash_fold(*(__be32*)(ptr+n->sel.hoff), &n->sel,n->fshift);
-
+               if (ht->divisor) {
+                       __be32 *data, _data;
+
+                       data = skb_header_pointer(skb, off + n->sel.hoff, 4,
+                                                 &_data);
+                       if (!data)
+                               goto out;
+                       sel = ht->divisor & u32_hash_fold(*data, &n->sel,
+                                                         n->fshift);
+               }
                if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT)))
                        goto next_ht;
 
                if (n->sel.flags&(TC_U32_OFFSET|TC_U32_VAROFFSET)) {
                        off2 = n->sel.off + 3;
-                       if (n->sel.flags&TC_U32_VAROFFSET)
-                               off2 += ntohs(n->sel.offmask & *(__be16*)(ptr+n->sel.offoff)) >>n->sel.offshift;
+                       if (n->sel.flags & TC_U32_VAROFFSET) {
+                               __be16 *data, _data;
+
+                               data = skb_header_pointer(skb,
+                                                         off + n->sel.offoff,
+                                                         2, &_data);
+                               if (!data)
+                                       goto out;
+                               off2 += ntohs(n->sel.offmask & *data) >>
+                                       n->sel.offshift;
+                       }
                        off2 &= ~3;
                }
                if (n->sel.flags&TC_U32_EAT) {
-                       ptr += off2;
+                       off += off2;
                        off2 = 0;
                }
 
-               if (ptr < skb_tail_pointer(skb))
+               if (off < skb->len)
                        goto next_ht;
        }
 
@@ -204,9 +226,10 @@ check_terminal:
        if (sdepth--) {
                n = stack[sdepth].knode;
                ht = n->ht_up;
-               ptr = stack[sdepth].ptr;
+               off = stack[sdepth].off;
                goto check_terminal;
        }
+out:
        return -1;
 
 deadloop:
index 6a329158bdfaa14de3891194e0c98ae70f4f1834..a3cca0a94346319dec462ef7ef2fb7df2265945e 100644 (file)
@@ -95,13 +95,13 @@ resume:
                        goto error_nolock;
                }
 
-               dst = dst_pop(dst);
+               dst = skb_dst_pop(skb);
                if (!dst) {
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
                        err = -EHOSTUNREACH;
                        goto error_nolock;
                }
-               skb_dst_set(skb, dst);
+               skb_dst_set_noref(skb, dst);
                x = dst->xfrm;
        } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
index d965a2bad8d3b9cf993f72eaa372fb791642f3bc..4bf27d90133336a1f862e6c7b28e4939397284c5 100644 (file)
@@ -2153,6 +2153,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
                return 0;
        }
 
+       skb_dst_force(skb);
        dst = skb_dst(skb);
 
        res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0;