Merge branch 'tipc_net-next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg...
authorDavid S. Miller <davem@davemloft.net>
Fri, 23 Nov 2012 19:08:43 +0000 (14:08 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 23 Nov 2012 19:09:27 +0000 (14:09 -0500)
Paul Gortmaker says:

====================
The most interesting thing here, at least from a user perspective,
is the broadcast link fix -- where there was a corner case where
two endpoints could get in a state where they disagree on where
to start Rx and ack of broadcast packets.

There is also the poll/wait changes which could also impact
end users for certain use cases - the fixes there also better
align tipc with the rest of the networking code.

The rest largely falls into routine cleanup category, by getting
rid of some unused routines, some Kconfig clutter, etc.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
32 files changed:
Documentation/ABI/testing/sysfs-class-net-batman-adv
Documentation/ABI/testing/sysfs-class-net-mesh
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igb/igb_ptp.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
net/batman-adv/Kconfig
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/bridge_loop_avoidance.h
net/batman-adv/debugfs.c
net/batman-adv/main.c
net/batman-adv/main.h
net/batman-adv/packet.h
net/batman-adv/routing.c
net/batman-adv/send.c
net/batman-adv/send.h
net/batman-adv/translation-table.c
net/batman-adv/types.h
net/batman-adv/unicast.c
net/batman-adv/vis.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv6/tcp_ipv6.c
net/ipv6/xfrm6_policy.c
net/xfrm/xfrm_ipcomp.c
net/xfrm/xfrm_replay.c

index 38dd762def4b8fda48daf66800b93ce2666bd01d..bdc00707c751b955d997aa7ce0c51bd8b0222ca5 100644 (file)
@@ -1,4 +1,10 @@
 
+What:           /sys/class/net/<iface>/batman-adv/iface_status
+Date:           May 2010
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
+Description:
+                Indicates the status of <iface> as it is seen by batman.
+
 What:           /sys/class/net/<iface>/batman-adv/mesh_iface
 Date:           May 2010
 Contact:        Marek Lindner <lindner_marek@yahoo.de>
@@ -7,8 +13,3 @@ Description:
                 displays the batman mesh interface this <iface>
                 currently is associated with.
 
-What:           /sys/class/net/<iface>/batman-adv/iface_status
-Date:           May 2010
-Contact:        Marek Lindner <lindner_marek@yahoo.de>
-Description:
-                Indicates the status of <iface> as it is seen by batman.
index c81fe89c4c46d4f48e7e3bc8954d587bb9e6d69d..bc41da61608d5dfc22e0c2836aa00c56499c9d98 100644 (file)
@@ -6,6 +6,14 @@ Description:
                 Indicates whether the batman protocol messages of the
                 mesh <mesh_iface> shall be aggregated or not.
 
+What:           /sys/class/net/<mesh_iface>/mesh/ap_isolation
+Date:           May 2011
+Contact:        Antonio Quartulli <ordex@autistici.org>
+Description:
+                Indicates whether the data traffic going from a
+                wireless client to another wireless client will be
+                silently dropped.
+
 What:           /sys/class/net/<mesh_iface>/mesh/bonding
 Date:           June 2010
 Contact:        Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
@@ -31,14 +39,6 @@ Description:
                 mesh will be fragmented or silently discarded if the
                 packet size exceeds the outgoing interface MTU.
 
-What:          /sys/class/net/<mesh_iface>/mesh/ap_isolation
-Date:          May 2011
-Contact:       Antonio Quartulli <ordex@autistici.org>
-Description:
-               Indicates whether the data traffic going from a
-               wireless client to another wireless client will be
-               silently dropped.
-
 What:           /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
 Date:           October 2010
 Contact:        Marek Lindner <lindner_marek@yahoo.de>
@@ -60,6 +60,13 @@ Description:
                 Defines the selection criteria this node will use
                 to choose a gateway if gw_mode was set to 'client'.
 
+What:           /sys/class/net/<mesh_iface>/mesh/hop_penalty
+Date:           Oct 2010
+Contact:        Linus Lüssing <linus.luessing@web.de>
+Description:
+                Defines the penalty which will be applied to an
+                originator message's tq-field on every hop.
+
 What:           /sys/class/net/<mesh_iface>/mesh/orig_interval
 Date:           May 2010
 Contact:        Marek Lindner <lindner_marek@yahoo.de>
@@ -67,19 +74,12 @@ Description:
                 Defines the interval in milliseconds in which batman
                 sends its protocol messages.
 
-What:           /sys/class/net/<mesh_iface>/mesh/hop_penalty
-Date:           Oct 2010
-Contact:        Linus Lüssing <linus.luessing@web.de>
-Description:
-               Defines the penalty which will be applied to an
-               originator message's tq-field on every hop.
-
-What:          /sys/class/net/<mesh_iface>/mesh/routing_algo
-Date:          Dec 2011
-Contact:       Marek Lindner <lindner_marek@yahoo.de>
+What:           /sys/class/net/<mesh_iface>/mesh/routing_algo
+Date:           Dec 2011
+Contact:        Marek Lindner <lindner_marek@yahoo.de>
 Description:
-               Defines the routing procotol this mesh instance
-               uses to find the optimal paths through the mesh.
+                Defines the routing procotol this mesh instance
+                uses to find the optimal paths through the mesh.
 
 What:           /sys/class/net/<mesh_iface>/mesh/vis_mode
 Date:           May 2010
index d8fd5b63af9a86afe5ecae7971af4cdc3438856f..c15a4811b476294679458c0fff11592fc8149f7b 100644 (file)
@@ -370,8 +370,6 @@ struct igb_adapter {
        u32 eims_other;
 
        /* to not mess up cache alignment, always add to the bottom */
-       u32 eeprom_wol;
-
        u16 tx_ring_count;
        u16 rx_ring_count;
        unsigned int vfs_allocated_count;
@@ -401,6 +399,7 @@ struct igb_adapter {
 #define IGB_FLAG_PTP                   (1 << 5)
 #define IGB_FLAG_RSS_FIELD_IPV4_UDP    (1 << 6)
 #define IGB_FLAG_RSS_FIELD_IPV6_UDP    (1 << 7)
+#define IGB_FLAG_WOL_SUPPORTED         (1 << 8)
 
 /* DMA Coalescing defines */
 #define IGB_MIN_TXPBSIZE           20408
index 0acf590d4a83cdb1f96fe8de544ce17b1350cb1b..e2288b5a9caa9755b19bdc41cacce71fc12cead1 100644 (file)
@@ -1966,54 +1966,6 @@ static void igb_diag_test(struct net_device *netdev,
        msleep_interruptible(4 * 1000);
 }
 
-static int igb_wol_exclusion(struct igb_adapter *adapter,
-                            struct ethtool_wolinfo *wol)
-{
-       struct e1000_hw *hw = &adapter->hw;
-       int retval = 1; /* fail by default */
-
-       switch (hw->device_id) {
-       case E1000_DEV_ID_82575GB_QUAD_COPPER:
-               /* WoL not supported */
-               wol->supported = 0;
-               break;
-       case E1000_DEV_ID_82575EB_FIBER_SERDES:
-       case E1000_DEV_ID_82576_FIBER:
-       case E1000_DEV_ID_82576_SERDES:
-               /* Wake events not supported on port B */
-               if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1) {
-                       wol->supported = 0;
-                       break;
-               }
-               /* return success for non excluded adapter ports */
-               retval = 0;
-               break;
-       case E1000_DEV_ID_82576_QUAD_COPPER:
-       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
-               /* quad port adapters only support WoL on port A */
-               if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
-                       wol->supported = 0;
-                       break;
-               }
-               /* return success for non excluded adapter ports */
-               retval = 0;
-               break;
-       default:
-               /* dual port cards only support WoL on port A from now on
-                * unless it was enabled in the eeprom for port B
-                * so exclude FUNC_1 ports from having WoL enabled */
-               if ((rd32(E1000_STATUS) & E1000_STATUS_FUNC_MASK) &&
-                   !adapter->eeprom_wol) {
-                       wol->supported = 0;
-                       break;
-               }
-
-               retval = 0;
-       }
-
-       return retval;
-}
-
 static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
@@ -2023,10 +1975,7 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
                         WAKE_PHY;
        wol->wolopts = 0;
 
-       /* this function will set ->supported = 0 and return 1 if wol is not
-        * supported by this hardware */
-       if (igb_wol_exclusion(adapter, wol) ||
-           !device_can_wakeup(&adapter->pdev->dev))
+       if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
                return;
 
        /* apply any specific unsupported masks here */
@@ -2054,8 +2003,7 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
                return -EOPNOTSUPP;
 
-       if (igb_wol_exclusion(adapter, wol) ||
-           !device_can_wakeup(&adapter->pdev->dev))
+       if (!(adapter->flags & IGB_FLAG_WOL_SUPPORTED))
                return wol->wolopts ? -EOPNOTSUPP : 0;
 
        /* these settings will always override what we currently have */
index 7044aaadeca1edaacc6435aa07fd2a4dc2606c7f..0ce145e93545c5e102a95931ac5bdf2005ff23f9 100644 (file)
@@ -1837,7 +1837,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
        unsigned long mmio_start, mmio_len;
        int err, pci_using_dac;
-       u16 eeprom_apme_mask = IGB_EEPROM_APME;
        u8 part_str[E1000_PBANUM_LENGTH];
 
        /* Catch broken hardware that put the wrong VF device ID in
@@ -2045,28 +2044,27 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
        igb_validate_mdi_setting(hw);
 
-       /* Initial Wake on LAN setting If APM wake is enabled in the EEPROM,
-        * enable the ACPI Magic Packet filter
-        */
-
+       /* By default, support wake on port A */
        if (hw->bus.func == 0)
-               hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
-       else if (hw->mac.type >= e1000_82580)
+               adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
+
+       /* Check the NVM for wake support on non-port A ports */
+       if (hw->mac.type >= e1000_82580)
                hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
                                 NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
                                 &eeprom_data);
        else if (hw->bus.func == 1)
                hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
 
-       if (eeprom_data & eeprom_apme_mask)
-               adapter->eeprom_wol |= E1000_WUFC_MAG;
+       if (eeprom_data & IGB_EEPROM_APME)
+               adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
 
        /* now that we have the eeprom settings, apply the special cases where
         * the eeprom may be wrong or the board simply won't support wake on
         * lan on a particular port */
        switch (pdev->device) {
        case E1000_DEV_ID_82575GB_QUAD_COPPER:
-               adapter->eeprom_wol = 0;
+               adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
                break;
        case E1000_DEV_ID_82575EB_FIBER_SERDES:
        case E1000_DEV_ID_82576_FIBER:
@@ -2074,24 +2072,38 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                /* Wake events only supported on port A for dual fiber
                 * regardless of eeprom setting */
                if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
-                       adapter->eeprom_wol = 0;
+                       adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
        case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* if quad port adapter, disable WoL on all but port A */
                if (global_quad_port_a != 0)
-                       adapter->eeprom_wol = 0;
+                       adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
                else
                        adapter->flags |= IGB_FLAG_QUAD_PORT_A;
                /* Reset for multiple quad port adapters */
                if (++global_quad_port_a == 4)
                        global_quad_port_a = 0;
                break;
+       default:
+               /* If the device can't wake, don't set software support */
+               if (!device_can_wakeup(&adapter->pdev->dev))
+                       adapter->flags &= ~IGB_FLAG_WOL_SUPPORTED;
        }
 
        /* initialize the wol settings based on the eeprom settings */
-       adapter->wol = adapter->eeprom_wol;
-       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+       if (adapter->flags & IGB_FLAG_WOL_SUPPORTED)
+               adapter->wol |= E1000_WUFC_MAG;
+
+       /* Some vendors want WoL disabled by default, but still supported */
+       if ((hw->mac.type == e1000_i350) &&
+           (pdev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
+               adapter->flags |= IGB_FLAG_WOL_SUPPORTED;
+               adapter->wol = 0;
+       }
+
+       device_set_wakeup_enable(&adapter->pdev->dev,
+                                adapter->flags & IGB_FLAG_WOL_SUPPORTED);
 
        /* reset the hardware with the new settings */
        igb_reset(adapter);
@@ -6133,20 +6145,23 @@ static unsigned int igb_get_headlen(unsigned char *data,
                if (hlen < sizeof(struct iphdr))
                        return hdr.network - data;
 
-               /* record next protocol */
-               nexthdr = hdr.ipv4->protocol;
-               hdr.network += hlen;
+               /* record next protocol if header is present */
+               if (!hdr.ipv4->frag_off)
+                       nexthdr = hdr.ipv4->protocol;
        } else if (protocol == __constant_htons(ETH_P_IPV6)) {
                if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
                        return max_len;
 
                /* record next protocol */
                nexthdr = hdr.ipv6->nexthdr;
-               hdr.network += sizeof(struct ipv6hdr);
+               hlen = sizeof(struct ipv6hdr);
        } else {
                return hdr.network - data;
        }
 
+       /* relocate pointer to start of L4 header */
+       hdr.network += hlen;
+
        /* finally sort out TCP */
        if (nexthdr == IPPROTO_TCP) {
                if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
index aa10f69f9f1614330042c86e0b6f2b150296fca3..ab3429729bde4134a0310a6199cf9eb1737369b6 100644 (file)
@@ -553,18 +553,6 @@ int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
        case HWTSTAMP_FILTER_NONE:
                tsync_rx_ctl = 0;
                break;
-       case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
-       case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
-       case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
-       case HWTSTAMP_FILTER_ALL:
-               /*
-                * register TSYNCRXCFG must be set, therefore it is not
-                * possible to time stamp both Sync and Delay_Req messages
-                * => fall back to time stamping all packets
-                */
-               tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
-               config.rx_filter = HWTSTAMP_FILTER_ALL;
-               break;
        case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
                tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
                tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
@@ -575,31 +563,33 @@ int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
                tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
                is_l4 = true;
                break;
+       case HWTSTAMP_FILTER_PTP_V2_EVENT:
+       case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+       case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+       case HWTSTAMP_FILTER_PTP_V2_SYNC:
        case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
        case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
-               tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
-               tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
-               is_l2 = true;
-               is_l4 = true;
-               config.rx_filter = HWTSTAMP_FILTER_SOME;
-               break;
+       case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
        case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
        case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
-               tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
-               tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
-               is_l2 = true;
-               is_l4 = true;
-               config.rx_filter = HWTSTAMP_FILTER_SOME;
-               break;
-       case HWTSTAMP_FILTER_PTP_V2_EVENT:
-       case HWTSTAMP_FILTER_PTP_V2_SYNC:
-       case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
                tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
                config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
                is_l2 = true;
                is_l4 = true;
                break;
+       case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+       case HWTSTAMP_FILTER_ALL:
+               /* 82576 cannot timestamp all packets, which it needs to do to
+                * support both V1 Sync and Delay_Req messages
+                */
+               if (hw->mac.type != e1000_82576) {
+                       tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
+                       config.rx_filter = HWTSTAMP_FILTER_ALL;
+                       break;
+               }
+               /* fall through */
        default:
+               config.rx_filter = HWTSTAMP_FILTER_NONE;
                return -ERANGE;
        }
 
@@ -617,6 +607,9 @@ int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
        if ((hw->mac.type >= e1000_82580) && tsync_rx_ctl) {
                tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
                tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
+               config.rx_filter = HWTSTAMP_FILTER_ALL;
+               is_l2 = true;
+               is_l4 = true;
 
                if ((hw->mac.type == e1000_i210) ||
                    (hw->mac.type == e1000_i211)) {
index 8f285edb5094af4dc1db301444f62b46e003be5e..5af1eebc32f1a25fc79f7a8553a6696529a634ce 100644 (file)
@@ -65,13 +65,12 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
  *  function check the device id to see if the associated phy supports
  *  autoneg flow control.
  **/
-static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
+s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
 {
 
        switch (hw->device_id) {
        case IXGBE_DEV_ID_X540T:
        case IXGBE_DEV_ID_X540T1:
-               return 0;
        case IXGBE_DEV_ID_82599_T3_LOM:
                return 0;
        default:
index 587db4728072f94d241a4d53827630586f2a1bf1..1b65b6cc07bfcf44a555725bb1bb4a4a0c406dbd 100644 (file)
@@ -78,6 +78,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
 s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
+s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
 void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
index 8d3a218890993cb39887b904848403a3f4d547f7..efaf9a73cc79a534edd877dd724bace80ba3cf5b 100644 (file)
@@ -36,20 +36,6 @@ static struct dentry *ixgbe_dbg_root;
 
 static char ixgbe_dbg_reg_ops_buf[256] = "";
 
-/**
- * ixgbe_dbg_reg_ops_open - prep the debugfs pokee data item when opened
- * @inode: inode that was opened
- * @filp:  file info
- *
- * Stash the adapter pointer hiding in the inode into the file pointer where
- * we can find it later in the read and write calls
- **/
-static int ixgbe_dbg_reg_ops_open(struct inode *inode, struct file *filp)
-{
-       filp->private_data = inode->i_private;
-       return 0;
-}
-
 /**
  * ixgbe_dbg_reg_ops_read - read for reg_ops datum
  * @filp: the opened file
@@ -142,27 +128,13 @@ static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp,
 
 static const struct file_operations ixgbe_dbg_reg_ops_fops = {
        .owner = THIS_MODULE,
-       .open =  ixgbe_dbg_reg_ops_open,
+       .open = simple_open,
        .read =  ixgbe_dbg_reg_ops_read,
        .write = ixgbe_dbg_reg_ops_write,
 };
 
 static char ixgbe_dbg_netdev_ops_buf[256] = "";
 
-/**
- * ixgbe_dbg_netdev_ops_open - prep the debugfs netdev_ops data item
- * @inode: inode that was opened
- * @filp: file info
- *
- * Stash the adapter pointer hiding in the inode into the file pointer
- * where we can find it later in the read and write calls
- **/
-static int ixgbe_dbg_netdev_ops_open(struct inode *inode, struct file *filp)
-{
-       filp->private_data = inode->i_private;
-       return 0;
-}
-
 /**
  * ixgbe_dbg_netdev_ops_read - read for netdev_ops datum
  * @filp: the opened file
@@ -238,7 +210,7 @@ static ssize_t ixgbe_dbg_netdev_ops_write(struct file *filp,
 
 static const struct file_operations ixgbe_dbg_netdev_ops_fops = {
        .owner = THIS_MODULE,
-       .open = ixgbe_dbg_netdev_ops_open,
+       .open = simple_open,
        .read = ixgbe_dbg_netdev_ops_read,
        .write = ixgbe_dbg_netdev_ops_write,
 };
index a545728e100c6a5cd03027fbcc84732d99e70735..32685842434565e609a5f8589b67497609074aa4 100644 (file)
@@ -383,6 +383,11 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
            (adapter->flags & IXGBE_FLAG_DCB_ENABLED))
                return -EINVAL;
 
+       /* some devices do not support autoneg of link flow control */
+       if ((pause->autoneg == AUTONEG_ENABLE) &&
+           (ixgbe_device_supports_autoneg_fc(hw) != 0))
+               return -EINVAL;
+
        fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE);
 
        if ((pause->rx_pause && pause->tx_pause) || pause->autoneg)
index 38fc186c53c48b6a0a1b2b6157bd1da7583297cb..80e3cb7c39e82c13e5a465361e2d20ba238e90b5 100644 (file)
@@ -336,11 +336,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
                goto exit;
 
        dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
-       pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
+       pr_info(" %s     %s              %s        %s\n",
+               "Queue [NTU] [NTC] [bi(ntc)->dma  ]",
+               "leng", "ntw", "timestamp");
        for (n = 0; n < adapter->num_tx_queues; n++) {
                tx_ring = adapter->tx_ring[n];
                tx_buffer = &tx_ring->tx_buffer_info[tx_ring->next_to_clean];
-               pr_info(" %5d %5X %5X %016llX %04X %p %016llX\n",
+               pr_info(" %5d %5X %5X %016llX %08X %p %016llX\n",
                           n, tx_ring->next_to_use, tx_ring->next_to_clean,
                           (u64)dma_unmap_addr(tx_buffer, dma),
                           dma_unmap_len(tx_buffer, len),
@@ -394,40 +396,43 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
                pr_info("------------------------------------\n");
                pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index);
                pr_info("------------------------------------\n");
-               pr_info("T [desc]     [address 63:0  ] "
-                       "[PlPOIdStDDt Ln] [bi->dma       ] "
-                       "leng  ntw timestamp        bi->skb\n");
+               pr_info("%s%s    %s              %s        %s          %s\n",
+                       "T [desc]     [address 63:0  ] ",
+                       "[PlPOIdStDDt Ln] [bi->dma       ] ",
+                       "leng", "ntw", "timestamp", "bi->skb");
 
                for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
                        tx_desc = IXGBE_TX_DESC(tx_ring, i);
                        tx_buffer = &tx_ring->tx_buffer_info[i];
                        u0 = (struct my_u0 *)tx_desc;
-                       pr_info("T [0x%03X]    %016llX %016llX %016llX"
-                               " %04X  %p %016llX %p", i,
-                               le64_to_cpu(u0->a),
-                               le64_to_cpu(u0->b),
-                               (u64)dma_unmap_addr(tx_buffer, dma),
-                               dma_unmap_len(tx_buffer, len),
-                               tx_buffer->next_to_watch,
-                               (u64)tx_buffer->time_stamp,
-                               tx_buffer->skb);
-                       if (i == tx_ring->next_to_use &&
-                               i == tx_ring->next_to_clean)
-                               pr_cont(" NTC/U\n");
-                       else if (i == tx_ring->next_to_use)
-                               pr_cont(" NTU\n");
-                       else if (i == tx_ring->next_to_clean)
-                               pr_cont(" NTC\n");
-                       else
-                               pr_cont("\n");
-
-                       if (netif_msg_pktdata(adapter) &&
-                           tx_buffer->skb)
-                               print_hex_dump(KERN_INFO, "",
-                                       DUMP_PREFIX_ADDRESS, 16, 1,
-                                       tx_buffer->skb->data,
+                       if (dma_unmap_len(tx_buffer, len) > 0) {
+                               pr_info("T [0x%03X]    %016llX %016llX %016llX %08X %p %016llX %p",
+                                       i,
+                                       le64_to_cpu(u0->a),
+                                       le64_to_cpu(u0->b),
+                                       (u64)dma_unmap_addr(tx_buffer, dma),
                                        dma_unmap_len(tx_buffer, len),
-                                       true);
+                                       tx_buffer->next_to_watch,
+                                       (u64)tx_buffer->time_stamp,
+                                       tx_buffer->skb);
+                               if (i == tx_ring->next_to_use &&
+                                       i == tx_ring->next_to_clean)
+                                       pr_cont(" NTC/U\n");
+                               else if (i == tx_ring->next_to_use)
+                                       pr_cont(" NTU\n");
+                               else if (i == tx_ring->next_to_clean)
+                                       pr_cont(" NTC\n");
+                               else
+                                       pr_cont("\n");
+
+                               if (netif_msg_pktdata(adapter) &&
+                                   tx_buffer->skb)
+                                       print_hex_dump(KERN_INFO, "",
+                                               DUMP_PREFIX_ADDRESS, 16, 1,
+                                               tx_buffer->skb->data,
+                                               dma_unmap_len(tx_buffer, len),
+                                               true);
+                       }
                }
        }
 
@@ -497,11 +502,13 @@ rx_ring_summary:
                pr_info("------------------------------------\n");
                pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index);
                pr_info("------------------------------------\n");
-               pr_info("R  [desc]      [ PktBuf     A0] "
-                       "[  HeadBuf   DD] [bi->dma       ] [bi->skb] "
+               pr_info("%s%s%s",
+                       "R  [desc]      [ PktBuf     A0] ",
+                       "[  HeadBuf   DD] [bi->dma       ] [bi->skb       ] ",
                        "<-- Adv Rx Read format\n");
-               pr_info("RWB[desc]      [PcsmIpSHl PtRs] "
-                       "[vl er S cks ln] ---------------- [bi->skb] "
+               pr_info("%s%s%s",
+                       "RWB[desc]      [PcsmIpSHl PtRs] ",
+                       "[vl er S cks ln] ---------------- [bi->skb       ] ",
                        "<-- Adv Rx Write-Back format\n");
 
                for (i = 0; i < rx_ring->count; i++) {
@@ -4560,7 +4567,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
        ixgbe_pbthresh_setup(adapter);
        hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
        hw->fc.send_xon = true;
-       hw->fc.disable_fc_autoneg = false;
+       hw->fc.disable_fc_autoneg =
+               (ixgbe_device_supports_autoneg_fc(hw) == 0) ? false : true;
 
 #ifdef CONFIG_PCI_IOV
        /* assign number of SR-IOV VFs */
@@ -6946,7 +6954,10 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
        if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
                return -EOPNOTSUPP;
 
-       if (ndm->ndm_state & NUD_PERMANENT) {
+       /* Hardware does not support aging addresses so if a
+        * ndm_state is given only allow permanent addresses
+        */
+       if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
                pr_info("%s: FDB only supports static addresses\n",
                        ixgbe_driver_name);
                return -EINVAL;
index 01d99af0b9bad90816ac9ccb9dc9f85bc8002617..1a751c9d09c47f319e45d76a9c2bbad8573016d3 100644 (file)
@@ -633,8 +633,7 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
        struct hwtstamp_config config;
        u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
        u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
-       u32 tsync_rx_mtrl = 0;
-       bool is_l4 = false;
+       u32 tsync_rx_mtrl = PTP_EV_PORT << 16;
        bool is_l2 = false;
        u32 regval;
 
@@ -657,16 +656,15 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
        switch (config.rx_filter) {
        case HWTSTAMP_FILTER_NONE:
                tsync_rx_ctl = 0;
+               tsync_rx_mtrl = 0;
                break;
        case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
                tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
                tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG;
-               is_l4 = true;
                break;
        case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
                tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
                tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
-               is_l4 = true;
                break;
        case HWTSTAMP_FILTER_PTP_V2_EVENT:
        case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
@@ -679,7 +677,6 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
        case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
                tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
                is_l2 = true;
-               is_l4 = true;
                config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
                break;
        case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
@@ -704,42 +701,15 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
        /* Store filter value for later use */
        adapter->rx_hwtstamp_filter = config.rx_filter;
 
-       /* define ethertype filter for timestamped packets */
+       /* define ethertype filter for timestamping L2 packets */
        if (is_l2)
-               IXGBE_WRITE_REG(hw, IXGBE_ETQF(3),
+               IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588),
                                (IXGBE_ETQF_FILTER_EN | /* enable filter */
                                 IXGBE_ETQF_1588 | /* enable timestamping */
                                 ETH_P_1588));     /* 1588 eth protocol type */
        else
-               IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_1588), 0);
 
-#define PTP_PORT 319
-       /* L4 Queue Filter[3]: filter by destination port and protocol */
-       if (is_l4) {
-               u32 ftqf = (IXGBE_FTQF_PROTOCOL_UDP /* UDP */
-                           | IXGBE_FTQF_POOL_MASK_EN /* Pool not compared */
-                           | IXGBE_FTQF_QUEUE_ENABLE);
-
-               ftqf |= ((IXGBE_FTQF_PROTOCOL_COMP_MASK /* protocol check */
-                         & IXGBE_FTQF_DEST_PORT_MASK /* dest check */
-                         & IXGBE_FTQF_SOURCE_PORT_MASK) /* source check */
-                        << IXGBE_FTQF_5TUPLE_MASK_SHIFT);
-
-               IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(3),
-                               (3 << IXGBE_IMIR_RX_QUEUE_SHIFT_82599 |
-                                IXGBE_IMIR_SIZE_BP_82599));
-
-               /* enable port check */
-               IXGBE_WRITE_REG(hw, IXGBE_SDPQF(3),
-                               (htons(PTP_PORT) |
-                                htons(PTP_PORT) << 16));
-
-               IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), ftqf);
-
-               tsync_rx_mtrl |= PTP_PORT << 16;
-       } else {
-               IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), 0);
-       }
 
        /* enable/disable TX */
        regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
index 250e0b58109c70544e0599140a9ad72a2f15b719..8d8afb134b3ac016799be9ab43d6fe45f40962bb 100644 (file)
@@ -6,6 +6,7 @@ config BATMAN_ADV
        tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
        depends on NET
        select CRC16
+       select LIBCRC32C
         default n
        help
           B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
index bda8b1710806eef8493956748674a2e0e8ce7a3b..5aebe9327d68c8fd691243f78880c12d69951611 100644 (file)
@@ -77,8 +77,15 @@ static int batadv_compare_backbone_gw(const struct hlist_node *node,
 {
        const void *data1 = container_of(node, struct batadv_backbone_gw,
                                         hash_entry);
+       const struct batadv_backbone_gw *gw1 = data1, *gw2 = data2;
 
-       return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
+       if (!batadv_compare_eth(gw1->orig, gw2->orig))
+               return 0;
+
+       if (gw1->vid != gw2->vid)
+               return 0;
+
+       return 1;
 }
 
 /* compares address and vid of two claims */
@@ -87,8 +94,15 @@ static int batadv_compare_claim(const struct hlist_node *node,
 {
        const void *data1 = container_of(node, struct batadv_claim,
                                         hash_entry);
+       const struct batadv_claim *cl1 = data1, *cl2 = data2;
 
-       return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
+       if (!batadv_compare_eth(cl1->addr, cl2->addr))
+               return 0;
+
+       if (cl1->vid != cl2->vid)
+               return 0;
+
+       return 1;
 }
 
 /* free a backbone gw */
@@ -1235,8 +1249,7 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
 /**
  * batadv_bla_check_bcast_duplist
  * @bat_priv: the bat priv with all the soft interface information
- * @bcast_packet: encapsulated broadcast frame plus batman header
- * @bcast_packet_len: length of encapsulated broadcast frame plus batman header
+ * @skb: contains the bcast_packet to be checked
  *
  * check if it is on our broadcast list. Another gateway might
  * have sent the same packet because it is connected to the same backbone,
@@ -1248,20 +1261,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
  * the same host however as this might be intended.
  */
 int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
-                                  struct batadv_bcast_packet *bcast_packet,
-                                  int bcast_packet_len)
+                                  struct sk_buff *skb)
 {
-       int i, length, curr, ret = 0;
-       uint8_t *content;
-       uint16_t crc;
+       int i, curr, ret = 0;
+       __be32 crc;
+       struct batadv_bcast_packet *bcast_packet;
        struct batadv_bcast_duplist_entry *entry;
 
-       length = bcast_packet_len - sizeof(*bcast_packet);
-       content = (uint8_t *)bcast_packet;
-       content += sizeof(*bcast_packet);
+       bcast_packet = (struct batadv_bcast_packet *)skb->data;
 
        /* calculate the crc ... */
-       crc = crc16(0, content, length);
+       crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
 
        spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
 
index 789cb73bde67acf8f19375d67e8c0ec2322f509f..196d9a0254bcbc6820c5f60f3c53a63638b683c9 100644 (file)
@@ -31,8 +31,7 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
                                             void *offset);
 int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig);
 int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
-                                  struct batadv_bcast_packet *bcast_packet,
-                                  int hdr_size);
+                                  struct sk_buff *skb);
 void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
                                    struct batadv_hard_iface *primary_if,
                                    struct batadv_hard_iface *oldif);
@@ -81,8 +80,7 @@ static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv,
 
 static inline int
 batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
-                              struct batadv_bcast_packet *bcast_packet,
-                              int hdr_size)
+                              struct sk_buff *skb)
 {
        return 0;
 }
index 3f679cb2d0e275de8cd62e050753d21677ece4c1..6f58ddd53bff8d2752c7a59dda1c20e40ec428e0 100644 (file)
@@ -323,7 +323,17 @@ struct batadv_debuginfo batadv_debuginfo_##_name = {       \
                }                                       \
 };
 
+/* the following attributes are general and therefore they will be directly
+ * placed in the BATADV_DEBUGFS_SUBDIR subdirectory of debugfs
+ */
 static BATADV_DEBUGINFO(routing_algos, S_IRUGO, batadv_algorithms_open);
+
+static struct batadv_debuginfo *batadv_general_debuginfos[] = {
+       &batadv_debuginfo_routing_algos,
+       NULL,
+};
+
+/* The following attributes are per soft interface */
 static BATADV_DEBUGINFO(originators, S_IRUGO, batadv_originators_open);
 static BATADV_DEBUGINFO(gateways, S_IRUGO, batadv_gateways_open);
 static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
@@ -358,7 +368,7 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
 
 void batadv_debugfs_init(void)
 {
-       struct batadv_debuginfo *bat_debug;
+       struct batadv_debuginfo **bat_debug;
        struct dentry *file;
 
        batadv_debugfs = debugfs_create_dir(BATADV_DEBUGFS_SUBDIR, NULL);
@@ -366,17 +376,23 @@ void batadv_debugfs_init(void)
                batadv_debugfs = NULL;
 
        if (!batadv_debugfs)
-               goto out;
+               goto err;
 
-       bat_debug = &batadv_debuginfo_routing_algos;
-       file = debugfs_create_file(bat_debug->attr.name,
-                                  S_IFREG | bat_debug->attr.mode,
-                                  batadv_debugfs, NULL, &bat_debug->fops);
-       if (!file)
-               pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name);
+       for (bat_debug = batadv_general_debuginfos; *bat_debug; ++bat_debug) {
+               file = debugfs_create_file(((*bat_debug)->attr).name,
+                                          S_IFREG | ((*bat_debug)->attr).mode,
+                                          batadv_debugfs, NULL,
+                                          &(*bat_debug)->fops);
+               if (!file) {
+                       pr_err("Can't add general debugfs file: %s\n",
+                              ((*bat_debug)->attr).name);
+                       goto err;
+               }
+       }
 
-out:
        return;
+err:
+       debugfs_remove_recursive(batadv_debugfs);
 }
 
 void batadv_debugfs_destroy(void)
index dc33a0c484a4e180f99468f4dec8c2ac2c2d07b6..f65a222b7b83c0d691f859f2eef1ea189ac84e2c 100644 (file)
@@ -17,6 +17,8 @@
  * 02110-1301, USA
  */
 
+#include <linux/crc32c.h>
+#include <linux/highmem.h>
 #include "main.h"
 #include "sysfs.h"
 #include "debugfs.h"
@@ -420,6 +422,38 @@ int batadv_algo_seq_print_text(struct seq_file *seq, void *offset)
        return 0;
 }
 
+/**
+ * batadv_skb_crc32 - calculate CRC32 of the whole packet and skip bytes in
+ *  the header
+ * @skb: skb pointing to fragmented socket buffers
+ * @payload_ptr: Pointer to position inside the head buffer of the skb
+ *  marking the start of the data to be CRC'ed
+ *
+ * payload_ptr must always point to an address in the skb head buffer and not to
+ * a fragment.
+ */
+__be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr)
+{
+       u32 crc = 0;
+       unsigned int from;
+       unsigned int to = skb->len;
+       struct skb_seq_state st;
+       const u8 *data;
+       unsigned int len;
+       unsigned int consumed = 0;
+
+       from = (unsigned int)(payload_ptr - skb->data);
+
+       skb_prepare_seq_read(skb, from, to, &st);
+       while ((len = skb_seq_read(consumed, &data, &st)) != 0) {
+               crc = crc32c(crc, data, len);
+               consumed += len;
+       }
+       skb_abort_seq_read(&st);
+
+       return htonl(crc);
+}
+
 static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
 {
        struct batadv_algo_ops *bat_algo_ops;
index 8f149bb66817231906029bcb527d73e840da599e..2f85577086a7cf923c6185f84f6efeb3bfb5fe84 100644 (file)
@@ -26,7 +26,7 @@
 #define BATADV_DRIVER_DEVICE "batman-adv"
 
 #ifndef BATADV_SOURCE_VERSION
-#define BATADV_SOURCE_VERSION "2012.4.0"
+#define BATADV_SOURCE_VERSION "2012.5.0"
 #endif
 
 /* B.A.T.M.A.N. parameters */
@@ -174,6 +174,7 @@ void batadv_recv_handler_unregister(uint8_t packet_type);
 int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
 int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
 int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
+__be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
 
 /**
  * enum batadv_dbg_level - available log levels
index df548ed196d37e5f5e325cd0becfd4818f876b23..1c5454d33f67425c69636160c5bf1182608c75e9 100644 (file)
@@ -173,6 +173,18 @@ struct batadv_icmp_packet_rr {
        uint8_t  rr[BATADV_RR_LEN][ETH_ALEN];
 };
 
+/* All packet headers in front of an ethernet header have to be completely
+ * divisible by 2 but not by 4 to make the payload after the ethernet
+ * header again 4 bytes boundary aligned.
+ *
+ * A packing of 2 is necessary to avoid extra padding at the end of the struct
+ * caused by a structure member which is larger than two bytes. Otherwise
+ * the structure would not fulfill the previously mentioned rule to avoid the
+ * misalignment of the payload after the ethernet header. It may also lead to
+ * leakage of information when the padding it not initialized before sending.
+ */
+#pragma pack(2)
+
 struct batadv_unicast_packet {
        struct batadv_header header;
        uint8_t  ttvn; /* destination translation table version number */
@@ -216,7 +228,9 @@ struct batadv_bcast_packet {
        /* "4 bytes boundary + 2 bytes" long to make the payload after the
         * following ethernet header again 4 bytes boundary aligned
         */
-} __packed;
+};
+
+#pragma pack()
 
 struct batadv_vis_packet {
        struct batadv_header header;
index 78d657264cbfe6227a5b2a2f2c0096a0b4aff55d..1aa1722d01870d69738f6be60a7e7868882cab88 100644 (file)
@@ -285,7 +285,6 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 {
        struct batadv_hard_iface *primary_if = NULL;
        struct batadv_orig_node *orig_node = NULL;
-       struct batadv_neigh_node *router = NULL;
        struct batadv_icmp_packet_rr *icmp_packet;
        int ret = NET_RX_DROP;
 
@@ -307,10 +306,6 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
        if (!orig_node)
                goto out;
 
-       router = batadv_orig_node_get_router(orig_node);
-       if (!router)
-               goto out;
-
        /* create a copy of the skb, if needed, to modify it. */
        if (skb_cow(skb, ETH_HLEN) < 0)
                goto out;
@@ -322,14 +317,12 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
        icmp_packet->msg_type = BATADV_ECHO_REPLY;
        icmp_packet->header.ttl = BATADV_TTL;
 
-       batadv_send_skb_packet(skb, router->if_incoming, router->addr);
-       ret = NET_RX_SUCCESS;
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+               ret = NET_RX_SUCCESS;
 
 out:
        if (primary_if)
                batadv_hardif_free_ref(primary_if);
-       if (router)
-               batadv_neigh_node_free_ref(router);
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
        return ret;
@@ -340,7 +333,6 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
 {
        struct batadv_hard_iface *primary_if = NULL;
        struct batadv_orig_node *orig_node = NULL;
-       struct batadv_neigh_node *router = NULL;
        struct batadv_icmp_packet *icmp_packet;
        int ret = NET_RX_DROP;
 
@@ -362,10 +354,6 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
        if (!orig_node)
                goto out;
 
-       router = batadv_orig_node_get_router(orig_node);
-       if (!router)
-               goto out;
-
        /* create a copy of the skb, if needed, to modify it. */
        if (skb_cow(skb, ETH_HLEN) < 0)
                goto out;
@@ -377,14 +365,12 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
        icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
        icmp_packet->header.ttl = BATADV_TTL;
 
-       batadv_send_skb_packet(skb, router->if_incoming, router->addr);
-       ret = NET_RX_SUCCESS;
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+               ret = NET_RX_SUCCESS;
 
 out:
        if (primary_if)
                batadv_hardif_free_ref(primary_if);
-       if (router)
-               batadv_neigh_node_free_ref(router);
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
        return ret;
@@ -398,7 +384,6 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        struct batadv_icmp_packet_rr *icmp_packet;
        struct ethhdr *ethhdr;
        struct batadv_orig_node *orig_node = NULL;
-       struct batadv_neigh_node *router = NULL;
        int hdr_size = sizeof(struct batadv_icmp_packet);
        int ret = NET_RX_DROP;
 
@@ -447,10 +432,6 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        if (!orig_node)
                goto out;
 
-       router = batadv_orig_node_get_router(orig_node);
-       if (!router)
-               goto out;
-
        /* create a copy of the skb, if needed, to modify it. */
        if (skb_cow(skb, ETH_HLEN) < 0)
                goto out;
@@ -461,12 +442,10 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
        icmp_packet->header.ttl--;
 
        /* route it */
-       batadv_send_skb_packet(skb, router->if_incoming, router->addr);
-       ret = NET_RX_SUCCESS;
+       if (batadv_send_skb_to_orig(skb, orig_node, recv_if))
+               ret = NET_RX_SUCCESS;
 
 out:
-       if (router)
-               batadv_neigh_node_free_ref(router);
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
        return ret;
@@ -882,8 +861,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
                           skb->len + ETH_HLEN);
 
        /* route it */
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-       ret = NET_RX_SUCCESS;
+       if (batadv_send_skb_to_orig(skb, orig_node, recv_if))
+               ret = NET_RX_SUCCESS;
 
 out:
        if (neigh_node)
@@ -1217,14 +1196,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
 
        spin_unlock_bh(&orig_node->bcast_seqno_lock);
 
-       /* keep skb linear for crc calculation */
-       if (skb_linearize(skb) < 0)
-               goto out;
-
-       bcast_packet = (struct batadv_bcast_packet *)skb->data;
-
        /* check whether this has been sent by another originator before */
-       if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len))
+       if (batadv_bla_check_bcast_duplist(bat_priv, skb))
                goto out;
 
        /* rebroadcast packet */
index 660d9bf7d219ee3714585059dfe29ddeecdf7301..c7f702376535c32d9de6a01c1e58300668043336 100644 (file)
@@ -78,6 +78,39 @@ send_skb_err:
        return NET_XMIT_DROP;
 }
 
+/**
+ * batadv_send_skb_to_orig - Lookup next-hop and transmit skb.
+ * @skb: Packet to be transmitted.
+ * @orig_node: Final destination of the packet.
+ * @recv_if: Interface used when receiving the packet (can be NULL).
+ *
+ * Looks up the best next-hop towards the passed originator and passes the
+ * skb on for preparation of MAC header. If the packet originated from this
+ * host, NULL can be passed as recv_if and no interface alternating is
+ * attempted.
+ *
+ * Returns TRUE on success; FALSE otherwise.
+ */
+bool batadv_send_skb_to_orig(struct sk_buff *skb,
+                            struct batadv_orig_node *orig_node,
+                            struct batadv_hard_iface *recv_if)
+{
+       struct batadv_priv *bat_priv = orig_node->bat_priv;
+       struct batadv_neigh_node *neigh_node;
+
+       /* batadv_find_router() increases neigh_nodes refcount if found. */
+       neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
+       if (!neigh_node)
+               return false;
+
+       /* route it */
+       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
+
+       batadv_neigh_node_free_ref(neigh_node);
+
+       return true;
+}
+
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
 {
        struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
index 643329b787ed125102beb687ad1f18c1b4a0ca8e..0078dece1abcd4cf6784b59cf5441ac150424330 100644 (file)
@@ -23,6 +23,9 @@
 int batadv_send_skb_packet(struct sk_buff *skb,
                           struct batadv_hard_iface *hard_iface,
                           const uint8_t *dst_addr);
+bool batadv_send_skb_to_orig(struct sk_buff *skb,
+                            struct batadv_orig_node *orig_node,
+                            struct batadv_hard_iface *recv_if);
 void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
 int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
                                    const struct sk_buff *skb,
index 582f13405df9286bc752b633ed61a3b9244d545f..22457a7952baae3fc85c3ce43bd14bbeb5acf068 100644 (file)
@@ -911,8 +911,44 @@ out:
        return ret;
 }
 
-/* print all orig nodes who announce the address for this global entry.
- * it is assumed that the caller holds rcu_read_lock();
+/* batadv_transtable_best_orig - Get best originator list entry from tt entry
+ * @tt_global_entry: global translation table entry to be analyzed
+ *
+ * This functon assumes the caller holds rcu_read_lock().
+ * Returns best originator list entry or NULL on errors.
+ */
+static struct batadv_tt_orig_list_entry *
+batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
+{
+       struct batadv_neigh_node *router = NULL;
+       struct hlist_head *head;
+       struct hlist_node *node;
+       struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
+       int best_tq = 0;
+
+       head = &tt_global_entry->orig_list;
+       hlist_for_each_entry_rcu(orig_entry, node, head, list) {
+               router = batadv_orig_node_get_router(orig_entry->orig_node);
+               if (!router)
+                       continue;
+
+               if (router->tq_avg > best_tq) {
+                       best_entry = orig_entry;
+                       best_tq = router->tq_avg;
+               }
+
+               batadv_neigh_node_free_ref(router);
+       }
+
+       return best_entry;
+}
+
+/* batadv_tt_global_print_entry - print all orig nodes who announce the address
+ * for this global entry
+ * @tt_global_entry: global translation table entry to be printed
+ * @seq: debugfs table seq_file struct
+ *
+ * This functon assumes the caller holds rcu_read_lock().
  */
 static void
 batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
@@ -920,21 +956,37 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
 {
        struct hlist_head *head;
        struct hlist_node *node;
-       struct batadv_tt_orig_list_entry *orig_entry;
+       struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
        struct batadv_tt_common_entry *tt_common_entry;
        uint16_t flags;
        uint8_t last_ttvn;
 
        tt_common_entry = &tt_global_entry->common;
+       flags = tt_common_entry->flags;
+
+       best_entry = batadv_transtable_best_orig(tt_global_entry);
+       if (best_entry) {
+               last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
+               seq_printf(seq, " %c %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
+                          '*', tt_global_entry->common.addr,
+                          best_entry->ttvn, best_entry->orig_node->orig,
+                          last_ttvn,
+                          (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
+                          (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
+                          (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
+       }
 
        head = &tt_global_entry->orig_list;
 
        hlist_for_each_entry_rcu(orig_entry, node, head, list) {
-               flags = tt_common_entry->flags;
+               if (best_entry == orig_entry)
+                       continue;
+
                last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
-               seq_printf(seq, " * %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
-                          tt_global_entry->common.addr, orig_entry->ttvn,
-                          orig_entry->orig_node->orig, last_ttvn,
+               seq_printf(seq, " %c %pM  (%3u) via %pM     (%3u)   [%c%c%c]\n",
+                          '+', tt_global_entry->common.addr,
+                          orig_entry->ttvn, orig_entry->orig_node->orig,
+                          last_ttvn,
                           (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
                           (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
                           (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
@@ -1280,11 +1332,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
        struct batadv_tt_local_entry *tt_local_entry = NULL;
        struct batadv_tt_global_entry *tt_global_entry = NULL;
        struct batadv_orig_node *orig_node = NULL;
-       struct batadv_neigh_node *router = NULL;
-       struct hlist_head *head;
-       struct hlist_node *node;
-       struct batadv_tt_orig_list_entry *orig_entry;
-       int best_tq;
+       struct batadv_tt_orig_list_entry *best_entry;
 
        if (src && atomic_read(&bat_priv->ap_isolation)) {
                tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
@@ -1304,25 +1352,15 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
            _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
                goto out;
 
-       best_tq = 0;
-
        rcu_read_lock();
-       head = &tt_global_entry->orig_list;
-       hlist_for_each_entry_rcu(orig_entry, node, head, list) {
-               router = batadv_orig_node_get_router(orig_entry->orig_node);
-               if (!router)
-                       continue;
-
-               if (router->tq_avg > best_tq) {
-                       orig_node = orig_entry->orig_node;
-                       best_tq = router->tq_avg;
-               }
-               batadv_neigh_node_free_ref(router);
-       }
+       best_entry = batadv_transtable_best_orig(tt_global_entry);
        /* found anything? */
+       if (best_entry)
+               orig_node = best_entry->orig_node;
        if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
                orig_node = NULL;
        rcu_read_unlock();
+
 out:
        if (tt_global_entry)
                batadv_tt_global_entry_free_ref(tt_global_entry);
@@ -1604,7 +1642,6 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
 {
        struct sk_buff *skb = NULL;
        struct batadv_tt_query_packet *tt_request;
-       struct batadv_neigh_node *neigh_node = NULL;
        struct batadv_hard_iface *primary_if;
        struct batadv_tt_req_node *tt_req_node = NULL;
        int ret = 1;
@@ -1642,23 +1679,15 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
        if (full_table)
                tt_request->flags |= BATADV_TT_FULL_TABLE;
 
-       neigh_node = batadv_orig_node_get_router(dst_orig_node);
-       if (!neigh_node)
-               goto out;
-
-       batadv_dbg(BATADV_DBG_TT, bat_priv,
-                  "Sending TT_REQUEST to %pM via %pM [%c]\n",
-                  dst_orig_node->orig, neigh_node->addr,
-                  (full_table ? 'F' : '.'));
+       batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
+                  dst_orig_node->orig, (full_table ? 'F' : '.'));
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
 
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-       ret = 0;
+       if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL))
+               ret = 0;
 
 out:
-       if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
        if (primary_if)
                batadv_hardif_free_ref(primary_if);
        if (ret)
@@ -1678,7 +1707,6 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
 {
        struct batadv_orig_node *req_dst_orig_node;
        struct batadv_orig_node *res_dst_orig_node = NULL;
-       struct batadv_neigh_node *neigh_node = NULL;
        struct batadv_hard_iface *primary_if = NULL;
        uint8_t orig_ttvn, req_ttvn, ttvn;
        int ret = false;
@@ -1704,10 +1732,6 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
        if (!res_dst_orig_node)
                goto out;
 
-       neigh_node = batadv_orig_node_get_router(res_dst_orig_node);
-       if (!neigh_node)
-               goto out;
-
        primary_if = batadv_primary_if_get_selected(bat_priv);
        if (!primary_if)
                goto out;
@@ -1779,14 +1803,13 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
                tt_response->flags |= BATADV_TT_FULL_TABLE;
 
        batadv_dbg(BATADV_DBG_TT, bat_priv,
-                  "Sending TT_RESPONSE %pM via %pM for %pM (ttvn: %u)\n",
-                  res_dst_orig_node->orig, neigh_node->addr,
-                  req_dst_orig_node->orig, req_ttvn);
+                  "Sending TT_RESPONSE %pM for %pM (ttvn: %u)\n",
+                  res_dst_orig_node->orig, req_dst_orig_node->orig, req_ttvn);
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
 
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-       ret = true;
+       if (batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL))
+               ret = true;
        goto out;
 
 unlock:
@@ -1797,8 +1820,6 @@ out:
                batadv_orig_node_free_ref(res_dst_orig_node);
        if (req_dst_orig_node)
                batadv_orig_node_free_ref(req_dst_orig_node);
-       if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
        if (primary_if)
                batadv_hardif_free_ref(primary_if);
        if (!ret)
@@ -1812,7 +1833,6 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
                           struct batadv_tt_query_packet *tt_request)
 {
        struct batadv_orig_node *orig_node;
-       struct batadv_neigh_node *neigh_node = NULL;
        struct batadv_hard_iface *primary_if = NULL;
        uint8_t my_ttvn, req_ttvn, ttvn;
        int ret = false;
@@ -1837,10 +1857,6 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
        if (!orig_node)
                goto out;
 
-       neigh_node = batadv_orig_node_get_router(orig_node);
-       if (!neigh_node)
-               goto out;
-
        primary_if = batadv_primary_if_get_selected(bat_priv);
        if (!primary_if)
                goto out;
@@ -1904,14 +1920,14 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
                tt_response->flags |= BATADV_TT_FULL_TABLE;
 
        batadv_dbg(BATADV_DBG_TT, bat_priv,
-                  "Sending TT_RESPONSE to %pM via %pM [%c]\n",
-                  orig_node->orig, neigh_node->addr,
+                  "Sending TT_RESPONSE to %pM [%c]\n",
+                  orig_node->orig,
                   (tt_response->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
 
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-       ret = true;
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+               ret = true;
        goto out;
 
 unlock:
@@ -1919,8 +1935,6 @@ unlock:
 out:
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
-       if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
        if (primary_if)
                batadv_hardif_free_ref(primary_if);
        if (!ret)
@@ -2185,7 +2199,6 @@ unlock:
 static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
                                 struct batadv_orig_node *orig_node)
 {
-       struct batadv_neigh_node *neigh_node = NULL;
        struct sk_buff *skb = NULL;
        struct batadv_roam_adv_packet *roam_adv_packet;
        int ret = 1;
@@ -2218,23 +2231,17 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
        memcpy(roam_adv_packet->dst, orig_node->orig, ETH_ALEN);
        memcpy(roam_adv_packet->client, client, ETH_ALEN);
 
-       neigh_node = batadv_orig_node_get_router(orig_node);
-       if (!neigh_node)
-               goto out;
-
        batadv_dbg(BATADV_DBG_TT, bat_priv,
-                  "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
-                  orig_node->orig, client, neigh_node->addr);
+                  "Sending ROAMING_ADV to %pM (client %pM)\n",
+                  orig_node->orig, client);
 
        batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
 
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-       ret = 0;
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+               ret = 0;
 
 out:
-       if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
-       if (ret)
+       if (ret && skb)
                kfree_skb(skb);
        return;
 }
index 7b3d0d7ef06a779f31614371346a2632746b0ae1..ae9ac9aca8c53d5ffd93b015cb6ff779f55c86fe 100644 (file)
@@ -156,7 +156,7 @@ struct batadv_neigh_node {
 #ifdef CONFIG_BATMAN_ADV_BLA
 struct batadv_bcast_duplist_entry {
        uint8_t orig[ETH_ALEN];
-       uint16_t crc;
+       __be32 crc;
        unsigned long entrytime;
 };
 #endif
index c9a1f6523c36e10b93977299f77b4542bcdd3347..10aff49fcf25adb106cefb020309e456d8f04a2f 100644 (file)
@@ -402,7 +402,7 @@ int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
        struct batadv_orig_node *orig_node;
        struct batadv_neigh_node *neigh_node;
        int data_len = skb->len;
-       int ret = 1;
+       int ret = NET_RX_DROP;
        unsigned int dev_mtu;
 
        /* get routing information */
@@ -466,15 +466,15 @@ find_router:
                goto out;
        }
 
-       batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
-       ret = 0;
+       if (batadv_send_skb_to_orig(skb, orig_node, NULL))
+               ret = 0;
 
 out:
        if (neigh_node)
                batadv_neigh_node_free_ref(neigh_node);
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
-       if (ret == 1)
+       if (ret == NET_RX_DROP)
                kfree_skb(skb);
        return ret;
 }
index ad14a6c91d6ad362be83fb749acefd84a9351a5e..0f65a9de5f749719b9b778cd8c989680b0b1eb4d 100644 (file)
@@ -698,15 +698,12 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
 static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
                                        struct batadv_vis_info *info)
 {
-       struct batadv_neigh_node *router;
        struct batadv_hashtable *hash = bat_priv->orig_hash;
        struct hlist_node *node;
        struct hlist_head *head;
        struct batadv_orig_node *orig_node;
        struct batadv_vis_packet *packet;
        struct sk_buff *skb;
-       struct batadv_hard_iface *hard_iface;
-       uint8_t dstaddr[ETH_ALEN];
        uint32_t i;
 
 
@@ -722,30 +719,20 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
                        if (!(orig_node->flags & BATADV_VIS_SERVER))
                                continue;
 
-                       router = batadv_orig_node_get_router(orig_node);
-                       if (!router)
-                               continue;
-
                        /* don't send it if we already received the packet from
                         * this node.
                         */
                        if (batadv_recv_list_is_in(bat_priv, &info->recv_list,
-                                                  orig_node->orig)) {
-                               batadv_neigh_node_free_ref(router);
+                                                  orig_node->orig))
                                continue;
-                       }
 
                        memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
-                       hard_iface = router->if_incoming;
-                       memcpy(dstaddr, router->addr, ETH_ALEN);
-
-                       batadv_neigh_node_free_ref(router);
-
                        skb = skb_clone(info->skb_packet, GFP_ATOMIC);
-                       if (skb)
-                               batadv_send_skb_packet(skb, hard_iface,
-                                                      dstaddr);
+                       if (!skb)
+                               continue;
 
+                       if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
+                               kfree_skb(skb);
                }
                rcu_read_unlock();
        }
@@ -755,7 +742,6 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
                                      struct batadv_vis_info *info)
 {
        struct batadv_orig_node *orig_node;
-       struct batadv_neigh_node *router = NULL;
        struct sk_buff *skb;
        struct batadv_vis_packet *packet;
 
@@ -765,17 +751,14 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
        if (!orig_node)
                goto out;
 
-       router = batadv_orig_node_get_router(orig_node);
-       if (!router)
+       skb = skb_clone(info->skb_packet, GFP_ATOMIC);
+       if (!skb)
                goto out;
 
-       skb = skb_clone(info->skb_packet, GFP_ATOMIC);
-       if (skb)
-               batadv_send_skb_packet(skb, router->if_incoming, router->addr);
+       if (!batadv_send_skb_to_orig(skb, orig_node, NULL))
+               kfree_skb(skb);
 
 out:
-       if (router)
-               batadv_neigh_node_free_ref(router);
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
 }
index 9dd5b34eb112aa4b4ad69fe36a141a6e612ed0c8..1ed230716d51baa64501e5c6354ec5e50ff20048 100644 (file)
@@ -138,14 +138,6 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
 }
 EXPORT_SYMBOL_GPL(tcp_twsk_unique);
 
-static int tcp_repair_connect(struct sock *sk)
-{
-       tcp_connect_init(sk);
-       tcp_finish_connect(sk, NULL);
-
-       return 0;
-}
-
 /* This will initiate an outgoing connection. */
 int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
@@ -250,10 +242,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 
        inet->inet_id = tp->write_seq ^ jiffies;
 
-       if (likely(!tp->repair))
-               err = tcp_connect(sk);
-       else
-               err = tcp_repair_connect(sk);
+       err = tcp_connect(sk);
 
        rt = NULL;
        if (err)
index 2798706cb06385aa87fdb05ba1ed2c6a0a14e6e5..8ac085573217b32cc2cc74e3b77408c607db971e 100644 (file)
@@ -2987,6 +2987,11 @@ int tcp_connect(struct sock *sk)
 
        tcp_connect_init(sk);
 
+       if (unlikely(tp->repair)) {
+               tcp_finish_connect(sk, NULL);
+               return 0;
+       }
+
        buff = alloc_skb_fclone(MAX_TCP_HEADER + 15, sk->sk_allocation);
        if (unlikely(buff == NULL))
                return -ENOBUFS;
index 6c0f2526f3f1742f011195cf00a8f24c9aaa0e99..6565cf55eb1e80f9109502995319655147bd1fd7 100644 (file)
@@ -295,7 +295,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (err)
                goto late_failure;
 
-       if (!tp->write_seq)
+       if (!tp->write_seq && likely(!tp->repair))
                tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
                                                             np->daddr.s6_addr32,
                                                             inet->inet_sport,
index f3ed8ca59b942497ba0193268fed95801c364d7a..c9844135c9caea041bd9a680e39da7bba4cf0997 100644 (file)
@@ -327,21 +327,7 @@ static struct ctl_table_header *sysctl_hdr;
 int __init xfrm6_init(void)
 {
        int ret;
-       unsigned int gc_thresh;
-
-       /*
-        * We need a good default value for the xfrm6 gc threshold.
-        * In ipv4 we set it to the route hash table size * 8, which
-        * is half the size of the maximaum route cache for ipv4.  It
-        * would be good to do the same thing for v6, except the table is
-        * constructed differently here.  Here each table for a net namespace
-        * can have FIB_TABLE_HASHSZ entries, so lets go with the same
-        * computation that we used for ipv4 here.  Also, lets keep the initial
-        * gc_thresh to a minimum of 1024, since, the ipv6 route cache defaults
-        * to that as a minimum as well
-        */
-       gc_thresh = FIB6_TABLE_HASHSZ * 8;
-       xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh;
+
        dst_entries_init(&xfrm6_dst_ops);
 
        ret = xfrm6_policy_init();
@@ -370,7 +356,6 @@ void xfrm6_fini(void)
        if (sysctl_hdr)
                unregister_net_sysctl_table(sysctl_hdr);
 #endif
-       //xfrm6_input_fini();
        xfrm6_policy_fini();
        xfrm6_state_fini();
        dst_entries_destroy(&xfrm6_dst_ops);
index e5246fbe36c4e661698242370b800043e12ce545..2906d520eea7c2b7636fc94f3a60f5131701f57d 100644 (file)
@@ -276,18 +276,16 @@ static struct crypto_comp * __percpu *ipcomp_alloc_tfms(const char *alg_name)
        struct crypto_comp * __percpu *tfms;
        int cpu;
 
-       /* This can be any valid CPU ID so we don't need locking. */
-       cpu = raw_smp_processor_id();
 
        list_for_each_entry(pos, &ipcomp_tfms_list, list) {
                struct crypto_comp *tfm;
 
-               tfms = pos->tfms;
-               tfm = *per_cpu_ptr(tfms, cpu);
+               /* This can be any valid CPU ID so we don't need locking. */
+               tfm = __this_cpu_read(*pos->tfms);
 
                if (!strcmp(crypto_comp_name(tfm), alg_name)) {
                        pos->users++;
-                       return tfms;
+                       return pos->tfms;
                }
        }
 
index 3efb07d3eb27425c8b9b5114c925eb9e7f402c9e..765f6fe951ebc7ed8fabaed3a4dc6ea4299aebfa 100644 (file)
@@ -521,13 +521,12 @@ int xfrm_init_replay(struct xfrm_state *x)
                    replay_esn->bmp_len * sizeof(__u32) * 8)
                        return -EINVAL;
 
-       if ((x->props.flags & XFRM_STATE_ESN) && replay_esn->replay_window == 0)
-               return -EINVAL;
-
-       if ((x->props.flags & XFRM_STATE_ESN) && x->replay_esn)
-               x->repl = &xfrm_replay_esn;
-       else
-               x->repl = &xfrm_replay_bmp;
+               if (x->props.flags & XFRM_STATE_ESN) {
+                       if (replay_esn->replay_window == 0)
+                               return -EINVAL;
+                       x->repl = &xfrm_replay_esn;
+               } else
+                       x->repl = &xfrm_replay_bmp;
        } else
                x->repl = &xfrm_replay_legacy;