Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (30 commits)
  xfrm: Restrict extended sequence numbers to esp
  xfrm: Check for esn buffer len in xfrm_new_ae
  xfrm: Assign esn pointers when cloning a state
  xfrm: Move the test on replay window size into the replay check functions
  netdev: bfin_mac: document TE setting in RMII modes
  drivers net: Fix declaration ordering in inline functions.
  cxgb3: Apply interrupt coalescing settings to all queues
  net: Always allocate at least 16 skb frags regardless of page size
  ipv4: Don't ip_rt_put() an error pointer in RAW sockets.
  net: fix ethtool->set_flags not intended -EINVAL return value
  mlx4_en: Fix loss of promiscuity
  tg3: Fix inline keyword usage
  tg3: use <linux/io.h> and <linux/uaccess.h> instead <asm/io.h> and <asm/uaccess.h>
  net: use CHECKSUM_NONE instead of magic number
  Net / jme: Do not use legacy PCI power management
  myri10ge: small rx_done refactoring
  bridge: notify applications if address of bridge device changes
  ipv4: Fix IP timestamp option (IPOPT_TS_PRESPEC) handling in ip_options_echo()
  can: c_can: Fix tx_bytes accounting
  can: c_can_platform: fix irq check in probe
  ...
This commit is contained in:
Linus Torvalds 2011-03-29 07:41:33 -07:00
commit cb1817b373
44 changed files with 326 additions and 189 deletions

View file

@ -1237,8 +1237,17 @@ 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)) && CONFIG_BF_REV_0_2
opmode |= TE;
#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;
}
#endif
}

View file

@ -8317,7 +8317,7 @@ static const struct net_device_ops bnx2_netdev_ops = {
#endif
};
static void inline vlan_features_add(struct net_device *dev, u32 flags)
static inline void vlan_features_add(struct net_device *dev, u32 flags)
{
dev->vlan_features |= flags;
}

View file

@ -588,14 +588,9 @@ static void c_can_chip_config(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
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);
/* enable automatic retransmission */
priv->write_reg(priv, &priv->regs->control,
CONTROL_ENABLE_AR);
if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY &
CAN_CTRLMODE_LOOPBACK)) {
@ -704,7 +699,6 @@ 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,
@ -713,6 +707,7 @@ 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);
}
}
@ -1112,8 +1107,7 @@ 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_ONE_SHOT |
CAN_CTRLMODE_LOOPBACK |
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_BERR_REPORTING;

View file

@ -73,7 +73,8 @@ 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, *irq;
struct resource *mem;
int irq;
#ifdef CONFIG_HAVE_CLK
struct clk *clk;
@ -88,8 +89,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_resource(pdev, IORESOURCE_IRQ, 0);
if (!mem || (irq <= 0)) {
irq = platform_get_irq(pdev, 0);
if (!mem || irq <= 0) {
ret = -ENODEV;
goto exit_free_clk;
}
@ -117,7 +118,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
dev->irq = irq->start;
dev->irq = irq;
priv->regs = addr;
#ifdef CONFIG_HAVE_CLK
priv->can.clock.freq = clk_get_rate(clk);

View file

@ -1983,14 +1983,20 @@ 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 = &adapter->params.sge.qset[0];
struct sge_qset *qs = &adapter->sge.qs[0];
struct qset_params *qsp;
struct sge_qset *qs;
int i;
if (c->rx_coalesce_usecs * 10 > M_NEWTIMER)
return -EINVAL;
qsp->coalesce_usecs = c->rx_coalesce_usecs;
t3_update_qset_coalesce(qs, qsp);
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);
}
return 0;
}

View file

@ -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);
pci_enable_wake(jme->pdev, PCI_D0, false);
device_set_wakeup_enable(&jme->pdev->dev, false);
}
static int
@ -2538,6 +2538,8 @@ 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;
}
@ -3172,9 +3174,9 @@ jme_shutdown(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
static int
jme_suspend(struct pci_dev *pdev, pm_message_t state)
static int jme_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
@ -3206,22 +3208,18 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
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 pci_dev *pdev)
static int jme_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
jme_clear_pm(jme);
pci_restore_state(pdev);
jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
@ -3238,6 +3236,13 @@ jme_resume(struct pci_dev *pdev)
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) = {
@ -3251,11 +3256,8 @@ 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

View file

@ -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 = 0;
org_skb->ip_summed = CHECKSUM_NONE;
skb->len = org_skb->len;
copy_old_skb(org_skb, skb);
}

View file

@ -742,6 +742,9 @@ 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);

View file

@ -1312,17 +1312,26 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
* page into an skb */
static inline int
myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
int bytes, int len, __wsum csum)
myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum,
int lro_enabled)
{
struct myri10ge_priv *mgp = ss->mgp;
struct sk_buff *skb;
struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
int i, idx, hlen, remainder;
struct myri10ge_rx_buf *rx;
int i, idx, hlen, remainder, bytes;
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;
@ -1341,7 +1350,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
remainder -= MYRI10GE_ALLOC_SIZE;
}
if (dev->features & NETIF_F_LRO) {
if (lro_enabled) {
rx_frags[0].page_offset += MXGEFW_PAD;
rx_frags[0].size -= MXGEFW_PAD;
len -= MXGEFW_PAD;
@ -1463,7 +1472,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;
@ -1474,18 +1483,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);
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_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled);
rx_packets += rx_ok;
rx_bytes += rx_ok * (unsigned long)length;
cnt++;
@ -1497,7 +1506,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 (netdev->features & NETIF_F_LRO)
if (lro_enabled)
lro_flush_all(&rx_done->lro_mgr);
/* restock receive rings if needed */

View file

@ -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 (data & ~ETH_FLAG_LRO)
if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
return -EINVAL;
if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))

View file

@ -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 (data & ~ETH_FLAG_LRO)
if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
return -EINVAL;
if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))

View file

@ -6726,7 +6726,7 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
int rc = 0;
int changed = 0;
if (data & ~ETH_FLAG_LRO)
if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO))
return -EINVAL;
if (data & ETH_FLAG_LRO) {

View file

@ -48,9 +48,9 @@
#include <net/ip.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
#ifdef CONFIG_SPARC
#include <asm/idprom.h>
@ -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 void inline vlan_features_add(struct net_device *dev, unsigned long flags)
static inline void vlan_features_add(struct net_device *dev, unsigned long flags)
{
dev->vlan_features |= flags;
}

View file

@ -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 (data & ~ETH_FLAG_LRO)
return -EOPNOTSUPP;
if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
return -EINVAL;
if (lro_requested ^ lro_present) {
/* toggle the LRO feature*/

View file

@ -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 (data & ~ETH_FLAG_RXHASH)
return -EOPNOTSUPP;
if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH))
return -EINVAL;
if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
return 0;

View file

@ -36,10 +36,10 @@
* @prot: pointer to struct proto structure.
*/
struct can_proto {
int type;
int protocol;
struct proto_ops *ops;
struct proto *prot;
int type;
int protocol;
const struct proto_ops *ops;
struct proto *prot;
};
/* function prototypes for the CAN networklayer core (af_can.c) */
@ -58,5 +58,6 @@ 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 */

View file

@ -680,6 +680,7 @@ 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);
/**
* &ethtool_ops - Alter and report network device settings

View file

@ -122,8 +122,14 @@ struct sk_buff_head {
struct sk_buff;
/* To allow 64K frame to be packed as single skb without frag_list */
/* 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
#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
#endif
typedef struct skb_frag_struct skb_frag_t;

View file

@ -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 = skb_dst(skb)->child;
struct dst_entry *child = dst_clone(skb_dst(skb)->child);
skb_dst_drop(skb);
return child;

View file

@ -14,6 +14,12 @@
#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
@ -214,7 +220,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 *, struct rose_facilities_struct *);
extern int rose_parse_facilities(unsigned char *, unsigned int, struct rose_facilities_struct *);
extern void rose_disconnect(struct sock *, int, int, int);
/* rose_timer.c */

View file

@ -1601,6 +1601,28 @@ 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);

View file

@ -389,6 +389,7 @@ 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) ||
@ -446,7 +447,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);
br_stp_recalculate_bridge_id(br);
changed_addr = br_stp_recalculate_bridge_id(br);
br_features_recompute(br);
if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
@ -456,6 +457,9 @@ 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);

View file

@ -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 void br_stp_recalculate_bridge_id(struct net_bridge *br);
extern bool 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);

View file

@ -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 */
void br_stp_recalculate_bridge_id(struct net_bridge *br)
bool br_stp_recalculate_bridge_id(struct net_bridge *br)
{
const unsigned char *br_mac_zero =
(const unsigned char *)br_mac_zero_aligned;
@ -222,8 +222,11 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
}
if (compare_ether_addr(br->bridge_id.addr, addr))
br_stp_change_bridge_id(br, addr);
if (compare_ether_addr(br->bridge_id.addr, addr) == 0)
return false; /* no change */
br_stp_change_bridge_id(br, addr);
return true;
}
/* called under bridge lock */

View file

@ -95,7 +95,7 @@ struct s_pstats can_pstats; /* receive list statistics */
* af_can socket functions
*/
static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
@ -108,6 +108,7 @@ static 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)
{
@ -698,13 +699,9 @@ 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)

View file

@ -1569,7 +1569,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
return size;
}
static struct proto_ops bcm_ops __read_mostly = {
static const struct proto_ops bcm_ops = {
.family = PF_CAN,
.release = bcm_release,
.bind = sock_no_bind,
@ -1578,7 +1578,7 @@ static struct proto_ops bcm_ops __read_mostly = {
.accept = sock_no_accept,
.getname = sock_no_getname,
.poll = datagram_poll,
.ioctl = NULL, /* use can_ioctl() from af_can.c */
.ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt,

View file

@ -742,7 +742,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
return size;
}
static struct proto_ops raw_ops __read_mostly = {
static const struct proto_ops raw_ops = {
.family = PF_CAN,
.release = raw_release,
.bind = raw_bind,
@ -751,7 +751,7 @@ static struct proto_ops raw_ops __read_mostly = {
.accept = sock_no_accept,
.getname = raw_getname,
.poll = datagram_poll,
.ioctl = NULL, /* use can_ioctl() from af_can.c */
.ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = raw_setsockopt,

View file

@ -1140,9 +1140,6 @@ static int __dev_open(struct net_device *dev)
ASSERT_RTNL();
/*
* Is it even present?
*/
if (!netif_device_present(dev))
return -ENODEV;
@ -1151,9 +1148,6 @@ 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)
@ -1162,31 +1156,12 @@ 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);
}
@ -1209,22 +1184,13 @@ 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);
@ -1240,10 +1206,6 @@ 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);
@ -1272,15 +1234,7 @@ 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();
}
@ -1309,9 +1263,6 @@ 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);
@ -1371,11 +1322,6 @@ 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
@ -1477,6 +1423,7 @@ 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);

View file

@ -141,9 +141,24 @@ 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 (data & ~supported)
if (ethtool_invalid_flags(dev, data, supported))
return -EINVAL;
dev->features = ((dev->features & ~flags_dup_features) |

View file

@ -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_miss++;
t->stats.semantic_match_passed++;
#endif
return 1;
return err;
}
if (fi->fib_flags & RTNH_F_DEAD)
continue;

View file

@ -140,11 +140,11 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
} else {
dopt->ts_needtime = 0;
if (soffset + 8 <= optlen) {
if (soffset + 7 <= optlen) {
__be32 addr;
memcpy(&addr, sptr+soffset-1, 4);
if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) {
memcpy(&addr, dptr+soffset-1, 4);
if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) {
dopt->ts_needtime = 1;
soffset += 8;
}

View file

@ -569,6 +569,7 @@ 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;
}
}

View file

@ -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 = 0;
skb->ip_summed = CHECKSUM_NONE;
skb->pkt_type = PACKET_HOST;
skb_tunnel_rx(skb, reg_dev);

View file

@ -656,10 +656,16 @@ 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';

View file

@ -105,6 +105,9 @@ 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';

View file

@ -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, len;
int n;
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));
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)) {
if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
&facilities)) {
rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76);
return 0;
}

View file

@ -73,9 +73,20 @@ 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];
dest = (rose_address *)(skb->data + 4);
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);
lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i;
skb_reset_transport_header(skb);

View file

@ -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 len, res = 0;
int res = 0;
char buf[11];
#if 0
@ -869,10 +869,17 @@ 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);
src_addr = (rose_address *)(skb->data + 9);
dest_addr = (rose_address *)(skb->data + 4);
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);
spin_lock_bh(&rose_neigh_list_lock);
spin_lock_bh(&rose_route_list_lock);
@ -1010,12 +1017,11 @@ 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 + len + 4, &facilities)) {
if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
&facilities)) {
rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
goto out;
}

View file

@ -142,7 +142,7 @@ void rose_write_internal(struct sock *sk, int frametype)
*dptr++ = ROSE_GFI | lci1;
*dptr++ = lci2;
*dptr++ = frametype;
*dptr++ = 0xAA;
*dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL;
memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN);
dptr += ROSE_ADDR_LEN;
memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN);
@ -246,12 +246,16 @@ 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;
@ -260,40 +264,61 @@ 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 (pt[6] & AX25_HBIT) {
if (facilities->dest_ndigis >= ROSE_MAX_DIGIS)
return -1;
memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
else
} else {
if (facilities->source_ndigis >= ROSE_MAX_DIGIS)
return -1;
memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
}
}
}
p += l + 2;
@ -314,25 +339,38 @@ 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);
@ -355,45 +393,44 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
return n;
}
int rose_parse_facilities(unsigned char *p,
int rose_parse_facilities(unsigned char *p, unsigned packet_len,
struct rose_facilities_struct *facilities)
{
int facilities_len, len;
facilities_len = *p++;
if (facilities_len == 0)
if (facilities_len == 0 || (unsigned)facilities_len > packet_len)
return 0;
while (facilities_len > 0) {
if (*p == 0x00) {
facilities_len--;
p++;
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);
facilities_len -= len + 1;
p += len + 1;
break;
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);
facilities_len -= len + 1;
p += 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);
facilities_len--;
p++;
break;
}
} else
break; /* Error in facilities format */
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;
}
return 1;
return facilities_len == 0;
}
static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)

View file

@ -173,7 +173,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop_unlock;
}
if (x->props.replay_window && x->repl->check(x, skb, seq)) {
if (x->repl->check(x, skb, seq)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}
@ -190,6 +190,8 @@ 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)

View file

@ -78,6 +78,8 @@ 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;
@ -94,7 +96,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
err = -EHOSTUNREACH;
goto error_nolock;
}
skb_dst_set(skb, dst_clone(dst));
skb_dst_set(skb, dst);
x = dst->xfrm;
} while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));

View file

@ -118,6 +118,9 @@ 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;
@ -193,9 +196,14 @@ 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;
u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
if (!replay_esn->replay_window)
return 0;
pos = (replay_esn->seq - 1) % replay_esn->replay_window;
if (unlikely(seq == 0))
goto err;
@ -373,12 +381,17 @@ 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;

View file

@ -1181,6 +1181,12 @@ 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);

View file

@ -127,6 +127,9 @@ 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;
@ -360,6 +363,23 @@ 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)
@ -1766,6 +1786,10 @@ 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);