diff --git a/[refs] b/[refs] index e72e7f92a1d0..ef6ba947486d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1309d7afbed112f0e8e90be9af975550caa0076b +refs/heads/master: cd22c0e44b105aecd78e5f9e77abab3a1b8dc00c diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 7beb0e25f1e1..1f46f1cd9225 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -980,7 +980,7 @@ int tpm_open(struct inode *inode, struct file *file) return -EBUSY; } - chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); + chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); if (chip->data_buffer == NULL) { clear_bit(0, &chip->is_open); put_device(chip->dev); diff --git a/trunk/drivers/net/bfin_mac.c b/trunk/drivers/net/bfin_mac.c index 68d45ba2d9b9..22abfb39d813 100644 --- a/trunk/drivers/net/bfin_mac.c +++ b/trunk/drivers/net/bfin_mac.c @@ -1237,17 +1237,8 @@ static int bfin_mac_enable(struct phy_device *phydev) if (phydev->interface == PHY_INTERFACE_MODE_RMII) { opmode |= RMII; /* For Now only 100MBit are supported */ -#if defined(CONFIG_BF537) || defined(CONFIG_BF536) - if (__SILICON_REVISION__ < 3) { - /* - * This isn't publicly documented (fun times!), but in - * silicon <=0.2, the RX and TX pins are clocked together. - * So in order to recv, we must enable the transmit side - * as well. This will cause a spurious TX interrupt too, - * but we can easily consume that. - */ - opmode |= TE; - } +#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2 + opmode |= TE; #endif } diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 8e6d618b5305..d1865cc97313 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -8317,7 +8317,7 @@ static const struct net_device_ops bnx2_netdev_ops = { #endif }; -static inline void vlan_features_add(struct net_device *dev, u32 flags) +static void inline vlan_features_add(struct net_device *dev, u32 flags) { dev->vlan_features |= flags; } diff --git a/trunk/drivers/net/can/c_can/c_can.c b/trunk/drivers/net/can/c_can/c_can.c index 31552959aed7..110eda01843c 100644 --- a/trunk/drivers/net/can/c_can/c_can.c +++ b/trunk/drivers/net/can/c_can/c_can.c @@ -588,9 +588,14 @@ static void c_can_chip_config(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); - /* enable automatic retransmission */ - priv->write_reg(priv, &priv->regs->control, - CONTROL_ENABLE_AR); + if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) + /* disable automatic retransmission */ + priv->write_reg(priv, &priv->regs->control, + CONTROL_DISABLE_AR); + else + /* enable automatic retransmission */ + priv->write_reg(priv, &priv->regs->control, + CONTROL_ENABLE_AR); if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & CAN_CTRLMODE_LOOPBACK)) { @@ -699,6 +704,7 @@ static void c_can_do_tx(struct net_device *dev) for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { msg_obj_no = get_tx_echo_msg_obj(priv); + c_can_inval_msg_object(dev, 0, msg_obj_no); val = c_can_read_reg32(priv, &priv->regs->txrqst1); if (!(val & (1 << msg_obj_no))) { can_get_echo_skb(dev, @@ -707,7 +713,6 @@ static void c_can_do_tx(struct net_device *dev) &priv->regs->ifregs[0].msg_cntrl) & IF_MCONT_DLC_MASK; stats->tx_packets++; - c_can_inval_msg_object(dev, 0, msg_obj_no); } } @@ -1107,7 +1112,8 @@ struct net_device *alloc_c_can_dev(void) priv->can.bittiming_const = &c_can_bittiming_const; priv->can.do_set_mode = c_can_set_mode; priv->can.do_get_berr_counter = c_can_get_berr_counter; - priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | + priv->can.ctrlmode_supported = CAN_CTRLMODE_ONE_SHOT | + CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_BERR_REPORTING; diff --git a/trunk/drivers/net/can/c_can/c_can_platform.c b/trunk/drivers/net/can/c_can/c_can_platform.c index cc90824f2c9c..e629b961ae2d 100644 --- a/trunk/drivers/net/can/c_can/c_can_platform.c +++ b/trunk/drivers/net/can/c_can/c_can_platform.c @@ -73,8 +73,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) void __iomem *addr; struct net_device *dev; struct c_can_priv *priv; - struct resource *mem; - int irq; + struct resource *mem, *irq; #ifdef CONFIG_HAVE_CLK struct clk *clk; @@ -89,8 +88,8 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) /* get the platform data */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!mem || irq <= 0) { + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mem || (irq <= 0)) { ret = -ENODEV; goto exit_free_clk; } @@ -118,7 +117,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) priv = netdev_priv(dev); - dev->irq = irq; + dev->irq = irq->start; priv->regs = addr; #ifdef CONFIG_HAVE_CLK priv->can.clock.freq = clk_get_rate(clk); diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 910893143295..4d538a4e9d55 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -1983,20 +1983,14 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - struct qset_params *qsp; - struct sge_qset *qs; - int i; + struct qset_params *qsp = &adapter->params.sge.qset[0]; + struct sge_qset *qs = &adapter->sge.qs[0]; if (c->rx_coalesce_usecs * 10 > M_NEWTIMER) return -EINVAL; - for (i = 0; i < pi->nqsets; i++) { - qsp = &adapter->params.sge.qset[i]; - qs = &adapter->sge.qs[i]; - qsp->coalesce_usecs = c->rx_coalesce_usecs; - t3_update_qset_coalesce(qs, qsp); - } - + qsp->coalesce_usecs = c->rx_coalesce_usecs; + t3_update_qset_coalesce(qs, qsp); return 0; } diff --git a/trunk/drivers/net/jme.c b/trunk/drivers/net/jme.c index 994c80939c7a..f690474f4409 100644 --- a/trunk/drivers/net/jme.c +++ b/trunk/drivers/net/jme.c @@ -273,7 +273,7 @@ jme_clear_pm(struct jme_adapter *jme) { jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs); pci_set_power_state(jme->pdev, PCI_D0); - device_set_wakeup_enable(&jme->pdev->dev, false); + pci_enable_wake(jme->pdev, PCI_D0, false); } static int @@ -2538,8 +2538,6 @@ jme_set_wol(struct net_device *netdev, jwrite32(jme, JME_PMCS, jme->reg_pmcs); - device_set_wakeup_enable(&jme->pdev->dev, jme->reg_pmcs); - return 0; } @@ -3174,9 +3172,9 @@ jme_shutdown(struct pci_dev *pdev) } #ifdef CONFIG_PM -static int jme_suspend(struct device *dev) +static int +jme_suspend(struct pci_dev *pdev, pm_message_t state) { - struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); @@ -3208,18 +3206,22 @@ static int jme_suspend(struct device *dev) tasklet_hi_enable(&jme->rxclean_task); tasklet_hi_enable(&jme->rxempty_task); + pci_save_state(pdev); jme_powersave_phy(jme); + pci_enable_wake(jme->pdev, PCI_D3hot, true); + pci_set_power_state(pdev, PCI_D3hot); return 0; } -static int jme_resume(struct device *dev) +static int +jme_resume(struct pci_dev *pdev) { - struct pci_dev *pdev = to_pci_dev(dev); struct net_device *netdev = pci_get_drvdata(pdev); struct jme_adapter *jme = netdev_priv(netdev); - jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs); + jme_clear_pm(jme); + pci_restore_state(pdev); jme_phy_on(jme); if (test_bit(JME_FLAG_SSET, &jme->flags)) @@ -3236,13 +3238,6 @@ static int jme_resume(struct device *dev) return 0; } - -static SIMPLE_DEV_PM_OPS(jme_pm_ops, jme_suspend, jme_resume); -#define JME_PM_OPS (&jme_pm_ops) - -#else - -#define JME_PM_OPS NULL #endif static DEFINE_PCI_DEVICE_TABLE(jme_pci_tbl) = { @@ -3256,8 +3251,11 @@ static struct pci_driver jme_driver = { .id_table = jme_pci_tbl, .probe = jme_init_one, .remove = __devexit_p(jme_remove_one), +#ifdef CONFIG_PM + .suspend = jme_suspend, + .resume = jme_resume, +#endif /* CONFIG_PM */ .shutdown = jme_shutdown, - .driver.pm = JME_PM_OPS, }; static int __init diff --git a/trunk/drivers/net/ksz884x.c b/trunk/drivers/net/ksz884x.c index 7f7d5708a658..540a8dcbcc46 100644 --- a/trunk/drivers/net/ksz884x.c +++ b/trunk/drivers/net/ksz884x.c @@ -4898,7 +4898,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) goto unlock; } skb_copy_and_csum_dev(org_skb, skb->data); - org_skb->ip_summed = CHECKSUM_NONE; + org_skb->ip_summed = 0; skb->len = org_skb->len; copy_old_skb(org_skb, skb); } diff --git a/trunk/drivers/net/mlx4/en_netdev.c b/trunk/drivers/net/mlx4/en_netdev.c index 4f158baa0246..5762ebde4455 100644 --- a/trunk/drivers/net/mlx4/en_netdev.c +++ b/trunk/drivers/net/mlx4/en_netdev.c @@ -742,9 +742,6 @@ int mlx4_en_start_port(struct net_device *dev) 0, MLX4_PROT_ETH)) mlx4_warn(mdev, "Failed Attaching Broadcast\n"); - /* Must redo promiscuous mode setup. */ - priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC); - /* Schedule multicast task to populate multicast list */ queue_work(mdev->workqueue, &priv->mcast_task); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 673dc600c891..1f4e8680a96a 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -1312,26 +1312,17 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, * page into an skb */ static inline int -myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, - int lro_enabled) +myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx, + int bytes, int len, __wsum csum) { struct myri10ge_priv *mgp = ss->mgp; struct sk_buff *skb; struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; - struct myri10ge_rx_buf *rx; - int i, idx, hlen, remainder, bytes; + int i, idx, hlen, remainder; struct pci_dev *pdev = mgp->pdev; struct net_device *dev = mgp->dev; u8 *va; - if (len <= mgp->small_bytes) { - rx = &ss->rx_small; - bytes = mgp->small_bytes; - } else { - rx = &ss->rx_big; - bytes = mgp->big_bytes; - } - len += MXGEFW_PAD; idx = rx->cnt & rx->mask; va = page_address(rx->info[idx].page) + rx->info[idx].page_offset; @@ -1350,7 +1341,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, remainder -= MYRI10GE_ALLOC_SIZE; } - if (lro_enabled) { + if (dev->features & NETIF_F_LRO) { rx_frags[0].page_offset += MXGEFW_PAD; rx_frags[0].size -= MXGEFW_PAD; len -= MXGEFW_PAD; @@ -1472,7 +1463,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) { struct myri10ge_rx_done *rx_done = &ss->rx_done; struct myri10ge_priv *mgp = ss->mgp; - + struct net_device *netdev = mgp->dev; unsigned long rx_bytes = 0; unsigned long rx_packets = 0; unsigned long rx_ok; @@ -1483,18 +1474,18 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) u16 length; __wsum checksum; - /* - * Prevent compiler from generating more than one ->features memory - * access to avoid theoretical race condition with functions that - * change NETIF_F_LRO flag at runtime. - */ - bool lro_enabled = ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO; - while (rx_done->entry[idx].length != 0 && work_done < budget) { length = ntohs(rx_done->entry[idx].length); rx_done->entry[idx].length = 0; checksum = csum_unfold(rx_done->entry[idx].checksum); - rx_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled); + if (length <= mgp->small_bytes) + rx_ok = myri10ge_rx_done(ss, &ss->rx_small, + mgp->small_bytes, + length, checksum); + else + rx_ok = myri10ge_rx_done(ss, &ss->rx_big, + mgp->big_bytes, + length, checksum); rx_packets += rx_ok; rx_bytes += rx_ok * (unsigned long)length; cnt++; @@ -1506,7 +1497,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) ss->stats.rx_packets += rx_packets; ss->stats.rx_bytes += rx_bytes; - if (lro_enabled) + if (netdev->features & NETIF_F_LRO) lro_flush_all(&rx_done->lro_mgr); /* restock receive rings if needed */ diff --git a/trunk/drivers/net/netxen/netxen_nic_ethtool.c b/trunk/drivers/net/netxen/netxen_nic_ethtool.c index 3bdcc803ec68..653d308e0f5d 100644 --- a/trunk/drivers/net/netxen/netxen_nic_ethtool.c +++ b/trunk/drivers/net/netxen/netxen_nic_ethtool.c @@ -871,7 +871,7 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data) struct netxen_adapter *adapter = netdev_priv(netdev); int hw_lro; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) + if (data & ~ETH_FLAG_LRO) return -EINVAL; if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)) diff --git a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c index 45b2755d6cba..4c14510e2a87 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c @@ -1003,7 +1003,7 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) struct qlcnic_adapter *adapter = netdev_priv(netdev); int hw_lro; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) + if (data & ~ETH_FLAG_LRO) return -EINVAL; if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 356e74d20b80..2ad6364103ea 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -6726,7 +6726,7 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) int rc = 0; int changed = 0; - if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO)) + if (data & ~ETH_FLAG_LRO) return -EINVAL; if (data & ETH_FLAG_LRO) { diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 73c942d85f07..ebec88882c3b 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -48,9 +48,9 @@ #include #include -#include +#include #include -#include +#include #ifdef CONFIG_SPARC #include @@ -13118,7 +13118,7 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); -static inline void vlan_features_add(struct net_device *dev, unsigned long flags) +static void inline vlan_features_add(struct net_device *dev, unsigned long flags) { dev->vlan_features |= flags; } diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c index 51f2ef142a5b..81254be85b92 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -304,8 +304,8 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data) u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1; unsigned long flags; - if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) - return -EINVAL; + if (data & ~ETH_FLAG_LRO) + return -EOPNOTSUPP; if (lro_requested ^ lro_present) { /* toggle the LRO feature*/ diff --git a/trunk/drivers/net/vxge/vxge-ethtool.c b/trunk/drivers/net/vxge/vxge-ethtool.c index c5eb034107fd..1dd3a21b3a43 100644 --- a/trunk/drivers/net/vxge/vxge-ethtool.c +++ b/trunk/drivers/net/vxge/vxge-ethtool.c @@ -1117,8 +1117,8 @@ static int vxge_set_flags(struct net_device *dev, u32 data) struct vxgedev *vdev = netdev_priv(dev); enum vxge_hw_status status; - if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH)) - return -EINVAL; + if (data & ~ETH_FLAG_RXHASH) + return -EOPNOTSUPP; if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en) return 0; diff --git a/trunk/fs/ceph/addr.c b/trunk/fs/ceph/addr.c index 37368ba2e67c..561438b6a50c 100644 --- a/trunk/fs/ceph/addr.c +++ b/trunk/fs/ceph/addr.c @@ -92,7 +92,7 @@ static int ceph_set_page_dirty(struct page *page) ci->i_head_snapc = ceph_get_snap_context(snapc); ++ci->i_wrbuffer_ref_head; if (ci->i_wrbuffer_ref == 0) - ihold(inode); + igrab(inode); ++ci->i_wrbuffer_ref; dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d " "snapc %p seq %lld (%d snaps)\n", diff --git a/trunk/fs/ceph/snap.c b/trunk/fs/ceph/snap.c index 0aee66b92af3..f40b9139e437 100644 --- a/trunk/fs/ceph/snap.c +++ b/trunk/fs/ceph/snap.c @@ -463,8 +463,8 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode, capsnap, snapc); - ihold(inode); - + igrab(inode); + atomic_set(&capsnap->nref, 1); capsnap->ci = ci; INIT_LIST_HEAD(&capsnap->ci_item); diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index a6804f704d9d..ab1bf5bb021f 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -590,8 +590,7 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner) state->owner = owner; atomic_inc(&owner->so_count); list_add(&state->inode_states, &nfsi->open_states); - ihold(inode); - state->inode = inode; + state->inode = igrab(inode); spin_unlock(&inode->i_lock); /* Note: The reclaim code dictates that we add stateless * and read-only stateids to the end of the list */ diff --git a/trunk/include/linux/can/core.h b/trunk/include/linux/can/core.h index 6f70a6d3a16e..6c507bea275f 100644 --- a/trunk/include/linux/can/core.h +++ b/trunk/include/linux/can/core.h @@ -36,10 +36,10 @@ * @prot: pointer to struct proto structure. */ struct can_proto { - int type; - int protocol; - const struct proto_ops *ops; - struct proto *prot; + int type; + int protocol; + struct proto_ops *ops; + struct proto *prot; }; /* function prototypes for the CAN networklayer core (af_can.c) */ @@ -58,6 +58,5 @@ extern void can_rx_unregister(struct net_device *dev, canid_t can_id, void *data); extern int can_send(struct sk_buff *skb, int loop); -extern int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); #endif /* CAN_CORE_H */ diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index c8fcbdd2b0e7..ae757bcf1280 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -680,7 +680,6 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data); u32 ethtool_op_get_flags(struct net_device *dev); int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported); void ethtool_ntuple_flush(struct net_device *dev); -bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); /** * ðtool_ops - Alter and report network device settings diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 239083bfea13..24cfa626931e 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -122,14 +122,8 @@ struct sk_buff_head { struct sk_buff; -/* To allow 64K frame to be packed as single skb without frag_list. Since - * GRO uses frags we allocate at least 16 regardless of page size. - */ -#if (65536/PAGE_SIZE + 2) < 16 -#define MAX_SKB_FRAGS 16 -#else +/* To allow 64K frame to be packed as single skb without frag_list */ #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2) -#endif typedef struct skb_frag_struct skb_frag_t; diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 75b95df4afe7..2a46cbaef92d 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -345,7 +345,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) { - struct dst_entry *child = dst_clone(skb_dst(skb)->child); + struct dst_entry *child = skb_dst(skb)->child; skb_dst_drop(skb); return child; diff --git a/trunk/include/net/rose.h b/trunk/include/net/rose.h index 555dd198aab7..5ba9f02731eb 100644 --- a/trunk/include/net/rose.h +++ b/trunk/include/net/rose.h @@ -14,12 +14,6 @@ #define ROSE_MIN_LEN 3 -#define ROSE_CALL_REQ_ADDR_LEN_OFF 3 -#define ROSE_CALL_REQ_ADDR_LEN_VAL 0xAA /* each address is 10 digits */ -#define ROSE_CALL_REQ_DEST_ADDR_OFF 4 -#define ROSE_CALL_REQ_SRC_ADDR_OFF 9 -#define ROSE_CALL_REQ_FACILITIES_OFF 14 - #define ROSE_GFI 0x10 #define ROSE_Q_BIT 0x80 #define ROSE_D_BIT 0x40 @@ -220,7 +214,7 @@ extern void rose_requeue_frames(struct sock *); extern int rose_validate_nr(struct sock *, unsigned short); extern void rose_write_internal(struct sock *, int); extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *); -extern int rose_parse_facilities(unsigned char *, unsigned int, struct rose_facilities_struct *); +extern int rose_parse_facilities(unsigned char *, struct rose_facilities_struct *); extern void rose_disconnect(struct sock *, int, int, int); /* rose_timer.c */ diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 6ae4bc5ce8a7..cffa5dc66449 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -1601,28 +1601,6 @@ static inline int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay } #ifdef CONFIG_XFRM_MIGRATE -static inline int xfrm_replay_clone(struct xfrm_state *x, - struct xfrm_state *orig) -{ - x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn), - GFP_KERNEL); - if (!x->replay_esn) - return -ENOMEM; - - x->replay_esn->bmp_len = orig->replay_esn->bmp_len; - x->replay_esn->replay_window = orig->replay_esn->replay_window; - - x->preplay_esn = kmemdup(x->replay_esn, - xfrm_replay_state_esn_len(x->replay_esn), - GFP_KERNEL); - if (!x->preplay_esn) { - kfree(x->replay_esn); - return -ENOMEM; - } - - return 0; -} - static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig) { return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL); diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index acf540768b8f..b3bf54f7d977 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -132,7 +132,7 @@ irq_get_pending(struct cpumask *mask, struct irq_desc *desc) } #else static inline bool irq_can_move_pcntxt(struct irq_data *data) { return true; } -static inline bool irq_move_pending(struct irq_desc *data) { return false; } +static inline bool irq_move_pending(struct irq_data *data) { return false; } static inline void irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask) { } static inline void diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 718b60366dfe..dce8f0009a12 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -389,7 +389,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; int err = 0; - bool changed_addr; /* Don't allow bridging non-ethernet like devices */ if ((dev->flags & IFF_LOOPBACK) || @@ -447,7 +446,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) list_add_rcu(&p->list, &br->port_list); spin_lock_bh(&br->lock); - changed_addr = br_stp_recalculate_bridge_id(br); + br_stp_recalculate_bridge_id(br); br_features_recompute(br); if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && @@ -457,9 +456,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) br_ifinfo_notify(RTM_NEWLINK, p); - if (changed_addr) - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - dev_set_mtu(br->dev, br_min_mtu(br)); kobject_uevent(&p->kobj, KOBJ_ADD); diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 387013d33745..19e2f46ed086 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -497,7 +497,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br); extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val); extern void br_stp_enable_port(struct net_bridge_port *p); extern void br_stp_disable_port(struct net_bridge_port *p); -extern bool br_stp_recalculate_bridge_id(struct net_bridge *br); +extern void br_stp_recalculate_bridge_id(struct net_bridge *br); extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); extern void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio); diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index 5593f5aec942..79372d4a4055 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -204,7 +204,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; /* called under bridge lock */ -bool br_stp_recalculate_bridge_id(struct net_bridge *br) +void br_stp_recalculate_bridge_id(struct net_bridge *br) { const unsigned char *br_mac_zero = (const unsigned char *)br_mac_zero_aligned; @@ -222,11 +222,8 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) } - if (compare_ether_addr(br->bridge_id.addr, addr) == 0) - return false; /* no change */ - - br_stp_change_bridge_id(br, addr); - return true; + if (compare_ether_addr(br->bridge_id.addr, addr)) + br_stp_change_bridge_id(br, addr); } /* called under bridge lock */ diff --git a/trunk/net/can/af_can.c b/trunk/net/can/af_can.c index 733d66f1b05a..702be5a2c956 100644 --- a/trunk/net/can/af_can.c +++ b/trunk/net/can/af_can.c @@ -95,7 +95,7 @@ struct s_pstats can_pstats; /* receive list statistics */ * af_can socket functions */ -int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; @@ -108,7 +108,6 @@ int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return -ENOIOCTLCMD; } } -EXPORT_SYMBOL(can_ioctl); static void can_sock_destruct(struct sock *sk) { @@ -699,9 +698,13 @@ int can_proto_register(struct can_proto *cp) printk(KERN_ERR "can: protocol %d already registered\n", proto); err = -EBUSY; - } else + } else { proto_tab[proto] = cp; + /* use generic ioctl function if not defined by module */ + if (!cp->ops->ioctl) + cp->ops->ioctl = can_ioctl; + } spin_unlock(&proto_tab_lock); if (err < 0) diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 871a0ad51025..092dc88a7c64 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -1569,7 +1569,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock, return size; } -static const struct proto_ops bcm_ops = { +static struct proto_ops bcm_ops __read_mostly = { .family = PF_CAN, .release = bcm_release, .bind = sock_no_bind, @@ -1578,7 +1578,7 @@ static const struct proto_ops bcm_ops = { .accept = sock_no_accept, .getname = sock_no_getname, .poll = datagram_poll, - .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ + .ioctl = NULL, /* use can_ioctl() from af_can.c */ .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt, diff --git a/trunk/net/can/raw.c b/trunk/net/can/raw.c index 649acfa7c70a..883e9d74fddf 100644 --- a/trunk/net/can/raw.c +++ b/trunk/net/can/raw.c @@ -742,7 +742,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, return size; } -static const struct proto_ops raw_ops = { +static struct proto_ops raw_ops __read_mostly = { .family = PF_CAN, .release = raw_release, .bind = raw_bind, @@ -751,7 +751,7 @@ static const struct proto_ops raw_ops = { .accept = sock_no_accept, .getname = raw_getname, .poll = datagram_poll, - .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ + .ioctl = NULL, /* use can_ioctl() from af_can.c */ .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = raw_setsockopt, diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 563ddc28139d..f453370131a0 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1140,6 +1140,9 @@ static int __dev_open(struct net_device *dev) ASSERT_RTNL(); + /* + * Is it even present? + */ if (!netif_device_present(dev)) return -ENODEV; @@ -1148,6 +1151,9 @@ static int __dev_open(struct net_device *dev) if (ret) return ret; + /* + * Call device private open method + */ set_bit(__LINK_STATE_START, &dev->state); if (ops->ndo_validate_addr) @@ -1156,12 +1162,31 @@ static int __dev_open(struct net_device *dev) if (!ret && ops->ndo_open) ret = ops->ndo_open(dev); + /* + * If it went open OK then: + */ + if (ret) clear_bit(__LINK_STATE_START, &dev->state); else { + /* + * Set the flags. + */ dev->flags |= IFF_UP; + + /* + * Enable NET_DMA + */ net_dmaengine_get(); + + /* + * Initialize multicasting status + */ dev_set_rx_mode(dev); + + /* + * Wakeup transmit queue engine + */ dev_activate(dev); } @@ -1184,13 +1209,22 @@ int dev_open(struct net_device *dev) { int ret; + /* + * Is it already up? + */ if (dev->flags & IFF_UP) return 0; + /* + * Open device + */ ret = __dev_open(dev); if (ret < 0) return ret; + /* + * ... and announce new interface. + */ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); call_netdevice_notifiers(NETDEV_UP, dev); @@ -1206,6 +1240,10 @@ static int __dev_close_many(struct list_head *head) might_sleep(); list_for_each_entry(dev, head, unreg_list) { + /* + * Tell people we are going down, so that they can + * prepare to death, when device is still operating. + */ call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); clear_bit(__LINK_STATE_START, &dev->state); @@ -1234,7 +1272,15 @@ static int __dev_close_many(struct list_head *head) if (ops->ndo_stop) ops->ndo_stop(dev); + /* + * Device is now down. + */ + dev->flags &= ~IFF_UP; + + /* + * Shutdown NET_DMA + */ net_dmaengine_put(); } @@ -1263,6 +1309,9 @@ static int dev_close_many(struct list_head *head) __dev_close_many(head); + /* + * Tell people we are down + */ list_for_each_entry(dev, head, unreg_list) { rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); call_netdevice_notifiers(NETDEV_DOWN, dev); @@ -1322,6 +1371,11 @@ EXPORT_SYMBOL(dev_disable_lro); static int dev_boot_phase = 1; +/* + * Device change register/unregister. These are not inline or static + * as we export them to the world. + */ + /** * register_netdevice_notifier - register a network notifier block * @nb: notifier @@ -1423,7 +1477,6 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev) ASSERT_RTNL(); return raw_notifier_call_chain(&netdev_chain, val, dev); } -EXPORT_SYMBOL(call_netdevice_notifiers); /* When > 0 there are consumers of rx skb time stamps */ static atomic_t netstamp_needed = ATOMIC_INIT(0); diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index 74ead9eca126..24bd57493c0d 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -141,24 +141,9 @@ u32 ethtool_op_get_flags(struct net_device *dev) } EXPORT_SYMBOL(ethtool_op_get_flags); -/* Check if device can enable (or disable) particular feature coded in "data" - * argument. Flags "supported" describe features that can be toggled by device. - * If feature can not be toggled, it state (enabled or disabled) must match - * hardcoded device features state, otherwise flags are marked as invalid. - */ -bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported) -{ - u32 features = dev->features & flags_dup_features; - /* "data" can contain only flags_dup_features bits, - * see __ethtool_set_flags */ - - return (features & ~supported) != (data & ~supported); -} -EXPORT_SYMBOL(ethtool_invalid_flags); - int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) { - if (ethtool_invalid_flags(dev, data, supported)) + if (data & ~supported) return -EINVAL; dev->features = ((dev->features & ~flags_dup_features) | diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index b92c86f6e9b3..90a3ff605591 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1365,9 +1365,9 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, err = fib_props[fa->fa_type].error; if (err) { #ifdef CONFIG_IP_FIB_TRIE_STATS - t->stats.semantic_match_passed++; + t->stats.semantic_match_miss++; #endif - return err; + return 1; } if (fi->fib_flags & RTNH_F_DEAD) continue; diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index 28a736f3442f..1906fa35860c 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -140,11 +140,11 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) } else { dopt->ts_needtime = 0; - if (soffset + 7 <= optlen) { + if (soffset + 8 <= optlen) { __be32 addr; - memcpy(&addr, dptr+soffset-1, 4); - if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) { + memcpy(&addr, sptr+soffset-1, 4); + if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) { dopt->ts_needtime = 1; soffset += 8; } diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 2d3c72e5bbbf..e837ffd3edc3 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -569,7 +569,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, rt = ip_route_output_flow(sock_net(sk), &fl4, sk); if (IS_ERR(rt)) { err = PTR_ERR(rt); - rt = NULL; goto done; } } diff --git a/trunk/net/ipv6/ip6mr.c b/trunk/net/ipv6/ip6mr.c index 29e48593bf22..7ff0343e05c7 100644 --- a/trunk/net/ipv6/ip6mr.c +++ b/trunk/net/ipv6/ip6mr.c @@ -663,7 +663,7 @@ static int pim6_rcv(struct sk_buff *skb) skb_pull(skb, (u8 *)encap - skb->data); skb_reset_network_header(skb); skb->protocol = htons(ETH_P_IPV6); - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; skb_tunnel_rx(skb, reg_dev); diff --git a/trunk/net/irda/iriap.c b/trunk/net/irda/iriap.c index 36477538cea8..5b743bdd89ba 100644 --- a/trunk/net/irda/iriap.c +++ b/trunk/net/irda/iriap.c @@ -656,16 +656,10 @@ static void iriap_getvaluebyclass_indication(struct iriap_cb *self, n = 1; name_len = fp[n++]; - - IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;); - memcpy(name, fp+n, name_len); n+=name_len; name[name_len] = '\0'; attr_len = fp[n++]; - - IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;); - memcpy(attr, fp+n, attr_len); n+=attr_len; attr[attr_len] = '\0'; diff --git a/trunk/net/irda/irnet/irnet_ppp.c b/trunk/net/irda/irnet/irnet_ppp.c index 2bb2beb6a373..7c567b8aa89a 100644 --- a/trunk/net/irda/irnet/irnet_ppp.c +++ b/trunk/net/irda/irnet/irnet_ppp.c @@ -105,9 +105,6 @@ irnet_ctrl_write(irnet_socket * ap, while(isspace(start[length - 1])) length--; - DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5, - -EINVAL, CTRL_ERROR, "Invalid nickname.\n"); - /* Copy the name for later reuse */ memcpy(ap->rname, start + 5, length - 5); ap->rname[length - 5] = '\0'; diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index a80aef6e3d1f..5ee0c62046a0 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -978,7 +978,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros struct sock *make; struct rose_sock *make_rose; struct rose_facilities_struct facilities; - int n; + int n, len; skb->sk = NULL; /* Initially we don't know who it's for */ @@ -987,9 +987,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros */ memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); - if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF, - skb->len - ROSE_CALL_REQ_FACILITIES_OFF, - &facilities)) { + len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; + len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; + if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76); return 0; } diff --git a/trunk/net/rose/rose_loopback.c b/trunk/net/rose/rose_loopback.c index 344456206b70..ae4a9d99aec7 100644 --- a/trunk/net/rose/rose_loopback.c +++ b/trunk/net/rose/rose_loopback.c @@ -73,20 +73,9 @@ static void rose_loopback_timer(unsigned long param) unsigned int lci_i, lci_o; while ((skb = skb_dequeue(&loopback_queue)) != NULL) { - if (skb->len < ROSE_MIN_LEN) { - kfree_skb(skb); - continue; - } lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); frametype = skb->data[2]; - if (frametype == ROSE_CALL_REQUEST && - (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF || - skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] != - ROSE_CALL_REQ_ADDR_LEN_VAL)) { - kfree_skb(skb); - continue; - } - dest = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF); + dest = (rose_address *)(skb->data + 4); lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i; skb_reset_transport_header(skb); diff --git a/trunk/net/rose/rose_route.c b/trunk/net/rose/rose_route.c index 08dcd2f29cdc..88a77e90e7e8 100644 --- a/trunk/net/rose/rose_route.c +++ b/trunk/net/rose/rose_route.c @@ -861,7 +861,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) unsigned int lci, new_lci; unsigned char cause, diagnostic; struct net_device *dev; - int res = 0; + int len, res = 0; char buf[11]; #if 0 @@ -869,17 +869,10 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) return res; #endif - if (skb->len < ROSE_MIN_LEN) - return res; frametype = skb->data[2]; lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); - if (frametype == ROSE_CALL_REQUEST && - (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF || - skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] != - ROSE_CALL_REQ_ADDR_LEN_VAL)) - return res; - src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF); - dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF); + src_addr = (rose_address *)(skb->data + 9); + dest_addr = (rose_address *)(skb->data + 4); spin_lock_bh(&rose_neigh_list_lock); spin_lock_bh(&rose_route_list_lock); @@ -1017,11 +1010,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) goto out; } + len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; + len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; + memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); - if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF, - skb->len - ROSE_CALL_REQ_FACILITIES_OFF, - &facilities)) { + if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76); goto out; } diff --git a/trunk/net/rose/rose_subr.c b/trunk/net/rose/rose_subr.c index f6c71caa94b9..1734abba26a2 100644 --- a/trunk/net/rose/rose_subr.c +++ b/trunk/net/rose/rose_subr.c @@ -142,7 +142,7 @@ void rose_write_internal(struct sock *sk, int frametype) *dptr++ = ROSE_GFI | lci1; *dptr++ = lci2; *dptr++ = frametype; - *dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL; + *dptr++ = 0xAA; memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN); dptr += ROSE_ADDR_LEN; memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN); @@ -246,16 +246,12 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * do { switch (*p & 0xC0) { case 0x00: - if (len < 2) - return -1; p += 2; n += 2; len -= 2; break; case 0x40: - if (len < 3) - return -1; if (*p == FAC_NATIONAL_RAND) facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF); p += 3; @@ -264,61 +260,40 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * break; case 0x80: - if (len < 4) - return -1; p += 4; n += 4; len -= 4; break; case 0xC0: - if (len < 2) - return -1; l = p[1]; - if (len < 2 + l) - return -1; if (*p == FAC_NATIONAL_DEST_DIGI) { if (!fac_national_digis_received) { - if (l < AX25_ADDR_LEN) - return -1; memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN); facilities->source_ndigis = 1; } } else if (*p == FAC_NATIONAL_SRC_DIGI) { if (!fac_national_digis_received) { - if (l < AX25_ADDR_LEN) - return -1; memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN); facilities->dest_ndigis = 1; } } else if (*p == FAC_NATIONAL_FAIL_CALL) { - if (l < AX25_ADDR_LEN) - return -1; memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN); } else if (*p == FAC_NATIONAL_FAIL_ADD) { - if (l < 1 + ROSE_ADDR_LEN) - return -1; memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN); } else if (*p == FAC_NATIONAL_DIGIS) { - if (l % AX25_ADDR_LEN) - return -1; fac_national_digis_received = 1; facilities->source_ndigis = 0; facilities->dest_ndigis = 0; for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) { - if (pt[6] & AX25_HBIT) { - if (facilities->dest_ndigis >= ROSE_MAX_DIGIS) - return -1; + if (pt[6] & AX25_HBIT) memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN); - } else { - if (facilities->source_ndigis >= ROSE_MAX_DIGIS) - return -1; + else memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN); - } } } p += l + 2; @@ -339,38 +314,25 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac do { switch (*p & 0xC0) { case 0x00: - if (len < 2) - return -1; p += 2; n += 2; len -= 2; break; case 0x40: - if (len < 3) - return -1; p += 3; n += 3; len -= 3; break; case 0x80: - if (len < 4) - return -1; p += 4; n += 4; len -= 4; break; case 0xC0: - if (len < 2) - return -1; l = p[1]; - - /* Prevent overflows*/ - if (l < 10 || l > 20) - return -1; - if (*p == FAC_CCITT_DEST_NSAP) { memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); memcpy(callsign, p + 12, l - 10); @@ -393,44 +355,45 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac return n; } -int rose_parse_facilities(unsigned char *p, unsigned packet_len, +int rose_parse_facilities(unsigned char *p, struct rose_facilities_struct *facilities) { int facilities_len, len; facilities_len = *p++; - if (facilities_len == 0 || (unsigned)facilities_len > packet_len) + if (facilities_len == 0) return 0; - while (facilities_len >= 3 && *p == 0x00) { - facilities_len--; - p++; - - switch (*p) { - case FAC_NATIONAL: /* National */ - len = rose_parse_national(p + 1, facilities, facilities_len - 1); - break; - - case FAC_CCITT: /* CCITT */ - len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); - break; - - default: - printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); - len = 1; - break; - } - - if (len < 0) - return 0; - if (WARN_ON(len >= facilities_len)) - return 0; - facilities_len -= len + 1; - p += len + 1; + while (facilities_len > 0) { + if (*p == 0x00) { + facilities_len--; + p++; + + switch (*p) { + case FAC_NATIONAL: /* National */ + len = rose_parse_national(p + 1, facilities, facilities_len - 1); + facilities_len -= len + 1; + p += len + 1; + break; + + case FAC_CCITT: /* CCITT */ + len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); + facilities_len -= len + 1; + p += len + 1; + break; + + default: + printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); + facilities_len--; + p++; + break; + } + } else + break; /* Error in facilities format */ } - return facilities_len == 0; + return 1; } static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index a026b0ef2443..872065ca7f8c 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -173,7 +173,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop_unlock; } - if (x->repl->check(x, skb, seq)) { + if (x->props.replay_window && x->repl->check(x, skb, seq)) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); goto drop_unlock; } @@ -190,8 +190,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) XFRM_SKB_CB(skb)->seq.input.low = seq; XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; - skb_dst_force(skb); - nexthdr = x->type->input(x, skb); if (nexthdr == -EINPROGRESS) diff --git a/trunk/net/xfrm/xfrm_output.c b/trunk/net/xfrm/xfrm_output.c index 47bacd8c0250..1aba03f449cc 100644 --- a/trunk/net/xfrm/xfrm_output.c +++ b/trunk/net/xfrm/xfrm_output.c @@ -78,8 +78,6 @@ static int xfrm_output_one(struct sk_buff *skb, int err) spin_unlock_bh(&x->lock); - skb_dst_force(skb); - err = x->type->output(x, skb); if (err == -EINPROGRESS) goto out_exit; @@ -96,7 +94,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) err = -EHOSTUNREACH; goto error_nolock; } - skb_dst_set(skb, dst); + skb_dst_set(skb, dst_clone(dst)); x = dst->xfrm; } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); diff --git a/trunk/net/xfrm/xfrm_replay.c b/trunk/net/xfrm/xfrm_replay.c index f218385950ca..2f5be5b15740 100644 --- a/trunk/net/xfrm/xfrm_replay.c +++ b/trunk/net/xfrm/xfrm_replay.c @@ -118,9 +118,6 @@ static int xfrm_replay_check(struct xfrm_state *x, u32 diff; u32 seq = ntohl(net_seq); - if (!x->props.replay_window) - return 0; - if (unlikely(seq == 0)) goto err; @@ -196,14 +193,9 @@ static int xfrm_replay_check_bmp(struct xfrm_state *x, { unsigned int bitnr, nr; struct xfrm_replay_state_esn *replay_esn = x->replay_esn; - u32 pos; u32 seq = ntohl(net_seq); u32 diff = replay_esn->seq - seq; - - if (!replay_esn->replay_window) - return 0; - - pos = (replay_esn->seq - 1) % replay_esn->replay_window; + u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window; if (unlikely(seq == 0)) goto err; @@ -381,17 +373,12 @@ static int xfrm_replay_check_esn(struct xfrm_state *x, unsigned int bitnr, nr; u32 diff; struct xfrm_replay_state_esn *replay_esn = x->replay_esn; - u32 pos; u32 seq = ntohl(net_seq); + u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window; u32 wsize = replay_esn->replay_window; u32 top = replay_esn->seq; u32 bottom = top - wsize + 1; - if (!wsize) - return 0; - - pos = (replay_esn->seq - 1) % replay_esn->replay_window; - if (unlikely(seq == 0 && replay_esn->seq_hi == 0 && (replay_esn->seq < replay_esn->replay_window - 1))) goto err; diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index dd78536d40de..f83a3d1da81b 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -1181,12 +1181,6 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) goto error; } - if (orig->replay_esn) { - err = xfrm_replay_clone(x, orig); - if (err) - goto error; - } - memcpy(&x->mark, &orig->mark, sizeof(x->mark)); err = xfrm_init_state(x); diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index 3d15d3e1b2c4..fc152d28753c 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -127,9 +127,6 @@ static inline int verify_replay(struct xfrm_usersa_info *p, if (!rt) return 0; - if (p->id.proto != IPPROTO_ESP) - return -EINVAL; - if (p->replay_window != 0) return -EINVAL; @@ -363,23 +360,6 @@ static int attach_aead(struct xfrm_algo_aead **algpp, u8 *props, return 0; } -static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_esn, - struct nlattr *rp) -{ - struct xfrm_replay_state_esn *up; - - if (!replay_esn || !rp) - return 0; - - up = nla_data(rp); - - if (xfrm_replay_state_esn_len(replay_esn) != - xfrm_replay_state_esn_len(up)) - return -EINVAL; - - return 0; -} - static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn, struct xfrm_replay_state_esn **preplay_esn, struct nlattr *rta) @@ -1786,10 +1766,6 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, if (x->km.state != XFRM_STATE_VALID) goto out; - err = xfrm_replay_verify_len(x->replay_esn, rp); - if (err) - goto out; - spin_lock_bh(&x->lock); xfrm_update_ae_params(x, attrs); spin_unlock_bh(&x->lock);