Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-next-2.6
This commit is contained in:
commit
5c5095494f
|
@ -343,32 +343,6 @@ out:
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_has_challenged_slaves
|
||||
* @bond: the bond we're working on
|
||||
*
|
||||
* Searches the slave list. Returns 1 if a vlan challenged slave
|
||||
* was found, 0 otherwise.
|
||||
*
|
||||
* Assumes bond->lock is held.
|
||||
*/
|
||||
static int bond_has_challenged_slaves(struct bonding *bond)
|
||||
{
|
||||
struct slave *slave;
|
||||
int i;
|
||||
|
||||
bond_for_each_slave(bond, slave, i) {
|
||||
if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) {
|
||||
pr_debug("found VLAN challenged slave - %s\n",
|
||||
slave->dev->name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("no VLAN challenged slaves found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_next_vlan - safely skip to the next item in the vlans list.
|
||||
* @bond: the bond we're working on
|
||||
|
@ -1406,52 +1380,68 @@ static int bond_sethwaddr(struct net_device *bond_dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define BOND_VLAN_FEATURES \
|
||||
(NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
|
||||
NETIF_F_HW_VLAN_FILTER)
|
||||
static u32 bond_fix_features(struct net_device *dev, u32 features)
|
||||
{
|
||||
struct slave *slave;
|
||||
struct bonding *bond = netdev_priv(dev);
|
||||
u32 mask;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Compute the common dev->feature set available to all slaves. Some
|
||||
* feature bits are managed elsewhere, so preserve those feature bits
|
||||
* on the master device.
|
||||
*/
|
||||
static int bond_compute_features(struct bonding *bond)
|
||||
read_lock(&bond->lock);
|
||||
|
||||
if (!bond->first_slave) {
|
||||
/* Disable adding VLANs to empty bond. But why? --mq */
|
||||
features |= NETIF_F_VLAN_CHALLENGED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mask = features;
|
||||
features &= ~NETIF_F_ONE_FOR_ALL;
|
||||
features |= NETIF_F_ALL_FOR_ALL;
|
||||
|
||||
bond_for_each_slave(bond, slave, i) {
|
||||
features = netdev_increment_features(features,
|
||||
slave->dev->features,
|
||||
mask);
|
||||
}
|
||||
|
||||
out:
|
||||
read_unlock(&bond->lock);
|
||||
return features;
|
||||
}
|
||||
|
||||
#define BOND_VLAN_FEATURES (NETIF_F_ALL_TX_OFFLOADS | \
|
||||
NETIF_F_SOFT_FEATURES | \
|
||||
NETIF_F_LRO)
|
||||
|
||||
static void bond_compute_features(struct bonding *bond)
|
||||
{
|
||||
struct slave *slave;
|
||||
struct net_device *bond_dev = bond->dev;
|
||||
u32 features = bond_dev->features;
|
||||
u32 vlan_features = 0;
|
||||
unsigned short max_hard_header_len = max((u16)ETH_HLEN,
|
||||
bond_dev->hard_header_len);
|
||||
u32 vlan_features = BOND_VLAN_FEATURES;
|
||||
unsigned short max_hard_header_len = ETH_HLEN;
|
||||
int i;
|
||||
|
||||
features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
|
||||
features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_NOCACHE_COPY;
|
||||
read_lock(&bond->lock);
|
||||
|
||||
if (!bond->first_slave)
|
||||
goto done;
|
||||
|
||||
features &= ~NETIF_F_ONE_FOR_ALL;
|
||||
|
||||
vlan_features = bond->first_slave->dev->vlan_features;
|
||||
bond_for_each_slave(bond, slave, i) {
|
||||
features = netdev_increment_features(features,
|
||||
slave->dev->features,
|
||||
NETIF_F_ONE_FOR_ALL);
|
||||
vlan_features = netdev_increment_features(vlan_features,
|
||||
slave->dev->vlan_features,
|
||||
NETIF_F_ONE_FOR_ALL);
|
||||
slave->dev->vlan_features, BOND_VLAN_FEATURES);
|
||||
|
||||
if (slave->dev->hard_header_len > max_hard_header_len)
|
||||
max_hard_header_len = slave->dev->hard_header_len;
|
||||
}
|
||||
|
||||
done:
|
||||
features |= (bond_dev->features & BOND_VLAN_FEATURES);
|
||||
bond_dev->features = netdev_fix_features(bond_dev, features);
|
||||
bond_dev->vlan_features = netdev_fix_features(bond_dev, vlan_features);
|
||||
bond_dev->vlan_features = vlan_features;
|
||||
bond_dev->hard_header_len = max_hard_header_len;
|
||||
|
||||
return 0;
|
||||
read_unlock(&bond->lock);
|
||||
|
||||
netdev_change_features(bond_dev);
|
||||
}
|
||||
|
||||
static void bond_setup_by_slave(struct net_device *bond_dev,
|
||||
|
@ -1544,7 +1534,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
struct netdev_hw_addr *ha;
|
||||
struct sockaddr addr;
|
||||
int link_reporting;
|
||||
int old_features = bond_dev->features;
|
||||
int res = 0;
|
||||
|
||||
if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
|
||||
|
@ -1577,16 +1566,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
pr_warning("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
|
||||
bond_dev->name, slave_dev->name,
|
||||
slave_dev->name, bond_dev->name);
|
||||
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
|
||||
}
|
||||
} else {
|
||||
pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
|
||||
if (bond->slave_cnt == 0) {
|
||||
/* First slave, and it is not VLAN challenged,
|
||||
* so remove the block of adding VLANs over the bond.
|
||||
*/
|
||||
bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1775,10 +1757,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
new_slave->delay = 0;
|
||||
new_slave->link_failure_count = 0;
|
||||
|
||||
bond_compute_features(bond);
|
||||
|
||||
write_unlock_bh(&bond->lock);
|
||||
|
||||
bond_compute_features(bond);
|
||||
|
||||
read_lock(&bond->lock);
|
||||
|
||||
new_slave->last_arp_rx = jiffies;
|
||||
|
@ -1958,7 +1940,7 @@ err_free:
|
|||
kfree(new_slave);
|
||||
|
||||
err_undo_flags:
|
||||
bond_dev->features = old_features;
|
||||
bond_compute_features(bond);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1979,6 +1961,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
struct bonding *bond = netdev_priv(bond_dev);
|
||||
struct slave *slave, *oldcurrent;
|
||||
struct sockaddr addr;
|
||||
u32 old_features = bond_dev->features;
|
||||
|
||||
/* slave is not a slave or master is not master of this slave */
|
||||
if (!(slave_dev->flags & IFF_SLAVE) ||
|
||||
|
@ -2039,8 +2022,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
/* release the slave from its bond */
|
||||
bond_detach_slave(bond, slave);
|
||||
|
||||
bond_compute_features(bond);
|
||||
|
||||
if (bond->primary_slave == slave)
|
||||
bond->primary_slave = NULL;
|
||||
|
||||
|
@ -2084,24 +2065,23 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
|
|||
*/
|
||||
memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
|
||||
|
||||
if (!bond->vlgrp) {
|
||||
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
|
||||
} else {
|
||||
if (bond->vlgrp) {
|
||||
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
|
||||
bond_dev->name, bond_dev->name);
|
||||
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
|
||||
bond_dev->name);
|
||||
}
|
||||
} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
|
||||
!bond_has_challenged_slaves(bond)) {
|
||||
pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
|
||||
bond_dev->name, slave_dev->name, bond_dev->name);
|
||||
bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
|
||||
}
|
||||
|
||||
write_unlock_bh(&bond->lock);
|
||||
unblock_netpoll_tx();
|
||||
|
||||
bond_compute_features(bond);
|
||||
if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
|
||||
(old_features & NETIF_F_VLAN_CHALLENGED))
|
||||
pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
|
||||
bond_dev->name, slave_dev->name, bond_dev->name);
|
||||
|
||||
/* must do this from outside any spinlocks */
|
||||
bond_destroy_slave_symlinks(bond_dev, slave_dev);
|
||||
|
||||
|
@ -2219,8 +2199,6 @@ static int bond_release_all(struct net_device *bond_dev)
|
|||
bond_alb_deinit_slave(bond, slave);
|
||||
}
|
||||
|
||||
bond_compute_features(bond);
|
||||
|
||||
bond_destroy_slave_symlinks(bond_dev, slave_dev);
|
||||
bond_del_vlans_from_slave(bond, slave_dev);
|
||||
|
||||
|
@ -2269,9 +2247,7 @@ static int bond_release_all(struct net_device *bond_dev)
|
|||
*/
|
||||
memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
|
||||
|
||||
if (!bond->vlgrp) {
|
||||
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
|
||||
} else {
|
||||
if (bond->vlgrp) {
|
||||
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
|
||||
bond_dev->name, bond_dev->name);
|
||||
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
|
||||
|
@ -2282,6 +2258,9 @@ static int bond_release_all(struct net_device *bond_dev)
|
|||
|
||||
out:
|
||||
write_unlock_bh(&bond->lock);
|
||||
|
||||
bond_compute_features(bond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4337,11 +4316,6 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
|
|||
static const struct ethtool_ops bond_ethtool_ops = {
|
||||
.get_drvinfo = bond_ethtool_get_drvinfo,
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_tx_csum = ethtool_op_get_tx_csum,
|
||||
.get_sg = ethtool_op_get_sg,
|
||||
.get_tso = ethtool_op_get_tso,
|
||||
.get_ufo = ethtool_op_get_ufo,
|
||||
.get_flags = ethtool_op_get_flags,
|
||||
};
|
||||
|
||||
static const struct net_device_ops bond_netdev_ops = {
|
||||
|
@ -4367,6 +4341,7 @@ static const struct net_device_ops bond_netdev_ops = {
|
|||
#endif
|
||||
.ndo_add_slave = bond_enslave,
|
||||
.ndo_del_slave = bond_release,
|
||||
.ndo_fix_features = bond_fix_features,
|
||||
};
|
||||
|
||||
static void bond_destructor(struct net_device *bond_dev)
|
||||
|
@ -4422,14 +4397,14 @@ static void bond_setup(struct net_device *bond_dev)
|
|||
* when there are slaves that are not hw accel
|
||||
* capable
|
||||
*/
|
||||
bond_dev->features |= (NETIF_F_HW_VLAN_TX |
|
||||
NETIF_F_HW_VLAN_RX |
|
||||
NETIF_F_HW_VLAN_FILTER);
|
||||
|
||||
/* By default, we enable GRO on bonding devices.
|
||||
* Actual support requires lowlevel drivers are GRO ready.
|
||||
*/
|
||||
bond_dev->features |= NETIF_F_GRO;
|
||||
bond_dev->hw_features = BOND_VLAN_FEATURES |
|
||||
NETIF_F_HW_VLAN_TX |
|
||||
NETIF_F_HW_VLAN_RX |
|
||||
NETIF_F_HW_VLAN_FILTER;
|
||||
|
||||
bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM);
|
||||
bond_dev->features |= bond_dev->hw_features;
|
||||
}
|
||||
|
||||
static void bond_work_cancel_all(struct bonding *bond)
|
||||
|
|
|
@ -3373,8 +3373,8 @@ relink:
|
|||
tg3_phy_copper_begin(tp);
|
||||
|
||||
tg3_readphy(tp, MII_BMSR, &bmsr);
|
||||
if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
|
||||
(bmsr & BMSR_LSTATUS))
|
||||
if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) ||
|
||||
(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
|
||||
current_link_up = 1;
|
||||
}
|
||||
|
||||
|
@ -6309,6 +6309,42 @@ dma_error:
|
|||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static void tg3_set_loopback(struct net_device *dev, u32 features)
|
||||
{
|
||||
struct tg3 *tp = netdev_priv(dev);
|
||||
|
||||
if (features & NETIF_F_LOOPBACK) {
|
||||
if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Clear MAC_MODE_HALF_DUPLEX or you won't get packets back in
|
||||
* loopback mode if Half-Duplex mode was negotiated earlier.
|
||||
*/
|
||||
tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
|
||||
|
||||
/* Enable internal MAC loopback mode */
|
||||
tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
|
||||
spin_lock_bh(&tp->lock);
|
||||
tw32(MAC_MODE, tp->mac_mode);
|
||||
netif_carrier_on(tp->dev);
|
||||
spin_unlock_bh(&tp->lock);
|
||||
netdev_info(dev, "Internal MAC loopback mode enabled.\n");
|
||||
} else {
|
||||
if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
|
||||
return;
|
||||
|
||||
/* Disable internal MAC loopback mode */
|
||||
tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
|
||||
spin_lock_bh(&tp->lock);
|
||||
tw32(MAC_MODE, tp->mac_mode);
|
||||
/* Force link status check */
|
||||
tg3_setup_phy(tp, 1);
|
||||
spin_unlock_bh(&tp->lock);
|
||||
netdev_info(dev, "Internal MAC loopback mode disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static u32 tg3_fix_features(struct net_device *dev, u32 features)
|
||||
{
|
||||
struct tg3 *tp = netdev_priv(dev);
|
||||
|
@ -6319,6 +6355,16 @@ static u32 tg3_fix_features(struct net_device *dev, u32 features)
|
|||
return features;
|
||||
}
|
||||
|
||||
static int tg3_set_features(struct net_device *dev, u32 features)
|
||||
{
|
||||
u32 changed = dev->features ^ features;
|
||||
|
||||
if ((changed & NETIF_F_LOOPBACK) && netif_running(dev))
|
||||
tg3_set_loopback(dev, features);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
|
||||
int new_mtu)
|
||||
{
|
||||
|
@ -9485,6 +9531,13 @@ static int tg3_open(struct net_device *dev)
|
|||
|
||||
netif_tx_start_all_queues(dev);
|
||||
|
||||
/*
|
||||
* Reset loopback feature if it was turned on while the device was down
|
||||
* make sure that it's installed properly now.
|
||||
*/
|
||||
if (dev->features & NETIF_F_LOOPBACK)
|
||||
tg3_set_loopback(dev, dev->features);
|
||||
|
||||
return 0;
|
||||
|
||||
err_out3:
|
||||
|
@ -15033,6 +15086,7 @@ static const struct net_device_ops tg3_netdev_ops = {
|
|||
.ndo_tx_timeout = tg3_tx_timeout,
|
||||
.ndo_change_mtu = tg3_change_mtu,
|
||||
.ndo_fix_features = tg3_fix_features,
|
||||
.ndo_set_features = tg3_set_features,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = tg3_poll_controller,
|
||||
#endif
|
||||
|
@ -15049,6 +15103,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
|
|||
.ndo_do_ioctl = tg3_ioctl,
|
||||
.ndo_tx_timeout = tg3_tx_timeout,
|
||||
.ndo_change_mtu = tg3_change_mtu,
|
||||
.ndo_set_features = tg3_set_features,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = tg3_poll_controller,
|
||||
#endif
|
||||
|
@ -15246,6 +15301,16 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|||
dev->features |= hw_features;
|
||||
dev->vlan_features |= hw_features;
|
||||
|
||||
/*
|
||||
* Add loopback capability only for a subset of devices that support
|
||||
* MAC-LOOPBACK. Eventually this need to be enhanced to allow INT-PHY
|
||||
* loopback for the remaining devices.
|
||||
*/
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780 &&
|
||||
!tg3_flag(tp, CPMU_PRESENT))
|
||||
/* Add the loopback capability */
|
||||
dev->hw_features |= NETIF_F_LOOPBACK;
|
||||
|
||||
if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
|
||||
!tg3_flag(tp, TSO_CAPABLE) &&
|
||||
!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
|
||||
|
|
|
@ -54,13 +54,13 @@
|
|||
#include <linux/usb/usbnet.h>
|
||||
#include <linux/usb/cdc.h>
|
||||
|
||||
#define DRIVER_VERSION "23-Apr-2011"
|
||||
#define DRIVER_VERSION "06-May-2011"
|
||||
|
||||
/* CDC NCM subclass 3.2.1 */
|
||||
#define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10
|
||||
|
||||
/* Maximum NTB length */
|
||||
#define CDC_NCM_NTB_MAX_SIZE_TX (16384 + 4) /* bytes, must be short terminated */
|
||||
#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */
|
||||
#define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */
|
||||
|
||||
/* Minimum value for MaxDatagramSize, ch. 6.2.9 */
|
||||
|
@ -722,7 +722,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
|
|||
|
||||
} else {
|
||||
/* reset variables */
|
||||
skb_out = alloc_skb(ctx->tx_max, GFP_ATOMIC);
|
||||
skb_out = alloc_skb((ctx->tx_max + 1), GFP_ATOMIC);
|
||||
if (skb_out == NULL) {
|
||||
if (skb != NULL) {
|
||||
dev_kfree_skb_any(skb);
|
||||
|
@ -861,8 +861,11 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb)
|
|||
/* store last offset */
|
||||
last_offset = offset;
|
||||
|
||||
if ((last_offset < ctx->tx_max) && ((last_offset %
|
||||
le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) {
|
||||
if (((last_offset < ctx->tx_max) && ((last_offset %
|
||||
le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) ||
|
||||
(((last_offset == ctx->tx_max) && ((ctx->tx_max %
|
||||
le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) &&
|
||||
(ctx->tx_max < le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)))) {
|
||||
/* force short packet */
|
||||
*(((u8 *)skb_out->data) + last_offset) = 0;
|
||||
last_offset++;
|
||||
|
|
|
@ -2884,6 +2884,9 @@ vmxnet3_probe_device(struct pci_dev *pdev,
|
|||
int num_tx_queues;
|
||||
int num_rx_queues;
|
||||
|
||||
if (!pci_msi_enabled())
|
||||
enable_mq = 0;
|
||||
|
||||
#ifdef VMXNET3_RSS
|
||||
if (enable_mq)
|
||||
num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES,
|
||||
|
|
|
@ -68,10 +68,10 @@
|
|||
/*
|
||||
* Version numbers
|
||||
*/
|
||||
#define VMXNET3_DRIVER_VERSION_STRING "1.0.25.0-k"
|
||||
#define VMXNET3_DRIVER_VERSION_STRING "1.1.9.0-k"
|
||||
|
||||
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
|
||||
#define VMXNET3_DRIVER_VERSION_NUM 0x01001900
|
||||
#define VMXNET3_DRIVER_VERSION_NUM 0x01010900
|
||||
|
||||
#if defined(CONFIG_PCI_MSI)
|
||||
/* RSS only makes sense if MSI-X is supported. */
|
||||
|
|
|
@ -1097,10 +1097,14 @@ struct net_device {
|
|||
|
||||
#define NETIF_F_ALL_TSO (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
|
||||
|
||||
#define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \
|
||||
NETIF_F_FSO)
|
||||
|
||||
#define NETIF_F_ALL_TX_OFFLOADS (NETIF_F_ALL_CSUM | NETIF_F_SG | \
|
||||
NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
|
||||
NETIF_F_HIGHDMA | \
|
||||
NETIF_F_SCTP_CSUM | NETIF_F_FCOE_CRC)
|
||||
NETIF_F_SCTP_CSUM | \
|
||||
NETIF_F_ALL_FCOE)
|
||||
|
||||
/*
|
||||
* If one device supports one of these features, then enable them
|
||||
|
@ -2561,6 +2565,7 @@ u32 netdev_increment_features(u32 all, u32 one, u32 mask);
|
|||
u32 netdev_fix_features(struct net_device *dev, u32 features);
|
||||
int __netdev_update_features(struct net_device *dev);
|
||||
void netdev_update_features(struct net_device *dev);
|
||||
void netdev_change_features(struct net_device *dev);
|
||||
|
||||
void netif_stacked_transfer_operstate(const struct net_device *rootdev,
|
||||
struct net_device *dev);
|
||||
|
|
|
@ -104,6 +104,7 @@ struct garp_applicant {
|
|||
struct sk_buff_head queue;
|
||||
struct sk_buff *pdu;
|
||||
struct rb_root gid;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
struct garp_port {
|
||||
|
|
|
@ -665,9 +665,7 @@ struct ip_vs_dest {
|
|||
struct dst_entry *dst_cache; /* destination cache entry */
|
||||
u32 dst_rtos; /* RT_TOS(tos) for dst */
|
||||
u32 dst_cookie;
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
struct in6_addr dst_saddr;
|
||||
#endif
|
||||
union nf_inet_addr dst_saddr;
|
||||
|
||||
/* for virtual service */
|
||||
struct ip_vs_service *svc; /* service it belongs to */
|
||||
|
@ -1253,7 +1251,8 @@ extern int ip_vs_tunnel_xmit
|
|||
extern int ip_vs_dr_xmit
|
||||
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
|
||||
extern int ip_vs_icmp_xmit
|
||||
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, int offset);
|
||||
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
|
||||
int offset, unsigned int hooknum);
|
||||
extern void ip_vs_dst_reset(struct ip_vs_dest *dest);
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
|
@ -1267,7 +1266,7 @@ extern int ip_vs_dr_xmit_v6
|
|||
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
|
||||
extern int ip_vs_icmp_xmit_v6
|
||||
(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
|
||||
int offset);
|
||||
int offset, unsigned int hooknum);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
|
|
@ -603,6 +603,11 @@ err1:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(garp_init_applicant);
|
||||
|
||||
static void garp_app_kfree_rcu(struct rcu_head *head)
|
||||
{
|
||||
kfree(container_of(head, struct garp_applicant, rcu));
|
||||
}
|
||||
|
||||
void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl)
|
||||
{
|
||||
struct garp_port *port = rtnl_dereference(dev->garp_port);
|
||||
|
@ -611,7 +616,6 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
|
|||
ASSERT_RTNL();
|
||||
|
||||
rcu_assign_pointer(port->applicants[appl->type], NULL);
|
||||
synchronize_rcu();
|
||||
|
||||
/* Delete timer and generate a final TRANSMIT_PDU event to flush out
|
||||
* all pending messages before the applicant is gone. */
|
||||
|
@ -621,7 +625,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
|
|||
garp_queue_xmit(app);
|
||||
|
||||
dev_mc_del(dev, appl->proto.group_address);
|
||||
kfree(app);
|
||||
call_rcu(&app->rcu, garp_app_kfree_rcu);
|
||||
garp_release_port(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(garp_uninit_applicant);
|
||||
|
@ -639,3 +643,9 @@ void garp_unregister_application(struct garp_application *appl)
|
|||
stp_proto_unregister(&appl->proto);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(garp_unregister_application);
|
||||
|
||||
static void __exit garp_cleanup_module(void)
|
||||
{
|
||||
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
||||
}
|
||||
module_exit(garp_cleanup_module);
|
||||
|
|
|
@ -528,7 +528,7 @@ static int vlan_dev_init(struct net_device *dev)
|
|||
(1<<__LINK_STATE_DORMANT))) |
|
||||
(1<<__LINK_STATE_PRESENT);
|
||||
|
||||
dev->hw_features = real_dev->vlan_features & NETIF_F_ALL_TX_OFFLOADS;
|
||||
dev->hw_features = NETIF_F_ALL_TX_OFFLOADS;
|
||||
dev->features |= real_dev->vlan_features | NETIF_F_LLTX;
|
||||
dev->gso_max_size = real_dev->gso_max_size;
|
||||
|
||||
|
@ -587,9 +587,11 @@ static u32 vlan_dev_fix_features(struct net_device *dev, u32 features)
|
|||
{
|
||||
struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
|
||||
|
||||
features &= (real_dev->features | NETIF_F_LLTX);
|
||||
features &= real_dev->features;
|
||||
features &= real_dev->vlan_features;
|
||||
if (dev_ethtool_get_rx_csum(real_dev))
|
||||
features |= NETIF_F_RXCSUM;
|
||||
features |= NETIF_F_LLTX;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
|
|
@ -5289,6 +5289,14 @@ int __netdev_update_features(struct net_device *dev)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* netdev_update_features - recalculate device features
|
||||
* @dev: the device to check
|
||||
*
|
||||
* Recalculate dev->features set and send notifications if it
|
||||
* has changed. Should be called after driver or hardware dependent
|
||||
* conditions might have changed that influence the features.
|
||||
*/
|
||||
void netdev_update_features(struct net_device *dev)
|
||||
{
|
||||
if (__netdev_update_features(dev))
|
||||
|
@ -5296,6 +5304,23 @@ void netdev_update_features(struct net_device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(netdev_update_features);
|
||||
|
||||
/**
|
||||
* netdev_change_features - recalculate device features
|
||||
* @dev: the device to check
|
||||
*
|
||||
* Recalculate dev->features set and send notifications even
|
||||
* if they have not changed. Should be called instead of
|
||||
* netdev_update_features() if also dev->vlan_features might
|
||||
* have changed to allow the changes to be propagated to stacked
|
||||
* VLAN devices.
|
||||
*/
|
||||
void netdev_change_features(struct net_device *dev)
|
||||
{
|
||||
__netdev_update_features(dev);
|
||||
netdev_features_change(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(netdev_change_features);
|
||||
|
||||
/**
|
||||
* netif_stacked_transfer_operstate - transfer operstate
|
||||
* @rootdev: the root or lower level device to transfer state from
|
||||
|
|
|
@ -361,7 +361,7 @@ static const char netdev_features_strings[ETHTOOL_DEV_FEATURE_WORDS * 32][ETH_GS
|
|||
/* NETIF_F_NTUPLE */ "rx-ntuple-filter",
|
||||
/* NETIF_F_RXHASH */ "rx-hashing",
|
||||
/* NETIF_F_RXCSUM */ "rx-checksum",
|
||||
/* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy"
|
||||
/* NETIF_F_NOCACHE_COPY */ "tx-nocache-copy",
|
||||
/* NETIF_F_LOOPBACK */ "loopback",
|
||||
};
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ int ip_forward(struct sk_buff *skb)
|
|||
|
||||
rt = skb_rtable(skb);
|
||||
|
||||
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
|
||||
if (opt->is_strictroute && iph->daddr != rt->rt_gateway)
|
||||
goto sr_failed;
|
||||
|
||||
if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
|
||||
|
|
|
@ -601,7 +601,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
|
|||
unsigned long orefdst;
|
||||
int err;
|
||||
|
||||
if (!opt->srr || !rt)
|
||||
if (!rt)
|
||||
return 0;
|
||||
|
||||
if (skb->pkt_type != PACKET_HOST)
|
||||
|
@ -635,7 +635,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
|
|||
if (rt2->rt_type != RTN_LOCAL)
|
||||
break;
|
||||
/* Superfast 8) loopback forward */
|
||||
memcpy(&iph->daddr, &optptr[srrptr-1], 4);
|
||||
iph->daddr = nexthop;
|
||||
opt->is_changed = 1;
|
||||
}
|
||||
if (srrptr <= srrspace) {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <linux/seq_file.h>
|
||||
#include <linux/termios.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/device.h> /* for MODULE_ALIAS_CHARDEV_MAJOR */
|
||||
|
||||
|
@ -1132,7 +1133,6 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
|
|||
struct sk_buff *skb)
|
||||
{
|
||||
struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
|
||||
struct tty_ldisc *ld;
|
||||
|
||||
IRDA_DEBUG(2, "%s()\n", __func__ );
|
||||
|
||||
|
@ -1161,15 +1161,11 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
|
|||
}
|
||||
|
||||
/*
|
||||
* Just give it over to the line discipline. There is no need to
|
||||
* involve the flip buffers, since we are not running in an interrupt
|
||||
* handler
|
||||
* Use flip buffer functions since the code may be called from interrupt
|
||||
* context
|
||||
*/
|
||||
|
||||
ld = tty_ldisc_ref(self->tty);
|
||||
if (ld)
|
||||
ld->ops->receive_buf(self->tty, skb->data, NULL, skb->len);
|
||||
tty_ldisc_deref(ld);
|
||||
tty_insert_flip_string(self->tty, skb->data, skb->len);
|
||||
tty_flip_buffer_push(self->tty);
|
||||
|
||||
/* No need to kfree_skb - see ircomm_ttp_data_indication() */
|
||||
|
||||
|
|
|
@ -1435,16 +1435,15 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
|
|||
|
||||
/* Add tunnel to our list */
|
||||
INIT_LIST_HEAD(&tunnel->list);
|
||||
spin_lock_bh(&pn->l2tp_tunnel_list_lock);
|
||||
list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
|
||||
spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
|
||||
synchronize_rcu();
|
||||
atomic_inc(&l2tp_tunnel_count);
|
||||
|
||||
/* Bump the reference count. The tunnel context is deleted
|
||||
* only when this drops to zero.
|
||||
* only when this drops to zero. Must be done before list insertion
|
||||
*/
|
||||
l2tp_tunnel_inc_refcount(tunnel);
|
||||
spin_lock_bh(&pn->l2tp_tunnel_list_lock);
|
||||
list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
|
||||
spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
|
||||
|
||||
err = 0;
|
||||
err:
|
||||
|
@ -1636,7 +1635,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
|
|||
hlist_add_head_rcu(&session->global_hlist,
|
||||
l2tp_session_id_hash_2(pn, session_id));
|
||||
spin_unlock_bh(&pn->l2tp_session_hlist_lock);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
/* Ignore management session in session count value */
|
||||
|
|
|
@ -1382,15 +1382,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
|
|||
ip_vs_in_stats(cp, skb);
|
||||
if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
|
||||
offset += 2 * sizeof(__u16);
|
||||
verdict = ip_vs_icmp_xmit(skb, cp, pp, offset);
|
||||
/* LOCALNODE from FORWARD hook is not supported */
|
||||
if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
|
||||
skb_rtable(skb)->rt_flags & RTCF_LOCAL) {
|
||||
IP_VS_DBG(1, "%s(): "
|
||||
"local delivery to %pI4 but in FORWARD\n",
|
||||
__func__, &skb_rtable(skb)->rt_dst);
|
||||
verdict = NF_DROP;
|
||||
}
|
||||
verdict = ip_vs_icmp_xmit(skb, cp, pp, offset, hooknum);
|
||||
|
||||
out:
|
||||
__ip_vs_conn_put(cp);
|
||||
|
@ -1412,7 +1404,6 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
|
|||
struct ip_vs_protocol *pp;
|
||||
struct ip_vs_proto_data *pd;
|
||||
unsigned int offset, verdict;
|
||||
struct rt6_info *rt;
|
||||
|
||||
*related = 1;
|
||||
|
||||
|
@ -1474,23 +1465,12 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
|
|||
if (!cp)
|
||||
return NF_ACCEPT;
|
||||
|
||||
verdict = NF_DROP;
|
||||
|
||||
/* do the statistics and put it back */
|
||||
ip_vs_in_stats(cp, skb);
|
||||
if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr ||
|
||||
IPPROTO_SCTP == cih->nexthdr)
|
||||
offset += 2 * sizeof(__u16);
|
||||
verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
|
||||
/* LOCALNODE from FORWARD hook is not supported */
|
||||
if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
|
||||
(rt = (struct rt6_info *) skb_dst(skb)) &&
|
||||
rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) {
|
||||
IP_VS_DBG(1, "%s(): "
|
||||
"local delivery to %pI6 but in FORWARD\n",
|
||||
__func__, &rt->rt6i_dst);
|
||||
verdict = NF_DROP;
|
||||
}
|
||||
verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum);
|
||||
|
||||
__ip_vs_conn_put(cp);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)
|
|||
/* Get route to destination or remote server */
|
||||
static struct rtable *
|
||||
__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
|
||||
__be32 daddr, u32 rtos, int rt_mode)
|
||||
__be32 daddr, u32 rtos, int rt_mode, __be32 *ret_saddr)
|
||||
{
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
struct rtable *rt; /* Route to the other host */
|
||||
|
@ -98,7 +98,12 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
spin_lock(&dest->dst_lock);
|
||||
if (!(rt = (struct rtable *)
|
||||
__ip_vs_dst_check(dest, rtos))) {
|
||||
rt = ip_route_output(net, dest->addr.ip, 0, rtos, 0);
|
||||
struct flowi4 fl4;
|
||||
|
||||
memset(&fl4, 0, sizeof(fl4));
|
||||
fl4.daddr = dest->addr.ip;
|
||||
fl4.flowi4_tos = rtos;
|
||||
rt = ip_route_output_key(net, &fl4);
|
||||
if (IS_ERR(rt)) {
|
||||
spin_unlock(&dest->dst_lock);
|
||||
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
|
||||
|
@ -106,18 +111,30 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
return NULL;
|
||||
}
|
||||
__ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0);
|
||||
IP_VS_DBG(10, "new dst %pI4, refcnt=%d, rtos=%X\n",
|
||||
&dest->addr.ip,
|
||||
dest->dst_saddr.ip = fl4.saddr;
|
||||
IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d, "
|
||||
"rtos=%X\n",
|
||||
&dest->addr.ip, &dest->dst_saddr.ip,
|
||||
atomic_read(&rt->dst.__refcnt), rtos);
|
||||
}
|
||||
daddr = dest->addr.ip;
|
||||
if (ret_saddr)
|
||||
*ret_saddr = dest->dst_saddr.ip;
|
||||
spin_unlock(&dest->dst_lock);
|
||||
} else {
|
||||
rt = ip_route_output(net, daddr, 0, rtos, 0);
|
||||
struct flowi4 fl4;
|
||||
|
||||
memset(&fl4, 0, sizeof(fl4));
|
||||
fl4.daddr = daddr;
|
||||
fl4.flowi4_tos = rtos;
|
||||
rt = ip_route_output_key(net, &fl4);
|
||||
if (IS_ERR(rt)) {
|
||||
IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
|
||||
&daddr);
|
||||
return NULL;
|
||||
}
|
||||
if (ret_saddr)
|
||||
*ret_saddr = fl4.saddr;
|
||||
}
|
||||
|
||||
local = rt->rt_flags & RTCF_LOCAL;
|
||||
|
@ -125,7 +142,7 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
rt_mode)) {
|
||||
IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI4\n",
|
||||
(rt->rt_flags & RTCF_LOCAL) ?
|
||||
"local":"non-local", &rt->rt_dst);
|
||||
"local":"non-local", &daddr);
|
||||
ip_rt_put(rt);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -133,14 +150,14 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
!((ort = skb_rtable(skb)) && ort->rt_flags & RTCF_LOCAL)) {
|
||||
IP_VS_DBG_RL("Redirect from non-local address %pI4 to local "
|
||||
"requires NAT method, dest: %pI4\n",
|
||||
&ip_hdr(skb)->daddr, &rt->rt_dst);
|
||||
&ip_hdr(skb)->daddr, &daddr);
|
||||
ip_rt_put(rt);
|
||||
return NULL;
|
||||
}
|
||||
if (unlikely(!local && ipv4_is_loopback(ip_hdr(skb)->saddr))) {
|
||||
IP_VS_DBG_RL("Stopping traffic from loopback address %pI4 "
|
||||
"to non-local address, dest: %pI4\n",
|
||||
&ip_hdr(skb)->saddr, &rt->rt_dst);
|
||||
&ip_hdr(skb)->saddr, &daddr);
|
||||
ip_rt_put(rt);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -229,8 +246,6 @@ out_err:
|
|||
|
||||
/*
|
||||
* Get route to destination or remote server
|
||||
* rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest,
|
||||
* &4=Allow redirect from remote daddr to local
|
||||
*/
|
||||
static struct rt6_info *
|
||||
__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
|
||||
|
@ -250,7 +265,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
u32 cookie;
|
||||
|
||||
dst = __ip_vs_route_output_v6(net, &dest->addr.in6,
|
||||
&dest->dst_saddr,
|
||||
&dest->dst_saddr.in6,
|
||||
do_xfrm);
|
||||
if (!dst) {
|
||||
spin_unlock(&dest->dst_lock);
|
||||
|
@ -260,11 +275,11 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
|
||||
__ip_vs_dst_set(dest, 0, dst_clone(&rt->dst), cookie);
|
||||
IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
|
||||
&dest->addr.in6, &dest->dst_saddr,
|
||||
&dest->addr.in6, &dest->dst_saddr.in6,
|
||||
atomic_read(&rt->dst.__refcnt));
|
||||
}
|
||||
if (ret_saddr)
|
||||
ipv6_addr_copy(ret_saddr, &dest->dst_saddr);
|
||||
ipv6_addr_copy(ret_saddr, &dest->dst_saddr.in6);
|
||||
spin_unlock(&dest->dst_lock);
|
||||
} else {
|
||||
dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm);
|
||||
|
@ -274,13 +289,14 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
|
|||
}
|
||||
|
||||
local = __ip_vs_is_local_route6(rt);
|
||||
if (!((local ? 1 : 2) & rt_mode)) {
|
||||
if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) &
|
||||
rt_mode)) {
|
||||
IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n",
|
||||
local ? "local":"non-local", daddr);
|
||||
dst_release(&rt->dst);
|
||||
return NULL;
|
||||
}
|
||||
if (local && !(rt_mode & 4) &&
|
||||
if (local && !(rt_mode & IP_VS_RT_MODE_RDR) &&
|
||||
!((ort = (struct rt6_info *) skb_dst(skb)) &&
|
||||
__ip_vs_is_local_route6(ort))) {
|
||||
IP_VS_DBG_RL("Redirect from non-local address %pI6 to local "
|
||||
|
@ -386,7 +402,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
EnterFunction(10);
|
||||
|
||||
if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, RT_TOS(iph->tos),
|
||||
IP_VS_RT_MODE_NON_LOCAL)))
|
||||
IP_VS_RT_MODE_NON_LOCAL, NULL)))
|
||||
goto tx_error_icmp;
|
||||
|
||||
/* MTU checking */
|
||||
|
@ -440,7 +456,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
|
||||
EnterFunction(10);
|
||||
|
||||
if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0, 2)))
|
||||
if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0,
|
||||
IP_VS_RT_MODE_NON_LOCAL)))
|
||||
goto tx_error_icmp;
|
||||
|
||||
/* MTU checking */
|
||||
|
@ -517,7 +534,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
RT_TOS(iph->tos),
|
||||
IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL |
|
||||
IP_VS_RT_MODE_RDR)))
|
||||
IP_VS_RT_MODE_RDR, NULL)))
|
||||
goto tx_error_icmp;
|
||||
local = rt->rt_flags & RTCF_LOCAL;
|
||||
/*
|
||||
|
@ -539,7 +556,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
#endif
|
||||
|
||||
/* From world but DNAT to loopback address? */
|
||||
if (local && ipv4_is_loopback(rt->rt_dst) &&
|
||||
if (local && ipv4_is_loopback(cp->daddr.ip) &&
|
||||
rt_is_input_route(skb_rtable(skb))) {
|
||||
IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): "
|
||||
"stopping DNAT to loopback address");
|
||||
|
@ -632,7 +649,9 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
}
|
||||
|
||||
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
|
||||
0, 1|2|4)))
|
||||
0, (IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL |
|
||||
IP_VS_RT_MODE_RDR))))
|
||||
goto tx_error_icmp;
|
||||
local = __ip_vs_is_local_route6(rt);
|
||||
/*
|
||||
|
@ -748,6 +767,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
struct ip_vs_protocol *pp)
|
||||
{
|
||||
struct rtable *rt; /* Route to the other host */
|
||||
__be32 saddr; /* Source for tunnel */
|
||||
struct net_device *tdev; /* Device to other host */
|
||||
struct iphdr *old_iph = ip_hdr(skb);
|
||||
u8 tos = old_iph->tos;
|
||||
|
@ -761,7 +781,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
|
||||
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
|
||||
RT_TOS(tos), IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL)))
|
||||
IP_VS_RT_MODE_NON_LOCAL,
|
||||
&saddr)))
|
||||
goto tx_error_icmp;
|
||||
if (rt->rt_flags & RTCF_LOCAL) {
|
||||
ip_rt_put(rt);
|
||||
|
@ -829,8 +850,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
iph->frag_off = df;
|
||||
iph->protocol = IPPROTO_IPIP;
|
||||
iph->tos = tos;
|
||||
iph->daddr = rt->rt_dst;
|
||||
iph->saddr = rt->rt_src;
|
||||
iph->daddr = cp->daddr.ip;
|
||||
iph->saddr = saddr;
|
||||
iph->ttl = old_iph->ttl;
|
||||
ip_select_ident(iph, &rt->dst, NULL);
|
||||
|
||||
|
@ -875,7 +896,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
EnterFunction(10);
|
||||
|
||||
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6,
|
||||
&saddr, 1, 1|2)))
|
||||
&saddr, 1, (IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL))))
|
||||
goto tx_error_icmp;
|
||||
if (__ip_vs_is_local_route6(rt)) {
|
||||
dst_release(&rt->dst);
|
||||
|
@ -992,7 +1014,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
|
||||
RT_TOS(iph->tos),
|
||||
IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL)))
|
||||
IP_VS_RT_MODE_NON_LOCAL, NULL)))
|
||||
goto tx_error_icmp;
|
||||
if (rt->rt_flags & RTCF_LOCAL) {
|
||||
ip_rt_put(rt);
|
||||
|
@ -1050,7 +1072,8 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
EnterFunction(10);
|
||||
|
||||
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
|
||||
0, 1|2)))
|
||||
0, (IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL))))
|
||||
goto tx_error_icmp;
|
||||
if (__ip_vs_is_local_route6(rt)) {
|
||||
dst_release(&rt->dst);
|
||||
|
@ -1109,12 +1132,13 @@ tx_error:
|
|||
*/
|
||||
int
|
||||
ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
||||
struct ip_vs_protocol *pp, int offset)
|
||||
struct ip_vs_protocol *pp, int offset, unsigned int hooknum)
|
||||
{
|
||||
struct rtable *rt; /* Route to the other host */
|
||||
int mtu;
|
||||
int rc;
|
||||
int local;
|
||||
int rt_mode;
|
||||
|
||||
EnterFunction(10);
|
||||
|
||||
|
@ -1135,11 +1159,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
* mangle and send the packet here (only for VS/NAT)
|
||||
*/
|
||||
|
||||
/* LOCALNODE from FORWARD hook is not supported */
|
||||
rt_mode = (hooknum != NF_INET_FORWARD) ?
|
||||
IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
|
||||
IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
|
||||
if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
|
||||
RT_TOS(ip_hdr(skb)->tos),
|
||||
IP_VS_RT_MODE_LOCAL |
|
||||
IP_VS_RT_MODE_NON_LOCAL |
|
||||
IP_VS_RT_MODE_RDR)))
|
||||
rt_mode, NULL)))
|
||||
goto tx_error_icmp;
|
||||
local = rt->rt_flags & RTCF_LOCAL;
|
||||
|
||||
|
@ -1162,7 +1188,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
#endif
|
||||
|
||||
/* From world but DNAT to loopback address? */
|
||||
if (local && ipv4_is_loopback(rt->rt_dst) &&
|
||||
if (local && ipv4_is_loopback(cp->daddr.ip) &&
|
||||
rt_is_input_route(skb_rtable(skb))) {
|
||||
IP_VS_DBG(1, "%s(): "
|
||||
"stopping DNAT to loopback %pI4\n",
|
||||
|
@ -1227,12 +1253,13 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
#ifdef CONFIG_IP_VS_IPV6
|
||||
int
|
||||
ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
||||
struct ip_vs_protocol *pp, int offset)
|
||||
struct ip_vs_protocol *pp, int offset, unsigned int hooknum)
|
||||
{
|
||||
struct rt6_info *rt; /* Route to the other host */
|
||||
int mtu;
|
||||
int rc;
|
||||
int local;
|
||||
int rt_mode;
|
||||
|
||||
EnterFunction(10);
|
||||
|
||||
|
@ -1253,8 +1280,12 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||
* mangle and send the packet here (only for VS/NAT)
|
||||
*/
|
||||
|
||||
/* LOCALNODE from FORWARD hook is not supported */
|
||||
rt_mode = (hooknum != NF_INET_FORWARD) ?
|
||||
IP_VS_RT_MODE_LOCAL | IP_VS_RT_MODE_NON_LOCAL |
|
||||
IP_VS_RT_MODE_RDR : IP_VS_RT_MODE_NON_LOCAL;
|
||||
if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL,
|
||||
0, 1|2|4)))
|
||||
0, rt_mode)))
|
||||
goto tx_error_icmp;
|
||||
|
||||
local = __ip_vs_is_local_route6(rt);
|
||||
|
|
|
@ -1496,7 +1496,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
|||
struct sctp_chunk *chunk;
|
||||
union sctp_addr to;
|
||||
struct sockaddr *msg_name = NULL;
|
||||
struct sctp_sndrcvinfo default_sinfo = { 0 };
|
||||
struct sctp_sndrcvinfo default_sinfo;
|
||||
struct sctp_sndrcvinfo *sinfo;
|
||||
struct sctp_initmsg *sinit;
|
||||
sctp_assoc_t associd = 0;
|
||||
|
@ -1760,6 +1760,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
|||
/* If the user didn't specify SNDRCVINFO, make up one with
|
||||
* some defaults.
|
||||
*/
|
||||
memset(&default_sinfo, 0, sizeof(default_sinfo));
|
||||
default_sinfo.sinfo_stream = asoc->default_stream;
|
||||
default_sinfo.sinfo_flags = asoc->default_flags;
|
||||
default_sinfo.sinfo_ppid = asoc->default_ppid;
|
||||
|
@ -1790,12 +1791,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
if (sinfo) {
|
||||
/* Check for invalid stream. */
|
||||
if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
/* Check for invalid stream. */
|
||||
if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
|
||||
|
|
Loading…
Reference in New Issue