Commit 596fa9e6 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull networking fixes from David Miller:

 1) Fix RTNL locking in batman-adv, from Matthias Schiffer.

 2) Don't allow non-passthrough macvlan devices to set NOPROMISC via
    netlink, otherwise we can end up with corrupted promisc counter
    values on the device.  From Michael S Tsirkin.

 3) Fix stmmac driver build with debugging defines enabled, from Dinh
    Nguyen.

 4) Make sure name string we give in socket address in AF_PACKET is NULL
    terminated, from Daniel Borkmann.

 5) Fix leaking of two uninitialized bytes of memory to userspace in
    l2tp, from Guillaume Nault.

 6) Clear IPCB(skb) before tunneling otherwise we touch dangling IP
    options state and crash.  From Saurabh Mohan.

 7) Fix suspend/resume for davinci_mdio by using suspend_late and
    resume_early.  From Mugunthan V N.

 8) Don't tag ip_tunnel_init_net and ip_tunnel_delete_net with
    __net_{init,exit}, they can be called outside of those contexts.
    From Eric Dumazet.

 9) Fix RX length error in sh_eth driver, from Yoshihiro Shimoda.

10) Fix missing sctp_outq initialization in some code paths of SCTP
    stack, from Neil Horman.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (21 commits)
  sctp: fully initialize sctp_outq in sctp_outq_init
  netiucv: Hold rtnl between name allocation and device registration.
  tulip: Properly check dma mapping result
  net: sh_eth: fix incorrect RX length error if R8A7740
  ip_tunnel: remove __net_init/exit from exported functions
  drivers: net: davinci_mdio: restore mdio clk divider in mdio resume
  drivers: net: davinci_mdio: moving mdio resume earlier than cpsw ethernet driver
  net/ipv4: ip_vti clear skb cb before tunneling.
  tg3: Wait for boot code to finish after power on
  l2tp: Fix sendmsg() return value
  l2tp: Fix PPP header erasure and memory leak
  bonding: fix igmp_retrans type and two related races
  bonding: reset master mac on first enslave failure
  packet: packet_getname_spkt: make sure string is always 0-terminated
  net: ethernet: stmicro: stmmac: Fix compile error when STMMAC_XMIT_DEBUG used
  be2net: Fix 32-bit DMA Mask handling
  xen-netback: don't de-reference vif pointer after having called xenvif_put()
  macvlan: don't touch promisc without passthrough
  batman-adv: Don't handle address updates when bla is disabled
  batman-adv: forward late OGMs from best next hop
  ...
parents 5938930e c5c7774d
...@@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) ...@@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
struct net_device *bond_dev, *vlan_dev, *upper_dev; struct net_device *bond_dev, *vlan_dev, *upper_dev;
struct vlan_entry *vlan; struct vlan_entry *vlan;
rcu_read_lock();
read_lock(&bond->lock); read_lock(&bond->lock);
rcu_read_lock();
bond_dev = bond->dev; bond_dev = bond->dev;
...@@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) ...@@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
if (vlan_dev) if (vlan_dev)
__bond_resend_igmp_join_requests(vlan_dev); __bond_resend_igmp_join_requests(vlan_dev);
} }
rcu_read_unlock();
if (--bond->igmp_retrans > 0) /* We use curr_slave_lock to protect against concurrent access to
* igmp_retrans from multiple running instances of this function and
* bond_change_active_slave
*/
write_lock_bh(&bond->curr_slave_lock);
if (bond->igmp_retrans > 1) {
bond->igmp_retrans--;
queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
}
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock); read_unlock(&bond->lock);
rcu_read_unlock();
} }
static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
...@@ -1957,6 +1964,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) ...@@ -1957,6 +1964,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
err_undo_flags: err_undo_flags:
bond_compute_features(bond); bond_compute_features(bond);
/* Enslave of first slave has failed and we need to fix master's mac */
if (bond->slave_cnt == 0 &&
ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr))
eth_hw_addr_random(bond_dev);
return res; return res;
} }
......
...@@ -225,7 +225,7 @@ struct bonding { ...@@ -225,7 +225,7 @@ struct bonding {
rwlock_t curr_slave_lock; rwlock_t curr_slave_lock;
u8 send_peer_notif; u8 send_peer_notif;
s8 setup_by_slave; s8 setup_by_slave;
s8 igmp_retrans; u8 igmp_retrans;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry; struct proc_dir_entry *proc_entry;
char proc_file_name[IFNAMSIZ]; char proc_file_name[IFNAMSIZ];
......
...@@ -1800,6 +1800,9 @@ static int tg3_poll_fw(struct tg3 *tp) ...@@ -1800,6 +1800,9 @@ static int tg3_poll_fw(struct tg3 *tp)
int i; int i;
u32 val; u32 val;
if (tg3_flag(tp, NO_FWARE_REPORTED))
return 0;
if (tg3_flag(tp, IS_SSB_CORE)) { if (tg3_flag(tp, IS_SSB_CORE)) {
/* We don't use firmware. */ /* We don't use firmware. */
return 0; return 0;
...@@ -10404,6 +10407,13 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy) ...@@ -10404,6 +10407,13 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
*/ */
static int tg3_init_hw(struct tg3 *tp, bool reset_phy) static int tg3_init_hw(struct tg3 *tp, bool reset_phy)
{ {
/* Chip may have been just powered on. If so, the boot code may still
* be running initialization. Wait for it to finish to avoid races in
* accessing the hardware.
*/
tg3_enable_register_access(tp);
tg3_poll_fw(tp);
tg3_switch_clocks(tp); tg3_switch_clocks(tp);
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
......
...@@ -76,6 +76,12 @@ int tulip_refill_rx(struct net_device *dev) ...@@ -76,6 +76,12 @@ int tulip_refill_rx(struct net_device *dev)
mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (dma_mapping_error(&tp->pdev->dev, mapping)) {
dev_kfree_skb(skb);
tp->rx_buffers[entry].skb = NULL;
break;
}
tp->rx_buffers[entry].mapping = mapping; tp->rx_buffers[entry].mapping = mapping;
tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping); tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
......
...@@ -4262,6 +4262,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) ...@@ -4262,6 +4262,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
netdev->features |= NETIF_F_HIGHDMA; netdev->features |= NETIF_F_HIGHDMA;
} else { } else {
status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (!status)
status = dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32));
if (status) { if (status) {
dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); dev_err(&pdev->dev, "Could not set PCI DMA Mask\n");
goto free_netdev; goto free_netdev;
......
...@@ -1401,16 +1401,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status) ...@@ -1401,16 +1401,23 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
desc_status = edmac_to_cpu(mdp, rxdesc->status); desc_status = edmac_to_cpu(mdp, rxdesc->status);
pkt_len = rxdesc->frame_length; pkt_len = rxdesc->frame_length;
#if defined(CONFIG_ARCH_R8A7740)
desc_status >>= 16;
#endif
if (--boguscnt < 0) if (--boguscnt < 0)
break; break;
if (!(desc_status & RDFEND)) if (!(desc_status & RDFEND))
ndev->stats.rx_length_errors++; ndev->stats.rx_length_errors++;
#if defined(CONFIG_ARCH_R8A7740)
/*
* In case of almost all GETHER/ETHERs, the Receive Frame State
* (RFS) bits in the Receive Descriptor 0 are from bit 9 to
* bit 0. However, in case of the R8A7740's GETHER, the RFS
* bits are from bit 25 to bit 16. So, the driver needs right
* shifting by 16.
*/
desc_status >>= 16;
#endif
if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
RD_RFS5 | RD_RFS6 | RD_RFS10)) { RD_RFS5 | RD_RFS6 | RD_RFS10)) {
ndev->stats.rx_errors++; ndev->stats.rx_errors++;
......
...@@ -1899,7 +1899,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1899,7 +1899,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
#ifdef STMMAC_XMIT_DEBUG #ifdef STMMAC_XMIT_DEBUG
if (netif_msg_pktdata(priv)) { if (netif_msg_pktdata(priv)) {
pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d" pr_info("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d",
__func__, (priv->cur_tx % txsize), __func__, (priv->cur_tx % txsize),
(priv->dirty_tx % txsize), entry, first, nfrags); (priv->dirty_tx % txsize), entry, first, nfrags);
if (priv->extend_desc) if (priv->extend_desc)
......
...@@ -459,15 +459,12 @@ static int davinci_mdio_suspend(struct device *dev) ...@@ -459,15 +459,12 @@ static int davinci_mdio_suspend(struct device *dev)
static int davinci_mdio_resume(struct device *dev) static int davinci_mdio_resume(struct device *dev)
{ {
struct davinci_mdio_data *data = dev_get_drvdata(dev); struct davinci_mdio_data *data = dev_get_drvdata(dev);
u32 ctrl;
pm_runtime_get_sync(data->dev); pm_runtime_get_sync(data->dev);
spin_lock(&data->lock); spin_lock(&data->lock);
/* restart the scan state machine */ /* restart the scan state machine */
ctrl = __raw_readl(&data->regs->control); __davinci_mdio_reset(data);
ctrl |= CONTROL_ENABLE;
__raw_writel(ctrl, &data->regs->control);
data->suspended = false; data->suspended = false;
spin_unlock(&data->lock); spin_unlock(&data->lock);
...@@ -476,8 +473,8 @@ static int davinci_mdio_resume(struct device *dev) ...@@ -476,8 +473,8 @@ static int davinci_mdio_resume(struct device *dev)
} }
static const struct dev_pm_ops davinci_mdio_pm_ops = { static const struct dev_pm_ops davinci_mdio_pm_ops = {
.suspend = davinci_mdio_suspend, .suspend_late = davinci_mdio_suspend,
.resume = davinci_mdio_resume, .resume_early = davinci_mdio_resume,
}; };
static const struct of_device_id davinci_mdio_of_mtable[] = { static const struct of_device_id davinci_mdio_of_mtable[] = {
......
...@@ -853,18 +853,24 @@ static int macvlan_changelink(struct net_device *dev, ...@@ -853,18 +853,24 @@ static int macvlan_changelink(struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[]) struct nlattr *tb[], struct nlattr *data[])
{ {
struct macvlan_dev *vlan = netdev_priv(dev); struct macvlan_dev *vlan = netdev_priv(dev);
if (data && data[IFLA_MACVLAN_MODE])
vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
if (data && data[IFLA_MACVLAN_FLAGS]) { if (data && data[IFLA_MACVLAN_FLAGS]) {
__u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC; bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC;
if (vlan->port->passthru && promisc) {
if (promisc && (flags & MACVLAN_FLAG_NOPROMISC)) int err;
dev_set_promiscuity(vlan->lowerdev, -1);
else if (promisc && !(flags & MACVLAN_FLAG_NOPROMISC)) if (flags & MACVLAN_FLAG_NOPROMISC)
dev_set_promiscuity(vlan->lowerdev, 1); err = dev_set_promiscuity(vlan->lowerdev, -1);
else
err = dev_set_promiscuity(vlan->lowerdev, 1);
if (err < 0)
return err;
}
vlan->flags = flags; vlan->flags = flags;
} }
if (data && data[IFLA_MACVLAN_MODE])
vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
return 0; return 0;
} }
......
...@@ -662,7 +662,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) ...@@ -662,7 +662,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
{ {
struct xenvif *vif = NULL, *tmp; struct xenvif *vif = NULL, *tmp;
s8 status; s8 status;
u16 irq, flags; u16 flags;
struct xen_netif_rx_response *resp; struct xen_netif_rx_response *resp;
struct sk_buff_head rxq; struct sk_buff_head rxq;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -771,13 +771,13 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) ...@@ -771,13 +771,13 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
sco->meta_slots_used); sco->meta_slots_used);
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->rx, ret); RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&vif->rx, ret);
irq = vif->irq;
if (ret && list_empty(&vif->notify_list))
list_add_tail(&vif->notify_list, &notify);
xenvif_notify_tx_completion(vif); xenvif_notify_tx_completion(vif);
xenvif_put(vif); if (ret && list_empty(&vif->notify_list))
list_add_tail(&vif->notify_list, &notify);
else
xenvif_put(vif);
npo.meta_cons += sco->meta_slots_used; npo.meta_cons += sco->meta_slots_used;
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
...@@ -785,6 +785,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk) ...@@ -785,6 +785,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
list_for_each_entry_safe(vif, tmp, &notify, notify_list) { list_for_each_entry_safe(vif, tmp, &notify, notify_list) {
notify_remote_via_irq(vif->irq); notify_remote_via_irq(vif->irq);
list_del_init(&vif->notify_list); list_del_init(&vif->notify_list);
xenvif_put(vif);
} }
/* More work to do? */ /* More work to do? */
......
...@@ -2040,6 +2040,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) ...@@ -2040,6 +2040,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
netiucv_setup_netdevice); netiucv_setup_netdevice);
if (!dev) if (!dev)
return NULL; return NULL;
rtnl_lock();
if (dev_alloc_name(dev, dev->name) < 0) if (dev_alloc_name(dev, dev->name) < 0)
goto out_netdev; goto out_netdev;
...@@ -2061,6 +2062,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) ...@@ -2061,6 +2062,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
out_fsm: out_fsm:
kfree_fsm(privptr->fsm); kfree_fsm(privptr->fsm);
out_netdev: out_netdev:
rtnl_unlock();
free_netdev(dev); free_netdev(dev);
return NULL; return NULL;
} }
...@@ -2100,6 +2102,7 @@ static ssize_t conn_write(struct device_driver *drv, ...@@ -2100,6 +2102,7 @@ static ssize_t conn_write(struct device_driver *drv,
rc = netiucv_register_device(dev); rc = netiucv_register_device(dev);
if (rc) { if (rc) {
rtnl_unlock();
IUCV_DBF_TEXT_(setup, 2, IUCV_DBF_TEXT_(setup, 2,
"ret %d from netiucv_register_device\n", rc); "ret %d from netiucv_register_device\n", rc);
goto out_free_ndev; goto out_free_ndev;
...@@ -2109,7 +2112,8 @@ static ssize_t conn_write(struct device_driver *drv, ...@@ -2109,7 +2112,8 @@ static ssize_t conn_write(struct device_driver *drv,
priv = netdev_priv(dev); priv = netdev_priv(dev);
SET_NETDEV_DEV(dev, priv->dev); SET_NETDEV_DEV(dev, priv->dev);
rc = register_netdev(dev); rc = register_netdevice(dev);
rtnl_unlock();
if (rc) if (rc)
goto out_unreg; goto out_unreg;
......
...@@ -95,10 +95,10 @@ struct ip_tunnel_net { ...@@ -95,10 +95,10 @@ struct ip_tunnel_net {
int ip_tunnel_init(struct net_device *dev); int ip_tunnel_init(struct net_device *dev);
void ip_tunnel_uninit(struct net_device *dev); void ip_tunnel_uninit(struct net_device *dev);
void ip_tunnel_dellink(struct net_device *dev, struct list_head *head); void ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
struct rtnl_link_ops *ops, char *devname); struct rtnl_link_ops *ops, char *devname);
void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn); void ip_tunnel_delete_net(struct ip_tunnel_net *itn);
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
const struct iphdr *tnl_params); const struct iphdr *tnl_params);
......
...@@ -29,6 +29,21 @@ ...@@ -29,6 +29,21 @@
#include "bat_algo.h" #include "bat_algo.h"
#include "network-coding.h" #include "network-coding.h"
/**
* batadv_dup_status - duplicate status
* @BATADV_NO_DUP: the packet is a duplicate
* @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the
* neighbor)
* @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor
* @BATADV_PROTECTED: originator is currently protected (after reboot)
*/
enum batadv_dup_status {
BATADV_NO_DUP = 0,
BATADV_ORIG_DUP,
BATADV_NEIGH_DUP,
BATADV_PROTECTED,
};
static struct batadv_neigh_node * static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr, const uint8_t *neigh_addr,
...@@ -650,7 +665,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, ...@@ -650,7 +665,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
const struct batadv_ogm_packet *batadv_ogm_packet, const struct batadv_ogm_packet *batadv_ogm_packet,
struct batadv_hard_iface *if_incoming, struct batadv_hard_iface *if_incoming,
const unsigned char *tt_buff, const unsigned char *tt_buff,
int is_duplicate) enum batadv_dup_status dup_status)
{ {
struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
struct batadv_neigh_node *router = NULL; struct batadv_neigh_node *router = NULL;
...@@ -676,7 +691,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, ...@@ -676,7 +691,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
continue; continue;
} }
if (is_duplicate) if (dup_status != BATADV_NO_DUP)
continue; continue;
spin_lock_bh(&tmp_neigh_node->lq_update_lock); spin_lock_bh(&tmp_neigh_node->lq_update_lock);
...@@ -718,7 +733,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, ...@@ -718,7 +733,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv);
spin_unlock_bh(&neigh_node->lq_update_lock); spin_unlock_bh(&neigh_node->lq_update_lock);
if (!is_duplicate) { if (dup_status == BATADV_NO_DUP) {
orig_node->last_ttl = batadv_ogm_packet->header.ttl; orig_node->last_ttl = batadv_ogm_packet->header.ttl;
neigh_node->last_ttl = batadv_ogm_packet->header.ttl; neigh_node->last_ttl = batadv_ogm_packet->header.ttl;
} }
...@@ -902,15 +917,16 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, ...@@ -902,15 +917,16 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
return ret; return ret;
} }
/* processes a batman packet for all interfaces, adjusts the sequence number and /**
* finds out whether it is a duplicate. * batadv_iv_ogm_update_seqnos - process a batman packet for all interfaces,
* returns: * adjust the sequence number and find out whether it is a duplicate
* 1 the packet is a duplicate * @ethhdr: ethernet header of the packet
* 0 the packet has not yet been received * @batadv_ogm_packet: OGM packet to be considered
* -1 the packet is old and has been received while the seqno window * @if_incoming: interface on which the OGM packet was received
* was protected. Caller should drop it. *
* Returns duplicate status as enum batadv_dup_status
*/ */
static int static enum batadv_dup_status
batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
const struct batadv_ogm_packet *batadv_ogm_packet, const struct batadv_ogm_packet *batadv_ogm_packet,
const struct batadv_hard_iface *if_incoming) const struct batadv_hard_iface *if_incoming)
...@@ -918,17 +934,18 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, ...@@ -918,17 +934,18 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct batadv_orig_node *orig_node; struct batadv_orig_node *orig_node;
struct batadv_neigh_node *tmp_neigh_node; struct batadv_neigh_node *tmp_neigh_node;
int is_duplicate = 0; int is_dup;
int32_t seq_diff; int32_t seq_diff;
int need_update = 0; int need_update = 0;
int set_mark, ret = -1; int set_mark;
enum batadv_dup_status ret = BATADV_NO_DUP;
uint32_t seqno = ntohl(batadv_ogm_packet->seqno); uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
uint8_t *neigh_addr; uint8_t *neigh_addr;
uint8_t packet_count; uint8_t packet_count;
orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
if (!orig_node) if (!orig_node)
return 0; return BATADV_NO_DUP;
spin_lock_bh(&orig_node->ogm_cnt_lock); spin_lock_bh(&orig_node->ogm_cnt_lock);
seq_diff = seqno - orig_node->last_real_seqno; seq_diff = seqno - orig_node->last_real_seqno;
...@@ -936,22 +953,29 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, ...@@ -936,22 +953,29 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
/* signalize caller that the packet is to be dropped. */ /* signalize caller that the packet is to be dropped. */
if (!hlist_empty(&orig_node->neigh_list) && if (!hlist_empty(&orig_node->neigh_list) &&
batadv_window_protected(bat_priv, seq_diff, batadv_window_protected(bat_priv, seq_diff,
&orig_node->batman_seqno_reset)) &orig_node->batman_seqno_reset)) {
ret = BATADV_PROTECTED;
goto out; goto out;
}
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(tmp_neigh_node, hlist_for_each_entry_rcu(tmp_neigh_node,
&orig_node->neigh_list, list) { &orig_node->neigh_list, list) {
is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits,
orig_node->last_real_seqno,
seqno);
neigh_addr = tmp_neigh_node->addr; neigh_addr = tmp_neigh_node->addr;
is_dup = batadv_test_bit(tmp_neigh_node->real_bits,
orig_node->last_real_seqno,
seqno);
if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
tmp_neigh_node->if_incoming == if_incoming) tmp_neigh_node->if_incoming == if_incoming) {
set_mark = 1; set_mark = 1;
else if (is_dup)
ret = BATADV_NEIGH_DUP;
} else {
set_mark = 0; set_mark = 0;
if (is_dup && (ret != BATADV_NEIGH_DUP))
ret = BATADV_ORIG_DUP;
}
/* if the window moved, set the update flag. */ /* if the window moved, set the update flag. */
need_update |= batadv_bit_get_packet(bat_priv, need_update |= batadv_bit_get_packet(bat_priv,
...@@ -971,8 +995,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, ...@@ -971,8 +995,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
orig_node->last_real_seqno = seqno; orig_node->last_real_seqno = seqno;
} }
ret = is_duplicate;
out: out:
spin_unlock_bh(&orig_node->ogm_cnt_lock); spin_unlock_bh(&orig_node->ogm_cnt_lock);
batadv_orig_node_free_ref(orig_node); batadv_orig_node_free_ref(orig_node);
...@@ -994,7 +1016,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -994,7 +1016,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
int is_broadcast = 0, is_bidirect; int is_broadcast = 0, is_bidirect;
bool is_single_hop_neigh = false; bool is_single_hop_neigh = false;
bool is_from_best_next_hop = false; bool is_from_best_next_hop = false;
int is_duplicate, sameseq, simlar_ttl; int sameseq, similar_ttl;
enum batadv_dup_status dup_status;
uint32_t if_incoming_seqno; uint32_t if_incoming_seqno;
uint8_t *prev_sender; uint8_t *prev_sender;
...@@ -1138,10 +1161,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -1138,10 +1161,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
if (!orig_node) if (!orig_node)
return; return;
is_duplicate = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet, dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet,
if_incoming); if_incoming);
if (is_duplicate == -1) { if (dup_status == BATADV_PROTECTED) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: packet within seqno protection time (sender: %pM)\n", "Drop packet: packet within seqno protection time (sender: %pM)\n",
ethhdr->h_source); ethhdr->h_source);
...@@ -1211,11 +1234,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -1211,11 +1234,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
* seqno and similar ttl as the non-duplicate * seqno and similar ttl as the non-duplicate
*/ */
sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno);
simlar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl; similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
if (is_bidirect && (!is_duplicate || (sameseq && simlar_ttl))) if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
(sameseq && similar_ttl)))
batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
batadv_ogm_packet, if_incoming, batadv_ogm_packet, if_incoming,
tt_buff, is_duplicate); tt_buff, dup_status);
/* is single hop (direct) neighbor */ /* is single hop (direct) neighbor */
if (is_single_hop_neigh) { if (is_single_hop_neigh) {
...@@ -1236,7 +1260,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -1236,7 +1260,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
goto out_neigh; goto out_neigh;
} }
if (is_duplicate) { if (dup_status == BATADV_NEIGH_DUP) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: duplicate packet received\n"); "Drop packet: duplicate packet received\n");
goto out_neigh; goto out_neigh;
......
...@@ -1067,6 +1067,10 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, ...@@ -1067,6 +1067,10 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN));
bat_priv->bla.claim_dest.group = group; bat_priv->bla.claim_dest.group = group;
/* purge everything when bridge loop avoidance is turned off */
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
oldif = NULL;
if (!oldif) { if (!oldif) {
batadv_bla_purge_claims(bat_priv, NULL, 1); batadv_bla_purge_claims(bat_priv, NULL, 1);
batadv_bla_purge_backbone_gw(bat_priv, 1); batadv_bla_purge_backbone_gw(bat_priv, 1);
......
...@@ -582,10 +582,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj, ...@@ -582,10 +582,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
(strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0)) (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
goto out; goto out;
if (!rtnl_trylock()) { rtnl_lock();
ret = -ERESTARTSYS;
goto out;
}
if (status_tmp == BATADV_IF_NOT_IN_USE) { if (status_tmp == BATADV_IF_NOT_IN_USE) {
batadv_hardif_disable_interface(hard_iface, batadv_hardif_disable_interface(hard_iface,
......
...@@ -853,7 +853,7 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) ...@@ -853,7 +853,7 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
} }
EXPORT_SYMBOL_GPL(ip_tunnel_dellink); EXPORT_SYMBOL_GPL(ip_tunnel_dellink);
int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
struct rtnl_link_ops *ops, char *devname) struct rtnl_link_ops *ops, char *devname)
{ {
struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id); struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id);
...@@ -899,7 +899,7 @@ static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head) ...@@ -899,7 +899,7 @@ static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head)
unregister_netdevice_queue(itn->fb_tunnel_dev, head); unregister_netdevice_queue(itn->fb_tunnel_dev, head);
} }
void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn) void ip_tunnel_delete_net(struct ip_tunnel_net *itn)
{ {
LIST_HEAD(list); LIST_HEAD(list);
......
...@@ -361,8 +361,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -361,8 +361,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
tunnel->err_count = 0; tunnel->err_count = 0;
} }
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
IPSKB_REROUTED);
skb_dst_drop(skb); skb_dst_drop(skb);
skb_dst_set(skb, &rt->dst); skb_dst_set(skb, &rt->dst);
nf_reset(skb); nf_reset(skb);
......
...@@ -346,19 +346,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh ...@@ -346,19 +346,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
skb_put(skb, 2); skb_put(skb, 2);
/* Copy user data into skb */ /* Copy user data into skb */
error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov,
total_len);
if (error < 0) { if (error < 0) {
kfree_skb(skb); kfree_skb(skb);
goto error_put_sess_tun; goto error_put_sess_tun;
} }
skb_put(skb, total_len);
l2tp_xmit_skb(session, skb, session->hdr_len); l2tp_xmit_skb(session, skb, session->hdr_len);
sock_put(ps->tunnel_sock); sock_put(ps->tunnel_sock);
sock_put(sk); sock_put(sk);
return error; return total_len;
error_put_sess_tun: error_put_sess_tun:
sock_put(ps->tunnel_sock); sock_put(ps->tunnel_sock);
......
...@@ -2851,12 +2851,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, ...@@ -2851,12 +2851,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
uaddr->sa_family = AF_PACKET; uaddr->sa_family = AF_PACKET;
memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data));
rcu_read_lock(); rcu_read_lock();
dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
if (dev) if (dev)
strncpy(uaddr->sa_data, dev->name, 14); strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data));
else
memset(uaddr->sa_data, 0, 14);
rcu_read_unlock(); rcu_read_unlock();
*uaddr_len = sizeof(*uaddr); *uaddr_len = sizeof(*uaddr);
......
...@@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, ...@@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary,
*/ */
void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
{ {
memset(q, 0, sizeof(struct sctp_outq));
q->asoc = asoc; q->asoc = asoc;
INIT_LIST_HEAD(&q->out_chunk_list); INIT_LIST_HEAD(&q->out_chunk_list);
INIT_LIST_HEAD(&q->control_chunk_list); INIT_LIST_HEAD(&q->control_chunk_list);
...@@ -213,11 +215,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) ...@@ -213,11 +215,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
INIT_LIST_HEAD(&q->sacked); INIT_LIST_HEAD(&q->sacked);
INIT_LIST_HEAD(&q->abandoned); INIT_LIST_HEAD(&q->abandoned);
q->fast_rtx = 0;
q->outstanding_bytes = 0;
q->empty = 1; q->empty = 1;
q->cork = 0;
q->out_qlen = 0;
} }
/* Free the outqueue structure and any related pending chunks. /* Free the outqueue structure and any related pending chunks.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment